diff options
Diffstat (limited to 'Source/WebCore/inspector')
155 files changed, 10621 insertions, 20734 deletions
diff --git a/Source/WebCore/inspector/CommandLineAPIHost.cpp b/Source/WebCore/inspector/CommandLineAPIHost.cpp index 92f1d27d2..2e5f2cdb3 100644 --- a/Source/WebCore/inspector/CommandLineAPIHost.cpp +++ b/Source/WebCore/inspector/CommandLineAPIHost.cpp @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,50 +31,34 @@ #include "config.h" #include "CommandLineAPIHost.h" -#if ENABLE(INSPECTOR) - -#include "Element.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "HTMLFrameOwnerElement.h" -#include "InspectorClient.h" -#include "InspectorConsoleAgent.h" +#include "Database.h" #include "InspectorDOMAgent.h" #include "InspectorDOMStorageAgent.h" #include "InspectorDatabaseAgent.h" -#include "InspectorWebFrontendDispatchers.h" +#include "JSCommandLineAPIHost.h" +#include "JSDOMGlobalObject.h" #include "Pasteboard.h" #include "Storage.h" -#include "markup.h" -#include <bindings/ScriptValue.h> #include <inspector/InspectorValues.h> #include <inspector/agents/InspectorAgent.h> +#include <inspector/agents/InspectorConsoleAgent.h> +#include <runtime/JSCInlines.h> #include <wtf/RefPtr.h> #include <wtf/StdLibExtras.h> -#if ENABLE(SQL_DATABASE) -#include "Database.h" -#endif - +using namespace JSC; using namespace Inspector; namespace WebCore { -PassRefPtr<CommandLineAPIHost> CommandLineAPIHost::create() +Ref<CommandLineAPIHost> CommandLineAPIHost::create() { - return adoptRef(new CommandLineAPIHost); + return adoptRef(*new CommandLineAPIHost); } CommandLineAPIHost::CommandLineAPIHost() - : m_inspectorAgent(nullptr) - , m_consoleAgent(nullptr) - , m_domAgent(nullptr) - , m_domStorageAgent(nullptr) -#if ENABLE(SQL_DATABASE) - , m_databaseAgent(nullptr) -#endif + : m_inspectedObject(std::make_unique<InspectableObject>()) { - m_defaultInspectableObject = adoptPtr(new InspectableObject); } CommandLineAPIHost::~CommandLineAPIHost() @@ -87,17 +71,20 @@ void CommandLineAPIHost::disconnect() m_consoleAgent = nullptr; m_domAgent = nullptr; m_domStorageAgent = nullptr; -#if ENABLE(SQL_DATABASE) m_databaseAgent = nullptr; -#endif } -void CommandLineAPIHost::inspectImpl(PassRefPtr<InspectorValue> object, PassRefPtr<InspectorValue> hints) +void CommandLineAPIHost::inspectImpl(RefPtr<InspectorValue>&& object, RefPtr<InspectorValue>&& hints) { - if (m_inspectorAgent) { - RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> remoteObject = Inspector::TypeBuilder::Runtime::RemoteObject::runtimeCast(object); - m_inspectorAgent->inspect(remoteObject, hints->asObject()); - } + if (!m_inspectorAgent) + return; + + RefPtr<InspectorObject> hintsObject; + if (!hints->asObject(hintsObject)) + return; + + auto remoteObject = BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(WTFMove(object)); + m_inspectorAgent->inspect(WTFMove(remoteObject), WTFMove(hintsObject)); } void CommandLineAPIHost::getEventListenersImpl(Node* node, Vector<EventListenerInfo>& listenersArray) @@ -109,8 +96,8 @@ void CommandLineAPIHost::getEventListenersImpl(Node* node, Vector<EventListenerI void CommandLineAPIHost::clearConsoleMessages() { if (m_consoleAgent) { - ErrorString error; - m_consoleAgent->clearMessages(&error); + ErrorString unused; + m_consoleAgent->clearMessages(unused); } } @@ -119,39 +106,27 @@ void CommandLineAPIHost::copyText(const String& text) Pasteboard::createForCopyAndPaste()->writePlainText(text, Pasteboard::CannotSmartReplace); } -Deprecated::ScriptValue CommandLineAPIHost::InspectableObject::get(JSC::ExecState*) +JSC::JSValue CommandLineAPIHost::InspectableObject::get(JSC::ExecState&) { - return Deprecated::ScriptValue(); -}; - -void CommandLineAPIHost::addInspectedObject(PassOwnPtr<CommandLineAPIHost::InspectableObject> object) -{ - m_inspectedObjects.insert(0, object); - while (m_inspectedObjects.size() > 5) - m_inspectedObjects.removeLast(); + return { }; } -void CommandLineAPIHost::clearInspectedObjects() +void CommandLineAPIHost::addInspectedObject(std::unique_ptr<CommandLineAPIHost::InspectableObject> object) { - m_inspectedObjects.clear(); + m_inspectedObject = WTFMove(object); } -CommandLineAPIHost::InspectableObject* CommandLineAPIHost::inspectedObject(unsigned index) +CommandLineAPIHost::InspectableObject* CommandLineAPIHost::inspectedObject() { - if (index >= m_inspectedObjects.size()) - return m_defaultInspectableObject.get(); - - return m_inspectedObjects[index].get(); + return m_inspectedObject.get(); } -#if ENABLE(SQL_DATABASE) String CommandLineAPIHost::databaseIdImpl(Database* database) { if (m_databaseAgent) return m_databaseAgent->databaseId(database); return String(); } -#endif String CommandLineAPIHost::storageIdImpl(Storage* storage) { @@ -160,6 +135,24 @@ String CommandLineAPIHost::storageIdImpl(Storage* storage) return String(); } -} // namespace WebCore +JSValue CommandLineAPIHost::wrapper(ExecState* exec, JSDOMGlobalObject* globalObject) +{ + JSValue value = m_wrappers.getWrapper(globalObject); + if (value) + return value; + + JSObject* prototype = JSCommandLineAPIHost::createPrototype(exec->vm(), globalObject); + Structure* structure = JSCommandLineAPIHost::createStructure(exec->vm(), globalObject, prototype); + JSCommandLineAPIHost* commandLineAPIHost = JSCommandLineAPIHost::create(structure, globalObject, makeRef(*this)); + m_wrappers.addWrapper(globalObject, commandLineAPIHost); + + return commandLineAPIHost; +} -#endif // ENABLE(INSPECTOR) +void CommandLineAPIHost::clearAllWrappers() +{ + m_wrappers.clearAllWrappers(); + m_inspectedObject = std::make_unique<InspectableObject>(); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/CommandLineAPIHost.h b/Source/WebCore/inspector/CommandLineAPIHost.h index 6f9025f08..3bcc07e9a 100644 --- a/Source/WebCore/inspector/CommandLineAPIHost.h +++ b/Source/WebCore/inspector/CommandLineAPIHost.h @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,21 +27,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CommandLineAPIHost_h -#define CommandLineAPIHost_h +#pragma once -#include "ConsoleTypes.h" -#include "ScriptState.h" +#include <inspector/PerGlobalObjectWrapperWorld.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> -namespace Deprecated { -class ScriptValue; +namespace JSC { +class JSValue; } namespace Inspector { class InspectorAgent; +class InspectorConsoleAgent; class InspectorObject; class InspectorValue; } @@ -49,10 +48,10 @@ class InspectorValue; namespace WebCore { class Database; -class InspectorConsoleAgent; class InspectorDOMAgent; class InspectorDOMStorageAgent; class InspectorDatabaseAgent; +class JSDOMGlobalObject; class Node; class Storage; @@ -60,25 +59,21 @@ struct EventListenerInfo; class CommandLineAPIHost : public RefCounted<CommandLineAPIHost> { public: - static PassRefPtr<CommandLineAPIHost> create(); + static Ref<CommandLineAPIHost> create(); ~CommandLineAPIHost(); void init(Inspector::InspectorAgent* inspectorAgent - , InspectorConsoleAgent* consoleAgent - , InspectorDOMAgent* domAgent - , InspectorDOMStorageAgent* domStorageAgent -#if ENABLE(SQL_DATABASE) - , InspectorDatabaseAgent* databaseAgent -#endif + , Inspector::InspectorConsoleAgent* consoleAgent + , InspectorDOMAgent* domAgent + , InspectorDOMStorageAgent* domStorageAgent + , InspectorDatabaseAgent* databaseAgent ) { m_inspectorAgent = inspectorAgent; m_consoleAgent = consoleAgent; m_domAgent = domAgent; m_domStorageAgent = domStorageAgent; -#if ENABLE(SQL_DATABASE) m_databaseAgent = databaseAgent; -#endif } void disconnect(); @@ -89,36 +84,32 @@ public: class InspectableObject { WTF_MAKE_FAST_ALLOCATED; public: - virtual Deprecated::ScriptValue get(JSC::ExecState*); + virtual JSC::JSValue get(JSC::ExecState&); virtual ~InspectableObject() { } }; - void addInspectedObject(PassOwnPtr<InspectableObject>); - void clearInspectedObjects(); - InspectableObject* inspectedObject(unsigned index); - void inspectImpl(PassRefPtr<Inspector::InspectorValue> objectToInspect, PassRefPtr<Inspector::InspectorValue> hints); + void addInspectedObject(std::unique_ptr<InspectableObject>); + InspectableObject* inspectedObject(); + void inspectImpl(RefPtr<Inspector::InspectorValue>&& objectToInspect, RefPtr<Inspector::InspectorValue>&& hints); void getEventListenersImpl(Node*, Vector<EventListenerInfo>& listenersArray); -#if ENABLE(SQL_DATABASE) String databaseIdImpl(Database*); -#endif String storageIdImpl(Storage*); + JSC::JSValue wrapper(JSC::ExecState*, JSDOMGlobalObject*); + void clearAllWrappers(); + private: CommandLineAPIHost(); - Inspector::InspectorAgent* m_inspectorAgent; - InspectorConsoleAgent* m_consoleAgent; - InspectorDOMAgent* m_domAgent; - InspectorDOMStorageAgent* m_domStorageAgent; -#if ENABLE(SQL_DATABASE) - InspectorDatabaseAgent* m_databaseAgent; -#endif + Inspector::InspectorAgent* m_inspectorAgent {nullptr}; + Inspector::InspectorConsoleAgent* m_consoleAgent {nullptr}; + InspectorDOMAgent* m_domAgent {nullptr}; + InspectorDOMStorageAgent* m_domStorageAgent {nullptr}; + InspectorDatabaseAgent* m_databaseAgent {nullptr}; - Vector<OwnPtr<InspectableObject>> m_inspectedObjects; - OwnPtr<InspectableObject> m_defaultInspectableObject; + std::unique_ptr<InspectableObject> m_inspectedObject; // $0 + Inspector::PerGlobalObjectWrapperWorld m_wrappers; }; } // namespace WebCore - -#endif // !defined(CommandLineAPIHost_h) diff --git a/Source/WebCore/inspector/CommandLineAPIHost.idl b/Source/WebCore/inspector/CommandLineAPIHost.idl index 228426c16..5a16155d3 100644 --- a/Source/WebCore/inspector/CommandLineAPIHost.idl +++ b/Source/WebCore/inspector/CommandLineAPIHost.idl @@ -32,13 +32,12 @@ [ NoInterfaceObject, - Conditional=INSPECTOR, ImplementationLacksVTable ] interface CommandLineAPIHost { void clearConsoleMessages(); void copyText(DOMString text); [Custom] void inspect(any objectId, any hints); - [Custom] any inspectedObject(int num); + [Custom] any inspectedObject(); [Custom] Array getEventListeners(Node node); [Custom] DOMString databaseId(any database); [Custom] DOMString storageId(any storage); diff --git a/Source/WebCore/inspector/CommandLineAPIModule.cpp b/Source/WebCore/inspector/CommandLineAPIModule.cpp index 90af6503f..e66ae8620 100644 --- a/Source/WebCore/inspector/CommandLineAPIModule.cpp +++ b/Source/WebCore/inspector/CommandLineAPIModule.cpp @@ -26,11 +26,10 @@ #include "config.h" #include "CommandLineAPIModule.h" -#if ENABLE(INSPECTOR) - #include "CommandLineAPIModuleSource.h" -#include "JSCommandLineAPIHost.h" -#include "PageInjectedScriptManager.h" +#include "JSDOMGlobalObject.h" +#include "WebInjectedScriptManager.h" +#include <heap/HeapInlines.h> #include <inspector/InjectedScript.h> using namespace JSC; @@ -38,31 +37,30 @@ using namespace Inspector; namespace WebCore { -CommandLineAPIModule::CommandLineAPIModule() - : InjectedScriptModule(ASCIILiteral("CommandLineAPI")) +void CommandLineAPIModule::injectIfNeeded(InjectedScriptManager* injectedScriptManager, const InjectedScript& injectedScript) { + CommandLineAPIModule module; + module.ensureInjected(injectedScriptManager, injectedScript); } -void CommandLineAPIModule::injectIfNeeded(InjectedScriptManager* injectedScriptManager, InjectedScript injectedScript) +CommandLineAPIModule::CommandLineAPIModule() + : InjectedScriptModule(ASCIILiteral("CommandLineAPI")) { - CommandLineAPIModule module; - module.ensureInjected(injectedScriptManager, injectedScript); } String CommandLineAPIModule::source() const { - return String(reinterpret_cast<const char*>(CommandLineAPIModuleSource_js), sizeof(CommandLineAPIModuleSource_js)); + return StringImpl::createWithoutCopying(CommandLineAPIModuleSource_js, sizeof(CommandLineAPIModuleSource_js)); } -JSC::JSValue CommandLineAPIModule::host(InjectedScriptManager* injectedScriptManager, JSC::ExecState* exec) const +JSValue CommandLineAPIModule::host(InjectedScriptManager* injectedScriptManager, ExecState* exec) const { - // CommandLineAPIModule should only ever be used by a PageInjectedScriptManager. - PageInjectedScriptManager* pageInjectedScriptManager = static_cast<PageInjectedScriptManager*>(injectedScriptManager); + // CommandLineAPIModule should only ever be used by a WebInjectedScriptManager. + WebInjectedScriptManager* pageInjectedScriptManager = static_cast<WebInjectedScriptManager*>(injectedScriptManager); ASSERT(pageInjectedScriptManager->commandLineAPIHost()); + JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()); - return toJS(exec, globalObject, pageInjectedScriptManager->commandLineAPIHost()); + return pageInjectedScriptManager->commandLineAPIHost()->wrapper(exec, globalObject); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/CommandLineAPIModule.h b/Source/WebCore/inspector/CommandLineAPIModule.h index 1f640e02e..fab392703 100644 --- a/Source/WebCore/inspector/CommandLineAPIModule.h +++ b/Source/WebCore/inspector/CommandLineAPIModule.h @@ -23,28 +23,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CommandLineAPIModule_h -#define CommandLineAPIModule_h +#pragma once #include <inspector/InjectedScriptModule.h> -#if ENABLE(INSPECTOR) - namespace WebCore { class CommandLineAPIModule final : public Inspector::InjectedScriptModule { public: CommandLineAPIModule(); - virtual String source() const override; - virtual JSC::JSValue host(Inspector::InjectedScriptManager*, JSC::ExecState*) const override; - virtual bool returnsObject() const override { return false; } + String source() const override; + JSC::JSValue host(Inspector::InjectedScriptManager*, JSC::ExecState*) const override; - static void injectIfNeeded(Inspector::InjectedScriptManager*, Inspector::InjectedScript); + static void injectIfNeeded(Inspector::InjectedScriptManager*, const Inspector::InjectedScript&); }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(CommandLineAPIModule_h) diff --git a/Source/WebCore/inspector/CommandLineAPIModuleSource.js b/Source/WebCore/inspector/CommandLineAPIModuleSource.js index 0e8baccb1..93ac8e970 100644 --- a/Source/WebCore/inspector/CommandLineAPIModuleSource.js +++ b/Source/WebCore/inspector/CommandLineAPIModuleSource.js @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,6 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +//# sourceURL=__InjectedScript_CommandLineAPIModuleSource.js + /** * @param {InjectedScriptHost} InjectedScriptHost * @param {Window} inspectedWindow @@ -35,40 +37,13 @@ */ (function (InjectedScriptHost, inspectedWindow, injectedScriptId, injectedScript, CommandLineAPIHost) { -/** - * @param {Arguments} array - * @param {number=} index - * @return {Array.<*>} - */ -function slice(array, index) -{ - var result = []; - for (var i = index || 0; i < array.length; ++i) - result.push(array[i]); - return result; -} +// FIXME: <https://webkit.org/b/152294> Web Inspector: Parse InjectedScriptSource as a built-in to get guaranteed non-user-overriden built-ins -/** - * Please use this bind, not the one from Function.prototype - * @param {function(...)} func - * @param {Object} thisObject - * @param {...number} var_args - */ -function bind(func, thisObject, var_args) +function bind(func, thisObject, ...outerArgs) { - var args = slice(arguments, 2); - - /** - * @param {...number} var_args - */ - function bound(var_args) - { - return func.apply(thisObject, args.concat(slice(arguments))); - } - bound.toString = function() { - return "bound: " + func; + return function(...innerArgs) { + return func.apply(thisObject, outerArgs.concat(innerArgs)); }; - return bound; } /** @@ -78,50 +53,21 @@ function bind(func, thisObject, var_args) */ function CommandLineAPI(commandLineAPIImpl, callFrame) { - /** - * @param {string} member - * @return {boolean} - */ - function inScopeVariables(member) - { - if (!callFrame) - return false; - - var scopeChain = callFrame.scopeChain; - for (var i = 0; i < scopeChain.length; ++i) { - if (member in scopeChain[i]) - return true; - } - return false; - } + this.$_ = injectedScript._lastResult; + this.$exception = injectedScript._exceptionValue; - /** - * @param {string} name The name of the method for which a toString method should be generated. - * @return {function():string} - */ - function customToStringMethod(name) - { - return function () { return "function " + name + "() { [Command Line API] }"; }; - } + // $0 + this.__defineGetter__("$0", bind(commandLineAPIImpl._inspectedObject, commandLineAPIImpl)); - for (var i = 0; i < CommandLineAPI.members_.length; ++i) { - var member = CommandLineAPI.members_[i]; - if (member in inspectedWindow || inScopeVariables(member)) - continue; + // $1-$99 + for (let i = 1; i <= injectedScript._savedResults.length; ++i) + this.__defineGetter__("$" + i, bind(injectedScript._savedResult, injectedScript, i)); + // Command Line API methods. + for (let member of CommandLineAPI.members_) { this[member] = bind(commandLineAPIImpl[member], commandLineAPIImpl); - this[member].toString = customToStringMethod(member); + this[member].toString = function() { return "function " + member + "() { [Command Line API] }" }; } - - for (var i = 0; i < 5; ++i) { - var member = "$" + i; - if (member in inspectedWindow || inScopeVariables(member)) - continue; - - this.__defineGetter__("$" + i, bind(commandLineAPIImpl._inspectedObject, commandLineAPIImpl, i)); - } - - this.$_ = injectedScript._lastResult; } /** @@ -129,7 +75,7 @@ function CommandLineAPI(commandLineAPIImpl, callFrame) * @const */ CommandLineAPI.members_ = [ - "$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", + "$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", "table", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear", "getEventListeners" ]; @@ -156,7 +102,7 @@ CommandLineAPIImpl.prototype = { if (selector && selector[0] !== "#") { result = inspectedWindow.document.getElementById(selector); if (result) { - inspectedWindow.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")", selector ); + inspectedWindow.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")", selector); return null; } } @@ -170,8 +116,8 @@ CommandLineAPIImpl.prototype = { $$: function (selector, start) { if (this._canQuerySelectorOnNode(start)) - return start.querySelectorAll(selector); - return inspectedWindow.document.querySelectorAll(selector); + return Array.from(start.querySelectorAll(selector)); + return Array.from(inspectedWindow.document.querySelectorAll(selector)); }, /** @@ -180,7 +126,7 @@ CommandLineAPIImpl.prototype = { */ _canQuerySelectorOnNode: function(node) { - return !!node && InjectedScriptHost.type(node) === "node" && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE); + return !!node && InjectedScriptHost.subtype(node) === "node" && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE); }, /** @@ -240,6 +186,11 @@ CommandLineAPIImpl.prototype = { return inspectedWindow.console.profileEnd.apply(inspectedWindow.console, arguments) }, + table: function() + { + return inspectedWindow.console.table.apply(inspectedWindow.console, arguments) + }, + /** * @param {Object} object * @param {Array.<string>|string=} types @@ -279,9 +230,27 @@ CommandLineAPIImpl.prototype = { copy: function(object) { - if (injectedScript._subtype(object) === "node") - object = object.outerHTML; - CommandLineAPIHost.copyText(object); + var string; + var subtype = injectedScript._subtype(object); + if (subtype === "node") + string = object.outerHTML; + else if (subtype === "regexp") + string = "" + object; + else if (injectedScript.isPrimitiveValue(object)) + string = "" + object; + else if (typeof object === "symbol") + string = String(object); + else if (typeof object === "function") + string = "" + object; + else { + try { + string = JSON.stringify(object, null, " "); + } catch (e) { + string = "" + object; + } + } + + CommandLineAPIHost.copyText(string); }, clear: function() @@ -297,12 +266,9 @@ CommandLineAPIImpl.prototype = { return CommandLineAPIHost.getEventListeners(node); }, - /** - * @param {number} num - */ - _inspectedObject: function(num) + _inspectedObject: function() { - return CommandLineAPIHost.inspectedObject(num); + return CommandLineAPIHost.inspectedObject(); }, /** diff --git a/Source/WebCore/inspector/ConsoleMessage.cpp b/Source/WebCore/inspector/ConsoleMessage.cpp deleted file mode 100644 index d3b93ac5c..000000000 --- a/Source/WebCore/inspector/ConsoleMessage.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ConsoleMessage.h" - -#if ENABLE(INSPECTOR) - -#include "Console.h" -#include "IdentifiersFactory.h" -#include "ScriptArguments.h" -#include "ScriptCallFrame.h" -#include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" -#include <bindings/ScriptValue.h> -#include <inspector/InjectedScript.h> -#include <inspector/InjectedScriptManager.h> -#include <inspector/InspectorValues.h> -#include <wtf/MainThread.h> - -using namespace Inspector; - -namespace WebCore { - -ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned long requestIdentifier) - : m_source(source) - , m_type(type) - , m_level(level) - , m_message(message) - , m_url() - , m_line(0) - , m_column(0) - , m_repeatCount(1) - , m_requestId(IdentifiersFactory::requestId(requestIdentifier)) -{ - autogenerateMetadata(canGenerateCallStack); -} - -ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier) - : m_source(source) - , m_type(type) - , m_level(level) - , m_message(message) - , m_url(url) - , m_line(line) - , m_column(column) - , m_repeatCount(1) - , m_requestId(IdentifiersFactory::requestId(requestIdentifier)) -{ - autogenerateMetadata(canGenerateCallStack, state); -} - -ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier) - : m_source(source) - , m_type(type) - , m_level(level) - , m_message(message) - , m_arguments(nullptr) - , m_line(0) - , m_column(0) - , m_repeatCount(1) - , m_requestId(IdentifiersFactory::requestId(requestIdentifier)) -{ - if (callStack && callStack->size()) { - const ScriptCallFrame& frame = callStack->at(0); - m_url = frame.sourceURL(); - m_line = frame.lineNumber(); - m_column = frame.columnNumber(); - } - m_callStack = callStack; -} - -ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, JSC::ExecState* state, unsigned long requestIdentifier) - : m_source(source) - , m_type(type) - , m_level(level) - , m_message(message) - , m_arguments(arguments) - , m_url() - , m_line(0) - , m_column(0) - , m_repeatCount(1) - , m_requestId(IdentifiersFactory::requestId(requestIdentifier)) -{ - autogenerateMetadata(canGenerateCallStack, state); -} - -ConsoleMessage::~ConsoleMessage() -{ -} - -void ConsoleMessage::autogenerateMetadata(bool canGenerateCallStack, JSC::ExecState* state) -{ - if (m_type == EndGroupMessageType) - return; - - if (state) - m_callStack = createScriptCallStackForConsole(state); - else if (canGenerateCallStack) - m_callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); - else - return; - - if (m_callStack && m_callStack->size()) { - const ScriptCallFrame& frame = m_callStack->at(0); - m_url = frame.sourceURL(); - m_line = frame.lineNumber(); - m_column = frame.columnNumber(); - return; - } - - m_callStack.clear(); -} - -// Keep in sync with inspector/front-end/ConsoleView.js -static Inspector::TypeBuilder::Console::ConsoleMessage::Source::Enum messageSourceValue(MessageSource source) -{ - switch (source) { - case XMLMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::XML; - case JSMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Javascript; - case NetworkMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Network; - case ConsoleAPIMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::ConsoleAPI; - case StorageMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Storage; - case AppCacheMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Appcache; - case RenderingMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Rendering; - case CSSMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::CSS; - case SecurityMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Security; - case OtherMessageSource: return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Other; - } - return Inspector::TypeBuilder::Console::ConsoleMessage::Source::Other; -} - -static Inspector::TypeBuilder::Console::ConsoleMessage::Type::Enum messageTypeValue(MessageType type) -{ - switch (type) { - case LogMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Log; - case ClearMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Clear; - case DirMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Dir; - case DirXMLMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::DirXML; - case TableMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Table; - case TraceMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Trace; - case StartGroupMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::StartGroup; - case StartGroupCollapsedMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::StartGroupCollapsed; - case EndGroupMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::EndGroup; - case AssertMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Assert; - case TimingMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Timing; - case ProfileMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Profile; - case ProfileEndMessageType: return Inspector::TypeBuilder::Console::ConsoleMessage::Type::ProfileEnd; - } - return Inspector::TypeBuilder::Console::ConsoleMessage::Type::Log; -} - -static Inspector::TypeBuilder::Console::ConsoleMessage::Level::Enum messageLevelValue(MessageLevel level) -{ - switch (level) { - case DebugMessageLevel: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Debug; - case LogMessageLevel: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Log; - case WarningMessageLevel: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Warning; - case ErrorMessageLevel: return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Error; - } - return Inspector::TypeBuilder::Console::ConsoleMessage::Level::Log; -} - -void ConsoleMessage::addToFrontend(InspectorConsoleFrontendDispatcher* consoleFrontendDispatcher, Inspector::InjectedScriptManager* injectedScriptManager, bool generatePreview) -{ - RefPtr<Inspector::TypeBuilder::Console::ConsoleMessage> jsonObj = Inspector::TypeBuilder::Console::ConsoleMessage::create() - .setSource(messageSourceValue(m_source)) - .setLevel(messageLevelValue(m_level)) - .setText(m_message); - // FIXME: only send out type for ConsoleAPI source messages. - jsonObj->setType(messageTypeValue(m_type)); - jsonObj->setLine(static_cast<int>(m_line)); - jsonObj->setColumn(static_cast<int>(m_column)); - jsonObj->setUrl(m_url); - jsonObj->setRepeatCount(static_cast<int>(m_repeatCount)); - if (m_source == NetworkMessageSource && !m_requestId.isEmpty()) - jsonObj->setNetworkRequestId(m_requestId); - if (m_arguments && m_arguments->argumentCount()) { - InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->globalState()); - if (!injectedScript.hasNoValue()) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::RemoteObject>> jsonArgs = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::RemoteObject>::create(); - if (m_type == TableMessageType && generatePreview && m_arguments->argumentCount()) { - Deprecated::ScriptValue table = m_arguments->argumentAt(0); - Deprecated::ScriptValue columns = m_arguments->argumentCount() > 1 ? m_arguments->argumentAt(1) : Deprecated::ScriptValue(); - RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns); - if (!inspectorValue) { - ASSERT_NOT_REACHED(); - return; - } - jsonArgs->addItem(inspectorValue); - } else { - for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) { - RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), "console", generatePreview); - if (!inspectorValue) { - ASSERT_NOT_REACHED(); - return; - } - jsonArgs->addItem(inspectorValue); - } - } - jsonObj->setParameters(jsonArgs); - } - } - if (m_callStack) - jsonObj->setStackTrace(m_callStack->buildInspectorArray()); - consoleFrontendDispatcher->messageAdded(jsonObj); -} - -void ConsoleMessage::updateRepeatCountInConsole(InspectorConsoleFrontendDispatcher* consoleFrontendDispatcher) -{ - consoleFrontendDispatcher->messageRepeatCountUpdated(m_repeatCount); -} - -bool ConsoleMessage::isEqual(ConsoleMessage* msg) const -{ - if (m_arguments) { - if (!m_arguments->isEqual(msg->m_arguments.get())) - return false; - // Never treat objects as equal - their properties might change over time. - for (size_t i = 0; i < m_arguments->argumentCount(); ++i) { - if (m_arguments->argumentAt(i).isObject()) - return false; - } - } else if (msg->m_arguments) - return false; - - if (m_callStack) { - if (!m_callStack->isEqual(msg->m_callStack.get())) - return false; - } else if (msg->m_callStack) - return false; - - return msg->m_source == m_source - && msg->m_type == m_type - && msg->m_level == m_level - && msg->m_message == m_message - && msg->m_line == m_line - && msg->m_column == m_column - && msg->m_url == m_url - && msg->m_requestId == m_requestId; -} - -void ConsoleMessage::windowCleared(DOMWindow* window) -{ - if (!m_arguments) - return; - if (domWindowFromExecState(m_arguments->globalState()) != window) - return; - if (!m_message) - m_message = "<message collected>"; - m_arguments.clear(); -} - -unsigned ConsoleMessage::argumentCount() -{ - if (m_arguments) - return m_arguments->argumentCount(); - return 0; -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/ConsoleMessage.h b/Source/WebCore/inspector/ConsoleMessage.h deleted file mode 100644 index 1a1eaa117..000000000 --- a/Source/WebCore/inspector/ConsoleMessage.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ConsoleMessage_h -#define ConsoleMessage_h - -#include "ConsoleAPITypes.h" -#include "ConsoleTypes.h" -#include "InspectorWebFrontendDispatchers.h" -#include "ScriptState.h" -#include <wtf/Forward.h> -#include <wtf/Vector.h> - -namespace Inspector { -class InjectedScriptManager; -class InspectorObject; -} - -namespace WebCore { - -class DOMWindow; -class ScriptArguments; -class ScriptCallFrame; -class ScriptCallStack; - -class ConsoleMessage { - WTF_MAKE_NONCOPYABLE(ConsoleMessage); WTF_MAKE_FAST_ALLOCATED; -public: - ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, unsigned long requestIdentifier = 0); - ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0); - ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0); - ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments>, JSC::ExecState*, unsigned long requestIdentifier = 0); - ~ConsoleMessage(); - - void addToFrontend(Inspector::InspectorConsoleFrontendDispatcher*, Inspector::InjectedScriptManager*, bool generatePreview); - void updateRepeatCountInConsole(Inspector::InspectorConsoleFrontendDispatcher*); - void incrementCount() { ++m_repeatCount; } - bool isEqual(ConsoleMessage* msg) const; - - MessageSource source() const { return m_source; } - const String& message() const { return m_message; } - MessageType type() const { return m_type; } - - void windowCleared(DOMWindow*); - - unsigned argumentCount(); - -private: - void autogenerateMetadata(bool canGenerateCallStack, JSC::ExecState* = nullptr); - - MessageSource m_source; - MessageType m_type; - MessageLevel m_level; - String m_message; - RefPtr<ScriptArguments> m_arguments; - RefPtr<ScriptCallStack> m_callStack; - String m_url; - unsigned m_line; - unsigned m_column; - unsigned m_repeatCount; - String m_requestId; -}; - -} // namespace WebCore - -#endif // ConsoleMessage_h diff --git a/Source/WebCore/inspector/DOMEditor.cpp b/Source/WebCore/inspector/DOMEditor.cpp index 7f2fab8bb..5e5707e80 100644 --- a/Source/WebCore/inspector/DOMEditor.cpp +++ b/Source/WebCore/inspector/DOMEditor.cpp @@ -29,15 +29,12 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "DOMEditor.h" #include "DOMPatchSupport.h" #include "Document.h" #include "Element.h" -#include "ExceptionCode.h" +#include "ExceptionCodeDescription.h" #include "InspectorHistory.h" #include "Node.h" #include "Text.h" @@ -46,411 +43,390 @@ namespace WebCore { -class DOMEditor::RemoveChildAction : public InspectorHistory::Action { +class DOMEditor::RemoveChildAction final : public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(RemoveChildAction); public: - RemoveChildAction(Node* parentNode, Node* node) - : InspectorHistory::Action("RemoveChild") + RemoveChildAction(Node& parentNode, Node& node) + : Action("RemoveChild") , m_parentNode(parentNode) , m_node(node) { } - virtual bool perform(ExceptionCode& ec) override + ExceptionOr<void> perform() final { m_anchorNode = m_node->nextSibling(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec); + return m_parentNode->insertBefore(m_node, m_anchorNode.get()); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - return m_parentNode->removeChild(m_node.get(), ec); + return m_parentNode->removeChild(m_node); } private: - RefPtr<Node> m_parentNode; - RefPtr<Node> m_node; + Ref<Node> m_parentNode; + Ref<Node> m_node; RefPtr<Node> m_anchorNode; }; -class DOMEditor::InsertBeforeAction : public InspectorHistory::Action { - WTF_MAKE_NONCOPYABLE(InsertBeforeAction); +class DOMEditor::InsertBeforeAction final : public InspectorHistory::Action { public: - InsertBeforeAction(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode) - : InspectorHistory::Action("InsertBefore") + InsertBeforeAction(Node& parentNode, Ref<Node>&& node, Node* anchorNode) + : Action("InsertBefore") , m_parentNode(parentNode) - , m_node(node) + , m_node(WTFMove(node)) , m_anchorNode(anchorNode) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { if (m_node->parentNode()) { - m_removeChildAction = adoptPtr(new RemoveChildAction(m_node->parentNode(), m_node.get())); - if (!m_removeChildAction->perform(ec)) - return false; + m_removeChildAction = std::make_unique<RemoveChildAction>(*m_node->parentNode(), m_node); + auto result = m_removeChildAction->perform(); + if (result.hasException()) + return result.releaseException(); } - return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec); + return m_parentNode->insertBefore(m_node, m_anchorNode.get()); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - if (!m_parentNode->removeChild(m_node.get(), ec)) - return false; - if (m_removeChildAction) - return m_removeChildAction->undo(ec); - return true; + auto result = m_parentNode->removeChild(m_node); + if (result.hasException()) + return result.releaseException(); + if (!m_removeChildAction) + return { }; + return m_removeChildAction->undo(); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - if (m_removeChildAction && !m_removeChildAction->redo(ec)) - return false; - return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec); + if (m_removeChildAction) { + auto result = m_removeChildAction->redo(); + if (result.hasException()) + return result.releaseException(); + } + return m_parentNode->insertBefore(m_node, m_anchorNode.get()); } -private: - RefPtr<Node> m_parentNode; - RefPtr<Node> m_node; + Ref<Node> m_parentNode; + Ref<Node> m_node; RefPtr<Node> m_anchorNode; - OwnPtr<RemoveChildAction> m_removeChildAction; + std::unique_ptr<RemoveChildAction> m_removeChildAction; }; -class DOMEditor::RemoveAttributeAction : public InspectorHistory::Action { +class DOMEditor::RemoveAttributeAction final : public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(RemoveAttributeAction); public: - RemoveAttributeAction(Element* element, const String& name) - : InspectorHistory::Action("RemoveAttribute") + RemoveAttributeAction(Element& element, const String& name) + : Action("RemoveAttribute") , m_element(element) , m_name(name) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { m_value = m_element->getAttribute(m_name); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - m_element->setAttribute(m_name, m_value, ec); - return true; + return m_element->setAttribute(m_name, m_value); } - virtual bool redo(ExceptionCode&) override + ExceptionOr<void> redo() final { m_element->removeAttribute(m_name); - return true; + return { }; } -private: - RefPtr<Element> m_element; + Ref<Element> m_element; String m_name; String m_value; }; -class DOMEditor::SetAttributeAction : public InspectorHistory::Action { +class DOMEditor::SetAttributeAction final : public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(SetAttributeAction); public: - SetAttributeAction(Element* element, const String& name, const String& value) - : InspectorHistory::Action("SetAttribute") + SetAttributeAction(Element& element, const AtomicString& name, const AtomicString& value) + : Action("SetAttribute") , m_element(element) , m_name(name) , m_value(value) - , m_hadAttribute(false) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { - m_hadAttribute = m_element->hasAttribute(m_name); - if (m_hadAttribute) - m_oldValue = m_element->getAttribute(m_name); - return redo(ec); + m_oldValue = m_element->getAttribute(m_name); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - if (m_hadAttribute) - m_element->setAttribute(m_name, m_oldValue, ec); - else + if (m_oldValue.isNull()) { m_element->removeAttribute(m_name); - return true; + return { }; + } + return m_element->setAttribute(m_name, m_oldValue); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - m_element->setAttribute(m_name, m_value, ec); - return true; + return m_element->setAttribute(m_name, m_value); } -private: - RefPtr<Element> m_element; - String m_name; - String m_value; - bool m_hadAttribute; - String m_oldValue; + Ref<Element> m_element; + AtomicString m_name; + AtomicString m_value; + AtomicString m_oldValue; }; -class DOMEditor::SetOuterHTMLAction : public InspectorHistory::Action { - WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction); +class DOMEditor::SetOuterHTMLAction final : public InspectorHistory::Action { public: SetOuterHTMLAction(Node& node, const String& html) - : InspectorHistory::Action("SetOuterHTML") + : Action("SetOuterHTML") , m_node(node) , m_nextSibling(node.nextSibling()) , m_html(html) - , m_newNode(nullptr) - , m_history(adoptPtr(new InspectorHistory())) - , m_domEditor(adoptPtr(new DOMEditor(m_history.get()))) { } - virtual bool perform(ExceptionCode& ec) override + Node* newNode() const { - m_oldHTML = createMarkup(m_node.get()); - DOMPatchSupport domPatchSupport(m_domEditor.get(), &m_node->document()); - m_newNode = domPatchSupport.patchNode(m_node.get(), m_html, ec); - return !ec; + return m_newNode.get(); } - virtual bool undo(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { - return m_history->undo(ec); + m_oldHTML = createMarkup(m_node.get()); + auto result = DOMPatchSupport { m_domEditor, m_node->document() }.patchNode(m_node, m_html); + if (result.hasException()) + return result.releaseException(); + m_newNode = result.releaseReturnValue(); + return { }; } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - return m_history->redo(ec); + return m_history.undo(); } - Node* newNode() + ExceptionOr<void> redo() final { - return m_newNode; + return m_history.redo(); } -private: Ref<Node> m_node; RefPtr<Node> m_nextSibling; String m_html; String m_oldHTML; - Node* m_newNode; - OwnPtr<InspectorHistory> m_history; - OwnPtr<DOMEditor> m_domEditor; + RefPtr<Node> m_newNode { nullptr }; + InspectorHistory m_history; + DOMEditor m_domEditor { m_history }; }; -class DOMEditor::ReplaceWholeTextAction : public InspectorHistory::Action { +class DOMEditor::ReplaceWholeTextAction final : public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction); public: - ReplaceWholeTextAction(Text* textNode, const String& text) - : InspectorHistory::Action("ReplaceWholeText") + ReplaceWholeTextAction(Text& textNode, const String& text) + : Action("ReplaceWholeText") , m_textNode(textNode) , m_text(text) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { m_oldText = m_textNode->wholeText(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - m_textNode->replaceWholeText(m_oldText, ec); - return true; + m_textNode->replaceWholeText(m_oldText); + return { }; } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - m_textNode->replaceWholeText(m_text, ec); - return true; + m_textNode->replaceWholeText(m_text); + return { }; } -private: - RefPtr<Text> m_textNode; + Ref<Text> m_textNode; String m_text; String m_oldText; }; -class DOMEditor::ReplaceChildNodeAction : public InspectorHistory::Action { +class DOMEditor::ReplaceChildNodeAction final: public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(ReplaceChildNodeAction); public: - ReplaceChildNodeAction(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode) - : InspectorHistory::Action("ReplaceChildNode") + ReplaceChildNodeAction(Node& parentNode, Ref<Node>&& newNode, Node& oldNode) + : Action("ReplaceChildNode") , m_parentNode(parentNode) - , m_newNode(newNode) + , m_newNode(WTFMove(newNode)) , m_oldNode(oldNode) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - return m_parentNode->replaceChild(m_oldNode, m_newNode.get(), ec); + return m_parentNode->replaceChild(m_oldNode, m_newNode); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - return m_parentNode->replaceChild(m_newNode, m_oldNode.get(), ec); + return m_parentNode->replaceChild(m_newNode, m_oldNode); } -private: - RefPtr<Node> m_parentNode; - RefPtr<Node> m_newNode; - RefPtr<Node> m_oldNode; + Ref<Node> m_parentNode; + Ref<Node> m_newNode; + Ref<Node> m_oldNode; }; -class DOMEditor::SetNodeValueAction : public InspectorHistory::Action { +class DOMEditor::SetNodeValueAction final : public InspectorHistory::Action { WTF_MAKE_NONCOPYABLE(SetNodeValueAction); public: - SetNodeValueAction(Node* node, const String& value) - : InspectorHistory::Action("SetNodeValue") + SetNodeValueAction(Node& node, const String& value) + : Action("SetNodeValue") , m_node(node) , m_value(value) { } - virtual bool perform(ExceptionCode& ec) override +private: + ExceptionOr<void> perform() final { m_oldValue = m_node->nodeValue(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr<void> undo() final { - m_node->setNodeValue(m_oldValue, ec); - return !ec; + return m_node->setNodeValue(m_oldValue); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr<void> redo() final { - m_node->setNodeValue(m_value, ec); - return !ec; + return m_node->setNodeValue(m_value); } -private: - RefPtr<Node> m_node; + Ref<Node> m_node; String m_value; String m_oldValue; }; -DOMEditor::DOMEditor(InspectorHistory* history) : m_history(history) { } +DOMEditor::DOMEditor(InspectorHistory& history) + : m_history(history) +{ +} -DOMEditor::~DOMEditor() { } +DOMEditor::~DOMEditor() +{ +} -bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::insertBefore(Node& parentNode, Ref<Node>&& node, Node* anchorNode) { - return m_history->perform(adoptPtr(new InsertBeforeAction(parentNode, node, anchorNode)), ec); + return m_history.perform(std::make_unique<InsertBeforeAction>(parentNode, WTFMove(node), anchorNode)); } -bool DOMEditor::removeChild(Node* parentNode, Node* node, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::removeChild(Node& parentNode, Node& node) { - return m_history->perform(adoptPtr(new RemoveChildAction(parentNode, node)), ec); + return m_history.perform(std::make_unique<RemoveChildAction>(parentNode, node)); } -bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::setAttribute(Element& element, const String& name, const String& value) { - return m_history->perform(adoptPtr(new SetAttributeAction(element, name, value)), ec); + return m_history.perform(std::make_unique<SetAttributeAction>(element, name, value)); } -bool DOMEditor::removeAttribute(Element* element, const String& name, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::removeAttribute(Element& element, const String& name) { - return m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), ec); + return m_history.perform(std::make_unique<RemoveAttributeAction>(element, name)); } -bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::setOuterHTML(Node& node, const String& html, Node*& newNode) { - OwnPtr<SetOuterHTMLAction> action = adoptPtr(new SetOuterHTMLAction(node, html)); - SetOuterHTMLAction* rawAction = action.get(); - bool result = m_history->perform(action.release(), ec); - if (result) - *newNode = rawAction->newNode(); + auto action = std::make_unique<SetOuterHTMLAction>(node, html); + auto& rawAction = *action; + auto result = m_history.perform(WTFMove(action)); + if (!result.hasException()) + newNode = rawAction.newNode(); return result; } -bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::replaceWholeText(Text& textNode, const String& text) { - return m_history->perform(adoptPtr(new ReplaceWholeTextAction(textNode, text)), ec); + return m_history.perform(std::make_unique<ReplaceWholeTextAction>(textNode, text)); } -bool DOMEditor::replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::replaceChild(Node& parentNode, Ref<Node>&& newNode, Node& oldNode) { - return m_history->perform(adoptPtr(new ReplaceChildNodeAction(parentNode, newNode, oldNode)), ec); + return m_history.perform(std::make_unique<ReplaceChildNodeAction>(parentNode, WTFMove(newNode), oldNode)); } -bool DOMEditor::setNodeValue(Node* node, const String& value, ExceptionCode& ec) +ExceptionOr<void> DOMEditor::setNodeValue(Node& node, const String& value) { - return m_history->perform(adoptPtr(new SetNodeValueAction(node, value)), ec); + return m_history.perform(std::make_unique<SetNodeValueAction>(node, value)); } -static void populateErrorString(const ExceptionCode& ec, ErrorString* errorString) +static bool populateErrorString(ExceptionOr<void>&& result, ErrorString& errorString) { - if (ec) { - ExceptionCodeDescription description(ec); - *errorString = description.name; - } + if (!result.hasException()) + return true; + errorString = ExceptionCodeDescription { result.releaseException().code() }.name; + return false; } -bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ErrorString* errorString) +bool DOMEditor::insertBefore(Node& parentNode, Ref<Node>&& node, Node* anchorNode, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = insertBefore(parentNode, node, anchorNode, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(insertBefore(parentNode, WTFMove(node), anchorNode), errorString); } -bool DOMEditor::removeChild(Node* parentNode, Node* node, ErrorString* errorString) +bool DOMEditor::removeChild(Node& parentNode, Node& node, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = removeChild(parentNode, node, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(removeChild(parentNode, node), errorString); } -bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ErrorString* errorString) +bool DOMEditor::setAttribute(Element& element, const String& name, const String& value, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = setAttribute(element, name, value, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(setAttribute(element, name, value), errorString); } -bool DOMEditor::removeAttribute(Element* element, const String& name, ErrorString* errorString) +bool DOMEditor::removeAttribute(Element& element, const String& name, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = removeAttribute(element, name, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(removeAttribute(element, name), errorString); } -bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ErrorString* errorString) +bool DOMEditor::setOuterHTML(Node& node, const String& html, Node*& newNode, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = setOuterHTML(node, html, newNode, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(setOuterHTML(node, html, newNode), errorString); } -bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ErrorString* errorString) +bool DOMEditor::replaceWholeText(Text& textNode, const String& text, ErrorString& errorString) { - ExceptionCode ec = 0; - bool result = replaceWholeText(textNode, text, ec); - populateErrorString(ec, errorString); - return result; + return populateErrorString(replaceWholeText(textNode, text), errorString); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/DOMEditor.h b/Source/WebCore/inspector/DOMEditor.h index 8cc441f18..e95a93687 100644 --- a/Source/WebCore/inspector/DOMEditor.h +++ b/Source/WebCore/inspector/DOMEditor.h @@ -28,12 +28,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DOMEditor_h -#define DOMEditor_h +#pragma once -#include "ExceptionCode.h" - -#include <wtf/text/WTFString.h> +#include "ExceptionOr.h" namespace WebCore { @@ -42,48 +39,42 @@ class InspectorHistory; class Node; class Text; -#if ENABLE(INSPECTOR) - typedef String ErrorString; class DOMEditor { WTF_MAKE_NONCOPYABLE(DOMEditor); WTF_MAKE_FAST_ALLOCATED; public: - explicit DOMEditor(InspectorHistory*); + explicit DOMEditor(InspectorHistory&); ~DOMEditor(); - bool insertBefore(Node* parentNode, PassRefPtr<Node>, Node* anchorNode, ExceptionCode&); - bool removeChild(Node* parentNode, Node*, ExceptionCode&); - bool setAttribute(Element*, const String& name, const String& value, ExceptionCode&); - bool removeAttribute(Element*, const String& name, ExceptionCode&); - bool setOuterHTML(Node&, const String& html, Node** newNode, ExceptionCode&); - bool replaceWholeText(Text*, const String& text, ExceptionCode&); - bool replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionCode&); - bool setNodeValue(Node* parentNode, const String& value, ExceptionCode&); + ExceptionOr<void> insertBefore(Node& parentNode, Ref<Node>&&, Node* anchorNode); + ExceptionOr<void> removeChild(Node& parentNode, Node&); + ExceptionOr<void> setAttribute(Element&, const String& name, const String& value); + ExceptionOr<void> removeAttribute(Element&, const String& name); + ExceptionOr<void> setOuterHTML(Node&, const String& html, Node*& newNode); + ExceptionOr<void> replaceWholeText(Text&, const String& text); + ExceptionOr<void> replaceChild(Node& parentNode, Ref<Node>&& newNode, Node& oldNode); + ExceptionOr<void> setNodeValue(Node& parentNode, const String& value); - bool insertBefore(Node* parentNode, PassRefPtr<Node>, Node* anchorNode, ErrorString*); - bool removeChild(Node* parentNode, Node*, ErrorString*); - bool setAttribute(Element*, const String& name, const String& value, ErrorString*); - bool removeAttribute(Element*, const String& name, ErrorString*); - bool setOuterHTML(Node&, const String& html, Node** newNode, ErrorString*); - bool replaceWholeText(Text*, const String& text, ErrorString*); + bool insertBefore(Node& parentNode, Ref<Node>&&, Node* anchorNode, ErrorString&); + bool removeChild(Node& parentNode, Node&, ErrorString&); + bool setAttribute(Element&, const String& name, const String& value, ErrorString&); + bool removeAttribute(Element&, const String& name, ErrorString&); + bool setOuterHTML(Node&, const String& html, Node*& newNode, ErrorString&); + bool replaceWholeText(Text&, const String& text, ErrorString&); private: class DOMAction; - class RemoveChildAction; class InsertBeforeAction; class RemoveAttributeAction; - class SetAttributeAction; - class SetOuterHTMLAction; - class ReplaceWholeTextAction; + class RemoveChildAction; class ReplaceChildNodeAction; + class ReplaceWholeTextAction; + class SetAttributeAction; class SetNodeValueAction; + class SetOuterHTMLAction; - InspectorHistory* m_history; + InspectorHistory& m_history; }; -#endif // ENABLE(INSPECTOR) - } // namespace WebCore - -#endif // !defined(DOMEditor_h) diff --git a/Source/WebCore/inspector/DOMPatchSupport.cpp b/Source/WebCore/inspector/DOMPatchSupport.cpp index 545128069..6acd8bc2a 100644 --- a/Source/WebCore/inspector/DOMPatchSupport.cpp +++ b/Source/WebCore/inspector/DOMPatchSupport.cpp @@ -29,9 +29,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "DOMPatchSupport.h" #include "Attribute.h" @@ -45,8 +42,8 @@ #include "HTMLNames.h" #include "InspectorHistory.h" #include "Node.h" +#include "XMLDocument.h" #include "XMLDocumentParser.h" - #include <wtf/Deque.h> #include <wtf/HashTraits.h> #include <wtf/RefPtr.h> @@ -61,41 +58,27 @@ using HTMLNames::headTag; using HTMLNames::htmlTag; struct DOMPatchSupport::Digest { - explicit Digest(Node* node) : m_node(node) { } - - String m_sha1; - String m_attrsSHA1; - Node* m_node; - Vector<OwnPtr<Digest>> m_children; + String sha1; + String attrsSHA1; + Node* node; + Vector<std::unique_ptr<Digest>> children; }; -void DOMPatchSupport::patchDocument(Document* document, const String& markup) -{ - InspectorHistory history; - DOMEditor domEditor(&history); - DOMPatchSupport patchSupport(&domEditor, document); - patchSupport.patchDocument(markup); -} - -DOMPatchSupport::DOMPatchSupport(DOMEditor* domEditor, Document* document) +DOMPatchSupport::DOMPatchSupport(DOMEditor& domEditor, Document& document) : m_domEditor(domEditor) , m_document(document) { } -DOMPatchSupport::~DOMPatchSupport() { } - void DOMPatchSupport::patchDocument(const String& markup) { RefPtr<Document> newDocument; - if (m_document->isHTMLDocument()) + if (m_document.isHTMLDocument()) newDocument = HTMLDocument::create(nullptr, URL()); - else if (m_document->isXHTMLDocument()) - newDocument = HTMLDocument::createXHTML(nullptr, URL()); -#if ENABLE(SVG) - else if (m_document->isSVGDocument()) - newDocument = Document::create(nullptr, URL()); -#endif + else if (m_document.isXHTMLDocument()) + newDocument = XMLDocument::createXHTML(nullptr, URL()); + else if (m_document.isSVGDocument()) + newDocument = XMLDocument::create(nullptr, URL()); ASSERT(newDocument); RefPtr<DocumentParser> parser; @@ -107,17 +90,17 @@ void DOMPatchSupport::patchDocument(const String& markup) parser->finish(); parser->detach(); - OwnPtr<Digest> oldInfo = createDigest(m_document->documentElement(), nullptr); - OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unusedNodesMap); + std::unique_ptr<Digest> oldInfo = createDigest(*m_document.documentElement(), nullptr); + std::unique_ptr<Digest> newInfo = createDigest(*newDocument->documentElement(), &m_unusedNodesMap); - if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) { + if (innerPatchNode(*oldInfo, *newInfo).hasException()) { // Fall back to rewrite. - m_document->write(markup); - m_document->close(); + m_document.write(markup); + m_document.close(); } } -Node* DOMPatchSupport::patchNode(Node& node, const String& markup, ExceptionCode& ec) +ExceptionOr<Node*> DOMPatchSupport::patchNode(Node& node, const String& markup) { // Don't parse <html> as a fragment. if (node.isDocumentNode() || (node.parentNode() && node.parentNode()->isDocumentNode())) { @@ -127,112 +110,113 @@ Node* DOMPatchSupport::patchNode(Node& node, const String& markup, ExceptionCode Node* previousSibling = node.previousSibling(); // FIXME: This code should use one of createFragment* in markup.h - RefPtr<DocumentFragment> fragment = DocumentFragment::create(*m_document); - if (m_document->isHTMLDocument()) - fragment->parseHTML(markup, node.parentElement() ? node.parentElement() : m_document->documentElement()); + RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document); + if (m_document.isHTMLDocument()) + fragment->parseHTML(markup, node.parentElement() ? node.parentElement() : m_document.documentElement()); else - fragment->parseXML(markup, node.parentElement() ? node.parentElement() : m_document->documentElement()); + fragment->parseXML(markup, node.parentElement() ? node.parentElement() : m_document.documentElement()); // Compose the old list. - ContainerNode* parentNode = node.parentNode(); - Vector<OwnPtr<Digest>> oldList; + auto* parentNode = node.parentNode(); + Vector<std::unique_ptr<Digest>> oldList; for (Node* child = parentNode->firstChild(); child; child = child->nextSibling()) - oldList.append(createDigest(child, nullptr)); + oldList.append(createDigest(*child, nullptr)); // Compose the new list. - String markupCopy = markup.lower(); - Vector<OwnPtr<Digest>> newList; + Vector<std::unique_ptr<Digest>> newList; for (Node* child = parentNode->firstChild(); child != &node; child = child->nextSibling()) - newList.append(createDigest(child, nullptr)); + newList.append(createDigest(*child, nullptr)); for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) { - if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.find("</head>") == notFound) + if (child->hasTagName(headTag) && !child->firstChild() && !markup.containsIgnoringASCIICase("</head>")) continue; // HTML5 parser inserts empty <head> tag whenever it parses <body> - if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.find("</body>") == notFound) + if (child->hasTagName(bodyTag) && !child->firstChild() && !markup.containsIgnoringASCIICase("</body>")) continue; // HTML5 parser inserts empty <body> tag whenever it parses </head> - newList.append(createDigest(child, &m_unusedNodesMap)); + newList.append(createDigest(*child, &m_unusedNodesMap)); } for (Node* child = node.nextSibling(); child; child = child->nextSibling()) - newList.append(createDigest(child, nullptr)); + newList.append(createDigest(*child, nullptr)); - if (!innerPatchChildren(parentNode, oldList, newList, ec)) { + if (innerPatchChildren(*parentNode, oldList, newList).hasException()) { // Fall back to total replace. - ec = 0; - if (!m_domEditor->replaceChild(parentNode, fragment.release(), &node, ec)) - return nullptr; + auto result = m_domEditor.replaceChild(*parentNode, *fragment, node); + if (result.hasException()) + return result.releaseException(); } return previousSibling ? previousSibling->nextSibling() : parentNode->firstChild(); } -bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, ExceptionCode& ec) +ExceptionOr<void> DOMPatchSupport::innerPatchNode(Digest& oldDigest, Digest& newDigest) { - if (oldDigest->m_sha1 == newDigest->m_sha1) - return true; + if (oldDigest.sha1 == newDigest.sha1) + return { }; - Node* oldNode = oldDigest->m_node; - Node* newNode = newDigest->m_node; + auto& oldNode = *oldDigest.node; + auto& newNode = *newDigest.node; - if (newNode->nodeType() != oldNode->nodeType() || newNode->nodeName() != oldNode->nodeName()) - return m_domEditor->replaceChild(oldNode->parentNode(), newNode, oldNode, ec); + if (newNode.nodeType() != oldNode.nodeType() || newNode.nodeName() != oldNode.nodeName()) + return m_domEditor.replaceChild(*oldNode.parentNode(), newNode, oldNode); - if (oldNode->nodeValue() != newNode->nodeValue()) { - if (!m_domEditor->setNodeValue(oldNode, newNode->nodeValue(), ec)) - return false; + if (oldNode.nodeValue() != newNode.nodeValue()) { + auto result = m_domEditor.setNodeValue(oldNode, newNode.nodeValue()); + if (result.hasException()) + return result.releaseException(); } - if (oldNode->nodeType() != Node::ELEMENT_NODE) - return true; + if (!is<Element>(oldNode)) + return { }; // Patch attributes - Element* oldElement = toElement(oldNode); - Element* newElement = toElement(newNode); - if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) { + auto& oldElement = downcast<Element>(oldNode); + auto& newElement = downcast<Element>(newNode); + if (oldDigest.attrsSHA1 != newDigest.attrsSHA1) { // FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important. - if (oldElement->hasAttributesWithoutUpdate()) { - while (oldElement->attributeCount()) { - const Attribute& attribute = oldElement->attributeAt(0); - if (!m_domEditor->removeAttribute(oldElement, attribute.localName(), ec)) - return false; + if (oldElement.hasAttributesWithoutUpdate()) { + while (oldElement.attributeCount()) { + auto result = m_domEditor.removeAttribute(oldElement, oldElement.attributeAt(0).localName()); + if (result.hasException()) + return result.releaseException(); } } // FIXME: Create a function in Element for copying properties. cloneDataFromElement() is close but not enough for this case. - if (newElement->hasAttributesWithoutUpdate()) { - for (const Attribute& attribute : newElement->attributesIterator()) { - if (!m_domEditor->setAttribute(oldElement, attribute.name().localName(), attribute.value(), ec)) - return false; + if (newElement.hasAttributesWithoutUpdate()) { + for (auto& attribute : newElement.attributesIterator()) { + auto result = m_domEditor.setAttribute(oldElement, attribute.name().localName(), attribute.value()); + if (result.hasException()) + return result.releaseException(); } } } - bool result = innerPatchChildren(oldElement, oldDigest->m_children, newDigest->m_children, ec); - m_unusedNodesMap.remove(newDigest->m_sha1); + auto result = innerPatchChildren(oldElement, oldDigest.children, newDigest.children); + m_unusedNodesMap.remove(newDigest.sha1); return result; } std::pair<DOMPatchSupport::ResultMap, DOMPatchSupport::ResultMap> -DOMPatchSupport::diff(const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr<Digest>>& newList) +DOMPatchSupport::diff(const Vector<std::unique_ptr<Digest>>& oldList, const Vector<std::unique_ptr<Digest>>& newList) { ResultMap newMap(newList.size()); ResultMap oldMap(oldList.size()); - for (size_t i = 0; i < oldMap.size(); ++i) { - oldMap[i].first = nullptr; - oldMap[i].second = 0; + for (auto& result : oldMap) { + result.first = nullptr; + result.second = 0; } - for (size_t i = 0; i < newMap.size(); ++i) { - newMap[i].first = nullptr; - newMap[i].second = 0; + for (auto& result : newMap) { + result.first = nullptr; + result.second = 0; } // Trim head and tail. - for (size_t i = 0; i < oldList.size() && i < newList.size() && oldList[i]->m_sha1 == newList[i]->m_sha1; ++i) { + for (size_t i = 0; i < oldList.size() && i < newList.size() && oldList[i]->sha1 == newList[i]->sha1; ++i) { oldMap[i].first = oldList[i].get(); oldMap[i].second = i; newMap[i].first = newList[i].get(); newMap[i].second = i; } - for (size_t i = 0; i < oldList.size() && i < newList.size() && oldList[oldList.size() - i - 1]->m_sha1 == newList[newList.size() - i - 1]->m_sha1; ++i) { + for (size_t i = 0; i < oldList.size() && i < newList.size() && oldList[oldList.size() - i - 1]->sha1 == newList[newList.size() - i - 1]->sha1; ++i) { size_t oldIndex = oldList.size() - i - 1; size_t newIndex = newList.size() - i - 1; oldMap[oldIndex].first = oldList[oldIndex].get(); @@ -245,26 +229,22 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr DiffTable newTable; DiffTable oldTable; - for (size_t i = 0; i < newList.size(); ++i) { - DiffTable::iterator it = newTable.add(newList[i]->m_sha1, Vector<size_t>()).iterator; - it->value.append(i); - } + for (size_t i = 0; i < newList.size(); ++i) + newTable.add(newList[i]->sha1, Vector<size_t>()).iterator->value.append(i); - for (size_t i = 0; i < oldList.size(); ++i) { - DiffTable::iterator it = oldTable.add(oldList[i]->m_sha1, Vector<size_t>()).iterator; - it->value.append(i); - } + for (size_t i = 0; i < oldList.size(); ++i) + oldTable.add(oldList[i]->sha1, Vector<size_t>()).iterator->value.append(i); - for (DiffTable::iterator newIt = newTable.begin(); newIt != newTable.end(); ++newIt) { - if (newIt->value.size() != 1) + for (auto& newEntry : newTable) { + if (newEntry.value.size() != 1) continue; - DiffTable::iterator oldIt = oldTable.find(newIt->key); + auto oldIt = oldTable.find(newEntry.key); if (oldIt == oldTable.end() || oldIt->value.size() != 1) continue; - newMap[newIt->value[0]] = std::make_pair(newList[newIt->value[0]].get(), oldIt->value[0]); - oldMap[oldIt->value[0]] = std::make_pair(oldList[oldIt->value[0]].get(), newIt->value[0]); + newMap[newEntry.value[0]] = std::make_pair(newList[newEntry.value[0]].get(), oldIt->value[0]); + oldMap[oldIt->value[0]] = std::make_pair(oldList[oldIt->value[0]].get(), newEntry.value[0]); } for (size_t i = 0; newList.size() > 0 && i < newList.size() - 1; ++i) { @@ -272,7 +252,7 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr continue; size_t j = newMap[i].second + 1; - if (j < oldMap.size() && !oldMap[j].first && newList[i + 1]->m_sha1 == oldList[j]->m_sha1) { + if (j < oldMap.size() && !oldMap[j].first && newList[i + 1]->sha1 == oldList[j]->sha1) { newMap[i + 1] = std::make_pair(newList[i + 1].get(), j); oldMap[j] = std::make_pair(oldList[j].get(), i + 1); } @@ -283,7 +263,7 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr continue; size_t j = newMap[i].second - 1; - if (!oldMap[j].first && newList[i - 1]->m_sha1 == oldList[j]->m_sha1) { + if (!oldMap[j].first && newList[i - 1]->sha1 == oldList[j]->sha1) { newMap[i - 1] = std::make_pair(newList[i - 1].get(), j); oldMap[j] = std::make_pair(oldList[j].get(), i - 1); } @@ -297,9 +277,9 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr return std::make_pair(oldMap, newMap); } -bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector<OwnPtr<Digest>>& oldList, const Vector<OwnPtr<Digest>>& newList, ExceptionCode& ec) +ExceptionOr<void> DOMPatchSupport::innerPatchChildren(ContainerNode& parentNode, const Vector<std::unique_ptr<Digest>>& oldList, const Vector<std::unique_ptr<Digest>>& newList) { - std::pair<ResultMap, ResultMap> resultMaps = diff(oldList, newList); + auto resultMaps = diff(oldList, newList); ResultMap& oldMap = resultMaps.first; ResultMap& newMap = resultMaps.second; @@ -321,33 +301,35 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector // Always match <head> and <body> tags with each other - we can't remove them from the DOM // upon patching. - if (oldList[i]->m_node->hasTagName(headTag)) { + if (oldList[i]->node->hasTagName(headTag)) { oldHead = oldList[i].get(); continue; } - if (oldList[i]->m_node->hasTagName(bodyTag)) { + if (oldList[i]->node->hasTagName(bodyTag)) { oldBody = oldList[i].get(); continue; } // Check if this change is between stable nodes. If it is, consider it as "modified". - if (!m_unusedNodesMap.contains(oldList[i]->m_sha1) && (!i || oldMap[i - 1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) { + if (!m_unusedNodesMap.contains(oldList[i]->sha1) && (!i || oldMap[i - 1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) { size_t anchorCandidate = i ? oldMap[i - 1].second + 1 : 0; size_t anchorAfter = i == oldMap.size() - 1 ? anchorCandidate + 1 : oldMap[i + 1].second; if (anchorAfter - anchorCandidate == 1 && anchorCandidate < newList.size()) merges.set(newList[anchorCandidate].get(), oldList[i].get()); else { - if (!removeChildAndMoveToNew(oldList[i].get(), ec)) - return false; + auto result = removeChildAndMoveToNew(*oldList[i]); + if (result.hasException()) + return result.releaseException(); } } else { - if (!removeChildAndMoveToNew(oldList[i].get(), ec)) - return false; + auto result = removeChildAndMoveToNew(*oldList[i]); + if (result.hasException()) + return result.releaseException(); } } // Mark retained nodes as used, do not reuse node more than once. - HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<size_t>> usedOldOrdinals; + HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<size_t>> usedOldOrdinals; for (size_t i = 0; i < newList.size(); ++i) { if (!newMap[i].first) continue; @@ -359,48 +341,50 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector continue; } usedOldOrdinals.add(oldOrdinal); - markNodeAsUsed(newMap[i].first); + markNodeAsUsed(*newMap[i].first); } // Mark <head> and <body> nodes for merge. if (oldHead || oldBody) { for (size_t i = 0; i < newList.size(); ++i) { - if (oldHead && newList[i]->m_node->hasTagName(headTag)) + if (oldHead && newList[i]->node->hasTagName(headTag)) merges.set(newList[i].get(), oldHead); - if (oldBody && newList[i]->m_node->hasTagName(bodyTag)) + if (oldBody && newList[i]->node->hasTagName(bodyTag)) merges.set(newList[i].get(), oldBody); } } // 2. Patch nodes marked for merge. - for (HashMap<Digest*, Digest*>::iterator it = merges.begin(); it != merges.end(); ++it) { - if (!innerPatchNode(it->value, it->key, ec)) - return false; + for (auto& merge : merges) { + auto result = innerPatchNode(*merge.value, *merge.key); + if (result.hasException()) + return result.releaseException(); } // 3. Insert missing nodes. for (size_t i = 0; i < newMap.size(); ++i) { if (newMap[i].first || merges.contains(newList[i].get())) continue; - if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->childNode(i), ec)) - return false; + auto result = insertBeforeAndMarkAsUsed(parentNode, *newList[i], parentNode.traverseToChildAt(i)); + if (result.hasException()) + return result.releaseException(); } // 4. Then put all nodes that retained into their slots (sort by new index). for (size_t i = 0; i < oldMap.size(); ++i) { if (!oldMap[i].first) continue; - RefPtr<Node> node = oldMap[i].first->m_node; - Node* anchorNode = parentNode->childNode(oldMap[i].second); - if (node.get() == anchorNode) + RefPtr<Node> node = oldMap[i].first->node; + auto* anchorNode = parentNode.traverseToChildAt(oldMap[i].second); + if (node == anchorNode) continue; if (node->hasTagName(bodyTag) || node->hasTagName(headTag)) continue; // Never move head or body, move the rest of the nodes around them. - - if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, ec)) - return false; + auto result = m_domEditor.insertBefore(parentNode, node.releaseNonNull(), anchorNode); + if (result.hasException()) + return result.releaseException(); } - return true; + return { }; } static void addStringToSHA1(SHA1& sha1, const String& string) @@ -409,102 +393,109 @@ static void addStringToSHA1(SHA1& sha1, const String& string) sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.length()); } -PassOwnPtr<DOMPatchSupport::Digest> DOMPatchSupport::createDigest(Node* node, UnusedNodesMap* unusedNodesMap) +std::unique_ptr<DOMPatchSupport::Digest> DOMPatchSupport::createDigest(Node& node, UnusedNodesMap* unusedNodesMap) { - Digest* digest = new Digest(node); - + auto digest = std::make_unique<Digest>(); + digest->node = &node; SHA1 sha1; - Node::NodeType nodeType = node->nodeType(); + auto nodeType = node.nodeType(); sha1.addBytes(reinterpret_cast<const uint8_t*>(&nodeType), sizeof(nodeType)); - addStringToSHA1(sha1, node->nodeName()); - addStringToSHA1(sha1, node->nodeValue()); + addStringToSHA1(sha1, node.nodeName()); + addStringToSHA1(sha1, node.nodeValue()); - if (node->nodeType() == Node::ELEMENT_NODE) { - Node* child = node->firstChild(); + if (node.nodeType() == Node::ELEMENT_NODE) { + Node* child = node.firstChild(); while (child) { - OwnPtr<Digest> childInfo = createDigest(child, unusedNodesMap); - addStringToSHA1(sha1, childInfo->m_sha1); + std::unique_ptr<Digest> childInfo = createDigest(*child, unusedNodesMap); + addStringToSHA1(sha1, childInfo->sha1); child = child->nextSibling(); - digest->m_children.append(childInfo.release()); + digest->children.append(WTFMove(childInfo)); } - Element* element = toElement(node); + auto& element = downcast<Element>(node); - if (element->hasAttributesWithoutUpdate()) { + if (element.hasAttributesWithoutUpdate()) { SHA1 attrsSHA1; - for (const Attribute& attribute : element->attributesIterator()) { + for (auto& attribute : element.attributesIterator()) { addStringToSHA1(attrsSHA1, attribute.name().toString()); addStringToSHA1(attrsSHA1, attribute.value()); } SHA1::Digest attrsHash; attrsSHA1.computeHash(attrsHash); - digest->m_attrsSHA1 = base64Encode(attrsHash.data(), 10); - addStringToSHA1(sha1, digest->m_attrsSHA1); + digest->attrsSHA1 = base64Encode(attrsHash.data(), 10); + addStringToSHA1(sha1, digest->attrsSHA1); } } SHA1::Digest hash; sha1.computeHash(hash); - digest->m_sha1 = base64Encode(hash.data(), 10); + digest->sha1 = base64Encode(hash.data(), 10); if (unusedNodesMap) - unusedNodesMap->add(digest->m_sha1, digest); - return adoptPtr(digest); + unusedNodesMap->add(digest->sha1, digest.get()); + + return digest; } -bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Digest* digest, Node* anchor, ExceptionCode& ec) +ExceptionOr<void> DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode& parentNode, Digest& digest, Node* anchor) { - bool result = m_domEditor->insertBefore(parentNode, digest->m_node, anchor, ec); + ASSERT(digest.node); + auto result = m_domEditor.insertBefore(parentNode, *digest.node, anchor); markNodeAsUsed(digest); return result; } -bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionCode& ec) +ExceptionOr<void> DOMPatchSupport::removeChildAndMoveToNew(Digest& oldDigest) { - RefPtr<Node> oldNode = oldDigest->m_node; - if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), ec)) - return false; + Ref<Node> oldNode = *oldDigest.node; + ASSERT(oldNode->parentNode()); + auto result = m_domEditor.removeChild(*oldNode->parentNode(), oldNode); + if (result.hasException()) + return result.releaseException(); // Diff works within levels. In order not to lose the node identity when user // prepends his HTML with "<div>" (i.e. all nodes are shifted to the next nested level), // prior to dropping the original node on the floor, check whether new DOM has a digest // with matching sha1. If it does, replace it with the original DOM chunk. Chances are // high that it will get merged back into the original DOM during the further patching. - UnusedNodesMap::iterator it = m_unusedNodesMap.find(oldDigest->m_sha1); + auto it = m_unusedNodesMap.find(oldDigest.sha1); if (it != m_unusedNodesMap.end()) { - Digest* newDigest = it->value; - Node* newNode = newDigest->m_node; - if (!m_domEditor->replaceChild(newNode->parentNode(), oldNode, newNode, ec)) - return false; - newDigest->m_node = oldNode.get(); + auto& newDigest = *it->value; + auto& newNode = *newDigest.node; + auto result = m_domEditor.replaceChild(*newNode.parentNode(), oldNode.get(), newNode); + if (result.hasException()) + return result.releaseException(); + newDigest.node = oldNode.ptr(); markNodeAsUsed(newDigest); - return true; + return { }; } - for (size_t i = 0; i < oldDigest->m_children.size(); ++i) { - if (!removeChildAndMoveToNew(oldDigest->m_children[i].get(), ec)) - return false; + for (auto& child : oldDigest.children) { + auto result = removeChildAndMoveToNew(*child); + if (result.hasException()) + return result.releaseException(); } - return true; + return { }; } -void DOMPatchSupport::markNodeAsUsed(Digest* digest) +void DOMPatchSupport::markNodeAsUsed(Digest& digest) { Deque<Digest*> queue; - queue.append(digest); + queue.append(&digest); while (!queue.isEmpty()) { - Digest* first = queue.takeFirst(); - m_unusedNodesMap.remove(first->m_sha1); - for (size_t i = 0; i < first->m_children.size(); ++i) - queue.append(first->m_children[i].get()); + auto& first = *queue.takeFirst(); + m_unusedNodesMap.remove(first.sha1); + for (auto& child : first.children) + queue.append(child.get()); } } #ifdef DEBUG_DOM_PATCH_SUPPORT + static String nodeName(Node* node) { if (node->document().isXHTMLDocument()) return node->nodeName(); - return node->nodeName().lower(); + return node->nodeName().convertToASCIILowercase(); } void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name) @@ -513,8 +504,7 @@ void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name) for (size_t i = 0; i < map.size(); ++i) fprintf(stderr, "%s[%lu]: %s (%p) - [%lu]\n", name.utf8().data(), i, map[i].first ? nodeName(map[i].first->m_node).utf8().data() : "", map[i].first, map[i].second); } + #endif } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/DOMPatchSupport.h b/Source/WebCore/inspector/DOMPatchSupport.h index ad5448487..d26c6f461 100644 --- a/Source/WebCore/inspector/DOMPatchSupport.h +++ b/Source/WebCore/inspector/DOMPatchSupport.h @@ -28,16 +28,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DOMPatchSupport_h -#define DOMPatchSupport_h - -#include "ExceptionCode.h" +#pragma once +#include "ExceptionOr.h" #include <wtf/HashMap.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> -#include <wtf/text/WTFString.h> namespace WebCore { @@ -46,43 +41,35 @@ class DOMEditor; class Document; class Node; -#if ENABLE(INSPECTOR) - -class DOMPatchSupport { - WTF_MAKE_NONCOPYABLE(DOMPatchSupport); +class DOMPatchSupport final { public: - static void patchDocument(Document*, const String& markup); - - DOMPatchSupport(DOMEditor*, Document*); - virtual ~DOMPatchSupport(); + DOMPatchSupport(DOMEditor&, Document&); void patchDocument(const String& markup); - Node* patchNode(Node&, const String& markup, ExceptionCode&); + ExceptionOr<Node*> patchNode(Node&, const String& markup); private: struct Digest; - typedef Vector<std::pair<Digest*, size_t>> ResultMap; - typedef HashMap<String, Digest*> UnusedNodesMap; - bool innerPatchNode(Digest* oldNode, Digest* newNode, ExceptionCode&); - std::pair<ResultMap, ResultMap> diff(const Vector<OwnPtr<Digest>>& oldChildren, const Vector<OwnPtr<Digest>>& newChildren); - bool innerPatchChildren(ContainerNode*, const Vector<OwnPtr<Digest>>& oldChildren, const Vector<OwnPtr<Digest>>& newChildren, ExceptionCode&); - PassOwnPtr<Digest> createDigest(Node*, UnusedNodesMap*); - bool insertBeforeAndMarkAsUsed(ContainerNode*, Digest*, Node* anchor, ExceptionCode&); - bool removeChildAndMoveToNew(Digest*, ExceptionCode&); - void markNodeAsUsed(Digest*); + using ResultMap = Vector<std::pair<Digest*, size_t>>; + using UnusedNodesMap = HashMap<String, Digest*>; + + ExceptionOr<void> innerPatchNode(Digest& oldNode, Digest& newNode); + std::pair<ResultMap, ResultMap> diff(const Vector<std::unique_ptr<Digest>>& oldChildren, const Vector<std::unique_ptr<Digest>>& newChildren); + ExceptionOr<void> innerPatchChildren(ContainerNode&, const Vector<std::unique_ptr<Digest>>& oldChildren, const Vector<std::unique_ptr<Digest>>& newChildren); + std::unique_ptr<Digest> createDigest(Node&, UnusedNodesMap*); + ExceptionOr<void> insertBeforeAndMarkAsUsed(ContainerNode&, Digest&, Node* anchor); + ExceptionOr<void> removeChildAndMoveToNew(Digest&); + void markNodeAsUsed(Digest&); + #ifdef DEBUG_DOM_PATCH_SUPPORT void dumpMap(const ResultMap&, const String& name); #endif - DOMEditor* m_domEditor; - Document* m_document; + DOMEditor& m_domEditor; + Document& m_document; UnusedNodesMap m_unusedNodesMap; }; -#endif // ENABLE(INSPECTOR) - } // namespace WebCore - -#endif // !defined(DOMPatchSupport_h) diff --git a/Source/WebCore/inspector/IdentifiersFactory.cpp b/Source/WebCore/inspector/IdentifiersFactory.cpp deleted file mode 100644 index dce2a2850..000000000 --- a/Source/WebCore/inspector/IdentifiersFactory.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "IdentifiersFactory.h" - -#include <wtf/text/StringBuilder.h> - -namespace WebCore { - -namespace { -static long s_lastUsedIdentifier = 0; -} - -// static -long IdentifiersFactory::s_processId; - -// static -String IdentifiersFactory::createIdentifier() -{ - return addProcessIdPrefixTo(String::number(++s_lastUsedIdentifier)); -} - -// static -String IdentifiersFactory::requestId(unsigned long identifier) -{ - if (identifier) - return addProcessIdPrefixTo(String::number(identifier)); - return String(); -} - -// static -String IdentifiersFactory::addProcessIdPrefixTo(const String& id) -{ - StringBuilder builder; - builder.appendNumber(s_processId); - builder.append('.'); - builder.append(id); - return builder.toString(); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp b/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp deleted file mode 100644 index 08d2c8f4f..000000000 --- a/Source/WebCore/inspector/InjectedScriptCanvasModule.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InjectedScriptCanvasModule.h" - -#include "InjectedScriptCanvasModuleSource.h" -#include "JSMainThreadExecState.h" -#include <bindings/ScriptFunctionCall.h> -#include <bindings/ScriptObject.h> -#include <inspector/InjectedScript.h> -#include <inspector/InjectedScriptManager.h> -#include <inspector/InspectorValues.h> - -using Inspector::TypeBuilder::Array; -using Inspector::TypeBuilder::Canvas::ResourceId; -using Inspector::TypeBuilder::Canvas::ResourceInfo; -using Inspector::TypeBuilder::Canvas::ResourceState; -using Inspector::TypeBuilder::Canvas::TraceLog; -using Inspector::TypeBuilder::Canvas::TraceLogId; - -using namespace JSC; -using namespace Inspector; - -namespace WebCore { - -InjectedScriptCanvasModule::InjectedScriptCanvasModule() - : Inspector::InjectedScriptModule("InjectedScriptCanvasModule") -{ -} - -InjectedScriptCanvasModule InjectedScriptCanvasModule::moduleForState(InjectedScriptManager* injectedScriptManager, JSC::ExecState* scriptState) -{ - InjectedScriptCanvasModule result; - result.ensureInjected(injectedScriptManager, scriptState); - return result; -} - -String InjectedScriptCanvasModule::source() const -{ - return String(reinterpret_cast<const char*>(InjectedScriptCanvasModuleSource_js), sizeof(InjectedScriptCanvasModuleSource_js)); -} - -JSC::JSValue InjectedScriptCanvasModule::host(InjectedScriptManager*, JSC::ExecState*) const -{ - return jsUndefined(); -} - -Deprecated::ScriptObject InjectedScriptCanvasModule::wrapCanvas2DContext(const Deprecated::ScriptObject& context) -{ - return callWrapContextFunction("wrapCanvas2DContext", context); -} - -#if ENABLE(WEBGL) -Deprecated::ScriptObject InjectedScriptCanvasModule::wrapWebGLContext(const Deprecated::ScriptObject& glContext) -{ - return callWrapContextFunction("wrapWebGLContext", glContext); -} -#endif // ENABLE(WEBGL) - -Deprecated::ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const Deprecated::ScriptObject& context) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), functionName, WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(context); - bool hadException = false; - Deprecated::ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); - if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) { - ASSERT_NOT_REACHED(); - return Deprecated::ScriptObject(); - } - return Deprecated::ScriptObject(context.scriptState(), resultValue); -} - -void InjectedScriptCanvasModule::markFrameEnd() -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "markFrameEnd", WebCore::functionCallHandlerFromAnyThread); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - ASSERT(resultValue); -} - -void InjectedScriptCanvasModule::captureFrame(ErrorString* errorString, TraceLogId* traceLogId) -{ - callStartCapturingFunction("captureFrame", errorString, traceLogId); -} - -void InjectedScriptCanvasModule::startCapturing(ErrorString* errorString, TraceLogId* traceLogId) -{ - callStartCapturingFunction("startCapturing", errorString, traceLogId); -} - -void InjectedScriptCanvasModule::callStartCapturingFunction(const String& functionName, ErrorString* errorString, TraceLogId* traceLogId) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), functionName, WebCore::functionCallHandlerFromAnyThread); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - if (!resultValue || resultValue->type() != InspectorValue::TypeString || !resultValue->asString(traceLogId)) - *errorString = "Internal error: " + functionName; -} - -void InjectedScriptCanvasModule::stopCapturing(ErrorString* errorString, const TraceLogId& traceLogId) -{ - callVoidFunctionWithTraceLogIdArgument("stopCapturing", errorString, traceLogId); -} - -void InjectedScriptCanvasModule::dropTraceLog(ErrorString* errorString, const TraceLogId& traceLogId) -{ - callVoidFunctionWithTraceLogIdArgument("dropTraceLog", errorString, traceLogId); -} - -void InjectedScriptCanvasModule::callVoidFunctionWithTraceLogIdArgument(const String& functionName, ErrorString* errorString, const TraceLogId& traceLogId) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), functionName, WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - bool hadException = false; - callFunctionWithEvalEnabled(function, hadException); - ASSERT(!hadException); - if (hadException) - *errorString = "Internal error: " + functionName; -} - -void InjectedScriptCanvasModule::traceLog(ErrorString* errorString, const TraceLogId& traceLogId, const int* startOffset, const int* maxLength, RefPtr<TraceLog>* traceLog) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "traceLog", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - if (startOffset) - function.appendArgument(*startOffset); - if (maxLength) - function.appendArgument(*maxLength); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - if (!resultValue || resultValue->type() != InspectorValue::TypeObject) { - if (!resultValue->asString(errorString)) - *errorString = "Internal error: traceLog"; - return; - } - *traceLog = TraceLog::runtimeCast(resultValue); -} - -void InjectedScriptCanvasModule::replayTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, int stepNo, RefPtr<ResourceState>* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "replayTraceLog", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - function.appendArgument(stepNo); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - if (!resultValue || resultValue->type() != InspectorValue::TypeObject) { - if (!resultValue->asString(errorString)) - *errorString = "Internal error: replayTraceLog"; - return; - } - *result = ResourceState::runtimeCast(resultValue); -} - -void InjectedScriptCanvasModule::resourceInfo(ErrorString* errorString, const ResourceId& resourceId, RefPtr<ResourceInfo>* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "resourceInfo", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(resourceId); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - if (!resultValue || resultValue->type() != InspectorValue::TypeObject) { - if (!resultValue->asString(errorString)) - *errorString = "Internal error: resourceInfo"; - return; - } - *result = ResourceInfo::runtimeCast(resultValue); -} - -void InjectedScriptCanvasModule::resourceState(ErrorString* errorString, const TraceLogId& traceLogId, const ResourceId& resourceId, RefPtr<ResourceState>* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "resourceState", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - function.appendArgument(resourceId); - RefPtr<InspectorValue> resultValue; - makeCall(function, &resultValue); - if (!resultValue || resultValue->type() != InspectorValue::TypeObject) { - if (!resultValue->asString(errorString)) - *errorString = "Internal error: resourceState"; - return; - } - *result = ResourceState::runtimeCast(resultValue); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModule.h b/Source/WebCore/inspector/InjectedScriptCanvasModule.h deleted file mode 100644 index 86ba700d8..000000000 --- a/Source/WebCore/inspector/InjectedScriptCanvasModule.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InjectedScriptCanvasModule_h -#define InjectedScriptCanvasModule_h - -#include "InspectorWebTypeBuilders.h" -#include "ScriptState.h" -#include <inspector/InjectedScriptModule.h> -#include <wtf/text/WTFString.h> - -namespace Deprecated { -class ScriptObject; -} - -namespace WebCore { - -typedef String ErrorString; - -#if ENABLE(INSPECTOR) - -class InjectedScriptCanvasModule final : public Inspector::InjectedScriptModule { -public: - InjectedScriptCanvasModule(); - - virtual String source() const override; - virtual JSC::JSValue host(Inspector::InjectedScriptManager*, JSC::ExecState*) const override; - virtual bool returnsObject() const override { return true; } - - static InjectedScriptCanvasModule moduleForState(Inspector::InjectedScriptManager*, JSC::ExecState*); - - Deprecated::ScriptObject wrapCanvas2DContext(const Deprecated::ScriptObject&); -#if ENABLE(WEBGL) - Deprecated::ScriptObject wrapWebGLContext(const Deprecated::ScriptObject&); -#endif - void markFrameEnd(); - - void captureFrame(ErrorString*, Inspector::TypeBuilder::Canvas::TraceLogId*); - void startCapturing(ErrorString*, Inspector::TypeBuilder::Canvas::TraceLogId*); - void stopCapturing(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&); - void dropTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&); - void traceLog(ErrorString*, const String&, const int*, const int*, RefPtr<Inspector::TypeBuilder::Canvas::TraceLog>*); - void replayTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, int, RefPtr<Inspector::TypeBuilder::Canvas::ResourceState>*); - void resourceInfo(ErrorString*, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr<Inspector::TypeBuilder::Canvas::ResourceInfo>*); - void resourceState(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr<Inspector::TypeBuilder::Canvas::ResourceState>*); - -private: - Deprecated::ScriptObject callWrapContextFunction(const String&, const Deprecated::ScriptObject&); - void callStartCapturingFunction(const String&, ErrorString*, String*); - void callVoidFunctionWithTraceLogIdArgument(const String&, ErrorString*, const String&); -}; - -#endif - -} // namespace WebCore - -#endif // !defined(InjectedScriptCanvasModule_h) diff --git a/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js b/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js deleted file mode 100644 index 8036985d5..000000000 --- a/Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js +++ /dev/null @@ -1,3216 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @param {InjectedScriptHost} InjectedScriptHost - * @param {Window} inspectedWindow - * @param {number} injectedScriptId - */ -(function (InjectedScriptHost, inspectedWindow, injectedScriptId) { - -var TypeUtils = { - /** - * http://www.khronos.org/registry/typedarray/specs/latest/#7 - * @const - * @type {!Array.<function(new:ArrayBufferView, ArrayBufferView)>} - */ - _typedArrayClasses: (function(typeNames) { - var result = []; - for (var i = 0, n = typeNames.length; i < n; ++i) { - if (inspectedWindow[typeNames[i]]) - result.push(inspectedWindow[typeNames[i]]); - } - return result; - })(["Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array"]), - - /** - * @const - * @type {!Array.<string>} - */ - _supportedPropertyPrefixes: ["webkit"], - - /** - * @param {*} array - * @return {function(new:ArrayBufferView, ArrayBufferView)|null} - */ - typedArrayClass: function(array) - { - var classes = TypeUtils._typedArrayClasses; - for (var i = 0, n = classes.length; i < n; ++i) { - if (array instanceof classes[i]) - return classes[i]; - } - return null; - }, - - /** - * @param {*} obj - * @return {*} - */ - clone: function(obj) - { - if (!obj) - return obj; - - var type = typeof obj; - if (type !== "object" && type !== "function") - return obj; - - // Handle Array and ArrayBuffer instances. - if (typeof obj.slice === "function") { - console.assert(obj instanceof Array || obj instanceof ArrayBuffer); - return obj.slice(0); - } - - var typedArrayClass = TypeUtils.typedArrayClass(obj); - if (typedArrayClass) - return new typedArrayClass(/** @type {ArrayBufferView} */ (obj)); - - if (obj instanceof HTMLImageElement) { - var img = /** @type {HTMLImageElement} */ (obj); - // Special case for Images with Blob URIs: cloneNode will fail if the Blob URI has already been revoked. - // FIXME: Maybe this is a bug in WebKit core? - if (/^blob:/.test(img.src)) - return TypeUtils.cloneIntoCanvas(img); - return img.cloneNode(true); - } - - if (obj instanceof HTMLCanvasElement) - return TypeUtils.cloneIntoCanvas(obj); - - if (obj instanceof HTMLVideoElement) - return TypeUtils.cloneIntoCanvas(obj, obj.videoWidth, obj.videoHeight); - - if (obj instanceof ImageData) { - var context = TypeUtils._dummyCanvas2dContext(); - // FIXME: suppress type checks due to outdated builtin externs for createImageData. - var result = (/** @type {?} */ (context)).createImageData(obj); - for (var i = 0, n = obj.data.length; i < n; ++i) - result.data[i] = obj.data[i]; - return result; - } - - console.error("ASSERT_NOT_REACHED: failed to clone object: ", obj); - return obj; - }, - - /** - * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} obj - * @param {number=} width - * @param {number=} height - * @return {HTMLCanvasElement} - */ - cloneIntoCanvas: function(obj, width, height) - { - var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas")); - canvas.width = width || +obj.width; - canvas.height = height || +obj.height; - var context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d"))); - context.drawImage(obj, 0, 0); - return canvas; - }, - - /** - * @param {Object=} obj - * @return {Object} - */ - cloneObject: function(obj) - { - if (!obj) - return null; - var result = {}; - for (var key in obj) - result[key] = obj[key]; - return result; - }, - - /** - * @param {!Array.<string>} names - * @return {!Object.<string, boolean>} - */ - createPrefixedPropertyNamesSet: function(names) - { - var result = Object.create(null); - for (var i = 0, name; name = names[i]; ++i) { - result[name] = true; - var suffix = name.substr(0, 1).toUpperCase() + name.substr(1); - for (var j = 0, prefix; prefix = TypeUtils._supportedPropertyPrefixes[j]; ++j) - result[prefix + suffix] = true; - } - return result; - }, - - /** - * @return {CanvasRenderingContext2D} - */ - _dummyCanvas2dContext: function() - { - var context = TypeUtils._dummyCanvas2dContextInstance; - if (!context) { - var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas")); - context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d"))); - TypeUtils._dummyCanvas2dContextInstance = context; - } - return context; - } -} - -/** - * @interface - */ -function StackTrace() -{ -} - -StackTrace.prototype = { - /** - * @param {number} index - * @return {{sourceURL: string, lineNumber: number, columnNumber: number}|undefined} - */ - callFrame: function(index) - { - } -} - -/** - * @param {number=} stackTraceLimit - * @param {Function=} topMostFunctionToIgnore - * @return {StackTrace} - */ -StackTrace.create = function(stackTraceLimit, topMostFunctionToIgnore) -{ - // FIXME: Support JSC, and maybe other browsers. - return null; -} - -/** - * @constructor - */ -function Cache() -{ - this.reset(); -} - -Cache.prototype = { - /** - * @return {number} - */ - size: function() - { - return this._size; - }, - - reset: function() - { - /** @type {!Object.<number, Object>} */ - this._items = Object.create(null); - /** @type {number} */ - this._size = 0; - }, - - /** - * @param {number} key - * @return {boolean} - */ - has: function(key) - { - return key in this._items; - }, - - /** - * @param {number} key - * @return {Object} - */ - get: function(key) - { - return this._items[key]; - }, - - /** - * @param {number} key - * @param {Object} item - */ - put: function(key, item) - { - if (!this.has(key)) - ++this._size; - this._items[key] = item; - } -} - -/** - * @constructor - * @param {Resource|Object} thisObject - * @param {string} functionName - * @param {Array|Arguments} args - * @param {Resource|*=} result - * @param {StackTrace=} stackTrace - */ -function Call(thisObject, functionName, args, result, stackTrace) -{ - this._thisObject = thisObject; - this._functionName = functionName; - this._args = Array.prototype.slice.call(args, 0); - this._result = result; - this._stackTrace = stackTrace || null; - - if (!this._functionName) - console.assert(this._args.length === 2 && typeof this._args[0] === "string"); -} - -Call.prototype = { - /** - * @return {Resource} - */ - resource: function() - { - return Resource.forObject(this._thisObject); - }, - - /** - * @return {string} - */ - functionName: function() - { - return this._functionName; - }, - - /** - * @return {boolean} - */ - isPropertySetter: function() - { - return !this._functionName; - }, - - /** - * @return {!Array} - */ - args: function() - { - return this._args; - }, - - /** - * @return {*} - */ - result: function() - { - return this._result; - }, - - /** - * @return {StackTrace} - */ - stackTrace: function() - { - return this._stackTrace; - }, - - /** - * @param {StackTrace} stackTrace - */ - setStackTrace: function(stackTrace) - { - this._stackTrace = stackTrace; - }, - - /** - * @param {*} result - */ - setResult: function(result) - { - this._result = result; - }, - - /** - * @param {string} name - * @param {Object} attachment - */ - setAttachment: function(name, attachment) - { - if (attachment) { - /** @type {Object.<string, Object>} */ - this._attachments = this._attachments || Object.create(null); - this._attachments[name] = attachment; - } else if (this._attachments) - delete this._attachments[name]; - }, - - /** - * @param {string} name - * @return {Object} - */ - attachment: function(name) - { - return this._attachments && this._attachments[name]; - }, - - freeze: function() - { - if (this._freezed) - return; - this._freezed = true; - for (var i = 0, n = this._args.length; i < n; ++i) { - // FIXME: freeze the Resources also! - if (!Resource.forObject(this._args[i])) - this._args[i] = TypeUtils.clone(this._args[i]); - } - }, - - /** - * @param {!Cache} cache - * @return {!ReplayableCall} - */ - toReplayable: function(cache) - { - this.freeze(); - var thisObject = /** @type {ReplayableResource} */ (Resource.toReplayable(this._thisObject, cache)); - var result = Resource.toReplayable(this._result, cache); - var args = this._args.map(function(obj) { - return Resource.toReplayable(obj, cache); - }); - var attachments = TypeUtils.cloneObject(this._attachments); - return new ReplayableCall(thisObject, this._functionName, args, result, this._stackTrace, attachments); - }, - - /** - * @param {!ReplayableCall} replayableCall - * @param {!Cache} cache - * @return {!Call} - */ - replay: function(replayableCall, cache) - { - var replayObject = ReplayableResource.replay(replayableCall.replayableResource(), cache); - var replayArgs = replayableCall.args().map(function(obj) { - return ReplayableResource.replay(obj, cache); - }); - var replayResult = undefined; - - if (replayableCall.isPropertySetter()) - replayObject[replayArgs[0]] = replayArgs[1]; - else { - var replayFunction = replayObject[replayableCall.functionName()]; - console.assert(typeof replayFunction === "function", "Expected a function to replay"); - replayResult = replayFunction.apply(replayObject, replayArgs); - if (replayableCall.result() instanceof ReplayableResource) { - var resource = replayableCall.result().replay(cache); - if (!resource.wrappedObject()) - resource.setWrappedObject(replayResult); - } - } - - this._thisObject = replayObject; - this._functionName = replayableCall.functionName(); - this._args = replayArgs; - this._result = replayResult; - this._stackTrace = replayableCall.stackTrace(); - this._freezed = true; - var attachments = replayableCall.attachments(); - if (attachments) - this._attachments = TypeUtils.cloneObject(attachments); - return this; - } -} - -/** - * @constructor - * @param {ReplayableResource} thisObject - * @param {string} functionName - * @param {Array.<ReplayableResource|*>} args - * @param {ReplayableResource|*} result - * @param {StackTrace} stackTrace - * @param {Object.<string, Object>} attachments - */ -function ReplayableCall(thisObject, functionName, args, result, stackTrace, attachments) -{ - this._thisObject = thisObject; - this._functionName = functionName; - this._args = args; - this._result = result; - this._stackTrace = stackTrace; - if (attachments) - this._attachments = attachments; -} - -ReplayableCall.prototype = { - /** - * @return {ReplayableResource} - */ - replayableResource: function() - { - return this._thisObject; - }, - - /** - * @return {string} - */ - functionName: function() - { - return this._functionName; - }, - - /** - * @return {boolean} - */ - isPropertySetter: function() - { - return !this._functionName; - }, - - /** - * @return {Array.<ReplayableResource|*>} - */ - args: function() - { - return this._args; - }, - - /** - * @return {ReplayableResource|*} - */ - result: function() - { - return this._result; - }, - - /** - * @return {StackTrace} - */ - stackTrace: function() - { - return this._stackTrace; - }, - - /** - * @return {Object.<string, Object>} - */ - attachments: function() - { - return this._attachments; - }, - - /** - * @param {string} name - * @return {Object} - */ - attachment: function(name) - { - return this._attachments && this._attachments[name]; - }, - - /** - * @param {Cache} cache - * @return {!Call} - */ - replay: function(cache) - { - var call = /** @type {!Call} */ (Object.create(Call.prototype)); - return call.replay(this, cache); - } -} - -/** - * @constructor - * @param {!Object} wrappedObject - * @param {string} name - */ -function Resource(wrappedObject, name) -{ - /** @type {number} */ - this._id = ++Resource._uniqueId; - /** @type {string} */ - this._name = name || "Resource"; - /** @type {number} */ - this._kindId = Resource._uniqueKindIds[this._name] = (Resource._uniqueKindIds[this._name] || 0) + 1; - /** @type {ResourceTrackingManager} */ - this._resourceManager = null; - /** @type {!Array.<Call>} */ - this._calls = []; - /** - * This is to prevent GC from collecting associated resources. - * Otherwise, for example in WebGL, subsequent calls to gl.getParameter() - * may return a recently created instance that is no longer bound to a - * Resource object (thus, no history to replay it later). - * - * @type {!Object.<string, Resource>} - */ - this._boundResources = Object.create(null); - this.setWrappedObject(wrappedObject); -} - -/** - * @type {number} - */ -Resource._uniqueId = 0; - -/** - * @type {!Object.<string, number>} - */ -Resource._uniqueKindIds = {}; - -/** - * @param {*} obj - * @return {Resource} - */ -Resource.forObject = function(obj) -{ - if (!obj) - return null; - if (obj instanceof Resource) - return obj; - if (typeof obj === "object") - return obj["__resourceObject"]; - return null; -} - -/** - * @param {Resource|*} obj - * @return {*} - */ -Resource.wrappedObject = function(obj) -{ - var resource = Resource.forObject(obj); - return resource ? resource.wrappedObject() : obj; -} - -/** - * @param {Resource|*} obj - * @param {!Cache} cache - * @return {ReplayableResource|*} - */ -Resource.toReplayable = function(obj, cache) -{ - var resource = Resource.forObject(obj); - return resource ? resource.toReplayable(cache) : obj; -} - -Resource.prototype = { - /** - * @return {number} - */ - id: function() - { - return this._id; - }, - - /** - * @return {Object} - */ - wrappedObject: function() - { - return this._wrappedObject; - }, - - /** - * @param {!Object} value - */ - setWrappedObject: function(value) - { - console.assert(value, "wrappedObject should not be NULL"); - console.assert(!(value instanceof Resource), "Binding a Resource object to another Resource object?"); - this._wrappedObject = value; - this._bindObjectToResource(value); - }, - - /** - * @return {Object} - */ - proxyObject: function() - { - if (!this._proxyObject) - this._proxyObject = this._wrapObject(); - return this._proxyObject; - }, - - /** - * @return {ResourceTrackingManager} - */ - manager: function() - { - return this._resourceManager; - }, - - /** - * @param {ResourceTrackingManager} value - */ - setManager: function(value) - { - this._resourceManager = value; - }, - - /** - * @return {!Array.<Call>} - */ - calls: function() - { - return this._calls; - }, - - /** - * @return {ContextResource} - */ - contextResource: function() - { - if (this instanceof ContextResource) - return /** @type {ContextResource} */ (this); - - if (this._calculatingContextResource) - return null; - - this._calculatingContextResource = true; - var result = null; - for (var i = 0, n = this._calls.length; i < n; ++i) { - result = this._calls[i].resource().contextResource(); - if (result) - break; - } - delete this._calculatingContextResource; - console.assert(result, "Failed to find context resource for " + this._name + "@" + this._kindId); - return result; - }, - - /** - * @return {string} - */ - toDataURL: function() - { - return ""; - }, - - /** - * @param {!Cache} cache - * @return {!ReplayableResource} - */ - toReplayable: function(cache) - { - var result = /** @type {ReplayableResource} */ (cache.get(this._id)); - if (result) - return result; - var data = { - id: this._id, - name: this._name, - kindId: this._kindId - }; - result = new ReplayableResource(this, data); - cache.put(this._id, result); // Put into the cache early to avoid loops. - data.calls = this._calls.map(function(call) { - return call.toReplayable(cache); - }); - this._populateReplayableData(data, cache); - var contextResource = this.contextResource(); - if (contextResource !== this) - data.contextResource = Resource.toReplayable(contextResource, cache); - return result; - }, - - /** - * @param {!Object} data - * @param {!Cache} cache - */ - _populateReplayableData: function(data, cache) - { - // Do nothing. Should be overridden by subclasses. - }, - - /** - * @param {!Object} data - * @param {!Cache} cache - * @return {!Resource} - */ - replay: function(data, cache) - { - var resource = /** @type {Resource} */ (cache.get(data.id)); - if (resource) - return resource; - this._id = data.id; - this._name = data.name; - this._kindId = data.kindId; - this._resourceManager = null; - this._calls = []; - this._boundResources = Object.create(null); - this._wrappedObject = null; - cache.put(data.id, this); // Put into the cache early to avoid loops. - this._doReplayCalls(data, cache); - console.assert(this._wrappedObject, "Resource should be reconstructed!"); - return this; - }, - - /** - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - for (var i = 0, n = data.calls.length; i < n; ++i) - this._calls.push(data.calls[i].replay(cache)); - }, - - /** - * @param {!Call} call - */ - pushCall: function(call) - { - call.freeze(); - this._calls.push(call); - }, - - /** - * @param {!Object} object - */ - _bindObjectToResource: function(object) - { - Object.defineProperty(object, "__resourceObject", { - value: this, - writable: false, - enumerable: false, - configurable: true - }); - }, - - /** - * @param {string} key - * @param {*} obj - */ - _registerBoundResource: function(key, obj) - { - var resource = Resource.forObject(obj); - if (resource) - this._boundResources[key] = resource; - else - delete this._boundResources[key]; - }, - - /** - * @return {Object} - */ - _wrapObject: function() - { - var wrappedObject = this.wrappedObject(); - if (!wrappedObject) - return null; - var proxy = Object.create(wrappedObject.__proto__); // In order to emulate "instanceof". - - var self = this; - var customWrapFunctions = this._customWrapFunctions(); - function processProperty(property) - { - if (typeof wrappedObject[property] === "function") { - var customWrapFunction = customWrapFunctions[property]; - if (customWrapFunction) - proxy[property] = self._wrapCustomFunction(self, wrappedObject, wrappedObject[property], property, customWrapFunction); - else - proxy[property] = self._wrapFunction(self, wrappedObject, wrappedObject[property], property); - } else if (/^[A-Z0-9_]+$/.test(property) && typeof wrappedObject[property] === "number") { - // Fast access to enums and constants. - proxy[property] = wrappedObject[property]; - } else { - Object.defineProperty(proxy, property, { - get: function() - { - var obj = wrappedObject[property]; - var resource = Resource.forObject(obj); - return resource ? resource : obj; - }, - set: self._wrapPropertySetter(self, wrappedObject, property), - enumerable: true - }); - } - } - - var isEmpty = true; - for (var property in wrappedObject) { - isEmpty = false; - processProperty(property); - } - if (isEmpty) - return wrappedObject; // Nothing to proxy. - - this._bindObjectToResource(proxy); - return proxy; - }, - - /** - * @param {!Resource} resource - * @param {!Object} originalObject - * @param {!Function} originalFunction - * @param {string} functionName - * @param {!Function} customWrapFunction - * @return {!Function} - */ - _wrapCustomFunction: function(resource, originalObject, originalFunction, functionName, customWrapFunction) - { - return function() - { - var manager = resource.manager(); - var isCapturing = manager && manager.capturing(); - if (isCapturing) - manager.captureArguments(resource, arguments); - var wrapFunction = new Resource.WrapFunction(originalObject, originalFunction, functionName, arguments); - customWrapFunction.apply(wrapFunction, arguments); - if (isCapturing) { - var call = wrapFunction.call(); - call.setStackTrace(StackTrace.create(1, arguments.callee)); - manager.captureCall(call); - } - return wrapFunction.result(); - }; - }, - - /** - * @param {!Resource} resource - * @param {!Object} originalObject - * @param {!Function} originalFunction - * @param {string} functionName - * @return {!Function} - */ - _wrapFunction: function(resource, originalObject, originalFunction, functionName) - { - return function() - { - var manager = resource.manager(); - if (!manager || !manager.capturing()) - return originalFunction.apply(originalObject, arguments); - manager.captureArguments(resource, arguments); - var result = originalFunction.apply(originalObject, arguments); - var stackTrace = StackTrace.create(1, arguments.callee); - var call = new Call(resource, functionName, arguments, result, stackTrace); - manager.captureCall(call); - return result; - }; - }, - - /** - * @param {!Resource} resource - * @param {!Object} originalObject - * @param {string} propertyName - * @return {function(*)} - */ - _wrapPropertySetter: function(resource, originalObject, propertyName) - { - return function(value) - { - resource._registerBoundResource(propertyName, value); - var manager = resource.manager(); - if (!manager || !manager.capturing()) { - originalObject[propertyName] = Resource.wrappedObject(value); - return; - } - var args = [propertyName, value]; - manager.captureArguments(resource, args); - originalObject[propertyName] = Resource.wrappedObject(value); - var stackTrace = StackTrace.create(1, arguments.callee); - var call = new Call(resource, "", args, undefined, stackTrace); - manager.captureCall(call); - }; - }, - - /** - * @return {!Object.<string, Function>} - */ - _customWrapFunctions: function() - { - return Object.create(null); // May be overridden by subclasses. - } -} - -/** - * @constructor - * @param {Object} originalObject - * @param {Function} originalFunction - * @param {string} functionName - * @param {Array|Arguments} args - */ -Resource.WrapFunction = function(originalObject, originalFunction, functionName, args) -{ - this._originalObject = originalObject; - this._originalFunction = originalFunction; - this._functionName = functionName; - this._args = args; - this._resource = Resource.forObject(originalObject); - console.assert(this._resource, "Expected a wrapped call on a Resource object."); -} - -Resource.WrapFunction.prototype = { - /** - * @return {*} - */ - result: function() - { - if (!this._executed) { - this._executed = true; - this._result = this._originalFunction.apply(this._originalObject, this._args); - } - return this._result; - }, - - /** - * @return {!Call} - */ - call: function() - { - if (!this._call) - this._call = new Call(this._resource, this._functionName, this._args, this.result()); - return this._call; - }, - - /** - * @param {*} result - */ - overrideResult: function(result) - { - var call = this.call(); - call.setResult(result); - this._result = result; - } -} - -/** - * @param {function(new:Resource, !Object, string)} resourceConstructor - * @param {string} resourceName - * @return {function(this:Resource.WrapFunction)} - */ -Resource.WrapFunction.resourceFactoryMethod = function(resourceConstructor, resourceName) -{ - /** @this Resource.WrapFunction */ - return function() - { - var wrappedObject = /** @type {Object} */ (this.result()); - if (!wrappedObject) - return; - var resource = new resourceConstructor(wrappedObject, resourceName); - var manager = this._resource.manager(); - if (manager) - manager.registerResource(resource); - this.overrideResult(resource.proxyObject()); - resource.pushCall(this.call()); - } -} - -/** - * @constructor - * @param {!Resource} originalResource - * @param {!Object} data - */ -function ReplayableResource(originalResource, data) -{ - this._proto = originalResource.__proto__; - this._data = data; -} - -ReplayableResource.prototype = { - /** - * @return {number} - */ - id: function() - { - return this._data.id; - }, - - /** - * @return {string} - */ - name: function() - { - return this._data.name; - }, - - /** - * @return {string} - */ - description: function() - { - return this._data.name + "@" + this._data.kindId; - }, - - /** - * @return {!ReplayableResource} - */ - replayableContextResource: function() - { - return this._data.contextResource || this; - }, - - /** - * @param {!Cache} cache - * @return {!Resource} - */ - replay: function(cache) - { - var result = /** @type {!Resource} */ (Object.create(this._proto)); - result = result.replay(this._data, cache) - console.assert(result.__proto__ === this._proto, "Wrong type of a replay result"); - return result; - } -} - -/** - * @param {ReplayableResource|*} obj - * @param {!Cache} cache - * @return {*} - */ -ReplayableResource.replay = function(obj, cache) -{ - return (obj instanceof ReplayableResource) ? obj.replay(cache).wrappedObject() : obj; -} - -/** - * @constructor - * @extends {Resource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function ContextResource(wrappedObject, name) -{ - Resource.call(this, wrappedObject, name); -} - -ContextResource.prototype = { - __proto__: Resource.prototype -} - -/** - * @constructor - * @extends {Resource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function LogEverythingResource(wrappedObject, name) -{ - Resource.call(this, wrappedObject, name); -} - -LogEverythingResource.prototype = { - /** - * @override - * @return {!Object.<string, Function>} - */ - _customWrapFunctions: function() - { - var wrapFunctions = Object.create(null); - var wrappedObject = this.wrappedObject(); - if (wrappedObject) { - for (var property in wrappedObject) { - /** @this Resource.WrapFunction */ - wrapFunctions[property] = function() - { - this._resource.pushCall(this.call()); - } - } - } - return wrapFunctions; - }, - - __proto__: Resource.prototype -} - -//////////////////////////////////////////////////////////////////////////////// -// WebGL -//////////////////////////////////////////////////////////////////////////////// - -/** - * @constructor - * @extends {Resource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLBoundResource(wrappedObject, name) -{ - Resource.call(this, wrappedObject, name); - /** @type {!Object.<string, *>} */ - this._state = {}; -} - -WebGLBoundResource.prototype = { - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _populateReplayableData: function(data, cache) - { - var state = this._state; - data.state = {}; - Object.keys(state).forEach(function(parameter) { - data.state[parameter] = Resource.toReplayable(state[parameter], cache); - }); - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - var gl = this._replayContextResource(data, cache).wrappedObject(); - - /** @type {!Object.<string, Array.<string>>} */ - var bindingsData = { - TEXTURE_2D: ["bindTexture", "TEXTURE_BINDING_2D"], - TEXTURE_CUBE_MAP: ["bindTexture", "TEXTURE_BINDING_CUBE_MAP"], - ARRAY_BUFFER: ["bindBuffer", "ARRAY_BUFFER_BINDING"], - ELEMENT_ARRAY_BUFFER: ["bindBuffer", "ELEMENT_ARRAY_BUFFER_BINDING"], - FRAMEBUFFER: ["bindFramebuffer", "FRAMEBUFFER_BINDING"], - RENDERBUFFER: ["bindRenderbuffer", "RENDERBUFFER_BINDING"] - }; - var originalBindings = {}; - Object.keys(bindingsData).forEach(function(bindingTarget) { - var bindingParameter = bindingsData[bindingTarget][1]; - originalBindings[bindingTarget] = gl.getParameter(gl[bindingParameter]); - }); - - var state = {}; - Object.keys(data.state).forEach(function(parameter) { - state[parameter] = ReplayableResource.replay(data.state[parameter], cache); - }); - this._state = state; - Resource.prototype._doReplayCalls.call(this, data, cache); - - Object.keys(bindingsData).forEach(function(bindingTarget) { - var bindMethodName = bindingsData[bindingTarget][0]; - gl[bindMethodName].call(gl, gl[bindingTarget], originalBindings[bindingTarget]); - }); - }, - - /** - * @param {!Object} data - * @param {!Cache} cache - * @return {WebGLRenderingContextResource} - */ - _replayContextResource: function(data, cache) - { - var calls = /** @type {!Array.<ReplayableCall>} */ (data.calls); - for (var i = 0, n = calls.length; i < n; ++i) { - var resource = ReplayableResource.replay(calls[i].replayableResource(), cache); - var contextResource = WebGLRenderingContextResource.forObject(resource); - if (contextResource) - return contextResource; - } - return null; - }, - - /** - * @param {number} target - * @param {string} bindMethodName - */ - pushBinding: function(target, bindMethodName) - { - if (this._state.BINDING !== target) { - this._state.BINDING = target; - this.pushCall(new Call(WebGLRenderingContextResource.forObject(this), bindMethodName, [target, this])); - } - }, - - __proto__: Resource.prototype -} - -/** - * @constructor - * @extends {WebGLBoundResource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLTextureResource(wrappedObject, name) -{ - WebGLBoundResource.call(this, wrappedObject, name); -} - -WebGLTextureResource.prototype = { - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - var gl = this._replayContextResource(data, cache).wrappedObject(); - - var state = {}; - WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) { - state[parameter] = gl.getParameter(gl[parameter]); - }); - - WebGLBoundResource.prototype._doReplayCalls.call(this, data, cache); - - WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) { - gl.pixelStorei(gl[parameter], state[parameter]); - }); - }, - - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - var gl = WebGLRenderingContextResource.forObject(call.resource()).wrappedObject(); - WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) { - var value = gl.getParameter(gl[parameter]); - if (this._state[parameter] !== value) { - this._state[parameter] = value; - var pixelStoreCall = new Call(gl, "pixelStorei", [gl[parameter], value]); - WebGLBoundResource.prototype.pushCall.call(this, pixelStoreCall); - } - }, this); - - // FIXME: remove any older calls that no longer contribute to the resource state. - // FIXME: optimize memory usage: maybe it's more efficient to store one texImage2D call instead of many texSubImage2D. - WebGLBoundResource.prototype.pushCall.call(this, call); - }, - - /** - * Handles: texParameteri, texParameterf - * @param {!Call} call - */ - pushCall_texParameter: function(call) - { - var args = call.args(); - var pname = args[1]; - var param = args[2]; - if (this._state[pname] !== param) { - this._state[pname] = param; - WebGLBoundResource.prototype.pushCall.call(this, call); - } - }, - - /** - * Handles: copyTexImage2D, copyTexSubImage2D - * copyTexImage2D and copyTexSubImage2D define a texture image with pixels from the current framebuffer. - * @param {!Call} call - */ - pushCall_copyTexImage2D: function(call) - { - var glResource = WebGLRenderingContextResource.forObject(call.resource()); - var gl = glResource.wrappedObject(); - var framebufferResource = /** @type {WebGLFramebufferResource} */ (glResource.currentBinding(gl.FRAMEBUFFER)); - if (framebufferResource) - this.pushCall(new Call(glResource, "bindFramebuffer", [gl.FRAMEBUFFER, framebufferResource])); - else { - // FIXME: Implement this case. - console.error("ASSERT_NOT_REACHED: Could not properly process a gl." + call.functionName() + " call while the DRAWING BUFFER is bound."); - } - this.pushCall(call); - }, - - __proto__: WebGLBoundResource.prototype -} - -/** - * @constructor - * @extends {Resource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLProgramResource(wrappedObject, name) -{ - Resource.call(this, wrappedObject, name); -} - -WebGLProgramResource.prototype = { - /** - * @override (overrides @return type) - * @return {WebGLProgram} - */ - wrappedObject: function() - { - return this._wrappedObject; - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _populateReplayableData: function(data, cache) - { - var glResource = WebGLRenderingContextResource.forObject(this); - var gl = glResource.wrappedObject(); - var program = this.wrappedObject(); - - var originalErrors = glResource.getAllErrors(); - - var uniforms = []; - var uniformsCount = /** @type {number} */ (gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)); - for (var i = 0; i < uniformsCount; ++i) { - var activeInfo = gl.getActiveUniform(program, i); - if (!activeInfo) - continue; - var uniformLocation = gl.getUniformLocation(program, activeInfo.name); - if (!uniformLocation) - continue; - var value = gl.getUniform(program, uniformLocation); - uniforms.push({ - name: activeInfo.name, - type: activeInfo.type, - value: value - }); - } - data.uniforms = uniforms; - - glResource.restoreErrors(originalErrors); - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - Resource.prototype._doReplayCalls.call(this, data, cache); - var gl = WebGLRenderingContextResource.forObject(this).wrappedObject(); - var program = this.wrappedObject(); - - var originalProgram = /** @type {WebGLProgram} */ (gl.getParameter(gl.CURRENT_PROGRAM)); - var currentProgram = originalProgram; - - data.uniforms.forEach(function(uniform) { - var uniformLocation = gl.getUniformLocation(program, uniform.name); - if (!uniformLocation) - return; - if (currentProgram !== program) { - currentProgram = program; - gl.useProgram(program); - } - var methodName = this._uniformMethodNameByType(gl, uniform.type); - if (methodName.indexOf("Matrix") === -1) - gl[methodName].call(gl, uniformLocation, uniform.value); - else - gl[methodName].call(gl, uniformLocation, false, uniform.value); - }.bind(this)); - - if (currentProgram !== originalProgram) - gl.useProgram(originalProgram); - }, - - /** - * @param {WebGLRenderingContext} gl - * @param {number} type - * @return {string} - */ - _uniformMethodNameByType: function(gl, type) - { - var uniformMethodNames = WebGLProgramResource._uniformMethodNames; - if (!uniformMethodNames) { - uniformMethodNames = {}; - uniformMethodNames[gl.FLOAT] = "uniform1f"; - uniformMethodNames[gl.FLOAT_VEC2] = "uniform2fv"; - uniformMethodNames[gl.FLOAT_VEC3] = "uniform3fv"; - uniformMethodNames[gl.FLOAT_VEC4] = "uniform4fv"; - uniformMethodNames[gl.INT] = "uniform1i"; - uniformMethodNames[gl.BOOL] = "uniform1i"; - uniformMethodNames[gl.SAMPLER_2D] = "uniform1i"; - uniformMethodNames[gl.SAMPLER_CUBE] = "uniform1i"; - uniformMethodNames[gl.INT_VEC2] = "uniform2iv"; - uniformMethodNames[gl.BOOL_VEC2] = "uniform2iv"; - uniformMethodNames[gl.INT_VEC3] = "uniform3iv"; - uniformMethodNames[gl.BOOL_VEC3] = "uniform3iv"; - uniformMethodNames[gl.INT_VEC4] = "uniform4iv"; - uniformMethodNames[gl.BOOL_VEC4] = "uniform4iv"; - uniformMethodNames[gl.FLOAT_MAT2] = "uniformMatrix2fv"; - uniformMethodNames[gl.FLOAT_MAT3] = "uniformMatrix3fv"; - uniformMethodNames[gl.FLOAT_MAT4] = "uniformMatrix4fv"; - WebGLProgramResource._uniformMethodNames = uniformMethodNames; - } - console.assert(uniformMethodNames[type], "Unknown uniform type " + type); - return uniformMethodNames[type]; - }, - - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - // FIXME: remove any older calls that no longer contribute to the resource state. - // FIXME: handle multiple attachShader && detachShader. - Resource.prototype.pushCall.call(this, call); - }, - - __proto__: Resource.prototype -} - -/** - * @constructor - * @extends {Resource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLShaderResource(wrappedObject, name) -{ - Resource.call(this, wrappedObject, name); -} - -WebGLShaderResource.prototype = { - /** - * @return {number} - */ - type: function() - { - var call = this._calls[0]; - if (call && call.functionName() === "createShader") - return call.args()[0]; - console.error("ASSERT_NOT_REACHED: Failed to restore shader type from the log.", call); - return 0; - }, - - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - // FIXME: remove any older calls that no longer contribute to the resource state. - // FIXME: handle multiple shaderSource calls. - Resource.prototype.pushCall.call(this, call); - }, - - __proto__: Resource.prototype -} - -/** - * @constructor - * @extends {WebGLBoundResource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLBufferResource(wrappedObject, name) -{ - WebGLBoundResource.call(this, wrappedObject, name); -} - -WebGLBufferResource.prototype = { - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - // FIXME: remove any older calls that no longer contribute to the resource state. - // FIXME: Optimize memory for bufferSubData. - WebGLBoundResource.prototype.pushCall.call(this, call); - }, - - __proto__: WebGLBoundResource.prototype -} - -/** - * @constructor - * @extends {WebGLBoundResource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLFramebufferResource(wrappedObject, name) -{ - WebGLBoundResource.call(this, wrappedObject, name); -} - -WebGLFramebufferResource.prototype = { - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - // FIXME: remove any older calls that no longer contribute to the resource state. - WebGLBoundResource.prototype.pushCall.call(this, call); - }, - - __proto__: WebGLBoundResource.prototype -} - -/** - * @constructor - * @extends {WebGLBoundResource} - * @param {!Object} wrappedObject - * @param {string} name - */ -function WebGLRenderbufferResource(wrappedObject, name) -{ - WebGLBoundResource.call(this, wrappedObject, name); -} - -WebGLRenderbufferResource.prototype = { - /** - * @override - * @param {!Call} call - */ - pushCall: function(call) - { - // FIXME: remove any older calls that no longer contribute to the resource state. - WebGLBoundResource.prototype.pushCall.call(this, call); - }, - - __proto__: WebGLBoundResource.prototype -} - -/** - * @constructor - * @extends {ContextResource} - * @param {!WebGLRenderingContext} glContext - */ -function WebGLRenderingContextResource(glContext) -{ - ContextResource.call(this, glContext, "WebGLRenderingContext"); - /** @type {Object.<number, boolean>} */ - this._customErrors = null; - /** @type {!Object.<string, boolean>} */ - this._extensions = {}; -} - -/** - * @const - * @type {!Array.<string>} - */ -WebGLRenderingContextResource.GLCapabilities = [ - "BLEND", - "CULL_FACE", - "DEPTH_TEST", - "DITHER", - "POLYGON_OFFSET_FILL", - "SAMPLE_ALPHA_TO_COVERAGE", - "SAMPLE_COVERAGE", - "SCISSOR_TEST", - "STENCIL_TEST" -]; - -/** - * @const - * @type {!Array.<string>} - */ -WebGLRenderingContextResource.PixelStoreParameters = [ - "PACK_ALIGNMENT", - "UNPACK_ALIGNMENT", - "UNPACK_COLORSPACE_CONVERSION_WEBGL", - "UNPACK_FLIP_Y_WEBGL", - "UNPACK_PREMULTIPLY_ALPHA_WEBGL" -]; - -/** - * @const - * @type {!Array.<string>} - */ -WebGLRenderingContextResource.StateParameters = [ - "ACTIVE_TEXTURE", - "ARRAY_BUFFER_BINDING", - "BLEND_COLOR", - "BLEND_DST_ALPHA", - "BLEND_DST_RGB", - "BLEND_EQUATION_ALPHA", - "BLEND_EQUATION_RGB", - "BLEND_SRC_ALPHA", - "BLEND_SRC_RGB", - "COLOR_CLEAR_VALUE", - "COLOR_WRITEMASK", - "CULL_FACE_MODE", - "CURRENT_PROGRAM", - "DEPTH_CLEAR_VALUE", - "DEPTH_FUNC", - "DEPTH_RANGE", - "DEPTH_WRITEMASK", - "ELEMENT_ARRAY_BUFFER_BINDING", - "FRAMEBUFFER_BINDING", - "FRONT_FACE", - "GENERATE_MIPMAP_HINT", - "LINE_WIDTH", - "PACK_ALIGNMENT", - "POLYGON_OFFSET_FACTOR", - "POLYGON_OFFSET_UNITS", - "RENDERBUFFER_BINDING", - "SAMPLE_COVERAGE_INVERT", - "SAMPLE_COVERAGE_VALUE", - "SCISSOR_BOX", - "STENCIL_BACK_FAIL", - "STENCIL_BACK_FUNC", - "STENCIL_BACK_PASS_DEPTH_FAIL", - "STENCIL_BACK_PASS_DEPTH_PASS", - "STENCIL_BACK_REF", - "STENCIL_BACK_VALUE_MASK", - "STENCIL_BACK_WRITEMASK", - "STENCIL_CLEAR_VALUE", - "STENCIL_FAIL", - "STENCIL_FUNC", - "STENCIL_PASS_DEPTH_FAIL", - "STENCIL_PASS_DEPTH_PASS", - "STENCIL_REF", - "STENCIL_VALUE_MASK", - "STENCIL_WRITEMASK", - "UNPACK_ALIGNMENT", - "UNPACK_COLORSPACE_CONVERSION_WEBGL", - "UNPACK_FLIP_Y_WEBGL", - "UNPACK_PREMULTIPLY_ALPHA_WEBGL", - "VIEWPORT" -]; - -/** - * @const - * @type {!Object.<string, boolean>} - */ -WebGLRenderingContextResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([ - "clear", - "drawArrays", - "drawElements" -]); - -/** - * @param {*} obj - * @return {WebGLRenderingContextResource} - */ -WebGLRenderingContextResource.forObject = function(obj) -{ - var resource = Resource.forObject(obj); - if (!resource) - return null; - resource = resource.contextResource(); - return (resource instanceof WebGLRenderingContextResource) ? resource : null; -} - -WebGLRenderingContextResource.prototype = { - /** - * @override (overrides @return type) - * @return {WebGLRenderingContext} - */ - wrappedObject: function() - { - return this._wrappedObject; - }, - - /** - * @override - * @return {string} - */ - toDataURL: function() - { - return this.wrappedObject().canvas.toDataURL(); - }, - - /** - * @return {Array.<number>} - */ - getAllErrors: function() - { - var errors = []; - var gl = this.wrappedObject(); - if (gl) { - while (true) { - var error = gl.getError(); - if (error === gl.NO_ERROR) - break; - this.clearError(error); - errors.push(error); - } - } - if (this._customErrors) { - for (var key in this._customErrors) { - var error = Number(key); - errors.push(error); - } - delete this._customErrors; - } - return errors; - }, - - /** - * @param {Array.<number>} errors - */ - restoreErrors: function(errors) - { - var gl = this.wrappedObject(); - if (gl) { - var wasError = false; - while (gl.getError() !== gl.NO_ERROR) - wasError = true; - console.assert(!wasError, "Error(s) while capturing current WebGL state."); - } - if (!errors.length) - delete this._customErrors; - else { - this._customErrors = {}; - for (var i = 0, n = errors.length; i < n; ++i) - this._customErrors[errors[i]] = true; - } - }, - - /** - * @param {number} error - */ - clearError: function(error) - { - if (this._customErrors) - delete this._customErrors[error]; - }, - - /** - * @return {number} - */ - nextError: function() - { - if (this._customErrors) { - for (var key in this._customErrors) { - var error = Number(key); - delete this._customErrors[error]; - return error; - } - } - delete this._customErrors; - var gl = this.wrappedObject(); - return gl ? gl.NO_ERROR : 0; - }, - - /** - * @param {string} name - */ - addExtension: function(name) - { - // FIXME: Wrap OES_vertex_array_object extension. - this._extensions[name.toLowerCase()] = true; - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _populateReplayableData: function(data, cache) - { - var gl = this.wrappedObject(); - data.originalCanvas = gl.canvas; - data.originalContextAttributes = gl.getContextAttributes(); - data.extensions = TypeUtils.cloneObject(this._extensions); - - var originalErrors = this.getAllErrors(); - - // Take a full GL state snapshot. - var glState = {}; - WebGLRenderingContextResource.GLCapabilities.forEach(function(parameter) { - glState[parameter] = gl.isEnabled(gl[parameter]); - }); - WebGLRenderingContextResource.StateParameters.forEach(function(parameter) { - glState[parameter] = Resource.toReplayable(gl.getParameter(gl[parameter]), cache); - }); - - // VERTEX_ATTRIB_ARRAYS - var maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS)); - var vertexAttribParameters = ["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", "VERTEX_ATTRIB_ARRAY_ENABLED", "VERTEX_ATTRIB_ARRAY_SIZE", "VERTEX_ATTRIB_ARRAY_STRIDE", "VERTEX_ATTRIB_ARRAY_TYPE", "VERTEX_ATTRIB_ARRAY_NORMALIZED", "CURRENT_VERTEX_ATTRIB"]; - var vertexAttribStates = []; - for (var i = 0; i < maxVertexAttribs; ++i) { - var state = {}; - vertexAttribParameters.forEach(function(attribParameter) { - state[attribParameter] = Resource.toReplayable(gl.getVertexAttrib(i, gl[attribParameter]), cache); - }); - state.VERTEX_ATTRIB_ARRAY_POINTER = gl.getVertexAttribOffset(i, gl.VERTEX_ATTRIB_ARRAY_POINTER); - vertexAttribStates.push(state); - } - glState.vertexAttribStates = vertexAttribStates; - - // TEXTURES - var currentTextureBinding = /** @type {number} */ (gl.getParameter(gl.ACTIVE_TEXTURE)); - var maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)); - var textureBindings = []; - for (var i = 0; i < maxTextureImageUnits; ++i) { - gl.activeTexture(gl.TEXTURE0 + i); - var state = { - TEXTURE_2D: Resource.toReplayable(gl.getParameter(gl.TEXTURE_BINDING_2D), cache), - TEXTURE_CUBE_MAP: Resource.toReplayable(gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP), cache) - }; - textureBindings.push(state); - } - glState.textureBindings = textureBindings; - gl.activeTexture(currentTextureBinding); - - data.glState = glState; - - this.restoreErrors(originalErrors); - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - this._customErrors = null; - this._extensions = TypeUtils.cloneObject(data.extensions) || {}; - - var canvas = data.originalCanvas.cloneNode(true); - var replayContext = null; - var contextIds = ["webgl", "experimental-webgl", "webkit-3d", "3d"]; - for (var i = 0, contextId; contextId = contextIds[i]; ++i) { - replayContext = canvas.getContext(contextId, data.originalContextAttributes); - if (replayContext) - break; - } - - console.assert(replayContext, "Failed to create a WebGLRenderingContext for the replay."); - - var gl = /** @type {!WebGLRenderingContext} */ (Resource.wrappedObject(replayContext)); - this.setWrappedObject(gl); - - // Enable corresponding WebGL extensions. - for (var name in this._extensions) - gl.getExtension(name); - - var glState = data.glState; - gl.bindFramebuffer(gl.FRAMEBUFFER, /** @type {WebGLFramebuffer} */ (ReplayableResource.replay(glState.FRAMEBUFFER_BINDING, cache))); - gl.bindRenderbuffer(gl.RENDERBUFFER, /** @type {WebGLRenderbuffer} */ (ReplayableResource.replay(glState.RENDERBUFFER_BINDING, cache))); - - // Enable or disable server-side GL capabilities. - WebGLRenderingContextResource.GLCapabilities.forEach(function(parameter) { - console.assert(parameter in glState); - if (glState[parameter]) - gl.enable(gl[parameter]); - else - gl.disable(gl[parameter]); - }); - - gl.blendColor(glState.BLEND_COLOR[0], glState.BLEND_COLOR[1], glState.BLEND_COLOR[2], glState.BLEND_COLOR[3]); - gl.blendEquationSeparate(glState.BLEND_EQUATION_RGB, glState.BLEND_EQUATION_ALPHA); - gl.blendFuncSeparate(glState.BLEND_SRC_RGB, glState.BLEND_DST_RGB, glState.BLEND_SRC_ALPHA, glState.BLEND_DST_ALPHA); - gl.clearColor(glState.COLOR_CLEAR_VALUE[0], glState.COLOR_CLEAR_VALUE[1], glState.COLOR_CLEAR_VALUE[2], glState.COLOR_CLEAR_VALUE[3]); - gl.clearDepth(glState.DEPTH_CLEAR_VALUE); - gl.clearStencil(glState.STENCIL_CLEAR_VALUE); - gl.colorMask(glState.COLOR_WRITEMASK[0], glState.COLOR_WRITEMASK[1], glState.COLOR_WRITEMASK[2], glState.COLOR_WRITEMASK[3]); - gl.cullFace(glState.CULL_FACE_MODE); - gl.depthFunc(glState.DEPTH_FUNC); - gl.depthMask(glState.DEPTH_WRITEMASK); - gl.depthRange(glState.DEPTH_RANGE[0], glState.DEPTH_RANGE[1]); - gl.frontFace(glState.FRONT_FACE); - gl.hint(gl.GENERATE_MIPMAP_HINT, glState.GENERATE_MIPMAP_HINT); - gl.lineWidth(glState.LINE_WIDTH); - - WebGLRenderingContextResource.PixelStoreParameters.forEach(function(parameter) { - gl.pixelStorei(gl[parameter], glState[parameter]); - }); - - gl.polygonOffset(glState.POLYGON_OFFSET_FACTOR, glState.POLYGON_OFFSET_UNITS); - gl.sampleCoverage(glState.SAMPLE_COVERAGE_VALUE, glState.SAMPLE_COVERAGE_INVERT); - gl.stencilFuncSeparate(gl.FRONT, glState.STENCIL_FUNC, glState.STENCIL_REF, glState.STENCIL_VALUE_MASK); - gl.stencilFuncSeparate(gl.BACK, glState.STENCIL_BACK_FUNC, glState.STENCIL_BACK_REF, glState.STENCIL_BACK_VALUE_MASK); - gl.stencilOpSeparate(gl.FRONT, glState.STENCIL_FAIL, glState.STENCIL_PASS_DEPTH_FAIL, glState.STENCIL_PASS_DEPTH_PASS); - gl.stencilOpSeparate(gl.BACK, glState.STENCIL_BACK_FAIL, glState.STENCIL_BACK_PASS_DEPTH_FAIL, glState.STENCIL_BACK_PASS_DEPTH_PASS); - gl.stencilMaskSeparate(gl.FRONT, glState.STENCIL_WRITEMASK); - gl.stencilMaskSeparate(gl.BACK, glState.STENCIL_BACK_WRITEMASK); - - gl.scissor(glState.SCISSOR_BOX[0], glState.SCISSOR_BOX[1], glState.SCISSOR_BOX[2], glState.SCISSOR_BOX[3]); - gl.viewport(glState.VIEWPORT[0], glState.VIEWPORT[1], glState.VIEWPORT[2], glState.VIEWPORT[3]); - - gl.useProgram(/** @type {WebGLProgram} */ (ReplayableResource.replay(glState.CURRENT_PROGRAM, cache))); - - // VERTEX_ATTRIB_ARRAYS - var maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS)); - for (var i = 0; i < maxVertexAttribs; ++i) { - var state = glState.vertexAttribStates[i] || {}; - if (state.VERTEX_ATTRIB_ARRAY_ENABLED) - gl.enableVertexAttribArray(i); - else - gl.disableVertexAttribArray(i); - if (state.CURRENT_VERTEX_ATTRIB) - gl.vertexAttrib4fv(i, state.CURRENT_VERTEX_ATTRIB); - var buffer = /** @type {WebGLBuffer} */ (ReplayableResource.replay(state.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, cache)); - if (buffer) { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.vertexAttribPointer(i, state.VERTEX_ATTRIB_ARRAY_SIZE, state.VERTEX_ATTRIB_ARRAY_TYPE, state.VERTEX_ATTRIB_ARRAY_NORMALIZED, state.VERTEX_ATTRIB_ARRAY_STRIDE, state.VERTEX_ATTRIB_ARRAY_POINTER); - } - } - gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ARRAY_BUFFER_BINDING, cache))); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ELEMENT_ARRAY_BUFFER_BINDING, cache))); - - // TEXTURES - var maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)); - for (var i = 0; i < maxTextureImageUnits; ++i) { - gl.activeTexture(gl.TEXTURE0 + i); - var state = glState.textureBindings[i] || {}; - gl.bindTexture(gl.TEXTURE_2D, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_2D, cache))); - gl.bindTexture(gl.TEXTURE_CUBE_MAP, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_CUBE_MAP, cache))); - } - gl.activeTexture(glState.ACTIVE_TEXTURE); - - ContextResource.prototype._doReplayCalls.call(this, data, cache); - }, - - /** - * @param {Object|number} target - * @return {Resource} - */ - currentBinding: function(target) - { - var resource = Resource.forObject(target); - if (resource) - return resource; - var gl = this.wrappedObject(); - var bindingParameter; - var bindMethodName; - var bindMethodTarget = target; - switch (target) { - case gl.ARRAY_BUFFER: - bindingParameter = gl.ARRAY_BUFFER_BINDING; - bindMethodName = "bindBuffer"; - break; - case gl.ELEMENT_ARRAY_BUFFER: - bindingParameter = gl.ELEMENT_ARRAY_BUFFER_BINDING; - bindMethodName = "bindBuffer"; - break; - case gl.TEXTURE_2D: - bindingParameter = gl.TEXTURE_BINDING_2D; - bindMethodName = "bindTexture"; - break; - case gl.TEXTURE_CUBE_MAP: - case gl.TEXTURE_CUBE_MAP_POSITIVE_X: - case gl.TEXTURE_CUBE_MAP_NEGATIVE_X: - case gl.TEXTURE_CUBE_MAP_POSITIVE_Y: - case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y: - case gl.TEXTURE_CUBE_MAP_POSITIVE_Z: - case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z: - bindingParameter = gl.TEXTURE_BINDING_CUBE_MAP; - bindMethodTarget = gl.TEXTURE_CUBE_MAP; - bindMethodName = "bindTexture"; - break; - case gl.FRAMEBUFFER: - bindingParameter = gl.FRAMEBUFFER_BINDING; - bindMethodName = "bindFramebuffer"; - break; - case gl.RENDERBUFFER: - bindingParameter = gl.RENDERBUFFER_BINDING; - bindMethodName = "bindRenderbuffer"; - break; - default: - console.error("ASSERT_NOT_REACHED: unknown binding target " + target); - return null; - } - resource = Resource.forObject(gl.getParameter(bindingParameter)); - if (resource) - resource.pushBinding(bindMethodTarget, bindMethodName); - return resource; - }, - - /** - * @override - * @return {!Object.<string, Function>} - */ - _customWrapFunctions: function() - { - var wrapFunctions = WebGLRenderingContextResource._wrapFunctions; - if (!wrapFunctions) { - wrapFunctions = Object.create(null); - - wrapFunctions["createBuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLBufferResource, "WebGLBuffer"); - wrapFunctions["createShader"] = Resource.WrapFunction.resourceFactoryMethod(WebGLShaderResource, "WebGLShader"); - wrapFunctions["createProgram"] = Resource.WrapFunction.resourceFactoryMethod(WebGLProgramResource, "WebGLProgram"); - wrapFunctions["createTexture"] = Resource.WrapFunction.resourceFactoryMethod(WebGLTextureResource, "WebGLTexture"); - wrapFunctions["createFramebuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLFramebufferResource, "WebGLFramebuffer"); - wrapFunctions["createRenderbuffer"] = Resource.WrapFunction.resourceFactoryMethod(WebGLRenderbufferResource, "WebGLRenderbuffer"); - wrapFunctions["getUniformLocation"] = Resource.WrapFunction.resourceFactoryMethod(Resource, "WebGLUniformLocation"); - - /** - * @param {string} methodName - * @param {function(this:Resource, !Call)=} pushCallFunc - */ - function stateModifyingWrapFunction(methodName, pushCallFunc) - { - if (pushCallFunc) { - /** - * @param {Object|number} target - * @this Resource.WrapFunction - */ - wrapFunctions[methodName] = function(target) - { - var resource = this._resource.currentBinding(target); - if (resource) - pushCallFunc.call(resource, this.call()); - } - } else { - /** - * @param {Object|number} target - * @this Resource.WrapFunction - */ - wrapFunctions[methodName] = function(target) - { - var resource = this._resource.currentBinding(target); - if (resource) - resource.pushCall(this.call()); - } - } - } - stateModifyingWrapFunction("bindAttribLocation"); - stateModifyingWrapFunction("compileShader"); - stateModifyingWrapFunction("detachShader"); - stateModifyingWrapFunction("linkProgram"); - stateModifyingWrapFunction("shaderSource"); - stateModifyingWrapFunction("bufferData"); - stateModifyingWrapFunction("bufferSubData"); - stateModifyingWrapFunction("compressedTexImage2D"); - stateModifyingWrapFunction("compressedTexSubImage2D"); - stateModifyingWrapFunction("copyTexImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D); - stateModifyingWrapFunction("copyTexSubImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D); - stateModifyingWrapFunction("generateMipmap"); - stateModifyingWrapFunction("texImage2D"); - stateModifyingWrapFunction("texSubImage2D"); - stateModifyingWrapFunction("texParameterf", WebGLTextureResource.prototype.pushCall_texParameter); - stateModifyingWrapFunction("texParameteri", WebGLTextureResource.prototype.pushCall_texParameter); - stateModifyingWrapFunction("renderbufferStorage"); - - /** @this Resource.WrapFunction */ - wrapFunctions["getError"] = function() - { - var gl = /** @type {WebGLRenderingContext} */ (this._originalObject); - var error = this.result(); - if (error !== gl.NO_ERROR) - this._resource.clearError(error); - else { - error = this._resource.nextError(); - if (error !== gl.NO_ERROR) - this.overrideResult(error); - } - } - - /** - * @param {string} name - * @this Resource.WrapFunction - */ - wrapFunctions["getExtension"] = function(name) - { - this._resource.addExtension(name); - } - - // - // Register bound WebGL resources. - // - - /** - * @param {WebGLProgram} program - * @param {WebGLShader} shader - * @this Resource.WrapFunction - */ - wrapFunctions["attachShader"] = function(program, shader) - { - var resource = this._resource.currentBinding(program); - if (resource) { - resource.pushCall(this.call()); - var shaderResource = /** @type {WebGLShaderResource} */ (Resource.forObject(shader)); - if (shaderResource) { - var shaderType = shaderResource.type(); - resource._registerBoundResource("__attachShader_" + shaderType, shaderResource); - } - } - } - /** - * @param {number} target - * @param {number} attachment - * @param {number} objectTarget - * @param {WebGLRenderbuffer|WebGLTexture} obj - * @this Resource.WrapFunction - */ - wrapFunctions["framebufferRenderbuffer"] = wrapFunctions["framebufferTexture2D"] = function(target, attachment, objectTarget, obj) - { - var resource = this._resource.currentBinding(target); - if (resource) { - resource.pushCall(this.call()); - resource._registerBoundResource("__framebufferAttachmentObjectName", obj); - } - } - /** - * @param {number} target - * @param {Object} obj - * @this Resource.WrapFunction - */ - wrapFunctions["bindBuffer"] = wrapFunctions["bindFramebuffer"] = wrapFunctions["bindRenderbuffer"] = function(target, obj) - { - this._resource._registerBoundResource("__bindBuffer_" + target, obj); - } - /** - * @param {number} target - * @param {WebGLTexture} obj - * @this Resource.WrapFunction - */ - wrapFunctions["bindTexture"] = function(target, obj) - { - var gl = /** @type {WebGLRenderingContext} */ (this._originalObject); - var currentTextureBinding = /** @type {number} */ (gl.getParameter(gl.ACTIVE_TEXTURE)); - this._resource._registerBoundResource("__bindTexture_" + target + "_" + currentTextureBinding, obj); - } - /** - * @param {WebGLProgram} program - * @this Resource.WrapFunction - */ - wrapFunctions["useProgram"] = function(program) - { - this._resource._registerBoundResource("__useProgram", program); - } - /** - * @param {number} index - * @this Resource.WrapFunction - */ - wrapFunctions["vertexAttribPointer"] = function(index) - { - var gl = /** @type {WebGLRenderingContext} */ (this._originalObject); - this._resource._registerBoundResource("__vertexAttribPointer_" + index, gl.getParameter(gl.ARRAY_BUFFER_BINDING)); - } - - WebGLRenderingContextResource._wrapFunctions = wrapFunctions; - } - return wrapFunctions; - }, - - __proto__: ContextResource.prototype -} - -//////////////////////////////////////////////////////////////////////////////// -// 2D Canvas -//////////////////////////////////////////////////////////////////////////////// - -/** - * @constructor - * @extends {ContextResource} - * @param {!CanvasRenderingContext2D} context - */ -function CanvasRenderingContext2DResource(context) -{ - ContextResource.call(this, context, "CanvasRenderingContext2D"); -} - -/** - * @const - * @type {!Array.<string>} - */ -CanvasRenderingContext2DResource.AttributeProperties = [ - "strokeStyle", - "fillStyle", - "globalAlpha", - "lineWidth", - "lineCap", - "lineJoin", - "miterLimit", - "shadowOffsetX", - "shadowOffsetY", - "shadowBlur", - "shadowColor", - "globalCompositeOperation", - "font", - "textAlign", - "textBaseline", - "lineDashOffset", - "webkitLineDash", - "webkitLineDashOffset" -]; - -/** - * @const - * @type {!Array.<string>} - */ -CanvasRenderingContext2DResource.PathMethods = [ - "beginPath", - "moveTo", - "closePath", - "lineTo", - "quadraticCurveTo", - "bezierCurveTo", - "arcTo", - "arc", - "rect" -]; - -/** - * @const - * @type {!Array.<string>} - */ -CanvasRenderingContext2DResource.TransformationMatrixMethods = [ - "scale", - "rotate", - "translate", - "transform", - "setTransform" -]; - -/** - * @const - * @type {!Object.<string, boolean>} - */ -CanvasRenderingContext2DResource.DrawingMethods = TypeUtils.createPrefixedPropertyNamesSet([ - "clearRect", - "drawImage", - "drawImageFromRect", - "drawCustomFocusRing", - "drawSystemFocusRing", - "fill", - "fillRect", - "fillText", - "putImageData", - "putImageDataHD", - "stroke", - "strokeRect", - "strokeText" -]); - -CanvasRenderingContext2DResource.prototype = { - /** - * @override (overrides @return type) - * @return {CanvasRenderingContext2D} - */ - wrappedObject: function() - { - return this._wrappedObject; - }, - - /** - * @override - * @return {string} - */ - toDataURL: function() - { - return this.wrappedObject().canvas.toDataURL(); - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _populateReplayableData: function(data, cache) - { - data.currentAttributes = this._currentAttributesState(); - data.originalCanvasCloned = TypeUtils.cloneIntoCanvas(this.wrappedObject().canvas); - }, - - /** - * @override - * @param {!Object} data - * @param {!Cache} cache - */ - _doReplayCalls: function(data, cache) - { - var canvas = TypeUtils.cloneIntoCanvas(data.originalCanvasCloned); - var ctx = /** @type {!CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d"))); - this.setWrappedObject(ctx); - - for (var i = 0, n = data.calls.length; i < n; ++i) { - var replayableCall = /** @type {ReplayableCall} */ (data.calls[i]); - if (replayableCall.functionName() === "save") - this._applyAttributesState(replayableCall.attachment("canvas2dAttributesState")); - this._calls.push(replayableCall.replay(cache)); - } - this._applyAttributesState(data.currentAttributes); - }, - - /** - * @param {!Call} call - */ - pushCall_setTransform: function(call) - { - var saveCallIndex = this._lastIndexOfMatchingSaveCall(); - var index = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods); - index = Math.max(index, saveCallIndex); - if (this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1)) - this._removeAllObsoleteCallsFromLog(); - this.pushCall(call); - }, - - /** - * @param {!Call} call - */ - pushCall_beginPath: function(call) - { - var index = this._lastIndexOfAnyCall(["clip"]); - if (this._removeCallsFromLog(CanvasRenderingContext2DResource.PathMethods, index + 1)) - this._removeAllObsoleteCallsFromLog(); - this.pushCall(call); - }, - - /** - * @param {!Call} call - */ - pushCall_save: function(call) - { - call.setAttachment("canvas2dAttributesState", this._currentAttributesState()); - this.pushCall(call); - }, - - /** - * @param {!Call} call - */ - pushCall_restore: function(call) - { - var lastIndexOfSave = this._lastIndexOfMatchingSaveCall(); - if (lastIndexOfSave === -1) - return; - this._calls[lastIndexOfSave].setAttachment("canvas2dAttributesState", null); // No longer needed, free memory. - - var modified = false; - if (this._removeCallsFromLog(["clip"], lastIndexOfSave + 1)) - modified = true; - - var lastIndexOfAnyPathMethod = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods); - var index = Math.max(lastIndexOfSave, lastIndexOfAnyPathMethod); - if (this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1)) - modified = true; - - if (modified) - this._removeAllObsoleteCallsFromLog(); - - var lastCall = this._calls[this._calls.length - 1]; - if (lastCall && lastCall.functionName() === "save") - this._calls.pop(); - else - this.pushCall(call); - }, - - /** - * @param {number=} fromIndex - * @return {number} - */ - _lastIndexOfMatchingSaveCall: function(fromIndex) - { - if (typeof fromIndex !== "number") - fromIndex = this._calls.length - 1; - else - fromIndex = Math.min(fromIndex, this._calls.length - 1); - var stackDepth = 1; - for (var i = fromIndex; i >= 0; --i) { - var functionName = this._calls[i].functionName(); - if (functionName === "restore") - ++stackDepth; - else if (functionName === "save") { - --stackDepth; - if (!stackDepth) - return i; - } - } - return -1; - }, - - /** - * @param {!Array.<string>} functionNames - * @param {number=} fromIndex - * @return {number} - */ - _lastIndexOfAnyCall: function(functionNames, fromIndex) - { - if (typeof fromIndex !== "number") - fromIndex = this._calls.length - 1; - else - fromIndex = Math.min(fromIndex, this._calls.length - 1); - for (var i = fromIndex; i >= 0; --i) { - if (functionNames.indexOf(this._calls[i].functionName()) !== -1) - return i; - } - return -1; - }, - - _removeAllObsoleteCallsFromLog: function() - { - // Remove all PATH methods between clip() and beginPath() calls. - var lastIndexOfBeginPath = this._lastIndexOfAnyCall(["beginPath"]); - while (lastIndexOfBeginPath !== -1) { - var index = this._lastIndexOfAnyCall(["clip"], lastIndexOfBeginPath - 1); - this._removeCallsFromLog(CanvasRenderingContext2DResource.PathMethods, index + 1, lastIndexOfBeginPath); - lastIndexOfBeginPath = this._lastIndexOfAnyCall(["beginPath"], index - 1); - } - - // Remove all TRASFORMATION MATRIX methods before restore() or setTransform() but after any PATH or corresponding save() method. - var lastRestore = this._lastIndexOfAnyCall(["restore", "setTransform"]); - while (lastRestore !== -1) { - var saveCallIndex = this._lastIndexOfMatchingSaveCall(lastRestore - 1); - var index = this._lastIndexOfAnyCall(CanvasRenderingContext2DResource.PathMethods, lastRestore - 1); - index = Math.max(index, saveCallIndex); - this._removeCallsFromLog(CanvasRenderingContext2DResource.TransformationMatrixMethods, index + 1, lastRestore); - lastRestore = this._lastIndexOfAnyCall(["restore", "setTransform"], index - 1); - } - - // Remove all save-restore consecutive pairs. - var restoreCalls = 0; - for (var i = this._calls.length - 1; i >= 0; --i) { - var functionName = this._calls[i].functionName(); - if (functionName === "restore") { - ++restoreCalls; - continue; - } - if (functionName === "save" && restoreCalls > 0) { - var saveCallIndex = i; - for (var j = i - 1; j >= 0 && i - j < restoreCalls; --j) { - if (this._calls[j].functionName() === "save") - saveCallIndex = j; - else - break; - } - this._calls.splice(saveCallIndex, (i - saveCallIndex + 1) * 2); - i = saveCallIndex; - } - restoreCalls = 0; - } - }, - - /** - * @param {!Array.<string>} functionNames - * @param {number} fromIndex - * @param {number=} toIndex - * @return {boolean} - */ - _removeCallsFromLog: function(functionNames, fromIndex, toIndex) - { - var oldLength = this._calls.length; - if (typeof toIndex !== "number") - toIndex = oldLength; - else - toIndex = Math.min(toIndex, oldLength); - var newIndex = Math.min(fromIndex, oldLength); - for (var i = newIndex; i < toIndex; ++i) { - var call = this._calls[i]; - if (functionNames.indexOf(call.functionName()) === -1) - this._calls[newIndex++] = call; - } - if (newIndex >= toIndex) - return false; - this._calls.splice(newIndex, toIndex - newIndex); - return true; - }, - - /** - * @return {!Object.<string, string>} - */ - _currentAttributesState: function() - { - var ctx = this.wrappedObject(); - var state = {}; - state.attributes = {}; - CanvasRenderingContext2DResource.AttributeProperties.forEach(function(attribute) { - state.attributes[attribute] = ctx[attribute]; - }); - if (ctx.getLineDash) - state.lineDash = ctx.getLineDash(); - return state; - }, - - /** - * @param {Object.<string, string>=} state - */ - _applyAttributesState: function(state) - { - if (!state) - return; - var ctx = this.wrappedObject(); - if (state.attributes) { - Object.keys(state.attributes).forEach(function(attribute) { - ctx[attribute] = state.attributes[attribute]; - }); - } - if (ctx.setLineDash) - ctx.setLineDash(state.lineDash); - }, - - /** - * @override - * @return {!Object.<string, Function>} - */ - _customWrapFunctions: function() - { - var wrapFunctions = CanvasRenderingContext2DResource._wrapFunctions; - if (!wrapFunctions) { - wrapFunctions = Object.create(null); - - wrapFunctions["createLinearGradient"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasGradient"); - wrapFunctions["createRadialGradient"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasGradient"); - wrapFunctions["createPattern"] = Resource.WrapFunction.resourceFactoryMethod(LogEverythingResource, "CanvasPattern"); - - /** - * @param {string} methodName - * @param {function(this:Resource, !Call)=} func - */ - function stateModifyingWrapFunction(methodName, func) - { - if (func) { - /** @this Resource.WrapFunction */ - wrapFunctions[methodName] = function() - { - func.call(this._resource, this.call()); - } - } else { - /** @this Resource.WrapFunction */ - wrapFunctions[methodName] = function() - { - this._resource.pushCall(this.call()); - } - } - } - - for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.TransformationMatrixMethods[i]; ++i) - stateModifyingWrapFunction(methodName, methodName === "setTransform" ? this.pushCall_setTransform : undefined); - for (var i = 0, methodName; methodName = CanvasRenderingContext2DResource.PathMethods[i]; ++i) - stateModifyingWrapFunction(methodName, methodName === "beginPath" ? this.pushCall_beginPath : undefined); - - stateModifyingWrapFunction("save", this.pushCall_save); - stateModifyingWrapFunction("restore", this.pushCall_restore); - stateModifyingWrapFunction("clip"); - - CanvasRenderingContext2DResource._wrapFunctions = wrapFunctions; - } - return wrapFunctions; - }, - - __proto__: ContextResource.prototype -} - -/** - * @constructor - * @param {!Object.<string, boolean>=} drawingMethodNames - */ -function CallFormatter(drawingMethodNames) -{ - this._drawingMethodNames = drawingMethodNames || Object.create(null); -} - -CallFormatter.prototype = { - /** - * @param {!ReplayableCall} replayableCall - * @return {!Object} - */ - formatCall: function(replayableCall) - { - var result = {}; - var functionName = replayableCall.functionName(); - if (functionName) { - result.functionName = functionName; - result.arguments = replayableCall.args().map(this.formatValue.bind(this)); - if (replayableCall.result() !== undefined) - result.result = this.formatValue(replayableCall.result()); - if (this._drawingMethodNames[functionName]) - result.isDrawingCall = true; - } else { - result.property = replayableCall.args()[0]; - result.value = this.formatValue(replayableCall.args()[1]); - } - return result; - }, - - /** - * @param {*} value - * @return {!Object} - */ - formatValue: function(value) - { - if (value instanceof ReplayableResource) - var description = value.description(); - else - var description = "" + value; - return { description: description }; - } -} - -/** - * @const - * @type {!Object.<string, !CallFormatter>} - */ -CallFormatter._formatters = {}; - -/** - * @param {string} resourceName - * @param {!CallFormatter} callFormatter - */ -CallFormatter.register = function(resourceName, callFormatter) -{ - CallFormatter._formatters[resourceName] = callFormatter; -} - -/** - * @param {!ReplayableCall} replayableCall - * @return {!Object} - */ -CallFormatter.formatCall = function(replayableCall) -{ - var resource = replayableCall.replayableResource(); - var formatter = CallFormatter._formatters[resource.name()]; - if (!formatter) { - var contextResource = resource.replayableContextResource(); - formatter = CallFormatter._formatters[contextResource.name()] || new CallFormatter(); - } - return formatter.formatCall(replayableCall); -} - -CallFormatter.register("CanvasRenderingContext2D", new CallFormatter(CanvasRenderingContext2DResource.DrawingMethods)); -CallFormatter.register("WebGLRenderingContext", new CallFormatter(WebGLRenderingContextResource.DrawingMethods)); - -/** - * @constructor - */ -function TraceLog() -{ - /** @type {!Array.<ReplayableCall>} */ - this._replayableCalls = []; - /** @type {!Cache} */ - this._replayablesCache = new Cache(); - /** @type {!Object.<number, boolean>} */ - this._frameEndCallIndexes = {}; -} - -TraceLog.prototype = { - /** - * @return {number} - */ - size: function() - { - return this._replayableCalls.length; - }, - - /** - * @return {!Array.<ReplayableCall>} - */ - replayableCalls: function() - { - return this._replayableCalls; - }, - - /** - * @param {number} id - * @return {ReplayableResource} - */ - replayableResource: function(id) - { - return /** @type {ReplayableResource} */ (this._replayablesCache.get(id)); - }, - - /** - * @param {!Resource} resource - */ - captureResource: function(resource) - { - resource.toReplayable(this._replayablesCache); - }, - - /** - * @param {!Call} call - */ - addCall: function(call) - { - this._replayableCalls.push(call.toReplayable(this._replayablesCache)); - }, - - addFrameEndMark: function() - { - var index = this._replayableCalls.length - 1; - if (index >= 0) - this._frameEndCallIndexes[index] = true; - }, - - /** - * @param {number} index - * @return {boolean} - */ - isFrameEndCallAt: function(index) - { - return !!this._frameEndCallIndexes[index]; - } -} - -/** - * @constructor - * @param {!TraceLog} traceLog - */ -function TraceLogPlayer(traceLog) -{ - /** @type {!TraceLog} */ - this._traceLog = traceLog; - /** @type {number} */ - this._nextReplayStep = 0; - /** @type {!Cache} */ - this._replayWorldCache = new Cache(); -} - -TraceLogPlayer.prototype = { - /** - * @return {!TraceLog} - */ - traceLog: function() - { - return this._traceLog; - }, - - /** - * @param {number} id - * @return {Resource} - */ - replayWorldResource: function(id) - { - return /** @type {Resource} */ (this._replayWorldCache.get(id)); - }, - - /** - * @return {number} - */ - nextReplayStep: function() - { - return this._nextReplayStep; - }, - - reset: function() - { - this._nextReplayStep = 0; - this._replayWorldCache.reset(); - }, - - /** - * @return {Call} - */ - step: function() - { - return this.stepTo(this._nextReplayStep); - }, - - /** - * @param {number} stepNum - * @return {Call} - */ - stepTo: function(stepNum) - { - stepNum = Math.min(stepNum, this._traceLog.size() - 1); - console.assert(stepNum >= 0); - if (this._nextReplayStep > stepNum) - this.reset(); - // FIXME: Replay all the cached resources first to warm-up. - var lastCall = null; - var replayableCalls = this._traceLog.replayableCalls(); - while (this._nextReplayStep <= stepNum) - lastCall = replayableCalls[this._nextReplayStep++].replay(this._replayWorldCache); - return lastCall; - }, - - /** - * @return {Call} - */ - replay: function() - { - return this.stepTo(this._traceLog.size() - 1); - } -} - -/** - * @constructor - */ -function ResourceTrackingManager() -{ - this._capturing = false; - this._stopCapturingOnFrameEnd = false; - this._lastTraceLog = null; -} - -ResourceTrackingManager.prototype = { - /** - * @return {boolean} - */ - capturing: function() - { - return this._capturing; - }, - - /** - * @return {TraceLog} - */ - lastTraceLog: function() - { - return this._lastTraceLog; - }, - - /** - * @param {!Resource} resource - */ - registerResource: function(resource) - { - resource.setManager(this); - }, - - startCapturing: function() - { - if (!this._capturing) - this._lastTraceLog = new TraceLog(); - this._capturing = true; - this._stopCapturingOnFrameEnd = false; - }, - - /** - * @param {TraceLog=} traceLog - */ - stopCapturing: function(traceLog) - { - if (traceLog && this._lastTraceLog !== traceLog) - return; - this._capturing = false; - this._stopCapturingOnFrameEnd = false; - if (this._lastTraceLog) - this._lastTraceLog.addFrameEndMark(); - }, - - /** - * @param {!TraceLog} traceLog - */ - dropTraceLog: function(traceLog) - { - this.stopCapturing(traceLog); - if (this._lastTraceLog === traceLog) - this._lastTraceLog = null; - }, - - captureFrame: function() - { - this._lastTraceLog = new TraceLog(); - this._capturing = true; - this._stopCapturingOnFrameEnd = true; - }, - - /** - * @param {!Resource} resource - * @param {Array|Arguments} args - */ - captureArguments: function(resource, args) - { - if (!this._capturing) - return; - this._lastTraceLog.captureResource(resource); - for (var i = 0, n = args.length; i < n; ++i) { - var res = Resource.forObject(args[i]); - if (res) - this._lastTraceLog.captureResource(res); - } - }, - - /** - * @param {!Call} call - */ - captureCall: function(call) - { - if (!this._capturing) - return; - this._lastTraceLog.addCall(call); - }, - - markFrameEnd: function() - { - if (!this._lastTraceLog) - return; - this._lastTraceLog.addFrameEndMark(); - if (this._stopCapturingOnFrameEnd && this._lastTraceLog.size()) - this.stopCapturing(this._lastTraceLog); - } -} - -/** - * @constructor - */ -var InjectedCanvasModule = function() -{ - /** @type {!ResourceTrackingManager} */ - this._manager = new ResourceTrackingManager(); - /** @type {number} */ - this._lastTraceLogId = 0; - /** @type {!Object.<string, TraceLog>} */ - this._traceLogs = {}; - /** @type {!Object.<string, TraceLogPlayer>} */ - this._traceLogPlayers = {}; -} - -InjectedCanvasModule.prototype = { - /** - * @param {!WebGLRenderingContext} glContext - * @return {Object} - */ - wrapWebGLContext: function(glContext) - { - var resource = Resource.forObject(glContext) || new WebGLRenderingContextResource(glContext); - this._manager.registerResource(resource); - return resource.proxyObject(); - }, - - /** - * @param {!CanvasRenderingContext2D} context - * @return {Object} - */ - wrapCanvas2DContext: function(context) - { - var resource = Resource.forObject(context) || new CanvasRenderingContext2DResource(context); - this._manager.registerResource(resource); - return resource.proxyObject(); - }, - - /** - * @return {CanvasAgent.TraceLogId} - */ - captureFrame: function() - { - return this._callStartCapturingFunction(this._manager.captureFrame); - }, - - /** - * @return {CanvasAgent.TraceLogId} - */ - startCapturing: function() - { - return this._callStartCapturingFunction(this._manager.startCapturing); - }, - - markFrameEnd: function() - { - this._manager.markFrameEnd(); - }, - - /** - * @param {function(this:ResourceTrackingManager)} func - * @return {CanvasAgent.TraceLogId} - */ - _callStartCapturingFunction: function(func) - { - var oldTraceLog = this._manager.lastTraceLog(); - func.call(this._manager); - var traceLog = this._manager.lastTraceLog(); - if (traceLog === oldTraceLog) { - for (var id in this._traceLogs) { - if (this._traceLogs[id] === traceLog) - return id; - } - } - var id = this._makeTraceLogId(); - this._traceLogs[id] = traceLog; - return id; - }, - - /** - * @param {CanvasAgent.TraceLogId} id - */ - stopCapturing: function(id) - { - var traceLog = this._traceLogs[id]; - if (traceLog) - this._manager.stopCapturing(traceLog); - }, - - /** - * @param {CanvasAgent.TraceLogId} id - */ - dropTraceLog: function(id) - { - var traceLog = this._traceLogs[id]; - if (traceLog) - this._manager.dropTraceLog(traceLog); - delete this._traceLogs[id]; - delete this._traceLogPlayers[id]; - }, - - /** - * @param {CanvasAgent.TraceLogId} id - * @param {number=} startOffset - * @param {number=} maxLength - * @return {!CanvasAgent.TraceLog|string} - */ - traceLog: function(id, startOffset, maxLength) - { - var traceLog = this._traceLogs[id]; - if (!traceLog) - return "Error: Trace log with the given ID not found."; - - // Ensure last call ends a frame. - traceLog.addFrameEndMark(); - - var replayableCalls = traceLog.replayableCalls(); - if (typeof startOffset !== "number") - startOffset = 0; - if (typeof maxLength !== "number") - maxLength = replayableCalls.length; - - var fromIndex = Math.max(0, startOffset); - var toIndex = Math.min(replayableCalls.length - 1, fromIndex + maxLength - 1); - - var alive = this._manager.capturing() && this._manager.lastTraceLog() === traceLog; - var result = { - id: id, - /** @type {Array.<CanvasAgent.Call>} */ - calls: [], - alive: alive, - startOffset: fromIndex, - totalAvailableCalls: replayableCalls.length - }; - for (var i = fromIndex; i <= toIndex; ++i) { - var call = replayableCalls[i]; - var contextResource = call.replayableResource().replayableContextResource(); - var stackTrace = call.stackTrace(); - var callFrame = stackTrace ? stackTrace.callFrame(0) || {} : {}; - var item = CallFormatter.formatCall(call); - item.contextId = this._makeStringResourceId(contextResource.id()); - item.sourceURL = callFrame.sourceURL; - item.lineNumber = callFrame.lineNumber; - item.columnNumber = callFrame.columnNumber; - item.isFrameEndCall = traceLog.isFrameEndCallAt(i); - result.calls.push(item); - } - return result; - }, - - /** - * @param {*} obj - * @return {!CanvasAgent.CallArgument} - */ - _makeCallArgument: function(obj) - { - if (obj instanceof ReplayableResource) - var description = obj.description(); - else - var description = "" + obj; - return { description: description }; - }, - - /** - * @param {CanvasAgent.TraceLogId} traceLogId - * @param {number} stepNo - * @return {!CanvasAgent.ResourceState|string} - */ - replayTraceLog: function(traceLogId, stepNo) - { - var traceLog = this._traceLogs[traceLogId]; - if (!traceLog) - return "Error: Trace log with the given ID not found."; - this._traceLogPlayers[traceLogId] = this._traceLogPlayers[traceLogId] || new TraceLogPlayer(traceLog); - var lastCall = this._traceLogPlayers[traceLogId].stepTo(stepNo); - var resource = lastCall.resource(); - var dataURL = resource.toDataURL(); - if (!dataURL) { - resource = resource.contextResource(); - dataURL = resource.toDataURL(); - } - return this._makeResourceState(this._makeStringResourceId(resource.id()), traceLogId, dataURL); - }, - - /** - * @param {CanvasAgent.ResourceId} stringResourceId - * @return {!CanvasAgent.ResourceInfo|string} - */ - resourceInfo: function(stringResourceId) - { - var resourceId = this._parseStringId(stringResourceId).resourceId; - if (!resourceId) - return "Error: Wrong resource ID: " + stringResourceId; - - var replayableResource = null; - for (var id in this._traceLogs) { - replayableResource = this._traceLogs[id].replayableResource(resourceId); - if (replayableResource) - break; - } - if (!replayableResource) - return "Error: Resource with the given ID not found."; - - return this._makeResourceInfo(stringResourceId, replayableResource.description()); - }, - - /** - * @param {CanvasAgent.TraceLogId} traceLogId - * @param {CanvasAgent.ResourceId} stringResourceId - * @return {!CanvasAgent.ResourceState|string} - */ - resourceState: function(traceLogId, stringResourceId) - { - var traceLog = this._traceLogs[traceLogId]; - if (!traceLog) - return "Error: Trace log with the given ID not found."; - - var traceLogPlayer = this._traceLogPlayers[traceLogId]; - if (!traceLogPlayer) - return "Error: Trace log replay has not started yet."; - - var parsedStringId1 = this._parseStringId(traceLogId); - var parsedStringId2 = this._parseStringId(stringResourceId); - if (parsedStringId1.injectedScriptId !== parsedStringId2.injectedScriptId) - return "Error: Both IDs must point to the same injected script."; - - var resourceId = parsedStringId2.resourceId; - if (!resourceId) - return "Error: Wrong resource ID: " + stringResourceId; - - var resource = traceLogPlayer.replayWorldResource(resourceId); - if (!resource) - return "Error: Resource with the given ID has not been replayed yet."; - - return this._makeResourceState(stringResourceId, traceLogId, resource.toDataURL()); - }, - - /** - * @return {CanvasAgent.TraceLogId} - */ - _makeTraceLogId: function() - { - return "{\"injectedScriptId\":" + injectedScriptId + ",\"traceLogId\":" + (++this._lastTraceLogId) + "}"; - }, - - /** - * @param {number} resourceId - * @return {CanvasAgent.ResourceId} - */ - _makeStringResourceId: function(resourceId) - { - return "{\"injectedScriptId\":" + injectedScriptId + ",\"resourceId\":" + resourceId + "}"; - }, - - /** - * @param {CanvasAgent.ResourceId} stringResourceId - * @param {string} description - * @return {!CanvasAgent.ResourceInfo} - */ - _makeResourceInfo: function(stringResourceId, description) - { - return { - id: stringResourceId, - description: description - }; - }, - - /** - * @param {CanvasAgent.ResourceId} stringResourceId - * @param {CanvasAgent.TraceLogId} traceLogId - * @param {string} imageURL - * @return {!CanvasAgent.ResourceState} - */ - _makeResourceState: function(stringResourceId, traceLogId, imageURL) - { - return { - id: stringResourceId, - traceLogId: traceLogId, - imageURL: imageURL - }; - }, - - /** - * @param {string} stringId - * @return {{injectedScriptId: number, traceLogId: ?number, resourceId: ?number}} - */ - _parseStringId: function(stringId) - { - return InjectedScriptHost.evaluate("(" + stringId + ")"); - } -} - -var injectedCanvasModule = new InjectedCanvasModule(); -return injectedCanvasModule; - -}) diff --git a/Source/WebCore/inspector/InspectorAllInOne.cpp b/Source/WebCore/inspector/InspectorAllInOne.cpp new file mode 100644 index 000000000..88728d41d --- /dev/null +++ b/Source/WebCore/inspector/InspectorAllInOne.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build. + +#include "CommandLineAPIHost.cpp" +#include "CommandLineAPIModule.cpp" +#include "DOMEditor.cpp" +#include "DOMPatchSupport.cpp" +#include "InspectorApplicationCacheAgent.cpp" +#include "InspectorCSSAgent.cpp" +#include "InspectorClient.cpp" +#include "InspectorController.cpp" +#include "InspectorDOMAgent.cpp" +#include "InspectorDOMDebuggerAgent.cpp" +#include "InspectorDOMStorageAgent.cpp" +#include "InspectorDatabaseAgent.cpp" +#include "InspectorDatabaseResource.cpp" +#include "InspectorFrontendClientLocal.cpp" +#include "InspectorFrontendHost.cpp" +#include "InspectorHistory.cpp" +#include "InspectorInstrumentation.cpp" +#include "InspectorInstrumentationCookie.cpp" +#include "InspectorLayerTreeAgent.cpp" +#include "InspectorNetworkAgent.cpp" +#include "InspectorNodeFinder.cpp" +#include "InspectorOverlay.cpp" +#include "InspectorPageAgent.cpp" +#include "InspectorStyleSheet.cpp" +#include "InspectorTimelineAgent.cpp" +#include "InspectorWorkerAgent.cpp" +#include "InstrumentingAgents.cpp" +#include "NetworkResourcesData.cpp" +#include "PageConsoleAgent.cpp" +#include "PageDebuggerAgent.cpp" +#include "PageHeapAgent.cpp" +#include "PageRuntimeAgent.cpp" +#include "PageScriptDebugServer.cpp" +#include "TimelineRecordFactory.cpp" +#include "WebConsoleAgent.cpp" +#include "WebDebuggerAgent.cpp" +#include "WebHeapAgent.cpp" +#include "WebInjectedScriptHost.cpp" +#include "WebInjectedScriptManager.cpp" +#include "WorkerConsoleAgent.cpp" +#include "WorkerDebuggerAgent.cpp" +#include "WorkerInspectorController.cpp" +#include "WorkerRuntimeAgent.cpp" +#include "WorkerScriptDebugServer.cpp" diff --git a/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp b/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp index 2a7a6917b..6e39bcdad 100644 --- a/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp +++ b/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorApplicationCacheAgent.h" #include "ApplicationCacheHost.h" @@ -34,40 +31,36 @@ #include "Frame.h" #include "FrameLoader.h" #include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" +#include "MainFrame.h" #include "NetworkStateNotifier.h" -#include "Page.h" -#include "ResourceResponse.h" #include <inspector/InspectorValues.h> +#include <wtf/text/StringBuilder.h> using namespace Inspector; namespace WebCore { -InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent) - : InspectorAgentBase(ASCIILiteral("ApplicationCache"), instrumentingAgents) +InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(WebAgentContext& context, InspectorPageAgent* pageAgent) + : InspectorAgentBase(ASCIILiteral("ApplicationCache"), context) + , m_frontendDispatcher(std::make_unique<Inspector::ApplicationCacheFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::ApplicationCacheBackendDispatcher::create(context.backendDispatcher, this)) , m_pageAgent(pageAgent) { } -void InspectorApplicationCacheAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorApplicationCacheAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorApplicationCacheFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorApplicationCacheBackendDispatcher::create(backendDispatcher, this); } -void InspectorApplicationCacheAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorApplicationCacheAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - m_instrumentingAgents->setInspectorApplicationCacheAgent(nullptr); + m_instrumentingAgents.setInspectorApplicationCacheAgent(nullptr); } -void InspectorApplicationCacheAgent::enable(ErrorString*) +void InspectorApplicationCacheAgent::enable(ErrorString&) { - m_instrumentingAgents->setInspectorApplicationCacheAgent(this); + m_instrumentingAgents.setInspectorApplicationCacheAgent(this); // We need to pass initial navigator.onOnline. networkStateChanged(); @@ -75,16 +68,17 @@ void InspectorApplicationCacheAgent::enable(ErrorString*) void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame) { - DocumentLoader* documentLoader = frame->loader().documentLoader(); + if (!frame) + return; + auto* documentLoader = frame->loader().documentLoader(); if (!documentLoader) return; - ApplicationCacheHost* host = documentLoader->applicationCacheHost(); - ApplicationCacheHost::Status status = host->status(); - ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo(); + auto& host = documentLoader->applicationCacheHost(); + int status = host.status(); + auto manifestURL = host.applicationCacheInfo().manifest.string(); - String manifestURL = info.m_manifest.string(); - m_frontendDispatcher->applicationCacheStatusUpdated(m_pageAgent->frameId(frame), manifestURL, static_cast<int>(status)); + m_frontendDispatcher->applicationCacheStatusUpdated(m_pageAgent->frameId(frame), manifestURL, status); } void InspectorApplicationCacheAgent::networkStateChanged() @@ -93,30 +87,28 @@ void InspectorApplicationCacheAgent::networkStateChanged() m_frontendDispatcher->networkStateUpdated(isNowOnline); } -void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::FrameWithManifest>>& result) +void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::FrameWithManifest>>& result) { - result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::FrameWithManifest>::create(); + result = Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::FrameWithManifest>::create(); - Frame* mainFrame = m_pageAgent->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext(mainFrame)) { - DocumentLoader* documentLoader = frame->loader().documentLoader(); + for (Frame* frame = &m_pageAgent->mainFrame(); frame; frame = frame->tree().traverseNext()) { + auto* documentLoader = frame->loader().documentLoader(); if (!documentLoader) continue; - ApplicationCacheHost* host = documentLoader->applicationCacheHost(); - ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo(); - String manifestURL = info.m_manifest.string(); + auto& host = documentLoader->applicationCacheHost(); + String manifestURL = host.applicationCacheInfo().manifest.string(); if (!manifestURL.isEmpty()) { - RefPtr<Inspector::TypeBuilder::ApplicationCache::FrameWithManifest> value = Inspector::TypeBuilder::ApplicationCache::FrameWithManifest::create() + result->addItem(Inspector::Protocol::ApplicationCache::FrameWithManifest::create() .setFrameId(m_pageAgent->frameId(frame)) .setManifestURL(manifestURL) - .setStatus(static_cast<int>(host->status())); - result->addItem(value); + .setStatus(static_cast<int>(host.status())) + .release()); } } } -DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString* errorString, String frameId) +DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString& errorString, const String& frameId) { Frame* frame = m_pageAgent->assertFrame(errorString, frameId); if (!frame) @@ -125,77 +117,68 @@ DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(Er return InspectorPageAgent::assertDocumentLoader(errorString, frame); } -void InspectorApplicationCacheAgent::getManifestForFrame(ErrorString* errorString, const String& frameId, String* manifestURL) +void InspectorApplicationCacheAgent::getManifestForFrame(ErrorString& errorString, const String& frameId, String* manifestURL) { DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId); if (!documentLoader) return; - ApplicationCacheHost::CacheInfo info = documentLoader->applicationCacheHost()->applicationCacheInfo(); - *manifestURL = info.m_manifest.string(); + *manifestURL = documentLoader->applicationCacheHost().applicationCacheInfo().manifest.string(); } -void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString* errorString, const String& frameId, RefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCache>& applicationCache) +void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString& errorString, const String& frameId, RefPtr<Inspector::Protocol::ApplicationCache::ApplicationCache>& applicationCache) { - DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId); + auto* documentLoader = assertFrameWithDocumentLoader(errorString, frameId); if (!documentLoader) return; - ApplicationCacheHost* host = documentLoader->applicationCacheHost(); - ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo(); - - ApplicationCacheHost::ResourceInfoList resources; - host->fillResourceList(&resources); - - applicationCache = buildObjectForApplicationCache(resources, info); + auto& host = documentLoader->applicationCacheHost(); + applicationCache = buildObjectForApplicationCache(host.resourceList(), host.applicationCacheInfo()); } -PassRefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCache> InspectorApplicationCacheAgent::buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo) +Ref<Inspector::Protocol::ApplicationCache::ApplicationCache> InspectorApplicationCacheAgent::buildObjectForApplicationCache(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo) { - return Inspector::TypeBuilder::ApplicationCache::ApplicationCache::create() - .setManifestURL(applicationCacheInfo.m_manifest.string()) - .setSize(applicationCacheInfo.m_size) - .setCreationTime(applicationCacheInfo.m_creationTime) - .setUpdateTime(applicationCacheInfo.m_updateTime) + return Inspector::Protocol::ApplicationCache::ApplicationCache::create() + .setManifestURL(applicationCacheInfo.manifest.string()) + .setSize(applicationCacheInfo.size) + .setCreationTime(applicationCacheInfo.creationTime) + .setUpdateTime(applicationCacheInfo.updateTime) .setResources(buildArrayForApplicationCacheResources(applicationCacheResources)) .release(); } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource>> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources) +Ref<Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource>> resources = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource>::create(); - - for (const auto& resourceInfo : applicationCacheResources) - resources->addItem(buildObjectForApplicationCacheResource(resourceInfo)); - - return resources; + auto result = Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>::create(); + for (auto& info : applicationCacheResources) + result->addItem(buildObjectForApplicationCacheResource(info)); + return result; } -PassRefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource> InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo) +Ref<Inspector::Protocol::ApplicationCache::ApplicationCacheResource> InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo) { - String types; - if (resourceInfo.m_isMaster) - types.append("Master "); + StringBuilder types; - if (resourceInfo.m_isManifest) - types.append("Manifest "); + if (resourceInfo.isMaster) + types.appendLiteral("Master "); - if (resourceInfo.m_isFallback) - types.append("Fallback "); + if (resourceInfo.isManifest) + types.appendLiteral("Manifest "); - if (resourceInfo.m_isForeign) - types.append("Foreign "); + if (resourceInfo.isFallback) + types.appendLiteral("Fallback "); - if (resourceInfo.m_isExplicit) - types.append("Explicit "); + if (resourceInfo.isForeign) + types.appendLiteral("Foreign "); - RefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource> value = Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource::create() - .setUrl(resourceInfo.m_resource.string()) - .setSize(static_cast<int>(resourceInfo.m_size)) - .setType(types); - return value; + if (resourceInfo.isExplicit) + types.appendLiteral("Explicit "); + + return Inspector::Protocol::ApplicationCache::ApplicationCacheResource::create() + .setUrl(resourceInfo.resource.string()) + .setSize(static_cast<int>(resourceInfo.size)) + .setType(types.toString()) + .release(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h index 52d8e0ede..48752efa0 100644 --- a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h +++ b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,20 +22,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorApplicationCacheAgent_h -#define InspectorApplicationCacheAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "ApplicationCacheHost.h" #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> namespace Inspector { -class InspectorApplicationCacheFrontendDispatcher; +class ApplicationCacheFrontendDispatcher; class InspectorObject; class InspectorValue; } @@ -44,42 +40,38 @@ namespace WebCore { class Frame; class InspectorPageAgent; -class InstrumentingAgents; class Page; -class ResourceResponse; typedef String ErrorString; -class InspectorApplicationCacheAgent : public InspectorAgentBase, public Inspector::InspectorApplicationCacheBackendDispatcherHandler { +class InspectorApplicationCacheAgent final : public InspectorAgentBase, public Inspector::ApplicationCacheBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorApplicationCacheAgent); WTF_MAKE_FAST_ALLOCATED; public: - InspectorApplicationCacheAgent(InstrumentingAgents*, InspectorPageAgent*); - ~InspectorApplicationCacheAgent() { } + InspectorApplicationCacheAgent(WebAgentContext&, InspectorPageAgent*); + virtual ~InspectorApplicationCacheAgent() { } - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; void updateApplicationCacheStatus(Frame*); void networkStateChanged(); - virtual void enable(ErrorString*) override; - virtual void getFramesWithManifests(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::FrameWithManifest>>& result) override; - virtual void getManifestForFrame(ErrorString*, const String& frameId, String* manifestURL) override; - virtual void getApplicationCacheForFrame(ErrorString*, const String& frameId, RefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCache>&) override; + void enable(ErrorString&) override; + void getFramesWithManifests(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::FrameWithManifest>>& result) override; + void getManifestForFrame(ErrorString&, const String& frameId, String* manifestURL) override; + void getApplicationCacheForFrame(ErrorString&, const String& frameId, RefPtr<Inspector::Protocol::ApplicationCache::ApplicationCache>&) override; private: - PassRefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCache> buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList&, const ApplicationCacheHost::CacheInfo&); - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource>> buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList&); - PassRefPtr<Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); + Ref<Inspector::Protocol::ApplicationCache::ApplicationCache> buildObjectForApplicationCache(const Vector<ApplicationCacheHost::ResourceInfo>&, const ApplicationCacheHost::CacheInfo&); + Ref<Inspector::Protocol::Array<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>> buildArrayForApplicationCacheResources(const Vector<ApplicationCacheHost::ResourceInfo>&); + Ref<Inspector::Protocol::ApplicationCache::ApplicationCacheResource> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); - DocumentLoader* assertFrameWithDocumentLoader(ErrorString*, String frameId); + DocumentLoader* assertFrameWithDocumentLoader(ErrorString&, const String& frameId); - InspectorPageAgent* m_pageAgent; - std::unique_ptr<Inspector::InspectorApplicationCacheFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorApplicationCacheBackendDispatcher> m_backendDispatcher; + std::unique_ptr<Inspector::ApplicationCacheFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::ApplicationCacheBackendDispatcher> m_backendDispatcher; + InspectorPageAgent* m_pageAgent { nullptr }; }; } // namespace WebCore -#endif // ENABLE(INSPECTOR) -#endif // InspectorApplicationCacheAgent_h diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp index 01a52da32..1a6c76803 100644 --- a/Source/WebCore/inspector/InspectorCSSAgent.cpp +++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2010, Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorCSSAgent.h" #include "CSSComputedStyleDeclaration.h" @@ -38,27 +36,28 @@ #include "CSSStyleSheet.h" #include "ContentSecurityPolicy.h" #include "DOMWindow.h" -#include "ExceptionCodePlaceholder.h" +#include "FontCache.h" #include "HTMLHeadElement.h" #include "HTMLStyleElement.h" -#include "InspectorDOMAgent.h" #include "InspectorHistory.h" -#include "InspectorWebTypeBuilders.h" +#include "InspectorPageAgent.h" #include "InstrumentingAgents.h" #include "NamedFlowCollection.h" #include "Node.h" #include "NodeList.h" -#include "RenderRegion.h" +#include "PseudoElement.h" +#include "RenderNamedFlowFragment.h" #include "SVGStyleElement.h" +#include "SelectorChecker.h" +#include "ShadowRoot.h" #include "StyleProperties.h" #include "StylePropertyShorthand.h" #include "StyleResolver.h" #include "StyleRule.h" +#include "StyleScope.h" #include "StyleSheetList.h" #include "WebKitNamedFlow.h" -#include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> -#include <wtf/HashSet.h> +#include <inspector/InspectorProtocolObjects.h> #include <wtf/Ref.h> #include <wtf/Vector.h> #include <wtf/text/CString.h> @@ -69,127 +68,65 @@ using namespace Inspector; namespace WebCore { enum ForcePseudoClassFlags { - PseudoNone = 0, - PseudoHover = 1 << 0, - PseudoFocus = 1 << 1, - PseudoActive = 1 << 2, - PseudoVisited = 1 << 3 + PseudoClassNone = 0, + PseudoClassHover = 1 << 0, + PseudoClassFocus = 1 << 1, + PseudoClassActive = 1 << 2, + PseudoClassVisited = 1 << 3 }; -static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray) +static unsigned computePseudoClassMask(const InspectorArray& pseudoClassArray) { - DEFINE_STATIC_LOCAL(String, active, (ASCIILiteral("active"))); - DEFINE_STATIC_LOCAL(String, hover, (ASCIILiteral("hover"))); - DEFINE_STATIC_LOCAL(String, focus, (ASCIILiteral("focus"))); - DEFINE_STATIC_LOCAL(String, visited, (ASCIILiteral("visited"))); - if (!pseudoClassArray || !pseudoClassArray->length()) - return PseudoNone; - - unsigned result = PseudoNone; - for (size_t i = 0; i < pseudoClassArray->length(); ++i) { - RefPtr<InspectorValue> pseudoClassValue = pseudoClassArray->get(i); + static NeverDestroyed<String> active(ASCIILiteral("active")); + static NeverDestroyed<String> hover(ASCIILiteral("hover")); + static NeverDestroyed<String> focus(ASCIILiteral("focus")); + static NeverDestroyed<String> visited(ASCIILiteral("visited")); + if (!pseudoClassArray.length()) + return PseudoClassNone; + + unsigned result = PseudoClassNone; + for (auto& pseudoClassValue : pseudoClassArray) { String pseudoClass; - bool success = pseudoClassValue->asString(&pseudoClass); + bool success = pseudoClassValue->asString(pseudoClass); if (!success) continue; if (pseudoClass == active) - result |= PseudoActive; + result |= PseudoClassActive; else if (pseudoClass == hover) - result |= PseudoHover; + result |= PseudoClassHover; else if (pseudoClass == focus) - result |= PseudoFocus; + result |= PseudoClassFocus; else if (pseudoClass == visited) - result |= PseudoVisited; + result |= PseudoClassVisited; } return result; } -class UpdateRegionLayoutTask { -public: - UpdateRegionLayoutTask(InspectorCSSAgent*); - void scheduleFor(WebKitNamedFlow*, int documentNodeId); - void unschedule(WebKitNamedFlow*); - void reset(); - void timerFired(Timer<UpdateRegionLayoutTask>&); - -private: - InspectorCSSAgent* m_cssAgent; - Timer<UpdateRegionLayoutTask> m_timer; - HashMap<WebKitNamedFlow*, int> m_namedFlows; -}; - -UpdateRegionLayoutTask::UpdateRegionLayoutTask(InspectorCSSAgent* cssAgent) - : m_cssAgent(cssAgent) - , m_timer(this, &UpdateRegionLayoutTask::timerFired) -{ -} - -void UpdateRegionLayoutTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId) -{ - m_namedFlows.add(namedFlow, documentNodeId); - - if (!m_timer.isActive()) - m_timer.startOneShot(0); -} - -void UpdateRegionLayoutTask::unschedule(WebKitNamedFlow* namedFlow) -{ - m_namedFlows.remove(namedFlow); -} - -void UpdateRegionLayoutTask::reset() -{ - m_timer.stop(); - m_namedFlows.clear(); -} - -void UpdateRegionLayoutTask::timerFired(Timer<UpdateRegionLayoutTask>&) -{ - // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed. - Vector<std::pair<WebKitNamedFlow*, int>> namedFlows; - - for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it) - namedFlows.append(std::make_pair(it->key, it->value)); - - for (unsigned i = 0, size = namedFlows.size(); i < size; ++i) { - WebKitNamedFlow* namedFlow = namedFlows.at(i).first; - int documentNodeId = namedFlows.at(i).second; - - if (m_namedFlows.contains(namedFlow)) { - m_cssAgent->regionLayoutUpdated(namedFlow, documentNodeId); - m_namedFlows.remove(namedFlow); - } - } - - if (!m_namedFlows.isEmpty() && !m_timer.isActive()) - m_timer.startOneShot(0); -} - class ChangeRegionOversetTask { public: ChangeRegionOversetTask(InspectorCSSAgent*); void scheduleFor(WebKitNamedFlow*, int documentNodeId); void unschedule(WebKitNamedFlow*); void reset(); - void timerFired(Timer<ChangeRegionOversetTask>&); - + void timerFired(); + private: InspectorCSSAgent* m_cssAgent; - Timer<ChangeRegionOversetTask> m_timer; + Timer m_timer; HashMap<WebKitNamedFlow*, int> m_namedFlows; }; ChangeRegionOversetTask::ChangeRegionOversetTask(InspectorCSSAgent* cssAgent) : m_cssAgent(cssAgent) - , m_timer(this, &ChangeRegionOversetTask::timerFired) + , m_timer(*this, &ChangeRegionOversetTask::timerFired) { } void ChangeRegionOversetTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId) { m_namedFlows.add(namedFlow, documentNodeId); - + if (!m_timer.isActive()) m_timer.startOneShot(0); } @@ -205,11 +142,11 @@ void ChangeRegionOversetTask::reset() m_namedFlows.clear(); } -void ChangeRegionOversetTask::timerFired(Timer<ChangeRegionOversetTask>&) +void ChangeRegionOversetTask::timerFired() { // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed. - for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it) - m_cssAgent->regionOversetChanged(it->key, it->value); + for (auto& namedFlow : m_namedFlows) + m_cssAgent->regionOversetChanged(namedFlow.key, namedFlow.value); m_namedFlows.clear(); } @@ -227,59 +164,59 @@ protected: RefPtr<InspectorStyleSheet> m_styleSheet; }; -class InspectorCSSAgent::SetStyleSheetTextAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetStyleSheetTextAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction); public: SetStyleSheetTextAction(InspectorStyleSheet* styleSheet, const String& text) - : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("SetStyleSheetText"), styleSheet) , m_text(text) { } - virtual bool perform(ExceptionCode& ec) +private: + ExceptionOr<void> perform() final { - if (!m_styleSheet->getText(&m_oldText)) - return false; - return redo(ec); + auto result = m_styleSheet->text(); + if (result.hasException()) + return result.releaseException(); + m_oldText = result.releaseReturnValue(); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - if (m_styleSheet->setText(m_oldText, ec)) { - m_styleSheet->reparseStyleSheet(m_oldText); - return true; - } - return false; + auto result = m_styleSheet->setText(m_oldText); + if (result.hasException()) + return result.releaseException(); + m_styleSheet->reparseStyleSheet(m_oldText); + return { }; } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - if (m_styleSheet->setText(m_text, ec)) { - m_styleSheet->reparseStyleSheet(m_text); - return true; - } - return false; + auto result = m_styleSheet->setText(m_text); + if (result.hasException()) + return result.releaseException(); + m_styleSheet->reparseStyleSheet(m_text); + return { }; } - virtual String mergeId() + String mergeId() final { return String::format("SetStyleSheetText %s", m_styleSheet->id().utf8().data()); } - virtual void merge(PassOwnPtr<Action> action) + void merge(std::unique_ptr<Action> action) override { ASSERT(action->mergeId() == mergeId()); - - SetStyleSheetTextAction* other = static_cast<SetStyleSheetTextAction*>(action.get()); - m_text = other->m_text; + m_text = static_cast<SetStyleSheetTextAction&>(*action).m_text; } -private: String m_text; String m_oldText; }; -class InspectorCSSAgent::SetStyleTextAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetStyleTextAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetStyleTextAction); public: SetStyleTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& text) @@ -289,28 +226,28 @@ public: { } - virtual bool perform(ExceptionCode& ec) + ExceptionOr<void> perform() override { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() override { - return m_styleSheet->setStyleText(m_cssId, m_oldText, 0, ec); + return m_styleSheet->setStyleText(m_cssId, m_oldText, nullptr); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() override { - return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText, ec); + return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText); } - virtual String mergeId() + String mergeId() override { ASSERT(m_styleSheet->id() == m_cssId.styleSheetId()); return String::format("SetStyleText %s:%u", m_styleSheet->id().utf8().data(), m_cssId.ordinal()); } - virtual void merge(PassOwnPtr<Action> action) + void merge(std::unique_ptr<Action> action) override { ASSERT(action->mergeId() == mergeId()); @@ -324,181 +261,89 @@ private: String m_oldText; }; -class InspectorCSSAgent::SetPropertyTextAction : public InspectorCSSAgent::StyleSheetAction { - WTF_MAKE_NONCOPYABLE(SetPropertyTextAction); -public: - SetPropertyTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite) - : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet) - , m_cssId(cssId) - , m_propertyIndex(propertyIndex) - , m_text(text) - , m_overwrite(overwrite) - { - } - - virtual String toString() - { - return mergeId() + ": " + m_oldText + " -> " + m_text; - } - - virtual bool perform(ExceptionCode& ec) - { - return redo(ec); - } - - virtual bool undo(ExceptionCode& ec) - { - String placeholder; - return m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_overwrite ? m_oldText : "", true, &placeholder, ec); - } - - virtual bool redo(ExceptionCode& ec) - { - String oldText; - bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText, ec); - m_oldText = oldText.stripWhiteSpace(); - // FIXME: remove this once the model handles this case. - if (!m_oldText.endsWith(';')) - m_oldText.append(';'); - - return result; - } - - virtual String mergeId() - { - return String::format("SetPropertyText %s:%u:%s", m_styleSheet->id().utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false"); - } - - virtual void merge(PassOwnPtr<Action> action) - { - ASSERT(action->mergeId() == mergeId()); - - SetPropertyTextAction* other = static_cast<SetPropertyTextAction*>(action.get()); - m_text = other->m_text; - } - -private: - InspectorCSSId m_cssId; - unsigned m_propertyIndex; - String m_text; - String m_oldText; - bool m_overwrite; -}; - -class InspectorCSSAgent::TogglePropertyAction : public InspectorCSSAgent::StyleSheetAction { - WTF_MAKE_NONCOPYABLE(TogglePropertyAction); -public: - TogglePropertyAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable) - : InspectorCSSAgent::StyleSheetAction("ToggleProperty", styleSheet) - , m_cssId(cssId) - , m_propertyIndex(propertyIndex) - , m_disable(disable) - { - } - - virtual bool perform(ExceptionCode& ec) - { - return redo(ec); - } - - virtual bool undo(ExceptionCode& ec) - { - return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, !m_disable, ec); - } - - virtual bool redo(ExceptionCode& ec) - { - return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, m_disable, ec); - } - -private: - InspectorCSSId m_cssId; - unsigned m_propertyIndex; - bool m_disable; -}; - -class InspectorCSSAgent::SetRuleSelectorAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetRuleSelectorAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction); public: SetRuleSelectorAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& selector) - : InspectorCSSAgent::StyleSheetAction("SetRuleSelector", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("SetRuleSelector"), styleSheet) , m_cssId(cssId) , m_selector(selector) { } - virtual bool perform(ExceptionCode& ec) +private: + ExceptionOr<void> perform() final { - m_oldSelector = m_styleSheet->ruleSelector(m_cssId, ec); - if (ec) - return false; - return redo(ec); + auto result = m_styleSheet->ruleSelector(m_cssId); + if (result.hasException()) + return result.releaseException(); + m_oldSelector = result.releaseReturnValue(); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector, ec); + return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - return m_styleSheet->setRuleSelector(m_cssId, m_selector, ec); + return m_styleSheet->setRuleSelector(m_cssId, m_selector); } -private: InspectorCSSId m_cssId; String m_selector; String m_oldSelector; }; -class InspectorCSSAgent::AddRuleAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::AddRuleAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(AddRuleAction); public: AddRuleAction(InspectorStyleSheet* styleSheet, const String& selector) - : InspectorCSSAgent::StyleSheetAction("AddRule", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("AddRule"), styleSheet) , m_selector(selector) { } - virtual bool perform(ExceptionCode& ec) + InspectorCSSId newRuleId() const { return m_newId; } + +private: + ExceptionOr<void> perform() final { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - return m_styleSheet->deleteRule(m_newId, ec); + return m_styleSheet->deleteRule(m_newId); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - CSSStyleRule* cssStyleRule = m_styleSheet->addRule(m_selector, ec); - if (ec) - return false; - m_newId = m_styleSheet->ruleId(cssStyleRule); - return true; + auto result = m_styleSheet->addRule(m_selector); + if (result.hasException()) + return result.releaseException(); + m_newId = m_styleSheet->ruleId(result.releaseReturnValue()); + return { }; } - InspectorCSSId newRuleId() { return m_newId; } - -private: InspectorCSSId m_newId; String m_selector; String m_oldSelector; }; -// static -CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule) +CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule& rule) { - if (rule->type() != CSSRule::STYLE_RULE) - return 0; - return static_cast<CSSStyleRule*>(rule); + if (!is<CSSStyleRule>(rule)) + return nullptr; + return downcast<CSSStyleRule>(&rule); } -InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent) - : InspectorAgentBase(ASCIILiteral("CSS"), instrumentingAgents) +InspectorCSSAgent::InspectorCSSAgent(WebAgentContext& context, InspectorDOMAgent* domAgent) + : InspectorAgentBase(ASCIILiteral("CSS"), context) + , m_frontendDispatcher(std::make_unique<CSSFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(CSSBackendDispatcher::create(context.backendDispatcher, this)) , m_domAgent(domAgent) - , m_lastStyleSheetId(1) { m_domAgent->setDOMListener(this); } @@ -509,236 +354,273 @@ InspectorCSSAgent::~InspectorCSSAgent() reset(); } -void InspectorCSSAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorCSSAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorCSSFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorCSSBackendDispatcher::create(backendDispatcher, this); } -void InspectorCSSAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorCSSAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - resetNonPersistentData(); + + String unused; + disable(unused); } void InspectorCSSAgent::discardAgent() { - m_domAgent->setDOMListener(0); - m_domAgent = 0; + m_domAgent->setDOMListener(nullptr); + m_domAgent = nullptr; } void InspectorCSSAgent::reset() { + // FIXME: Should we be resetting on main frame navigations? m_idToInspectorStyleSheet.clear(); m_cssStyleSheetToInspectorStyleSheet.clear(); m_nodeToInspectorStyleSheet.clear(); m_documentToInspectorStyleSheet.clear(); + m_documentToKnownCSSStyleSheets.clear(); resetNonPersistentData(); } void InspectorCSSAgent::resetNonPersistentData() { m_namedFlowCollectionsRequested.clear(); - if (m_updateRegionLayoutTask) - m_updateRegionLayoutTask->reset(); if (m_changeRegionOversetTask) m_changeRegionOversetTask->reset(); resetPseudoStates(); } -void InspectorCSSAgent::enable(ErrorString*) +void InspectorCSSAgent::enable(ErrorString&) { - m_instrumentingAgents->setInspectorCSSAgent(this); + m_instrumentingAgents.setInspectorCSSAgent(this); + + for (auto* document : m_domAgent->documents()) + activeStyleSheetsUpdated(*document); } -void InspectorCSSAgent::disable(ErrorString*) +void InspectorCSSAgent::disable(ErrorString&) { - m_instrumentingAgents->setInspectorCSSAgent(0); + m_instrumentingAgents.setInspectorCSSAgent(nullptr); +} + +void InspectorCSSAgent::documentDetached(Document& document) +{ + Vector<CSSStyleSheet*> emptyList; + setActiveStyleSheetsForDocument(document, emptyList); + + m_documentToKnownCSSStyleSheets.remove(&document); + m_documentToInspectorStyleSheet.remove(&document); + m_documentsWithForcedPseudoStates.remove(&document); } void InspectorCSSAgent::mediaQueryResultChanged() { - if (m_frontendDispatcher) - m_frontendDispatcher->mediaQueryResultChanged(); + m_frontendDispatcher->mediaQueryResultChanged(); } -void InspectorCSSAgent::didCreateNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::activeStyleSheetsUpdated(Document& document) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); - if (!documentNodeId) - return; + Vector<CSSStyleSheet*> cssStyleSheets; + collectAllDocumentStyleSheets(document, cssStyleSheets); - ErrorString errorString; - m_frontendDispatcher->namedFlowCreated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + setActiveStyleSheetsForDocument(document, cssStyleSheets); } -void InspectorCSSAgent::willRemoveNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::setActiveStyleSheetsForDocument(Document& document, Vector<CSSStyleSheet*>& activeStyleSheets) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); - if (!documentNodeId) - return; + HashSet<CSSStyleSheet*>& previouslyKnownActiveStyleSheets = m_documentToKnownCSSStyleSheets.add(&document, HashSet<CSSStyleSheet*>()).iterator->value; - if (m_updateRegionLayoutTask) - m_updateRegionLayoutTask->unschedule(namedFlow); - - if (m_changeRegionOversetTask) - m_changeRegionOversetTask->unschedule(namedFlow); + HashSet<CSSStyleSheet*> removedStyleSheets(previouslyKnownActiveStyleSheets); + Vector<CSSStyleSheet*> addedStyleSheets; + for (auto& activeStyleSheet : activeStyleSheets) { + if (removedStyleSheets.contains(activeStyleSheet)) + removedStyleSheets.remove(activeStyleSheet); + else + addedStyleSheets.append(activeStyleSheet); + } - m_frontendDispatcher->namedFlowRemoved(documentNodeId, namedFlow->name().string()); + for (auto* cssStyleSheet : removedStyleSheets) { + previouslyKnownActiveStyleSheets.remove(cssStyleSheet); + RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(cssStyleSheet); + if (m_idToInspectorStyleSheet.contains(inspectorStyleSheet->id())) { + String id = unbindStyleSheet(inspectorStyleSheet.get()); + m_frontendDispatcher->styleSheetRemoved(id); + } + } + + for (auto* cssStyleSheet : addedStyleSheets) { + previouslyKnownActiveStyleSheets.add(cssStyleSheet); + if (!m_cssStyleSheetToInspectorStyleSheet.contains(cssStyleSheet)) { + InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssStyleSheet); + m_frontendDispatcher->styleSheetAdded(inspectorStyleSheet->buildObjectForStyleSheetInfo()); + } + } } -void InspectorCSSAgent::didUpdateRegionLayout(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::didCreateNamedFlow(Document& document, WebKitNamedFlow& namedFlow) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - if (!m_updateRegionLayoutTask) - m_updateRegionLayoutTask = adoptPtr(new UpdateRegionLayoutTask(this)); - m_updateRegionLayoutTask->scheduleFor(namedFlow, documentNodeId); + ErrorString unused; + m_frontendDispatcher->namedFlowCreated(buildObjectForNamedFlow(unused, &namedFlow, documentNodeId)); } -void InspectorCSSAgent::regionLayoutUpdated(WebKitNamedFlow* namedFlow, int documentNodeId) +void InspectorCSSAgent::willRemoveNamedFlow(Document& document, WebKitNamedFlow& namedFlow) { - if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull) + int documentNodeId = documentNodeWithRequestedFlowsId(&document); + if (!documentNodeId) return; - ErrorString errorString; - Ref<WebKitNamedFlow> protect(*namedFlow); + if (m_changeRegionOversetTask) + m_changeRegionOversetTask->unschedule(&namedFlow); - m_frontendDispatcher->regionLayoutUpdated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + m_frontendDispatcher->namedFlowRemoved(documentNodeId, namedFlow.name().string()); } -void InspectorCSSAgent::didChangeRegionOverset(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::didChangeRegionOverset(Document& document, WebKitNamedFlow& namedFlow) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - + if (!m_changeRegionOversetTask) - m_changeRegionOversetTask = adoptPtr(new ChangeRegionOversetTask(this)); - m_changeRegionOversetTask->scheduleFor(namedFlow, documentNodeId); + m_changeRegionOversetTask = std::make_unique<ChangeRegionOversetTask>(this); + m_changeRegionOversetTask->scheduleFor(&namedFlow, documentNodeId); } void InspectorCSSAgent::regionOversetChanged(WebKitNamedFlow* namedFlow, int documentNodeId) { if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull) return; - - ErrorString errorString; + + ErrorString unused; Ref<WebKitNamedFlow> protect(*namedFlow); - - m_frontendDispatcher->regionOversetChanged(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + + m_frontendDispatcher->regionOversetChanged(buildObjectForNamedFlow(unused, namedFlow, documentNodeId)); } -void InspectorCSSAgent::didRegisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement, Node* nextContentElement) +void InspectorCSSAgent::didRegisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement, Node* nextContentElement) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - ErrorString errorString; - int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement); - int nextContentElementNodeId = nextContentElement ? m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, nextContentElement) : 0; - m_frontendDispatcher->registeredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId, nextContentElementNodeId); + ErrorString unused; + int contentElementNodeId = m_domAgent->pushNodeToFrontend(unused, documentNodeId, &contentElement); + int nextContentElementNodeId = nextContentElement ? m_domAgent->pushNodeToFrontend(unused, documentNodeId, nextContentElement) : 0; + m_frontendDispatcher->registeredNamedFlowContentElement(documentNodeId, namedFlow.name().string(), contentElementNodeId, nextContentElementNodeId); } -void InspectorCSSAgent::didUnregisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement) +void InspectorCSSAgent::didUnregisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - ErrorString errorString; - int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement); + ErrorString unused; + int contentElementNodeId = m_domAgent->pushNodeToFrontend(unused, documentNodeId, &contentElement); if (!contentElementNodeId) { // We've already notified that the DOM node was removed from the DOM, so there's no need to send another event. return; } - m_frontendDispatcher->unregisteredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId); + m_frontendDispatcher->unregisteredNamedFlowContentElement(documentNodeId, namedFlow.name().string(), contentElementNodeId); } -bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType) +bool InspectorCSSAgent::forcePseudoState(const Element& element, CSSSelector::PseudoClassType pseudoClassType) { if (m_nodeIdToForcedPseudoState.isEmpty()) return false; - int nodeId = m_domAgent->boundNodeId(element); + int nodeId = m_domAgent->boundNodeId(&element); if (!nodeId) return false; - NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId); + auto it = m_nodeIdToForcedPseudoState.find(nodeId); if (it == m_nodeIdToForcedPseudoState.end()) return false; unsigned forcedPseudoState = it->value; - switch (pseudoType) { - case CSSSelector::PseudoActive: - return forcedPseudoState & PseudoActive; - case CSSSelector::PseudoFocus: - return forcedPseudoState & PseudoFocus; - case CSSSelector::PseudoHover: - return forcedPseudoState & PseudoHover; - case CSSSelector::PseudoVisited: - return forcedPseudoState & PseudoVisited; + switch (pseudoClassType) { + case CSSSelector::PseudoClassActive: + return forcedPseudoState & PseudoClassActive; + case CSSSelector::PseudoClassFocus: + return forcedPseudoState & PseudoClassFocus; + case CSSSelector::PseudoClassHover: + return forcedPseudoState & PseudoClassHover; + case CSSSelector::PseudoClassVisited: + return forcedPseudoState & PseudoClassVisited; default: return false; } } -void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>>& pseudoIdMatches, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>>& inheritedEntries) +void InspectorCSSAgent::getMatchedStylesForNode(ErrorString& errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>>& pseudoIdMatches, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>>& inheritedEntries) { Element* element = elementForId(errorString, nodeId); if (!element) return; - // Matched rules. - StyleResolver& styleResolver = element->document().ensureStyleResolver(); - Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.styleRulesForElement(element, StyleResolver::AllCSSRules); - matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, element); - - // Pseudo elements. - if (!includePseudo || *includePseudo) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>> pseudoElements = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>::create(); - for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { - Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); - if (!matchedRules.isEmpty()) { - RefPtr<Inspector::TypeBuilder::CSS::PseudoIdMatches> matches = Inspector::TypeBuilder::CSS::PseudoIdMatches::create() - .setPseudoId(static_cast<int>(pseudoId)) - .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, element)); - pseudoElements->addItem(matches.release()); - } + Element* originalElement = element; + PseudoId elementPseudoId = element->pseudoId(); + if (elementPseudoId) { + element = downcast<PseudoElement>(*element).hostElement(); + if (!element) { + errorString = ASCIILiteral("Pseudo element has no parent"); + return; } - - pseudoIdMatches = pseudoElements.release(); } - // Inherited styles. - if (!includeInherited || *includeInherited) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>> entries = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>::create(); - Element* parentElement = element->parentElement(); - while (parentElement) { - StyleResolver& parentStyleResolver = parentElement->document().ensureStyleResolver(); - Vector<RefPtr<StyleRuleBase>> parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules); - RefPtr<Inspector::TypeBuilder::CSS::InheritedStyleEntry> entry = Inspector::TypeBuilder::CSS::InheritedStyleEntry::create() - .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules, styleResolver, parentElement)); - if (parentElement->style() && parentElement->style()->length()) { - InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement); - if (styleSheet) - entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); + // Matched rules. + StyleResolver& styleResolver = element->styleResolver(); + auto matchedRules = styleResolver.pseudoStyleRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules); + matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, *element, elementPseudoId); + + if (!originalElement->isPseudoElement()) { + // Pseudo elements. + if (!includePseudo || *includePseudo) { + auto pseudoElements = Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>::create(); + for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { + auto matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); + if (!matchedRules.isEmpty()) { + auto matches = Inspector::Protocol::CSS::PseudoIdMatches::create() + .setPseudoId(static_cast<int>(pseudoId)) + .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, *element, pseudoId)) + .release(); + pseudoElements->addItem(WTFMove(matches)); + } } - entries->addItem(entry.release()); - parentElement = parentElement->parentElement(); + pseudoIdMatches = WTFMove(pseudoElements); } - inheritedEntries = entries.release(); + // Inherited styles. + if (!includeInherited || *includeInherited) { + auto entries = Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>::create(); + Element* parentElement = element->parentElement(); + while (parentElement) { + StyleResolver& parentStyleResolver = parentElement->styleResolver(); + auto parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules); + auto entry = Inspector::Protocol::CSS::InheritedStyleEntry::create() + .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules, styleResolver, *parentElement, NOPSEUDO)) + .release(); + if (parentElement->cssomStyle() && parentElement->cssomStyle()->length()) { + if (InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement)) + entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); + } + + entries->addItem(WTFMove(entry)); + parentElement = parentElement->parentElement(); + } + + inheritedEntries = WTFMove(entries); + } } } -void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& attributesStyle) +void InspectorCSSAgent::getInlineStylesForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::Protocol::CSS::CSSStyle>& attributesStyle) { Element* element = elementForId(errorString, nodeId); if (!element) @@ -748,37 +630,65 @@ void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nod if (!styleSheet) return; - inlineStyle = styleSheet->buildObjectForStyle(element->style()); - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element); - attributesStyle = attributes ? attributes.release() : 0; + inlineStyle = styleSheet->buildObjectForStyle(element->cssomStyle()); + if (auto attributes = buildObjectForAttributesStyle(element)) + attributesStyle = WTFMove(attributes); + else + attributesStyle = nullptr; } -void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>>& style) +void InspectorCSSAgent::getComputedStyleForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>>& style) { Element* element = elementForId(errorString, nodeId); if (!element) return; - RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(element, true); - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0); + RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(*element, true); + Ref<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, nullptr); style = inspectorStyle->buildArrayForComputedStyle(); } -void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>>& styleInfos) +void InspectorCSSAgent::getAllStyleSheets(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>>& styleInfos) +{ + styleInfos = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>::create(); + + Vector<InspectorStyleSheet*> inspectorStyleSheets; + collectAllStyleSheets(inspectorStyleSheets); + for (auto* inspectorStyleSheet : inspectorStyleSheets) + styleInfos->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo()); +} + +void InspectorCSSAgent::collectAllStyleSheets(Vector<InspectorStyleSheet*>& result) +{ + Vector<CSSStyleSheet*> cssStyleSheets; + for (auto* document : m_domAgent->documents()) + collectAllDocumentStyleSheets(*document, cssStyleSheets); + + for (auto* cssStyleSheet : cssStyleSheets) + result.append(bindStyleSheet(cssStyleSheet)); +} + +void InspectorCSSAgent::collectAllDocumentStyleSheets(Document& document, Vector<CSSStyleSheet*>& result) { - styleInfos = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>::create(); - Vector<Document*> documents = m_domAgent->documents(); - for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) { - StyleSheetList* list = (*it)->styleSheets(); - for (unsigned i = 0; i < list->length(); ++i) { - StyleSheet* styleSheet = list->item(i); - if (styleSheet->isCSSStyleSheet()) - collectStyleSheets(static_cast<CSSStyleSheet*>(styleSheet), styleInfos.get()); + auto cssStyleSheets = document.styleScope().activeStyleSheetsForInspector(); + for (auto& cssStyleSheet : cssStyleSheets) + collectStyleSheets(cssStyleSheet.get(), result); +} + +void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector<CSSStyleSheet*>& result) +{ + result.append(styleSheet); + + for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { + CSSRule* rule = styleSheet->item(i); + if (is<CSSImportRule>(*rule)) { + if (CSSStyleSheet* importedStyleSheet = downcast<CSSImportRule>(*rule).styleSheet()) + collectStyleSheets(importedStyleSheet, result); } } } -void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject) +void InspectorCSSAgent::getStyleSheet(ErrorString& errorString, const String& styleSheetId, RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody>& styleSheetObject) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) @@ -787,27 +697,29 @@ void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& st styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet(); } -void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result) +void InspectorCSSAgent::getStyleSheetText(ErrorString& errorString, const String& styleSheetId, String* result) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) return; - inspectorStyleSheet->getText(result); + auto text = inspectorStyleSheet->text(); + if (!text.hasException()) + *result = text.releaseReturnValue(); } -void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text) +void InspectorCSSAgent::setStyleSheetText(ErrorString& errorString, const String& styleSheetId, const String& text) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(inspectorStyleSheet, text)), ec); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto result = m_domAgent->history()->perform(std::make_unique<SetStyleSheetTextAction>(inspectorStyleSheet, text)); + if (result.hasException()) + errorString = InspectorDOMAgent::toErrorString(result.releaseException()); } -void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, const String& text, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::setStyleText(ErrorString& errorString, const InspectorObject& fullStyleId, const String& text, RefPtr<Inspector::Protocol::CSS::CSSStyle>& result) { InspectorCSSId compoundId(fullStyleId); ASSERT(!compoundId.isEmpty()); @@ -816,133 +728,182 @@ void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<Insp if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetStyleTextAction(inspectorStyleSheet, compoundId, text)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto performResult = m_domAgent->history()->perform(std::make_unique<SetStyleTextAction>(inspectorStyleSheet, compoundId, text)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); + return; + } + + result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } -void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::setRuleSelector(ErrorString& errorString, const InspectorObject& fullRuleId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) { - InspectorCSSId compoundId(fullStyleId); + InspectorCSSId compoundId(fullRuleId); ASSERT(!compoundId.isEmpty()); InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto performResult = m_domAgent->history()->perform(std::make_unique<SetRuleSelectorAction>(inspectorStyleSheet, compoundId, selector)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); + return; + } + + result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId), nullptr); } -void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::createStyleSheet(ErrorString& errorString, const String& frameId, String* styleSheetId) { - InspectorCSSId compoundId(fullStyleId); - ASSERT(!compoundId.isEmpty()); + Frame* frame = m_domAgent->pageAgent()->frameForId(frameId); + if (!frame) { + errorString = ASCIILiteral("No frame for given id found"); + return; + } - InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); - if (!inspectorStyleSheet) + Document* document = frame->document(); + if (!document) { + errorString = ASCIILiteral("No document for frame"); return; + } - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(inspectorStyleSheet, compoundId, propertyIndex, disable)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + InspectorStyleSheet* inspectorStyleSheet = createInspectorStyleSheetForDocument(*document); + if (!inspectorStyleSheet) { + errorString = ASCIILiteral("Could not create stylesheet for the frame."); + return; + } + + *styleSheetId = inspectorStyleSheet->id(); } -void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<InspectorObject>& fullRuleId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) +InspectorStyleSheet* InspectorCSSAgent::createInspectorStyleSheetForDocument(Document& document) { - InspectorCSSId compoundId(fullRuleId); - ASSERT(!compoundId.isEmpty()); + if (!document.isHTMLDocument() && !document.isSVGDocument()) + return nullptr; - InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); - if (!inspectorStyleSheet) - return; + auto styleElement = HTMLStyleElement::create(document); + styleElement->setAttributeWithoutSynchronization(HTMLNames::typeAttr, AtomicString("text/css", AtomicString::ConstructFromLiteral)); + + ContainerNode* targetNode; + // HEAD is absent in ImageDocuments, for example. + if (auto* head = document.head()) + targetNode = head; + else if (auto* body = document.bodyOrFrameset()) + targetNode = body; + else + return nullptr; + + // Inserting this <style> into the document will trigger activeStyleSheetsUpdated + // and we will create an InspectorStyleSheet for this <style>'s CSSStyleSheet. + // Set this flag, so when we create it, we put it into the via inspector map. + m_creatingViaInspectorStyleSheet = true; + InlineStyleOverrideScope overrideScope(document); + auto appendResult = targetNode->appendChild(styleElement); + document.styleScope().flushPendingUpdate(); + m_creatingViaInspectorStyleSheet = false; + if (appendResult.hasException()) + return nullptr; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), ec); + auto iterator = m_documentToInspectorStyleSheet.find(&document); + ASSERT(iterator != m_documentToInspectorStyleSheet.end()); + if (iterator == m_documentToInspectorStyleSheet.end()) + return nullptr; - if (success) - result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto& inspectorStyleSheetsForDocument = iterator->value; + ASSERT(!inspectorStyleSheetsForDocument.isEmpty()); + if (inspectorStyleSheetsForDocument.isEmpty()) + return nullptr; + + return inspectorStyleSheetsForDocument.last().get(); } -void InspectorCSSAgent::addRule(ErrorString* errorString, const int contextNodeId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) +void InspectorCSSAgent::addRule(ErrorString& errorString, const String& styleSheetId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) { - Node* node = m_domAgent->assertNode(errorString, contextNodeId); - if (!node) - return; - - InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(&node->document(), true); + InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) { - *errorString = "No target stylesheet found"; + errorString = ASCIILiteral("No target stylesheet found"); return; } - ExceptionCode ec = 0; - OwnPtr<AddRuleAction> action = adoptPtr(new AddRuleAction(inspectorStyleSheet, selector)); - AddRuleAction* rawAction = action.get(); - bool success = m_domAgent->history()->perform(action.release(), ec); - if (!success) { - *errorString = InspectorDOMAgent::toErrorString(ec); + auto action = std::make_unique<AddRuleAction>(inspectorStyleSheet, selector); + auto& rawAction = *action; + auto performResult = m_domAgent->history()->perform(WTFMove(action)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); return; } - InspectorCSSId ruleId = rawAction->newRuleId(); + InspectorCSSId ruleId = rawAction.newRuleId(); CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId); - result = inspectorStyleSheet->buildObjectForRule(rule); + result = inspectorStyleSheet->buildObjectForRule(rule, nullptr); } -void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>>& cssProperties) +void InspectorCSSAgent::getSupportedCSSProperties(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>>& cssProperties) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>> properties = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>::create(); + auto properties = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>::create(); for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) { CSSPropertyID id = convertToCSSPropertyID(i); - RefPtr<Inspector::TypeBuilder::CSS::CSSPropertyInfo> property = Inspector::TypeBuilder::CSS::CSSPropertyInfo::create() - .setName(getPropertyNameString(id)); + if (isInternalCSSProperty(id)) + continue; + + auto property = Inspector::Protocol::CSS::CSSPropertyInfo::create() + .setName(getPropertyNameString(id)) + .release(); const StylePropertyShorthand& shorthand = shorthandForProperty(id); if (!shorthand.length()) { - properties->addItem(property.release()); + properties->addItem(WTFMove(property)); continue; } - RefPtr<Inspector::TypeBuilder::Array<String>> longhands = Inspector::TypeBuilder::Array<String>::create(); + auto longhands = Inspector::Protocol::Array<String>::create(); for (unsigned j = 0; j < shorthand.length(); ++j) { CSSPropertyID longhandID = shorthand.properties()[j]; longhands->addItem(getPropertyNameString(longhandID)); } - property->setLonghands(longhands); - properties->addItem(property.release()); + property->setLonghands(WTFMove(longhands)); + properties->addItem(WTFMove(property)); } - cssProperties = properties.release(); + cssProperties = WTFMove(properties); +} + +void InspectorCSSAgent::getSupportedSystemFontFamilyNames(ErrorString&, RefPtr<Inspector::Protocol::Array<String>>& fontFamilyNames) +{ + auto families = Inspector::Protocol::Array<String>::create(); + + Vector<String> systemFontFamilies = FontCache::singleton().systemFontFamilies(); + for (const auto& familyName : systemFontFamilies) + families->addItem(familyName); + + fontFamilyNames = WTFMove(families); } -void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>& forcedPseudoClasses) +void InspectorCSSAgent::forcePseudoState(ErrorString& errorString, int nodeId, const InspectorArray& forcedPseudoClasses) { Element* element = m_domAgent->assertElement(errorString, nodeId); if (!element) return; - unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses.get()); - NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId); + auto it = m_nodeIdToForcedPseudoState.find(nodeId); + unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses); unsigned currentForcedPseudoState = it == m_nodeIdToForcedPseudoState.end() ? 0 : it->value; - bool needStyleRecalc = forcedPseudoState != currentForcedPseudoState; - if (!needStyleRecalc) + if (forcedPseudoState == currentForcedPseudoState) return; - if (forcedPseudoState) + if (forcedPseudoState) { m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState); - else + m_documentsWithForcedPseudoStates.add(&element->document()); + } else { m_nodeIdToForcedPseudoState.remove(nodeId); - element->document().styleResolverChanged(RecalcStyleImmediately); + if (m_nodeIdToForcedPseudoState.isEmpty()) + m_documentsWithForcedPseudoStates.clear(); + } + + element->document().styleScope().didChangeStyleSheetEnvironment(); } -void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int documentNodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>>& result) +void InspectorCSSAgent::getNamedFlowCollection(ErrorString& errorString, int documentNodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>>& result) { Document* document = m_domAgent->assertDocument(errorString, documentNodeId); if (!document) @@ -950,25 +911,25 @@ void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int doc m_namedFlowCollectionsRequested.add(documentNodeId); - Vector<RefPtr<WebKitNamedFlow>> namedFlowsVector = document->namedFlows()->namedFlows(); - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>> namedFlows = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>::create(); + Vector<RefPtr<WebKitNamedFlow>> namedFlowsVector = document->namedFlows().namedFlows(); + auto namedFlows = Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>::create(); - for (Vector<RefPtr<WebKitNamedFlow>>::iterator it = namedFlowsVector.begin(); it != namedFlowsVector.end(); ++it) - namedFlows->addItem(buildObjectForNamedFlow(errorString, it->get(), documentNodeId)); + for (auto& namedFlow : namedFlowsVector) + namedFlows->addItem(buildObjectForNamedFlow(errorString, namedFlow.get(), documentNodeId)); - result = namedFlows.release(); + result = WTFMove(namedFlows); } InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element) { NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element); if (it == m_nodeToInspectorStyleSheet.end()) { - CSSStyleDeclaration* style = element->isStyledElement() ? element->style() : 0; + CSSStyleDeclaration* style = element->cssomStyle(); if (!style) - return 0; + return nullptr; String newStyleSheetId = String::number(m_lastStyleSheetId++); - RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_domAgent->pageAgent(), newStyleSheetId, element, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular, this); + RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_domAgent->pageAgent(), newStyleSheetId, element, Inspector::Protocol::CSS::StyleSheetOrigin::Regular, this); m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet); m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet); return inspectorStyleSheet.get(); @@ -977,18 +938,18 @@ InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Elem return it->value.get(); } -Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId) +Element* InspectorCSSAgent::elementForId(ErrorString& errorString, int nodeId) { Node* node = m_domAgent->nodeForId(nodeId); if (!node) { - *errorString = "No node with given id found"; - return 0; + errorString = ASCIILiteral("No node with given id found"); + return nullptr; } - if (!node->isElementNode()) { - *errorString = "Not an element node"; - return 0; + if (!is<Element>(*node)) { + errorString = ASCIILiteral("Not an element node"); + return nullptr; } - return toElement(node); + return downcast<Element>(node); } int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document) @@ -1000,18 +961,13 @@ int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document) return documentNodeId; } -void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>* result) +String InspectorCSSAgent::unbindStyleSheet(InspectorStyleSheet* inspectorStyleSheet) { - InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(static_cast<CSSStyleSheet*>(styleSheet)); - result->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo()); - for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { - CSSRule* rule = styleSheet->item(i); - if (rule->type() == CSSRule::IMPORT_RULE) { - CSSStyleSheet* importedStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet(); - if (importedStyleSheet) - collectStyleSheets(importedStyleSheet, result); - } - } + String id = inspectorStyleSheet->id(); + m_idToInspectorStyleSheet.remove(id); + if (inspectorStyleSheet->pageStyleSheet()) + m_cssStyleSheetToInspectorStyleSheet.remove(inspectorStyleSheet->pageStyleSheet()); + return id; } InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet) @@ -1023,190 +979,146 @@ InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, styleSheet, detectOrigin(styleSheet, document), InspectorDOMAgent::documentURLString(document), this); m_idToInspectorStyleSheet.set(id, inspectorStyleSheet); m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet); + if (m_creatingViaInspectorStyleSheet) { + auto& inspectorStyleSheetsForDocument = m_documentToInspectorStyleSheet.add(document, Vector<RefPtr<InspectorStyleSheet>>()).iterator->value; + inspectorStyleSheetsForDocument.append(inspectorStyleSheet); + } } return inspectorStyleSheet.get(); } -InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* document, bool createIfAbsent) -{ - if (!document) { - ASSERT(!createIfAbsent); - return 0; - } - - if (!document->isHTMLDocument() && !document->isSVGDocument()) - return 0; - - RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToInspectorStyleSheet.get(document); - if (inspectorStyleSheet || !createIfAbsent) - return inspectorStyleSheet.get(); - - ExceptionCode ec = 0; - RefPtr<Element> styleElement = document->createElement("style", ec); - if (!ec) - styleElement->setAttribute("type", "text/css", ec); - if (!ec) { - ContainerNode* targetNode; - // HEAD is absent in ImageDocuments, for example. - if (document->head()) - targetNode = document->head(); - else if (document->body()) - targetNode = document->body(); - else - return 0; - - InlineStyleOverrideScope overrideScope(document); - targetNode->appendChild(styleElement, ec); - } - if (ec) - return 0; - - CSSStyleSheet* cssStyleSheet = 0; - if (styleElement->isHTMLElement()) - cssStyleSheet = toHTMLStyleElement(styleElement.get())->sheet(); -#if ENABLE(SVG) - else if (styleElement->isSVGElement()) - cssStyleSheet = toSVGStyleElement(styleElement.get())->sheet(); -#endif - - if (!cssStyleSheet) - return 0; - - String id = String::number(m_lastStyleSheetId++); - inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, cssStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector, InspectorDOMAgent::documentURLString(document), this); - m_idToInspectorStyleSheet.set(id, inspectorStyleSheet); - m_cssStyleSheetToInspectorStyleSheet.set(cssStyleSheet, inspectorStyleSheet); - m_documentToInspectorStyleSheet.set(document, inspectorStyleSheet); - return inspectorStyleSheet.get(); -} - -InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId) +InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString& errorString, const String& styleSheetId) { IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId); if (it == m_idToInspectorStyleSheet.end()) { - *errorString = "No style sheet with given id found"; - return 0; + errorString = ASCIILiteral("No stylesheet with given id found"); + return nullptr; } return it->value.get(); } -Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument) +Inspector::Protocol::CSS::StyleSheetOrigin InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument) { - Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular; + if (m_creatingViaInspectorStyleSheet) + return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector; + if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty()) - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::UserAgent; - else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document") - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::User; - else { - InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false); - if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet()) - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector; + return Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent; + + if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document") + return Inspector::Protocol::CSS::StyleSheetOrigin::User; + + auto iterator = m_documentToInspectorStyleSheet.find(ownerDocument); + if (iterator != m_documentToInspectorStyleSheet.end()) { + for (auto& inspectorStyleSheet : iterator->value) { + if (pageStyleSheet == inspectorStyleSheet->pageStyleSheet()) + return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector; + } } - return origin; + + return Inspector::Protocol::CSS::StyleSheetOrigin::Regular; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver) +RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver, Element& element) { if (!styleRule) - return 0; + return nullptr; // StyleRules returned by StyleResolver::styleRulesForElement lack parent pointers since that infomation is not cheaply available. // Since the inspector wants to walk the parent chain, we construct the full wrappers here. - CSSStyleRule* cssomWrapper = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(styleRule, styleResolver.document().styleSheetCollection()); + styleResolver.inspectorCSSOMWrappers().collectDocumentWrappers(styleResolver.document().extensionStyleSheets()); + styleResolver.inspectorCSSOMWrappers().collectScopeWrappers(Style::Scope::forNode(element)); + + // Possiblity of :host styles if this element has a shadow root. + if (ShadowRoot* shadowRoot = element.shadowRoot()) + styleResolver.inspectorCSSOMWrappers().collectScopeWrappers(shadowRoot->styleScope()); + + CSSStyleRule* cssomWrapper = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(styleRule); if (!cssomWrapper) - return 0; + return nullptr; + InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssomWrapper->parentStyleSheet()); - return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper) : 0; + return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper, &element) : nullptr; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule) +RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule) { if (!rule) - return 0; + return nullptr; ASSERT(rule->parentStyleSheet()); InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet()); - return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule) : 0; + return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule, nullptr) : nullptr; } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList) +RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>> InspectorCSSAgent::buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRule>>& matchedRules, StyleResolver& styleResolver, Element& element, PseudoId pseudoId) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>::create(); - if (!ruleList) - return result.release(); + auto result = Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>::create(); - for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { - CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); - RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); - if (!ruleObject) - continue; - result->addItem(ruleObject); - } - return result.release(); -} + SelectorChecker::CheckingContext context(SelectorChecker::Mode::CollectingRules); + context.pseudoId = pseudoId ? pseudoId : element.pseudoId(); + SelectorChecker selectorChecker(element.document()); -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> InspectorCSSAgent::buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRuleBase>>& matchedRules, StyleResolver& styleResolver, Element* element) -{ - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>::create(); - - for (unsigned i = 0; i < matchedRules.size(); ++i) { - if (!matchedRules[i]->isStyleRule()) - continue; - StyleRule* matchedStyleRule = static_cast<StyleRule*>(matchedRules[i].get()); - RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(matchedStyleRule, styleResolver); + for (auto& matchedRule : matchedRules) { + RefPtr<Inspector::Protocol::CSS::CSSRule> ruleObject = buildObjectForRule(matchedRule.get(), styleResolver, element); if (!ruleObject) continue; - RefPtr<Inspector::TypeBuilder::Array<int>> matchingSelectors = Inspector::TypeBuilder::Array<int>::create(); - const CSSSelectorList& selectorList = matchedStyleRule->selectorList(); - long index = 0; + + auto matchingSelectors = Inspector::Protocol::Array<int>::create(); + const CSSSelectorList& selectorList = matchedRule->selectorList(); + int index = 0; for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) { - bool matched = element->webkitMatchesSelector(selector->selectorText(), IGNORE_EXCEPTION); + unsigned ignoredSpecificity; + bool matched = selectorChecker.match(*selector, element, context, ignoredSpecificity); if (matched) matchingSelectors->addItem(index); ++index; } - RefPtr<Inspector::TypeBuilder::CSS::RuleMatch> match = Inspector::TypeBuilder::CSS::RuleMatch::create() - .setRule(ruleObject) - .setMatchingSelectors(matchingSelectors); - result->addItem(match); + + auto match = Inspector::Protocol::CSS::RuleMatch::create() + .setRule(WTFMove(ruleObject)) + .setMatchingSelectors(WTFMove(matchingSelectors)) + .release(); + result->addItem(WTFMove(match)); } - return result.release(); + return WTFMove(result); } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element) +RefPtr<Inspector::Protocol::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element) { - if (!element->isStyledElement()) - return 0; + ASSERT(element); + if (!is<StyledElement>(*element)) + return nullptr; // FIXME: Ugliness below. - StyleProperties* attributeStyle = const_cast<StyleProperties*>(toStyledElement(element)->presentationAttributeStyle()); + StyleProperties* attributeStyle = const_cast<StyleProperties*>(downcast<StyledElement>(element)->presentationAttributeStyle()); if (!attributeStyle) - return 0; + return nullptr; ASSERT_WITH_SECURITY_IMPLICATION(attributeStyle->isMutable()); MutableStyleProperties* mutableAttributeStyle = static_cast<MutableStyleProperties*>(attributeStyle); - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), 0); + Ref<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), nullptr); return inspectorStyle->buildObjectForStyle(); } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> InspectorCSSAgent::buildArrayForRegions(ErrorString* errorString, PassRefPtr<NodeList> regionList, int documentNodeId) +RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::Region>> InspectorCSSAgent::buildArrayForRegions(ErrorString& errorString, RefPtr<NodeList>&& regionList, int documentNodeId) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> regions = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>::create(); + auto regions = Inspector::Protocol::Array<Inspector::Protocol::CSS::Region>::create(); for (unsigned i = 0; i < regionList->length(); ++i) { - Inspector::TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset; + Inspector::Protocol::CSS::Region::RegionOverset regionOverset; - switch (toElement(regionList->item(i))->renderRegion()->regionOversetState()) { + switch (downcast<Element>(regionList->item(i))->regionOversetState()) { case RegionFit: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Fit; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Fit; break; case RegionEmpty: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Empty; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Empty; break; case RegionOverset: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Overset; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Overset; break; case RegionUndefined: continue; @@ -1215,66 +1127,52 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> I continue; } - RefPtr<Inspector::TypeBuilder::CSS::Region> region = Inspector::TypeBuilder::CSS::Region::create() + auto region = Inspector::Protocol::CSS::Region::create() .setRegionOverset(regionOverset) // documentNodeId was previously asserted - .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i))); + .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i))) + .release(); - regions->addItem(region); + regions->addItem(WTFMove(region)); } - return regions.release(); + return WTFMove(regions); } -PassRefPtr<Inspector::TypeBuilder::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString* errorString, WebKitNamedFlow* webkitNamedFlow, int documentNodeId) +RefPtr<Inspector::Protocol::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString& errorString, WebKitNamedFlow* webkitNamedFlow, int documentNodeId) { RefPtr<NodeList> contentList = webkitNamedFlow->getContent(); - RefPtr<Inspector::TypeBuilder::Array<int>> content = Inspector::TypeBuilder::Array<int>::create(); + auto content = Inspector::Protocol::Array<int>::create(); for (unsigned i = 0; i < contentList->length(); ++i) { // documentNodeId was previously asserted content->addItem(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, contentList->item(i))); } - RefPtr<Inspector::TypeBuilder::CSS::NamedFlow> namedFlow = Inspector::TypeBuilder::CSS::NamedFlow::create() + return Inspector::Protocol::CSS::NamedFlow::create() .setDocumentNodeId(documentNodeId) .setName(webkitNamedFlow->name().string()) .setOverset(webkitNamedFlow->overset()) - .setContent(content) - .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId)); - - return namedFlow.release(); + .setContent(WTFMove(content)) + .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId)) + .release(); } -void InspectorCSSAgent::didRemoveDocument(Document* document) +void InspectorCSSAgent::didRemoveDOMNode(Node& node, int nodeId) { - if (document) - m_documentToInspectorStyleSheet.remove(document); -} - -void InspectorCSSAgent::didRemoveDOMNode(Node* node) -{ - if (!node) - return; + m_nodeIdToForcedPseudoState.remove(nodeId); - int nodeId = m_domAgent->boundNodeId(node); - if (nodeId) - m_nodeIdToForcedPseudoState.remove(nodeId); - - NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node); + auto it = m_nodeToInspectorStyleSheet.find(&node); if (it == m_nodeToInspectorStyleSheet.end()) return; m_idToInspectorStyleSheet.remove(it->value->id()); - m_nodeToInspectorStyleSheet.remove(node); + m_nodeToInspectorStyleSheet.remove(&node); } -void InspectorCSSAgent::didModifyDOMAttr(Element* element) +void InspectorCSSAgent::didModifyDOMAttr(Element& element) { - if (!element) - return; - - NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element); + auto it = m_nodeToInspectorStyleSheet.find(&element); if (it == m_nodeToInspectorStyleSheet.end()) return; @@ -1283,23 +1181,16 @@ void InspectorCSSAgent::didModifyDOMAttr(Element* element) void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheet* styleSheet) { - if (m_frontendDispatcher) - m_frontendDispatcher->styleSheetChanged(styleSheet->id()); + m_frontendDispatcher->styleSheetChanged(styleSheet->id()); } void InspectorCSSAgent::resetPseudoStates() { - HashSet<Document*> documentsToChange; - for (NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.begin(), end = m_nodeIdToForcedPseudoState.end(); it != end; ++it) { - if (Element* element = toElement(m_domAgent->nodeForId(it->key))) - documentsToChange.add(&element->document()); - } + for (auto& document : m_documentsWithForcedPseudoStates) + document->styleScope().didChangeStyleSheetEnvironment(); m_nodeIdToForcedPseudoState.clear(); - for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it) - (*it)->styleResolverChanged(RecalcStyleImmediately); + m_documentsWithForcedPseudoStates.clear(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorCSSAgent.h b/Source/WebCore/inspector/InspectorCSSAgent.h index 10b4fe91f..78ebca7a0 100644 --- a/Source/WebCore/inspector/InspectorCSSAgent.h +++ b/Source/WebCore/inspector/InspectorCSSAgent.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2010, Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,60 +23,51 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorCSSAgent_h -#define InspectorCSSAgent_h +#pragma once #include "CSSSelector.h" #include "ContentSecurityPolicy.h" #include "InspectorDOMAgent.h" #include "InspectorStyleSheet.h" #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" #include "SecurityContext.h" +#include <inspector/InspectorBackendDispatchers.h> #include <inspector/InspectorValues.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/text/WTFString.h> namespace Inspector { -class InspectorCSSFrontendDispatcher; +class CSSFrontendDispatcher; } namespace WebCore { class CSSRule; -class CSSRuleList; -class CSSStyleDeclaration; class CSSStyleRule; class CSSStyleSheet; +class ChangeRegionOversetTask; class Document; -class DocumentStyleSheetCollection; class Element; -class InspectorCSSOMWrappers; -class InstrumentingAgents; -class NameNodeMap; class Node; class NodeList; class StyleResolver; class StyleRule; -class UpdateRegionLayoutTask; -class ChangeRegionOversetTask; - -#if ENABLE(INSPECTOR) +class WebKitNamedFlow; -class InspectorCSSAgent +class InspectorCSSAgent final : public InspectorAgentBase , public InspectorDOMAgent::DOMListener - , public Inspector::InspectorCSSBackendDispatcherHandler + , public Inspector::CSSBackendDispatcherHandler , public InspectorStyleSheet::Listener { WTF_MAKE_NONCOPYABLE(InspectorCSSAgent); + WTF_MAKE_FAST_ALLOCATED; public: class InlineStyleOverrideScope { public: - InlineStyleOverrideScope(SecurityContext* context) - : m_contentSecurityPolicy(context->contentSecurityPolicy()) + InlineStyleOverrideScope(SecurityContext& context) + : m_contentSecurityPolicy(context.contentSecurityPolicy()) { m_contentSecurityPolicy->setOverrideAllowInlineStyle(true); } @@ -89,106 +81,107 @@ public: ContentSecurityPolicy* m_contentSecurityPolicy; }; - InspectorCSSAgent(InstrumentingAgents*, InspectorDOMAgent*); - ~InspectorCSSAgent(); + InspectorCSSAgent(WebAgentContext&, InspectorDOMAgent*); + virtual ~InspectorCSSAgent(); - static CSSStyleRule* asCSSStyleRule(CSSRule*); + static CSSStyleRule* asCSSStyleRule(CSSRule&); - bool forcePseudoState(Element*, CSSSelector::PseudoType); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - virtual void discardAgent() override; - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; + void discardAgent() override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void regionOversetChanged(WebKitNamedFlow*, int documentNodeId); void reset(); + + // InspectorInstrumentation + void documentDetached(Document&); void mediaQueryResultChanged(); - void didCreateNamedFlow(Document*, WebKitNamedFlow*); - void willRemoveNamedFlow(Document*, WebKitNamedFlow*); - void didUpdateRegionLayout(Document*, WebKitNamedFlow*); - void regionLayoutUpdated(WebKitNamedFlow*, int documentNodeId); - void didChangeRegionOverset(Document*, WebKitNamedFlow*); - void regionOversetChanged(WebKitNamedFlow*, int documentNodeId); - void didRegisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement, Node* nextContentElement = nullptr); - void didUnregisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement); - - virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>>&) override; - virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& attributes) override; - virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>>& pseudoIdMatches, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>>& inheritedEntries) override; - virtual void getAllStyleSheets(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>>& styleSheetInfos) override; - virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody>& result) override; - virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result) override; - virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text) override; - virtual void setStyleText(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, const String& text, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override; - virtual void setPropertyText(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override; - virtual void toggleProperty(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, int propertyIndex, bool disable, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override; - virtual void setRuleSelector(ErrorString*, const RefPtr<Inspector::InspectorObject>& ruleId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) override; - virtual void addRule(ErrorString*, int contextNodeId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) override; - virtual void getSupportedCSSProperties(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>>& result) override; - virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<Inspector::InspectorArray>& forcedPseudoClasses) override; - virtual void getNamedFlowCollection(ErrorString*, int documentNodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>>& result) override; + void activeStyleSheetsUpdated(Document&); + void didCreateNamedFlow(Document&, WebKitNamedFlow&); + void willRemoveNamedFlow(Document&, WebKitNamedFlow&); + void didChangeRegionOverset(Document&, WebKitNamedFlow&); + void didRegisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement, Node* nextContentElement = nullptr); + void didUnregisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement); + bool forcePseudoState(const Element&, CSSSelector::PseudoClassType); + + void getComputedStyleForNode(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>>&) override; + void getInlineStylesForNode(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::Protocol::CSS::CSSStyle>& attributes) override; + void getMatchedStylesForNode(ErrorString&, int nodeId, const bool* const includePseudo, const bool* const includeInherited, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>>&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>>& inheritedEntries) override; + void getAllStyleSheets(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>>& styleSheetInfos) override; + void getStyleSheet(ErrorString&, const String& styleSheetId, RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody>& result) override; + void getStyleSheetText(ErrorString&, const String& styleSheetId, String* result) override; + void setStyleSheetText(ErrorString&, const String& styleSheetId, const String& text) override; + void setStyleText(ErrorString&, const Inspector::InspectorObject& styleId, const String& text, RefPtr<Inspector::Protocol::CSS::CSSStyle>& result) override; + void setRuleSelector(ErrorString&, const Inspector::InspectorObject& ruleId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) override; + void createStyleSheet(ErrorString&, const String& frameId, String* styleSheetId) override; + void addRule(ErrorString&, const String& styleSheetId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) override; + void getSupportedCSSProperties(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>>& result) override; + void getSupportedSystemFontFamilyNames(ErrorString&, RefPtr<Inspector::Protocol::Array<String>>& result) override; + void forcePseudoState(ErrorString&, int nodeId, const Inspector::InspectorArray& forcedPseudoClasses) override; + void getNamedFlowCollection(ErrorString&, int documentNodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>>& result) override; private: class StyleSheetAction; class SetStyleSheetTextAction; class SetStyleTextAction; - class SetPropertyTextAction; - class TogglePropertyAction; class SetRuleSelectorAction; class AddRuleAction; typedef HashMap<String, RefPtr<InspectorStyleSheet>> IdToInspectorStyleSheet; typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet>> CSSStyleSheetToInspectorStyleSheet; typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle>> NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles - typedef HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet>> DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets + typedef HashMap<RefPtr<Document>, Vector<RefPtr<InspectorStyleSheet>>> DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets typedef HashMap<int, unsigned> NodeIdToForcedPseudoState; void resetNonPersistentData(); InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element); - Element* elementForId(ErrorString*, int nodeId); + Element* elementForId(ErrorString&, int nodeId); int documentNodeWithRequestedFlowsId(Document*); - void collectStyleSheets(CSSStyleSheet*, Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>*); + void collectAllStyleSheets(Vector<InspectorStyleSheet*>&); + void collectAllDocumentStyleSheets(Document&, Vector<CSSStyleSheet*>&); + void collectStyleSheets(CSSStyleSheet*, Vector<CSSStyleSheet*>&); + void setActiveStyleSheetsForDocument(Document&, Vector<CSSStyleSheet*>& activeStyleSheets); + + String unbindStyleSheet(InspectorStyleSheet*); InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*); - InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent); - InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&); - Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument); - - PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> buildObjectForRule(StyleRule*, StyleResolver&); - PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*); - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> buildArrayForRuleList(CSSRuleList*); - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRuleBase>>&, StyleResolver&, Element*); - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*); - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> buildArrayForRegions(ErrorString*, PassRefPtr<NodeList>, int documentNodeId); - PassRefPtr<Inspector::TypeBuilder::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString*, WebKitNamedFlow*, int documentNodeId); + InspectorStyleSheet* assertStyleSheetForId(ErrorString&, const String&); + InspectorStyleSheet* createInspectorStyleSheetForDocument(Document&); + Inspector::Protocol::CSS::StyleSheetOrigin detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument); + + RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(StyleRule*, StyleResolver&, Element&); + RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*); + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>> buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRule>>&, StyleResolver&, Element&, PseudoId); + RefPtr<Inspector::Protocol::CSS::CSSStyle> buildObjectForAttributesStyle(Element*); + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::Region>> buildArrayForRegions(ErrorString&, RefPtr<NodeList>&&, int documentNodeId); + RefPtr<Inspector::Protocol::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString&, WebKitNamedFlow*, int documentNodeId); // InspectorDOMAgent::DOMListener implementation - virtual void didRemoveDocument(Document*) override; - virtual void didRemoveDOMNode(Node*) override; - virtual void didModifyDOMAttr(Element*) override; + void didRemoveDOMNode(Node&, int nodeId) override; + void didModifyDOMAttr(Element&) override; // InspectorCSSAgent::Listener implementation - virtual void styleSheetChanged(InspectorStyleSheet*) override; + void styleSheetChanged(InspectorStyleSheet*) override; void resetPseudoStates(); - std::unique_ptr<Inspector::InspectorCSSFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorCSSBackendDispatcher> m_backendDispatcher; - InspectorDOMAgent* m_domAgent; + std::unique_ptr<Inspector::CSSFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::CSSBackendDispatcher> m_backendDispatcher; + InspectorDOMAgent* m_domAgent { nullptr }; IdToInspectorStyleSheet m_idToInspectorStyleSheet; CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet; NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet; DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet; + HashMap<Document*, HashSet<CSSStyleSheet*>> m_documentToKnownCSSStyleSheets; NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState; + HashSet<Document*> m_documentsWithForcedPseudoStates; HashSet<int> m_namedFlowCollectionsRequested; - OwnPtr<UpdateRegionLayoutTask> m_updateRegionLayoutTask; - OwnPtr<ChangeRegionOversetTask> m_changeRegionOversetTask; + std::unique_ptr<ChangeRegionOversetTask> m_changeRegionOversetTask; - int m_lastStyleSheetId; + int m_lastStyleSheetId { 1 }; + bool m_creatingViaInspectorStyleSheet { false }; }; -#endif - } // namespace WebCore - -#endif // !defined(InspectorCSSAgent_h) diff --git a/Source/WebCore/inspector/InspectorCanvasAgent.cpp b/Source/WebCore/inspector/InspectorCanvasAgent.cpp deleted file mode 100644 index 95258efd4..000000000 --- a/Source/WebCore/inspector/InspectorCanvasAgent.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorCanvasAgent.h" - -#include "DOMWindow.h" -#include "HTMLCanvasElement.h" -#include "HTMLNames.h" -#include "InjectedScriptCanvasModule.h" -#include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InstrumentingAgents.h" -#include "MainFrame.h" -#include "NodeList.h" -#include "Page.h" -#include "ScriptProfiler.h" -#include "ScriptState.h" -#include <bindings/ScriptObject.h> -#include <inspector/InjectedScript.h> -#include <inspector/InjectedScriptManager.h> - -using Inspector::TypeBuilder::Array; -using Inspector::TypeBuilder::Canvas::ResourceId; -using Inspector::TypeBuilder::Canvas::ResourceInfo; -using Inspector::TypeBuilder::Canvas::ResourceState; -using Inspector::TypeBuilder::Canvas::TraceLog; -using Inspector::TypeBuilder::Canvas::TraceLogId; -using Inspector::TypeBuilder::Network::FrameId; - -using namespace Inspector; - -namespace WebCore { - -InspectorCanvasAgent::InspectorCanvasAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager) - : InspectorAgentBase(ASCIILiteral("Canvas"), instrumentingAgents) - , m_pageAgent(pageAgent) - , m_injectedScriptManager(injectedScriptManager) - , m_enabled(false) -{ -} - -InspectorCanvasAgent::~InspectorCanvasAgent() -{ -} - -void InspectorCanvasAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) -{ - m_frontendDispatcher = std::make_unique<InspectorCanvasFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorCanvasBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorCanvasAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) -{ - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - disable(nullptr); -} - -void InspectorCanvasAgent::enable(ErrorString*) -{ - if (m_enabled) - return; - m_enabled = true; - m_instrumentingAgents->setInspectorCanvasAgent(this); - findFramesWithUninstrumentedCanvases(); -} - -void InspectorCanvasAgent::disable(ErrorString*) -{ - m_enabled = false; - m_instrumentingAgents->setInspectorCanvasAgent(nullptr); - m_framesWithUninstrumentedCanvases.clear(); -} - -void InspectorCanvasAgent::dropTraceLog(ErrorString* errorString, const TraceLogId& traceLogId) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId); - if (!module.hasNoValue()) - module.dropTraceLog(errorString, traceLogId); -} - -void InspectorCanvasAgent::hasUninstrumentedCanvases(ErrorString* errorString, bool* result) -{ - if (!checkIsEnabled(errorString)) - return; - for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) { - if (it->value) { - *result = true; - return; - } - } - *result = false; -} - -void InspectorCanvasAgent::captureFrame(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId) -{ - Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame(); - if (!frame) - return; - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldExecState(frame)); - if (!module.hasNoValue()) - module.captureFrame(errorString, traceLogId); -} - -void InspectorCanvasAgent::startCapturing(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId) -{ - Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame(); - if (!frame) - return; - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldExecState(frame)); - if (!module.hasNoValue()) - module.startCapturing(errorString, traceLogId); -} - -void InspectorCanvasAgent::stopCapturing(ErrorString* errorString, const TraceLogId& traceLogId) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId); - if (!module.hasNoValue()) - module.stopCapturing(errorString, traceLogId); -} - -void InspectorCanvasAgent::getTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, const int* startOffset, const int* maxLength, RefPtr<TraceLog>& traceLog) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId); - if (!module.hasNoValue()) - module.traceLog(errorString, traceLogId, startOffset, maxLength, &traceLog); -} - -void InspectorCanvasAgent::replayTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, int stepNo, RefPtr<ResourceState>& result) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId); - if (!module.hasNoValue()) - module.replayTraceLog(errorString, traceLogId, stepNo, &result); -} - -void InspectorCanvasAgent::getResourceInfo(ErrorString* errorString, const ResourceId& resourceId, RefPtr<ResourceInfo>& result) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, resourceId); - if (!module.hasNoValue()) - module.resourceInfo(errorString, resourceId, &result); -} - -void InspectorCanvasAgent::getResourceState(ErrorString* errorString, const TraceLogId& traceLogId, const ResourceId& resourceId, RefPtr<ResourceState>& result) -{ - InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId); - if (!module.hasNoValue()) - module.resourceState(errorString, traceLogId, resourceId, &result); -} - -Deprecated::ScriptObject InspectorCanvasAgent::wrapCanvas2DRenderingContextForInstrumentation(const Deprecated::ScriptObject& context) -{ - ErrorString error; - InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, context); - if (module.hasNoValue()) - return Deprecated::ScriptObject(); - return notifyRenderingContextWasWrapped(module.wrapCanvas2DContext(context)); -} - -#if ENABLE(WEBGL) -Deprecated::ScriptObject InspectorCanvasAgent::wrapWebGLRenderingContextForInstrumentation(const Deprecated::ScriptObject& glContext) -{ - ErrorString error; - InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, glContext); - if (module.hasNoValue()) - return Deprecated::ScriptObject(); - return notifyRenderingContextWasWrapped(module.wrapWebGLContext(glContext)); -} -#endif - -Deprecated::ScriptObject InspectorCanvasAgent::notifyRenderingContextWasWrapped(const Deprecated::ScriptObject& wrappedContext) -{ - ASSERT(m_frontendDispatcher); - JSC::ExecState* scriptState = wrappedContext.scriptState(); - DOMWindow* domWindow = scriptState ? domWindowFromExecState(scriptState) : nullptr; - Frame* frame = domWindow ? domWindow->frame() : nullptr; - if (frame && !m_framesWithUninstrumentedCanvases.contains(frame)) - m_framesWithUninstrumentedCanvases.set(frame, false); - String frameId = m_pageAgent->frameId(frame); - if (!frameId.isEmpty()) - m_frontendDispatcher->contextCreated(frameId); - return wrappedContext; -} - -InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, JSC::ExecState* scriptState) -{ - if (!checkIsEnabled(errorString)) - return InjectedScriptCanvasModule(); - InjectedScriptCanvasModule module = InjectedScriptCanvasModule::moduleForState(m_injectedScriptManager, scriptState); - if (module.hasNoValue()) { - ASSERT_NOT_REACHED(); - *errorString = "Internal error: no Canvas module"; - } - return module; -} - -InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, const Deprecated::ScriptObject& scriptObject) -{ - if (!checkIsEnabled(errorString)) - return InjectedScriptCanvasModule(); - if (scriptObject.hasNoValue()) { - ASSERT_NOT_REACHED(); - *errorString = "Internal error: original Deprecated::ScriptObject has no value"; - return InjectedScriptCanvasModule(); - } - return injectedScriptCanvasModule(errorString, scriptObject.scriptState()); -} - -InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, const String& objectId) -{ - if (!checkIsEnabled(errorString)) - return InjectedScriptCanvasModule(); - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); - if (injectedScript.hasNoValue()) { - *errorString = "Inspected frame has gone"; - return InjectedScriptCanvasModule(); - } - return injectedScriptCanvasModule(errorString, injectedScript.scriptState()); -} - -void InspectorCanvasAgent::findFramesWithUninstrumentedCanvases() -{ - m_framesWithUninstrumentedCanvases.clear(); - - for (Frame* frame = &m_pageAgent->page()->mainFrame(); frame; frame = frame->tree().traverseNext()) { - if (!frame->document()) - continue; - - RefPtr<NodeList> canvases = frame->document()->getElementsByTagName(HTMLNames::canvasTag.localName()); - if (canvases) { - for (unsigned i = 0, length = canvases->length(); i < length; i++) { - const HTMLCanvasElement* canvas = toHTMLCanvasElement(canvases->item(i)); - if (canvas->renderingContext()) { - m_framesWithUninstrumentedCanvases.set(frame, true); - break; - } - } - } - } - - for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) { - String frameId = m_pageAgent->frameId(it->key); - if (!frameId.isEmpty()) - m_frontendDispatcher->contextCreated(frameId); - } -} - -bool InspectorCanvasAgent::checkIsEnabled(ErrorString* errorString) const -{ - if (m_enabled) - return true; - *errorString = "Canvas agent is not enabled"; - return false; -} - -void InspectorCanvasAgent::frameNavigated(Frame* frame) -{ - if (!m_enabled) - return; - if (frame == m_pageAgent->mainFrame()) { - for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) - m_framesWithUninstrumentedCanvases.set(it->key, false); - m_frontendDispatcher->traceLogsRemoved(nullptr, nullptr); - } else { - while (frame) { - if (m_framesWithUninstrumentedCanvases.contains(frame)) - m_framesWithUninstrumentedCanvases.set(frame, false); - if (m_pageAgent->hasIdForFrame(frame)) { - String frameId = m_pageAgent->frameId(frame); - m_frontendDispatcher->traceLogsRemoved(&frameId, nullptr); - } - frame = frame->tree().traverseNext(); - } - } -} - -void InspectorCanvasAgent::frameDetached(Frame* frame) -{ - if (m_enabled) - m_framesWithUninstrumentedCanvases.remove(frame); -} - -void InspectorCanvasAgent::didBeginFrame() -{ - if (!m_enabled) - return; - ErrorString error; - for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) { - InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, mainWorldExecState(it->key)); - if (!module.hasNoValue()) - module.markFrameEnd(); - } -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorCanvasAgent.h b/Source/WebCore/inspector/InspectorCanvasAgent.h deleted file mode 100644 index a9a38e237..000000000 --- a/Source/WebCore/inspector/InspectorCanvasAgent.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorCanvasAgent_h -#define InspectorCanvasAgent_h - -#if ENABLE(INSPECTOR) - -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InspectorWebTypeBuilders.h" -#include "ScriptState.h" -#include <wtf/HashMap.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/text/WTFString.h> - -namespace Deprecated { -class ScriptObject; -} - -namespace Inspector { -class InjectedScriptManager; -} - -namespace WebCore { - -class Frame; -class InjectedScriptCanvasModule; -class InspectorPageAgent; -class InstrumentingAgents; - -typedef String ErrorString; - -class InspectorCanvasAgent : public InspectorAgentBase, public Inspector::InspectorCanvasBackendDispatcherHandler { -public: - InspectorCanvasAgent(InstrumentingAgents*, InspectorPageAgent*, Inspector::InjectedScriptManager*); - ~InspectorCanvasAgent(); - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - void frameNavigated(Frame*); - void frameDetached(Frame*); - void didBeginFrame(); - - // Called from InspectorCanvasInstrumentation. - Deprecated::ScriptObject wrapCanvas2DRenderingContextForInstrumentation(const Deprecated::ScriptObject&); -#if ENABLE(WEBGL) - Deprecated::ScriptObject wrapWebGLRenderingContextForInstrumentation(const Deprecated::ScriptObject&); -#endif - - // Called from the front-end. - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void dropTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&) override; - virtual void hasUninstrumentedCanvases(ErrorString*, bool*) override; - virtual void captureFrame(ErrorString*, const Inspector::TypeBuilder::Network::FrameId*, Inspector::TypeBuilder::Canvas::TraceLogId*) override; - virtual void startCapturing(ErrorString*, const Inspector::TypeBuilder::Network::FrameId*, Inspector::TypeBuilder::Canvas::TraceLogId*) override; - virtual void stopCapturing(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&) override; - virtual void getTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, const int*, const int*, RefPtr<Inspector::TypeBuilder::Canvas::TraceLog>&) override; - virtual void replayTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, int, RefPtr<Inspector::TypeBuilder::Canvas::ResourceState>&) override; - virtual void getResourceInfo(ErrorString*, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr<Inspector::TypeBuilder::Canvas::ResourceInfo>&) override; - virtual void getResourceState(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr<Inspector::TypeBuilder::Canvas::ResourceState>&) override; - -private: - InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, JSC::ExecState*); - InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, const Deprecated::ScriptObject&); - InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, const String&); - - void findFramesWithUninstrumentedCanvases(); - bool checkIsEnabled(ErrorString*) const; - Deprecated::ScriptObject notifyRenderingContextWasWrapped(const Deprecated::ScriptObject&); - - InspectorPageAgent* m_pageAgent; - Inspector::InjectedScriptManager* m_injectedScriptManager; - std::unique_ptr<Inspector::InspectorCanvasFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorCanvasBackendDispatcher> m_backendDispatcher; - bool m_enabled; - // Contains all frames with canvases, value is true only for frames that have an uninstrumented canvas. - typedef HashMap<Frame*, bool> FramesWithUninstrumentedCanvases; - FramesWithUninstrumentedCanvases m_framesWithUninstrumentedCanvases; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorCanvasAgent_h) diff --git a/Source/WebCore/inspector/InspectorCanvasInstrumentation.h b/Source/WebCore/inspector/InspectorCanvasInstrumentation.h deleted file mode 100644 index 0150c922b..000000000 --- a/Source/WebCore/inspector/InspectorCanvasInstrumentation.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorCanvasInstrumentation_h -#define InspectorCanvasInstrumentation_h - -#include "InspectorCanvasAgent.h" -#include "InspectorInstrumentation.h" -#include "InstrumentingAgents.h" -#include <bindings/ScriptObject.h> - -namespace WebCore { - -Deprecated::ScriptObject InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(Document* document, const Deprecated::ScriptObject& context) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) { - if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent()) - return canvasAgent->wrapCanvas2DRenderingContextForInstrumentation(context); - } -#else - UNUSED_PARAM(document); - UNUSED_PARAM(context); -#endif - return Deprecated::ScriptObject(); -} - -#if ENABLE(WEBGL) -Deprecated::ScriptObject InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(Document* document, const Deprecated::ScriptObject& glContext) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) { - if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent()) - return canvasAgent->wrapWebGLRenderingContextForInstrumentation(glContext); - } -#else - UNUSED_PARAM(document); - UNUSED_PARAM(glContext); -#endif - return Deprecated::ScriptObject(); -} -#endif // ENABLE(WEBGL) - -} // namespace WebCore - -#endif // !defined(InspectorCanvasInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorClient.cpp b/Source/WebCore/inspector/InspectorClient.cpp index c33e6ac01..21ee2b3d0 100644 --- a/Source/WebCore/inspector/InspectorClient.cpp +++ b/Source/WebCore/inspector/InspectorClient.cpp @@ -29,33 +29,28 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorClient.h" +#include "InspectorController.h" #include "MainFrame.h" #include "Page.h" #include "ScriptController.h" #include "ScriptSourceCode.h" -#include <bindings/ScriptValue.h> +#include <interpreter/FrameTracers.h> +using namespace JSC; using namespace Inspector; namespace WebCore { -bool InspectorClient::doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message) +void InspectorClient::doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message) { if (!frontendPage) - return false; + return; - String dispatchToFrontend = "InspectorFrontendAPI.dispatchMessageAsync(" + message + ");"; - - // FIXME: This should execute the script in the appropriate world. + SuspendExceptionScope scope(&frontendPage->inspectorController().vm()); + String dispatchToFrontend = makeString("InspectorFrontendAPI.dispatchMessageAsync(", message, ");"); frontendPage->mainFrame().script().evaluate(ScriptSourceCode(dispatchToFrontend)); - return true; } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorClient.h b/Source/WebCore/inspector/InspectorClient.h index fec673854..4de356cb1 100644 --- a/Source/WebCore/inspector/InspectorClient.h +++ b/Source/WebCore/inspector/InspectorClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2015 Apple Inc. All rights reserved. * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -24,71 +24,44 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorClient_h -#define InspectorClient_h +#pragma once -#include "InspectorForwarding.h" #include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> + +namespace Inspector { +class FrontendChannel; +} namespace WebCore { -class InspectorController; +class FloatRect; class Frame; +class InspectorController; class Page; class InspectorClient { public: virtual ~InspectorClient() { } - virtual void inspectorDestroyed() = 0; + virtual void inspectedPageDestroyed() = 0; - virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*) = 0; - virtual void closeInspectorFrontend() = 0; + virtual Inspector::FrontendChannel* openLocalFrontend(InspectorController*) = 0; virtual void bringFrontendToFront() = 0; virtual void didResizeMainFrame(Frame*) { } -#if ENABLE(REMOTE_INSPECTOR) - virtual pid_t parentProcessIdentifier() const { return 0; } -#endif - virtual void highlight() = 0; virtual void hideHighlight() = 0; - virtual void indicate() { } - virtual void hideIndication() { } + virtual void showInspectorIndication() { } + virtual void hideInspectorIndication() { } - virtual bool canClearBrowserCache() { return false; } - virtual void clearBrowserCache() { } - virtual bool canClearBrowserCookies() { return false; } - virtual void clearBrowserCookies() { } - virtual bool canMonitorMainThread() { return false; } - - virtual bool overridesShowPaintRects() { return false; } + virtual bool overridesShowPaintRects() const { return false; } virtual void setShowPaintRects(bool) { } - - virtual bool canShowDebugBorders() { return false; } - virtual void setShowDebugBorders(bool) { } - - virtual bool canShowFPSCounter() { return false; } - virtual void setShowFPSCounter(bool) { } - - virtual bool canContinuouslyPaint() { return false; } - virtual void setContinuousPaintingEnabled(bool) { } - - virtual bool supportsFrameInstrumentation() { return false; } - + virtual void showPaintRect(const FloatRect&) { } virtual void didSetSearchingForNode(bool) { } + virtual void elementSelectionChanged(bool) { } - virtual void getAllocatedObjects(HashSet<const void*>&) { } - virtual void dumpUncountedAllocatedObjects(const HashMap<const void*, size_t>&) { } - - virtual bool handleJavaScriptDialog(bool, const String*) { return false; } - - static bool doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message); + WEBCORE_EXPORT static void doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message); }; } // namespace WebCore - -#endif // !defined(InspectorClient_h) diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.cpp b/Source/WebCore/inspector/InspectorConsoleAgent.cpp deleted file mode 100644 index 701aea7ac..000000000 --- a/Source/WebCore/inspector/InspectorConsoleAgent.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorConsoleAgent.h" - -#include "CommandLineAPIHost.h" -#include "Console.h" -#include "ConsoleMessage.h" -#include "DOMWindow.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InstrumentingAgents.h" -#include "PageInjectedScriptManager.h" -#include "ResourceError.h" -#include "ResourceResponse.h" -#include "ScriptArguments.h" -#include "ScriptCallFrame.h" -#include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" -#include "ScriptController.h" -#include "ScriptProfiler.h" -#include <bindings/ScriptObject.h> -#include <wtf/CurrentTime.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/text/StringBuilder.h> -#include <wtf/text/WTFString.h> - -using namespace Inspector; - -namespace WebCore { - -static const unsigned maximumConsoleMessages = 1000; -static const int expireConsoleMessagesStep = 100; - -int InspectorConsoleAgent::s_enabledAgentCount = 0; - -InspectorConsoleAgent::InspectorConsoleAgent(InstrumentingAgents* instrumentingAgents, PageInjectedScriptManager* injectedScriptManager) - : InspectorAgentBase(ASCIILiteral("Console"), instrumentingAgents) - , m_injectedScriptManager(injectedScriptManager) - , m_previousMessage(nullptr) - , m_expiredConsoleMessageCount(0) - , m_enabled(false) - , m_monitoringXHREnabled(false) -{ - m_instrumentingAgents->setInspectorConsoleAgent(this); -} - -InspectorConsoleAgent::~InspectorConsoleAgent() -{ - m_instrumentingAgents->setInspectorConsoleAgent(nullptr); - m_instrumentingAgents = nullptr; - m_injectedScriptManager = nullptr; -} - -void InspectorConsoleAgent::enable(ErrorString*) -{ - if (m_enabled) - return; - m_enabled = true; - if (!s_enabledAgentCount) - ScriptController::setCaptureCallStackForUncaughtExceptions(true); - ++s_enabledAgentCount; - - if (m_expiredConsoleMessageCount) { - ConsoleMessage expiredMessage(!isWorkerAgent(), OtherMessageSource, LogMessageType, WarningMessageLevel, String::format("%d console messages are not shown.", m_expiredConsoleMessageCount)); - expiredMessage.addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, false); - } - - size_t messageCount = m_consoleMessages.size(); - for (size_t i = 0; i < messageCount; ++i) - m_consoleMessages[i]->addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, false); -} - -void InspectorConsoleAgent::disable(ErrorString*) -{ - if (!m_enabled) - return; - m_enabled = false; - if (!(--s_enabledAgentCount)) - ScriptController::setCaptureCallStackForUncaughtExceptions(false); -} - -void InspectorConsoleAgent::clearMessages(ErrorString*) -{ - m_consoleMessages.clear(); - m_expiredConsoleMessageCount = 0; - m_previousMessage = nullptr; - m_injectedScriptManager->releaseObjectGroup("console"); - if (m_frontendDispatcher && m_enabled) - m_frontendDispatcher->messagesCleared(); -} - -void InspectorConsoleAgent::reset() -{ - ErrorString error; - clearMessages(&error); - m_times.clear(); - m_counts.clear(); -} - -void InspectorConsoleAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) -{ - m_frontendDispatcher = std::make_unique<InspectorConsoleFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorConsoleBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorConsoleAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) -{ - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - String errorString; - disable(&errorString); -} - -void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - - if (type == ClearMessageType) { - ErrorString error; - clearMessages(&error); - } - - addConsoleMessage(adoptPtr(new ConsoleMessage(!isWorkerAgent(), source, type, level, message, callStack, requestIdentifier))); -} - -void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - - if (type == ClearMessageType) { - ErrorString error; - clearMessages(&error); - } - - addConsoleMessage(adoptPtr(new ConsoleMessage(!isWorkerAgent(), source, type, level, message, arguments, state, requestIdentifier))); -} - -void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - - if (type == ClearMessageType) { - ErrorString error; - clearMessages(&error); - } - - bool canGenerateCallStack = !isWorkerAgent() && m_frontendDispatcher; - addConsoleMessage(adoptPtr(new ConsoleMessage(canGenerateCallStack, source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier))); -} - -Vector<unsigned> InspectorConsoleAgent::consoleMessageArgumentCounts() -{ - Vector<unsigned> result(m_consoleMessages.size()); - for (size_t i = 0; i < m_consoleMessages.size(); i++) - result[i] = m_consoleMessages[i]->argumentCount(); - return result; -} - -void InspectorConsoleAgent::startTiming(const String& title) -{ - // Follow Firebug's behavior of requiring a title that is not null or - // undefined for timing functions - if (title.isNull()) - return; - - m_times.add(title, monotonicallyIncreasingTime()); -} - -void InspectorConsoleAgent::stopTiming(const String& title, PassRefPtr<ScriptCallStack> callStack) -{ - // Follow Firebug's behavior of requiring a title that is not null or - // undefined for timing functions - if (title.isNull()) - return; - - HashMap<String, double>::iterator it = m_times.find(title); - if (it == m_times.end()) - return; - - double startTime = it->value; - m_times.remove(it); - - double elapsed = monotonicallyIncreasingTime() - startTime; - String message = title + String::format(": %.3fms", elapsed * 1000); - addMessageToConsole(ConsoleAPIMessageSource, TimingMessageType, DebugMessageLevel, message, callStack); -} - -void InspectorConsoleAgent::count(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments) -{ - RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state)); - const ScriptCallFrame& lastCaller = callStack->at(0); - // Follow Firebug's behavior of counting with null and undefined title in - // the same bucket as no argument - String title; - arguments->getFirstArgumentAsString(title); - String identifier = title + '@' + lastCaller.sourceURL() + ':' + String::number(lastCaller.lineNumber()); - - HashMap<String, unsigned>::iterator it = m_counts.find(identifier); - int count; - if (it == m_counts.end()) - count = 1; - else { - count = it->value + 1; - m_counts.remove(it); - } - - m_counts.add(identifier, count); - - String message = title + ": " + String::number(count); - addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, callStack); -} - -void InspectorConsoleAgent::frameWindowDiscarded(DOMWindow* window) -{ - size_t messageCount = m_consoleMessages.size(); - for (size_t i = 0; i < messageCount; ++i) - m_consoleMessages[i]->windowCleared(window); - m_injectedScriptManager->discardInjectedScriptsFor(window); -} - -void InspectorConsoleAgent::didFinishXHRLoading(unsigned long requestIdentifier, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - if (m_frontendDispatcher && m_monitoringXHREnabled) { - String message = "XHR finished loading: \"" + url + "\"."; - addMessageToConsole(NetworkMessageSource, LogMessageType, DebugMessageLevel, message, sendURL, sendLineNumber, sendColumnNumber, nullptr, requestIdentifier); - } -} - -void InspectorConsoleAgent::didReceiveResponse(unsigned long requestIdentifier, const ResourceResponse& response) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - - if (response.httpStatusCode() >= 400) { - String message = "Failed to load resource: the server responded with a status of " + String::number(response.httpStatusCode()) + " (" + response.httpStatusText() + ')'; - addMessageToConsole(NetworkMessageSource, LogMessageType, ErrorMessageLevel, message, response.url().string(), 0, 0, nullptr, requestIdentifier); - } -} - -void InspectorConsoleAgent::didFailLoading(unsigned long requestIdentifier, const ResourceError& error) -{ - if (!m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - if (error.isCancellation()) // Report failures only. - return; - StringBuilder message; - message.appendLiteral("Failed to load resource"); - if (!error.localizedDescription().isEmpty()) { - message.appendLiteral(": "); - message.append(error.localizedDescription()); - } - addMessageToConsole(NetworkMessageSource, LogMessageType, ErrorMessageLevel, message.toString(), error.failingURL(), 0, 0, nullptr, requestIdentifier); -} - -void InspectorConsoleAgent::setMonitoringXHREnabled(ErrorString*, bool enabled) -{ - m_monitoringXHREnabled = enabled; -} - -static bool isGroupMessage(MessageType type) -{ - return type == StartGroupMessageType - || type == StartGroupCollapsedMessageType - || type == EndGroupMessageType; -} - -void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr<ConsoleMessage> consoleMessage) -{ - ASSERT(m_instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()); - ASSERT_ARG(consoleMessage, consoleMessage); - - if (m_previousMessage && !isGroupMessage(m_previousMessage->type()) && m_previousMessage->isEqual(consoleMessage.get())) { - m_previousMessage->incrementCount(); - if (m_frontendDispatcher && m_enabled) - m_previousMessage->updateRepeatCountInConsole(m_frontendDispatcher.get()); - } else { - m_previousMessage = consoleMessage.get(); - m_consoleMessages.append(consoleMessage); - if (m_frontendDispatcher && m_enabled) - m_previousMessage->addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, true); - } - - if (!m_frontendDispatcher && m_consoleMessages.size() >= maximumConsoleMessages) { - m_expiredConsoleMessageCount += expireConsoleMessagesStep; - m_consoleMessages.remove(0, expireConsoleMessagesStep); - } -} - -class InspectableHeapObject final : public CommandLineAPIHost::InspectableObject { -public: - explicit InspectableHeapObject(int heapObjectId) : m_heapObjectId(heapObjectId) { } - virtual Deprecated::ScriptValue get(JSC::ExecState*) override - { - return ScriptProfiler::objectByHeapObjectId(m_heapObjectId); - } -private: - int m_heapObjectId; -}; - -void InspectorConsoleAgent::addInspectedHeapObject(ErrorString*, int inspectedHeapObjectId) -{ - if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) - commandLineAPIHost->addInspectedObject(adoptPtr(new InspectableHeapObject(inspectedHeapObjectId))); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.h b/Source/WebCore/inspector/InspectorConsoleAgent.h deleted file mode 100644 index 26c9d2ce0..000000000 --- a/Source/WebCore/inspector/InspectorConsoleAgent.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorConsoleAgent_h -#define InspectorConsoleAgent_h - -#if ENABLE(INSPECTOR) - -#include "ConsoleAPITypes.h" -#include "ConsoleTypes.h" -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include "ScriptState.h" -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/Noncopyable.h> -#include <wtf/Vector.h> -#include <wtf/text/StringHash.h> - -namespace WebCore { - -class ConsoleMessage; -class DOMWindow; -class InstrumentingAgents; -class PageInjectedScriptManager; -class ResourceError; -class ResourceResponse; -class ScriptArguments; -class ScriptCallStack; -class ScriptProfile; - -typedef String ErrorString; - -class InspectorConsoleAgent : public InspectorAgentBase, public Inspector::InspectorConsoleBackendDispatcherHandler { - WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent); -public: - InspectorConsoleAgent(InstrumentingAgents*, PageInjectedScriptManager*); - virtual ~InspectorConsoleAgent(); - - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void clearMessages(ErrorString*) override; - bool enabled() const { return m_enabled; } - void reset(); - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, JSC::ExecState*, PassRefPtr<ScriptArguments>, unsigned long requestIdentifier = 0); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0); - - // FIXME: Remove once we no longer generate stacks outside of Inspector. - void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0); - - Vector<unsigned> consoleMessageArgumentCounts(); - - void startTiming(const String& title); - void stopTiming(const String& title, PassRefPtr<ScriptCallStack>); - void count(JSC::ExecState*, PassRefPtr<ScriptArguments>); - - void frameWindowDiscarded(DOMWindow*); - - void didFinishXHRLoading(unsigned long requestIdentifier, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); - void didReceiveResponse(unsigned long requestIdentifier, const ResourceResponse&); - void didFailLoading(unsigned long requestIdentifier, const ResourceError&); - void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - virtual void setMonitoringXHREnabled(ErrorString*, bool enabled) override; - virtual void addInspectedNode(ErrorString*, int nodeId) = 0; - virtual void addInspectedHeapObject(ErrorString*, int inspectedHeapObjectId) override; - - virtual bool isWorkerAgent() = 0; - -protected: - void addConsoleMessage(PassOwnPtr<ConsoleMessage>); - - PageInjectedScriptManager* m_injectedScriptManager; - std::unique_ptr<Inspector::InspectorConsoleFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorConsoleBackendDispatcher> m_backendDispatcher; - ConsoleMessage* m_previousMessage; - Vector<OwnPtr<ConsoleMessage>> m_consoleMessages; - int m_expiredConsoleMessageCount; - HashMap<String, unsigned> m_counts; - HashMap<String, double> m_times; - bool m_enabled; - bool m_monitoringXHREnabled; -private: - static int s_enabledAgentCount; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorConsoleAgent_h) diff --git a/Source/WebCore/inspector/InspectorConsoleInstrumentation.h b/Source/WebCore/inspector/InspectorConsoleInstrumentation.h deleted file mode 100644 index eee787c98..000000000 --- a/Source/WebCore/inspector/InspectorConsoleInstrumentation.h +++ /dev/null @@ -1,227 +0,0 @@ -/* -* Copyright (C) 2011 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef InspectorConsoleInstrumentation_h -#define InspectorConsoleInstrumentation_h - -#include "InspectorInstrumentation.h" -#include "ScriptArguments.h" -#include "ScriptCallStack.h" -#include "ScriptProfile.h" -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - addMessageToConsoleImpl(instrumentingAgents, source, type, level, message, callStack, requestIdentifier); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(source); - UNUSED_PARAM(type); - UNUSED_PARAM(level); - UNUSED_PARAM(message); - UNUSED_PARAM(callStack); - UNUSED_PARAM(requestIdentifier); -#endif -} - -inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - addMessageToConsoleImpl(instrumentingAgents, source, type, level, message, state, arguments, requestIdentifier); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(source); - UNUSED_PARAM(type); - UNUSED_PARAM(level); - UNUSED_PARAM(message); - UNUSED_PARAM(state); - UNUSED_PARAM(arguments); - UNUSED_PARAM(requestIdentifier); -#endif -} - -inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - addMessageToConsoleImpl(instrumentingAgents, source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(source); - UNUSED_PARAM(type); - UNUSED_PARAM(level); - UNUSED_PARAM(message); - UNUSED_PARAM(scriptID); - UNUSED_PARAM(lineNumber); - UNUSED_PARAM(state); - UNUSED_PARAM(requestIdentifier); - UNUSED_PARAM(columnNumber); -#endif -} - -inline void InspectorInstrumentation::addMessageToConsole(WorkerGlobalScope* workerGlobalScope, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForWorkerGlobalScope(workerGlobalScope)) - addMessageToConsoleImpl(instrumentingAgents, source, type, level, message, callStack, requestIdentifier); -#else - UNUSED_PARAM(workerGlobalScope); - UNUSED_PARAM(source); - UNUSED_PARAM(type); - UNUSED_PARAM(level); - UNUSED_PARAM(message); - UNUSED_PARAM(callStack); - UNUSED_PARAM(requestIdentifier); -#endif -} - -inline void InspectorInstrumentation::addMessageToConsole(WorkerGlobalScope* workerGlobalScope, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForWorkerGlobalScope(workerGlobalScope)) - addMessageToConsoleImpl(instrumentingAgents, source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier); -#else - UNUSED_PARAM(workerGlobalScope); - UNUSED_PARAM(source); - UNUSED_PARAM(type); - UNUSED_PARAM(level); - UNUSED_PARAM(message); - UNUSED_PARAM(scriptID); - UNUSED_PARAM(lineNumber); - UNUSED_PARAM(columnNumber); - UNUSED_PARAM(state); - UNUSED_PARAM(requestIdentifier); -#endif -} - -inline void InspectorInstrumentation::consoleCount(Page* page, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - consoleCountImpl(instrumentingAgents, state, arguments); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(state); - UNUSED_PARAM(arguments); -#endif -} - -inline void InspectorInstrumentation::startConsoleTiming(Frame* frame, const String& title) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - startConsoleTimingImpl(instrumentingAgents, frame, title); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(title); -#endif -} - -inline void InspectorInstrumentation::stopConsoleTiming(Frame* frame, const String& title, PassRefPtr<ScriptCallStack> stack) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - stopConsoleTimingImpl(instrumentingAgents, frame, title, stack); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(title); - UNUSED_PARAM(stack); -#endif -} - -inline void InspectorInstrumentation::consoleTimeStamp(Frame* frame, PassRefPtr<ScriptArguments> arguments) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - consoleTimeStampImpl(instrumentingAgents, frame, arguments); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(arguments); -#endif -} - -inline void InspectorInstrumentation::addStartProfilingMessageToConsole(Page* page, const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - addStartProfilingMessageToConsoleImpl(instrumentingAgents, title, lineNumber, columnNumber, sourceURL); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(title); - UNUSED_PARAM(lineNumber); - UNUSED_PARAM(columnNumber); - UNUSED_PARAM(sourceURL); -#endif -} - -inline void InspectorInstrumentation::addProfile(Page* page, RefPtr<ScriptProfile> profile, PassRefPtr<ScriptCallStack> callStack) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - addProfileImpl(instrumentingAgents, profile, callStack); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(profile); - UNUSED_PARAM(callStack); -#endif -} - -inline bool InspectorInstrumentation::profilerEnabled(Page* page) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return profilerEnabledImpl(instrumentingAgents); -#else - UNUSED_PARAM(page); -#endif - return false; -} - -inline String InspectorInstrumentation::getCurrentUserInitiatedProfileName(Page* page, bool incrementProfileNumber) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(instrumentingAgents, incrementProfileNumber); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(incrementProfileNumber); -#endif - return ""; -} - -} // namespace WebCore - -#endif // !defined(InspectorConsoleInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp index 197eff2a5..2d05e5182 100644 --- a/Source/WebCore/inspector/InspectorController.cpp +++ b/Source/WebCore/inspector/InspectorController.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,36 +32,29 @@ #include "config.h" #include "InspectorController.h" -#if ENABLE(INSPECTOR) - #include "CommandLineAPIHost.h" +#include "CommonVM.h" #include "DOMWrapperWorld.h" #include "GraphicsContext.h" -#include "IdentifiersFactory.h" #include "InspectorApplicationCacheAgent.h" #include "InspectorCSSAgent.h" -#include "InspectorCanvasAgent.h" #include "InspectorClient.h" #include "InspectorDOMAgent.h" #include "InspectorDOMDebuggerAgent.h" #include "InspectorDOMStorageAgent.h" #include "InspectorDatabaseAgent.h" #include "InspectorFrontendClient.h" -#include "InspectorHeapProfilerAgent.h" #include "InspectorIndexedDBAgent.h" -#include "InspectorInputAgent.h" #include "InspectorInstrumentation.h" #include "InspectorLayerTreeAgent.h" #include "InspectorMemoryAgent.h" -#include "InspectorOverlay.h" +#include "InspectorNetworkAgent.h" #include "InspectorPageAgent.h" -#include "InspectorProfilerAgent.h" -#include "InspectorResourceAgent.h" +#include "InspectorReplayAgent.h" #include "InspectorTimelineAgent.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" #include "InspectorWorkerAgent.h" #include "InstrumentingAgents.h" +#include "JSDOMBindingSecurity.h" #include "JSDOMWindow.h" #include "JSDOMWindowCustom.h" #include "JSMainThreadExecState.h" @@ -68,13 +62,25 @@ #include "Page.h" #include "PageConsoleAgent.h" #include "PageDebuggerAgent.h" -#include "PageInjectedScriptHost.h" -#include "PageInjectedScriptManager.h" +#include "PageHeapAgent.h" #include "PageRuntimeAgent.h" +#include "PageScriptDebugServer.h" #include "Settings.h" +#include "WebInjectedScriptHost.h" +#include "WebInjectedScriptManager.h" +#include <inspector/IdentifiersFactory.h> #include <inspector/InspectorBackendDispatcher.h> +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <inspector/InspectorFrontendRouter.h> #include <inspector/agents/InspectorAgent.h> +#include <inspector/agents/InspectorScriptProfilerAgent.h> #include <runtime/JSLock.h> +#include <wtf/Stopwatch.h> + +#if ENABLE(REMOTE_INSPECTOR) +#include "PageDebuggable.h" +#endif using namespace JSC; using namespace Inspector; @@ -83,91 +89,99 @@ namespace WebCore { InspectorController::InspectorController(Page& page, InspectorClient* inspectorClient) : m_instrumentingAgents(InstrumentingAgents::create(*this)) - , m_injectedScriptManager(std::make_unique<PageInjectedScriptManager>(*this, PageInjectedScriptHost::create())) + , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create())) + , m_frontendRouter(FrontendRouter::create()) + , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) , m_overlay(std::make_unique<InspectorOverlay>(page, inspectorClient)) - , m_inspectorFrontendChannel(nullptr) + , m_executionStopwatch(Stopwatch::create()) + , m_scriptDebugServer(page) , m_page(page) , m_inspectorClient(inspectorClient) - , m_isUnderTest(false) -#if ENABLE(REMOTE_INSPECTOR) - , m_hasRemoteFrontend(false) -#endif { ASSERT_ARG(inspectorClient, inspectorClient); - auto inspectorAgentPtr = std::make_unique<InspectorAgent>(); + AgentContext baseContext = { + *this, + *m_injectedScriptManager, + m_frontendRouter.get(), + m_backendDispatcher.get() + }; + + WebAgentContext webContext = { + baseContext, + m_instrumentingAgents.get() + }; + + PageAgentContext pageContext = { + webContext, + m_page + }; + + auto inspectorAgentPtr = std::make_unique<InspectorAgent>(pageContext); m_inspectorAgent = inspectorAgentPtr.get(); m_instrumentingAgents->setInspectorAgent(m_inspectorAgent); - m_agents.append(std::move(inspectorAgentPtr)); + m_agents.append(WTFMove(inspectorAgentPtr)); - auto pageAgentPtr = std::make_unique<InspectorPageAgent>(m_instrumentingAgents.get(), &page, inspectorClient, m_overlay.get()); + auto pageAgentPtr = std::make_unique<InspectorPageAgent>(pageContext, inspectorClient, m_overlay.get()); InspectorPageAgent* pageAgent = pageAgentPtr.get(); m_pageAgent = pageAgentPtr.get(); - m_agents.append(std::move(pageAgentPtr)); + m_agents.append(WTFMove(pageAgentPtr)); - auto runtimeAgentPtr = std::make_unique<PageRuntimeAgent>(m_injectedScriptManager.get(), &page, pageAgent); + auto runtimeAgentPtr = std::make_unique<PageRuntimeAgent>(pageContext, pageAgent); PageRuntimeAgent* runtimeAgent = runtimeAgentPtr.get(); m_instrumentingAgents->setPageRuntimeAgent(runtimeAgent); - m_agents.append(std::move(runtimeAgentPtr)); + m_agents.append(WTFMove(runtimeAgentPtr)); - auto domAgentPtr = std::make_unique<InspectorDOMAgent>(m_instrumentingAgents.get(), pageAgent, m_injectedScriptManager.get(), m_overlay.get()); + auto domAgentPtr = std::make_unique<InspectorDOMAgent>(pageContext, pageAgent, m_overlay.get()); m_domAgent = domAgentPtr.get(); - m_agents.append(std::move(domAgentPtr)); + m_agents.append(WTFMove(domAgentPtr)); - m_agents.append(std::make_unique<InspectorCSSAgent>(m_instrumentingAgents.get(), m_domAgent)); + m_agents.append(std::make_unique<InspectorCSSAgent>(pageContext, m_domAgent)); -#if ENABLE(SQL_DATABASE) - auto databaseAgentPtr = std::make_unique<InspectorDatabaseAgent>(m_instrumentingAgents.get()); + auto databaseAgentPtr = std::make_unique<InspectorDatabaseAgent>(pageContext); InspectorDatabaseAgent* databaseAgent = databaseAgentPtr.get(); - m_agents.append(std::move(databaseAgentPtr)); -#endif + m_agents.append(WTFMove(databaseAgentPtr)); + + m_agents.append(std::make_unique<InspectorNetworkAgent>(pageContext, pageAgent)); #if ENABLE(INDEXED_DATABASE) - m_agents.append(std::make_unique<InspectorIndexedDBAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get(), pageAgent)); + m_agents.append(std::make_unique<InspectorIndexedDBAgent>(pageContext, pageAgent)); #endif - auto domStorageAgentPtr = std::make_unique<InspectorDOMStorageAgent>(m_instrumentingAgents.get(), m_pageAgent); - InspectorDOMStorageAgent* domStorageAgent = domStorageAgentPtr.get(); - m_agents.append(std::move(domStorageAgentPtr)); - - auto memoryAgentPtr = std::make_unique<InspectorMemoryAgent>(m_instrumentingAgents.get()); - m_memoryAgent = memoryAgentPtr.get(); - m_agents.append(std::move(memoryAgentPtr)); - - m_agents.append(std::make_unique<InspectorTimelineAgent>(m_instrumentingAgents.get(), pageAgent, m_memoryAgent, InspectorTimelineAgent::PageInspector, inspectorClient)); - m_agents.append(std::make_unique<InspectorApplicationCacheAgent>(m_instrumentingAgents.get(), pageAgent)); - - auto resourceAgentPtr = std::make_unique<InspectorResourceAgent>(m_instrumentingAgents.get(), pageAgent, inspectorClient); - m_resourceAgent = resourceAgentPtr.get(); - m_agents.append(std::move(resourceAgentPtr)); - - auto consoleAgentPtr = std::make_unique<PageConsoleAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get(), m_domAgent); - InspectorConsoleAgent* consoleAgent = consoleAgentPtr.get(); - m_agents.append(std::move(consoleAgentPtr)); +#if ENABLE(RESOURCE_USAGE) + m_agents.append(std::make_unique<InspectorMemoryAgent>(pageContext)); +#endif - auto debuggerAgentPtr = std::make_unique<PageDebuggerAgent>(m_injectedScriptManager.get(), m_instrumentingAgents.get(), pageAgent, m_overlay.get()); - m_debuggerAgent = debuggerAgentPtr.get(); - m_agents.append(std::move(debuggerAgentPtr)); +#if ENABLE(WEB_REPLAY) + m_agents.append(std::make_unique<InspectorReplayAgent>(pageContext)); +#endif - auto domDebuggerAgentPtr = std::make_unique<InspectorDOMDebuggerAgent>(m_instrumentingAgents.get(), m_domAgent, m_debuggerAgent); - m_domDebuggerAgent = domDebuggerAgentPtr.get(); - m_agents.append(std::move(domDebuggerAgentPtr)); + auto domStorageAgentPtr = std::make_unique<InspectorDOMStorageAgent>(pageContext, m_pageAgent); + InspectorDOMStorageAgent* domStorageAgent = domStorageAgentPtr.get(); + m_agents.append(WTFMove(domStorageAgentPtr)); - auto profilerAgentPtr = InspectorProfilerAgent::create(m_instrumentingAgents.get(), consoleAgent, &page, m_injectedScriptManager.get()); - m_profilerAgent = profilerAgentPtr.get(); - m_agents.append(std::move(profilerAgentPtr)); + auto heapAgentPtr = std::make_unique<PageHeapAgent>(pageContext); + InspectorHeapAgent* heapAgent = heapAgentPtr.get(); + m_agents.append(WTFMove(heapAgentPtr)); - m_agents.append(std::make_unique<InspectorHeapProfilerAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get())); + auto scriptProfilerAgentPtr = std::make_unique<InspectorScriptProfilerAgent>(pageContext); + InspectorScriptProfilerAgent* scriptProfilerAgent = scriptProfilerAgentPtr.get(); + m_agents.append(WTFMove(scriptProfilerAgentPtr)); - m_agents.append(std::make_unique<InspectorWorkerAgent>(m_instrumentingAgents.get())); + auto consoleAgentPtr = std::make_unique<PageConsoleAgent>(pageContext, heapAgent, m_domAgent); + WebConsoleAgent* consoleAgent = consoleAgentPtr.get(); + m_instrumentingAgents->setWebConsoleAgent(consoleAgentPtr.get()); + m_agents.append(WTFMove(consoleAgentPtr)); - m_agents.append(std::make_unique<InspectorCanvasAgent>(m_instrumentingAgents.get(), pageAgent, m_injectedScriptManager.get())); + auto debuggerAgentPtr = std::make_unique<PageDebuggerAgent>(pageContext, pageAgent, m_overlay.get()); + PageDebuggerAgent* debuggerAgent = debuggerAgentPtr.get(); + m_agents.append(WTFMove(debuggerAgentPtr)); - m_agents.append(std::make_unique<InspectorInputAgent>(m_instrumentingAgents.get(), &page)); - -#if USE(ACCELERATED_COMPOSITING) - m_agents.append(std::make_unique<InspectorLayerTreeAgent>(m_instrumentingAgents.get())); -#endif + m_agents.append(std::make_unique<InspectorTimelineAgent>(pageContext, scriptProfilerAgent, heapAgent, pageAgent)); + m_agents.append(std::make_unique<InspectorDOMDebuggerAgent>(pageContext, m_domAgent, debuggerAgent)); + m_agents.append(std::make_unique<InspectorApplicationCacheAgent>(pageContext, pageAgent)); + m_agents.append(std::make_unique<InspectorLayerTreeAgent>(pageContext)); + m_agents.append(std::make_unique<InspectorWorkerAgent>(pageContext)); ASSERT(m_injectedScriptManager->commandLineAPIHost()); if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) { @@ -175,137 +189,157 @@ InspectorController::InspectorController(Page& page, InspectorClient* inspectorC , consoleAgent , m_domAgent , domStorageAgent -#if ENABLE(SQL_DATABASE) , databaseAgent -#endif ); } - - runtimeAgent->setScriptDebugServer(&m_debuggerAgent->scriptDebugServer()); } InspectorController::~InspectorController() { m_instrumentingAgents->reset(); - m_agents.discardAgents(); ASSERT(!m_inspectorClient); } void InspectorController::inspectedPageDestroyed() { - disconnectFrontend(InspectorDisconnectReason::InspectedTargetDestroyed); m_injectedScriptManager->disconnect(); - m_inspectorClient->inspectorDestroyed(); + + // Clean up resources and disconnect local and remote frontends. + disconnectAllFrontends(); + + // Disconnect the client. + m_inspectorClient->inspectedPageDestroyed(); m_inspectorClient = nullptr; + + m_agents.discardValues(); } -void InspectorController::setInspectorFrontendClient(std::unique_ptr<InspectorFrontendClient> inspectorFrontendClient) +void InspectorController::setInspectorFrontendClient(InspectorFrontendClient* inspectorFrontendClient) { - m_inspectorFrontendClient = std::move(inspectorFrontendClient); + m_inspectorFrontendClient = inspectorFrontendClient; } bool InspectorController::hasLocalFrontend() const { -#if ENABLE(REMOTE_INSPECTOR) - return hasFrontend() && !m_hasRemoteFrontend; -#else - return hasFrontend(); -#endif + return m_frontendRouter->hasLocalFrontend(); } bool InspectorController::hasRemoteFrontend() const { -#if ENABLE(REMOTE_INSPECTOR) - return m_hasRemoteFrontend; -#else - return false; -#endif + return m_frontendRouter->hasRemoteFrontend(); } -bool InspectorController::hasInspectorFrontendClient() const +unsigned InspectorController::inspectionLevel() const { - return m_inspectorFrontendClient.get(); + return m_inspectorFrontendClient ? m_inspectorFrontendClient->inspectionLevel() : 0; } -void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld& world) +void InspectorController::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld& world) { if (&world != &mainThreadNormalWorld()) return; - if (frame->isMainFrame()) + if (frame.isMainFrame()) m_injectedScriptManager->discardInjectedScripts(); // If the page is supposed to serve as InspectorFrontend notify inspector frontend // client that it's cleared so that the client can expose inspector bindings. - if (m_inspectorFrontendClient && frame->isMainFrame()) + if (m_inspectorFrontendClient && frame.isMainFrame()) m_inspectorFrontendClient->windowObjectCleared(); } -void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel) +void InspectorController::connectFrontend(Inspector::FrontendChannel* frontendChannel, bool isAutomaticInspection) { - ASSERT(frontendChannel); + ASSERT_ARG(frontendChannel, frontendChannel); ASSERT(m_inspectorClient); - ASSERT(!m_inspectorFrontendChannel); - ASSERT(!m_inspectorBackendDispatcher); - m_inspectorFrontendChannel = frontendChannel; - m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel); + bool connectedFirstFrontend = !m_frontendRouter->hasFrontends(); + m_isAutomaticInspection = isAutomaticInspection; - m_agents.didCreateFrontendAndBackend(frontendChannel, m_inspectorBackendDispatcher.get()); + m_frontendRouter->connectFrontend(frontendChannel); - InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get()); InspectorInstrumentation::frontendCreated(); + if (connectedFirstFrontend) { + InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get()); + m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get()); + } + #if ENABLE(REMOTE_INSPECTOR) - if (!m_hasRemoteFrontend) + if (!m_frontendRouter->hasRemoteFrontend()) m_page.remoteInspectorInformationDidChange(); #endif } -void InspectorController::disconnectFrontend(InspectorDisconnectReason reason) +void InspectorController::disconnectFrontend(FrontendChannel* frontendChannel) { - if (!m_inspectorFrontendChannel) - return; + m_frontendRouter->disconnectFrontend(frontendChannel); + m_isAutomaticInspection = false; - m_agents.willDestroyFrontendAndBackend(reason); + InspectorInstrumentation::frontendDeleted(); - m_inspectorBackendDispatcher->clearFrontend(); - m_inspectorBackendDispatcher.clear(); - m_inspectorFrontendChannel = nullptr; + bool disconnectedLastFrontend = !m_frontendRouter->hasFrontends(); + if (disconnectedLastFrontend) { + // Notify agents first. + m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed); - // relese overlay page resources - m_overlay->freePage(); - InspectorInstrumentation::frontendDeleted(); - InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get()); + // Destroy the inspector overlay's page. + m_overlay->freePage(); + + // Unplug all instrumentations since they aren't needed now. + InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get()); + } #if ENABLE(REMOTE_INSPECTOR) - if (!m_hasRemoteFrontend) + if (!m_frontendRouter->hasFrontends()) m_page.remoteInspectorInformationDidChange(); #endif } -void InspectorController::show() +void InspectorController::disconnectAllFrontends() { - ASSERT(!hasRemoteFrontend()); + // If the local frontend page was destroyed, close the window. + if (m_inspectorFrontendClient) + m_inspectorFrontendClient->closeWindow(); - if (!enabled()) + // The frontend should call setInspectorFrontendClient(nullptr) under closeWindow(). + ASSERT(!m_inspectorFrontendClient); + + if (!m_frontendRouter->hasFrontends()) return; - if (m_inspectorFrontendChannel) - m_inspectorClient->bringFrontendToFront(); - else { - InspectorFrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this); - if (frontendChannel) - connectFrontend(frontendChannel); - } + for (unsigned i = 0; i < m_frontendRouter->frontendCount(); ++i) + InspectorInstrumentation::frontendDeleted(); + + // Unplug all instrumentations to prevent further agent callbacks. + InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get()); + + // Notify agents first, since they may need to use InspectorClient. + m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed); + + // Destroy the inspector overlay's page. + m_overlay->freePage(); + + // Disconnect any remaining remote frontends. + m_frontendRouter->disconnectAllFrontends(); + m_isAutomaticInspection = false; + +#if ENABLE(REMOTE_INSPECTOR) + m_page.remoteInspectorInformationDidChange(); +#endif } -void InspectorController::close() +void InspectorController::show() { - if (!m_inspectorFrontendChannel) + ASSERT(!m_frontendRouter->hasRemoteFrontend()); + + if (!enabled()) return; - disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed); - m_inspectorClient->closeInspectorFrontend(); + + if (m_frontendRouter->hasLocalFrontend()) + m_inspectorClient->bringFrontendToFront(); + else if (Inspector::FrontendChannel* frontendChannel = m_inspectorClient->openLocalFrontend(this)) + connectFrontend(frontendChannel); } void InspectorController::setProcessId(long processId) @@ -313,15 +347,20 @@ void InspectorController::setProcessId(long processId) IdentifiersFactory::setProcessId(processId); } -bool InspectorController::isUnderTest() +void InspectorController::setIsUnderTest(bool value) { - return m_isUnderTest; + if (value == m_isUnderTest) + return; + + m_isUnderTest = value; + + // <rdar://problem/26768628> Try to catch suspicious scenarios where we may have a dangling frontend while running tests. + RELEASE_ASSERT(!m_isUnderTest || !m_frontendRouter->hasFrontends()); } -void InspectorController::evaluateForTestInFrontend(long callId, const String& script) +void InspectorController::evaluateForTestInFrontend(const String& script) { - m_isUnderTest = true; - m_inspectorAgent->evaluateForTestInFrontend(callId, script); + m_inspectorAgent->evaluateForTestInFrontend(script); } void InspectorController::drawHighlight(GraphicsContext& context) const @@ -329,14 +368,14 @@ void InspectorController::drawHighlight(GraphicsContext& context) const m_overlay->paint(context); } -void InspectorController::getHighlight(Highlight* highlight) const +void InspectorController::getHighlight(Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem) const { - m_overlay->getHighlight(highlight); + m_overlay->getHighlight(highlight, coordinateSystem); } -PassRefPtr<InspectorObject> InspectorController::buildObjectForHighlightedNode() const +Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> InspectorController::buildObjectForHighlightedNodes() const { - return m_overlay->buildObjectForHighlightedNode(); + return m_overlay->buildObjectForHighlightedNodes(); } void InspectorController::inspect(Node* node) @@ -362,14 +401,13 @@ Page& InspectorController::inspectedPage() const void InspectorController::dispatchMessageFromFrontend(const String& message) { - if (m_inspectorBackendDispatcher) - m_inspectorBackendDispatcher->dispatch(message); + m_backendDispatcher->dispatch(message); } void InspectorController::hideHighlight() { - ErrorString error; - m_domAgent->hideHighlight(&error); + ErrorString unused; + m_domAgent->hideHighlight(unused); } Node* InspectorController::highlightedNode() const @@ -379,64 +417,14 @@ Node* InspectorController::highlightedNode() const void InspectorController::setIndicating(bool indicating) { - // FIXME: For non-iOS clients, we should have InspectorOverlay do something here. +#if !PLATFORM(IOS) + m_overlay->setIndicating(indicating); +#else if (indicating) - m_inspectorClient->indicate(); - else - m_inspectorClient->hideIndication(); -} - -bool InspectorController::profilerEnabled() const -{ - return m_profilerAgent->enabled(); -} - -void InspectorController::setProfilerEnabled(bool enable) -{ - ErrorString error; - if (enable) - m_profilerAgent->enable(&error); + m_inspectorClient->showInspectorIndication(); else - m_profilerAgent->disable(&error); -} - -void InspectorController::resume() -{ - if (m_debuggerAgent) { - ErrorString error; - m_debuggerAgent->resume(&error); - } -} - -void InspectorController::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize) -{ - m_resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize); -} - -void InspectorController::didBeginFrame() -{ - if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didBeginFrame(); - if (InspectorCanvasAgent* canvasAgent = m_instrumentingAgents->inspectorCanvasAgent()) - canvasAgent->didBeginFrame(); -} - -void InspectorController::didCancelFrame() -{ - if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didCancelFrame(); -} - -void InspectorController::willComposite() -{ - if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->willComposite(); -} - -void InspectorController::didComposite() -{ - if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didComposite(); + m_inspectorClient->hideInspectorIndication(); +#endif } bool InspectorController::developerExtrasEnabled() const @@ -447,11 +435,12 @@ bool InspectorController::developerExtrasEnabled() const bool InspectorController::canAccessInspectedScriptState(JSC::ExecState* scriptState) const { JSLockHolder lock(scriptState); - JSDOMWindow* inspectedWindow = toJSDOMWindow(scriptState->lexicalGlobalObject()); + + JSDOMWindow* inspectedWindow = toJSDOMWindow(scriptState->vm(), scriptState->lexicalGlobalObject()); if (!inspectedWindow) return false; - return BindingSecurity::shouldAllowAccessToDOMWindow(scriptState, inspectedWindow->impl(), DoNotReportSecurityError); + return BindingSecurity::shouldAllowAccessToDOMWindow(scriptState, inspectedWindow->wrapped(), DoNotReportSecurityError); } InspectorFunctionCallHandler InspectorController::functionCallHandler() const @@ -464,20 +453,32 @@ InspectorEvaluateHandler InspectorController::evaluateHandler() const return WebCore::evaluateHandlerFromAnyThread; } -void InspectorController::willCallInjectedScriptFunction(JSC::ExecState* scriptState, const String& scriptName, int scriptLine) +void InspectorController::frontendInitialized() { - ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(scriptState); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(scriptExecutionContext, scriptName, scriptLine); - m_injectedScriptInstrumentationCookies.append(cookie); +#if ENABLE(REMOTE_INSPECTOR) + if (m_isAutomaticInspection) + m_page.inspectorDebuggable().unpauseForInitializedInspector(); +#endif } -void InspectorController::didCallInjectedScriptFunction() +Ref<Stopwatch> InspectorController::executionStopwatch() { - ASSERT(!m_injectedScriptInstrumentationCookies.isEmpty()); - InspectorInstrumentationCookie cookie = m_injectedScriptInstrumentationCookies.takeLast(); - InspectorInstrumentation::didCallFunction(cookie); + return m_executionStopwatch.copyRef(); } -} // namespace WebCore +PageScriptDebugServer& InspectorController::scriptDebugServer() +{ + return m_scriptDebugServer; +} -#endif // ENABLE(INSPECTOR) +JSC::VM& InspectorController::vm() +{ + return commonVM(); +} + +void InspectorController::didComposite(Frame& frame) +{ + InspectorInstrumentation::didComposite(frame); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h index 07bd72dbf..fd9693a9b 100644 --- a/Source/WebCore/inspector/InspectorController.h +++ b/Source/WebCore/inspector/InspectorController.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,26 +29,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorController_h -#define InspectorController_h +#pragma once -#if ENABLE(INSPECTOR) - -#include "InspectorInstrumentationCookie.h" +#include "InspectorOverlay.h" +#include "PageScriptDebugServer.h" #include <inspector/InspectorAgentRegistry.h> #include <inspector/InspectorEnvironment.h> #include <wtf/Forward.h> -#include <wtf/HashMap.h> #include <wtf/Noncopyable.h> -#include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace Inspector { +class BackendDispatcher; +class FrontendChannel; +class FrontendRouter; class InspectorAgent; -class InspectorBackendDispatcher; -class InspectorDebuggerAgent; -class InspectorFrontendChannel; -class InspectorObject; + +namespace Protocol { +namespace OverlayTypes { +class NodeHighlightData; +} +} } namespace WebCore { @@ -55,23 +57,15 @@ namespace WebCore { class DOMWrapperWorld; class Frame; class GraphicsContext; -class InspectorApplicationCacheAgent; class InspectorClient; class InspectorDOMAgent; -class InspectorDOMDebuggerAgent; class InspectorFrontendClient; -class InspectorMemoryAgent; -class InspectorOverlay; +class InspectorInstrumentation; class InspectorPageAgent; -class InspectorProfilerAgent; -class InspectorResourceAgent; class InstrumentingAgents; -class IntSize; -class Page; -class PageInjectedScriptManager; class Node; - -struct Highlight; +class Page; +class WebInjectedScriptManager; class InspectorController final : public Inspector::InspectorEnvironment { WTF_MAKE_NONCOPYABLE(InspectorController); @@ -85,94 +79,74 @@ public: bool enabled() const; Page& inspectedPage() const; - void show(); - void close(); + WEBCORE_EXPORT void show(); - void setInspectorFrontendClient(std::unique_ptr<InspectorFrontendClient>); - bool hasInspectorFrontendClient() const; - void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld&); + WEBCORE_EXPORT void setInspectorFrontendClient(InspectorFrontendClient*); + unsigned inspectionLevel() const; + void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&); - void dispatchMessageFromFrontend(const String& message); + WEBCORE_EXPORT void dispatchMessageFromFrontend(const String& message); - bool hasFrontend() const { return !!m_inspectorFrontendChannel; } bool hasLocalFrontend() const; bool hasRemoteFrontend() const; - void connectFrontend(Inspector::InspectorFrontendChannel*); - void disconnectFrontend(Inspector::InspectorDisconnectReason); + WEBCORE_EXPORT void connectFrontend(Inspector::FrontendChannel*, bool isAutomaticInspection = false); + WEBCORE_EXPORT void disconnectFrontend(Inspector::FrontendChannel*); + WEBCORE_EXPORT void disconnectAllFrontends(); void setProcessId(long); -#if ENABLE(REMOTE_INSPECTOR) - void setHasRemoteFrontend(bool hasRemote) { m_hasRemoteFrontend = hasRemote; } -#endif - void inspect(Node*); - void drawHighlight(GraphicsContext&) const; - void getHighlight(Highlight*) const; + WEBCORE_EXPORT void drawHighlight(GraphicsContext&) const; + WEBCORE_EXPORT void getHighlight(Highlight&, InspectorOverlay::CoordinateSystem) const; void hideHighlight(); Node* highlightedNode() const; void setIndicating(bool); - PassRefPtr<Inspector::InspectorObject> buildObjectForHighlightedNode() const; + WEBCORE_EXPORT Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> buildObjectForHighlightedNodes() const; - bool isUnderTest(); - void evaluateForTestInFrontend(long callId, const String& script); + WEBCORE_EXPORT void didComposite(Frame&); - bool profilerEnabled() const; - void setProfilerEnabled(bool); - - void resume(); - - void setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize); + bool isUnderTest() const { return m_isUnderTest; } + WEBCORE_EXPORT void setIsUnderTest(bool); + WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script); InspectorClient* inspectorClient() const { return m_inspectorClient; } + InspectorFrontendClient* inspectorFrontendClient() const { return m_inspectorFrontendClient; } InspectorPageAgent* pageAgent() const { return m_pageAgent; } - void didBeginFrame(); - void didCancelFrame(); - void willComposite(); - void didComposite(); - - virtual bool developerExtrasEnabled() const override; - virtual bool canAccessInspectedScriptState(JSC::ExecState*) const override; - virtual Inspector::InspectorFunctionCallHandler functionCallHandler() const override; - virtual Inspector::InspectorEvaluateHandler evaluateHandler() const override; - virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String& scriptName, int scriptLine) override; - virtual void didCallInjectedScriptFunction() override; + // InspectorEnvironment + bool developerExtrasEnabled() const override; + bool canAccessInspectedScriptState(JSC::ExecState*) const override; + Inspector::InspectorFunctionCallHandler functionCallHandler() const override; + Inspector::InspectorEvaluateHandler evaluateHandler() const override; + void frontendInitialized() override; + Ref<WTF::Stopwatch> executionStopwatch() override; + PageScriptDebugServer& scriptDebugServer() override; + JSC::VM& vm() override; private: - friend InstrumentingAgents* instrumentationForPage(Page*); + friend class InspectorInstrumentation; - RefPtr<InstrumentingAgents> m_instrumentingAgents; - std::unique_ptr<PageInjectedScriptManager> m_injectedScriptManager; + Ref<InstrumentingAgents> m_instrumentingAgents; + std::unique_ptr<WebInjectedScriptManager> m_injectedScriptManager; + Ref<Inspector::FrontendRouter> m_frontendRouter; + Ref<Inspector::BackendDispatcher> m_backendDispatcher; std::unique_ptr<InspectorOverlay> m_overlay; + Ref<WTF::Stopwatch> m_executionStopwatch; + PageScriptDebugServer m_scriptDebugServer; + Inspector::AgentRegistry m_agents; - Inspector::InspectorAgent* m_inspectorAgent; - InspectorDOMAgent* m_domAgent; - InspectorResourceAgent* m_resourceAgent; - InspectorPageAgent* m_pageAgent; - InspectorMemoryAgent* m_memoryAgent; - Inspector::InspectorDebuggerAgent* m_debuggerAgent; - InspectorDOMDebuggerAgent* m_domDebuggerAgent; - InspectorProfilerAgent* m_profilerAgent; - - RefPtr<Inspector::InspectorBackendDispatcher> m_inspectorBackendDispatcher; - std::unique_ptr<InspectorFrontendClient> m_inspectorFrontendClient; - Inspector::InspectorFrontendChannel* m_inspectorFrontendChannel; Page& m_page; InspectorClient* m_inspectorClient; - Inspector::InspectorAgentRegistry m_agents; - Vector<InspectorInstrumentationCookie, 2> m_injectedScriptInstrumentationCookies; - bool m_isUnderTest; + InspectorFrontendClient* m_inspectorFrontendClient { nullptr }; -#if ENABLE(REMOTE_INSPECTOR) - bool m_hasRemoteFrontend; -#endif -}; + Inspector::InspectorAgent* m_inspectorAgent { nullptr }; + InspectorDOMAgent* m_domAgent { nullptr }; + InspectorPageAgent* m_pageAgent { nullptr }; -} - -#endif // ENABLE(INSPECTOR) + bool m_isUnderTest { false }; + bool m_isAutomaticInspection { false }; +}; -#endif // !defined(InspectorController_h) +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorCounters.cpp b/Source/WebCore/inspector/InspectorCounters.cpp deleted file mode 100644 index 6f85f8762..000000000 --- a/Source/WebCore/inspector/InspectorCounters.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Copyright (C) 2012 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorCounters.h" - -#include "ThreadGlobalData.h" - -namespace WebCore { - -int InspectorCounters::s_counters[CounterTypeLength]; - -int InspectorCounters::counterValue(CounterType type) -{ - return s_counters[type]; -} - -ThreadLocalInspectorCounters::ThreadLocalInspectorCounters() -{ - for (size_t i = 0; i < CounterTypeLength; i++) - m_counters[i] = 0; -} - -int ThreadLocalInspectorCounters::counterValue(CounterType type) -{ - return m_counters[type]; -} - -ThreadLocalInspectorCounters& ThreadLocalInspectorCounters::current() -{ - return threadGlobalData().inspectorCounters(); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorCounters.h b/Source/WebCore/inspector/InspectorCounters.h deleted file mode 100644 index 29bd1bd62..000000000 --- a/Source/WebCore/inspector/InspectorCounters.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -* Copyright (C) 2012 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef InspectorCounters_h -#define InspectorCounters_h - -#include <wtf/FastMalloc.h> - -#if !ASSERT_DISABLED -#include <wtf/MainThread.h> -#if PLATFORM(IOS) -#include "WebCoreThread.h" -#endif -#endif - -namespace WebCore { - -class InspectorCounters { -public: - enum CounterType { - DocumentCounter, - NodeCounter, - JSEventListenerCounter, - CounterTypeLength - }; - - static inline void incrementCounter(CounterType type) - { -#if ENABLE(INSPECTOR) - ASSERT(isMainThread()); - ++s_counters[type]; -#else - UNUSED_PARAM(type); -#endif - } - - static inline void decrementCounter(CounterType type) - { -#if ENABLE(INSPECTOR) - ASSERT(isMainThread()); - --s_counters[type]; -#else - UNUSED_PARAM(type); -#endif - } - -#if ENABLE(INSPECTOR) - static int counterValue(CounterType); -#endif - -private: - InspectorCounters(); - -#if ENABLE(INSPECTOR) - static int s_counters[CounterTypeLength]; -#endif -}; - - -#if ENABLE(INSPECTOR) -class ThreadLocalInspectorCounters { - WTF_MAKE_FAST_ALLOCATED; -public: - enum CounterType { - JSEventListenerCounter, - CounterTypeLength - }; - ThreadLocalInspectorCounters(); - - inline void incrementCounter(CounterType type) - { - ++m_counters[type]; - } - - inline void decrementCounter(CounterType type) - { - --m_counters[type]; - } - - int counterValue(CounterType); - - static ThreadLocalInspectorCounters& current(); - -private: - int m_counters[CounterTypeLength]; -}; -#endif - -} // namespace WebCore - -#endif // !defined(InspectorCounters_h) diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp index f24caaa74..69331f427 100644 --- a/Source/WebCore/inspector/InspectorDOMAgent.cpp +++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) 2011 Google Inc. All rights reserved. * Copyright (C) 2009 Joseph Pecoraro * @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -29,11 +29,10 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorDOMAgent.h" +#include "AXObjectCache.h" +#include "AccessibilityNodeObject.h" #include "Attr.h" #include "CSSComputedStyleDeclaration.h" #include "CSSPropertyNames.h" @@ -50,27 +49,28 @@ #include "DOMPatchSupport.h" #include "DOMWindow.h" #include "Document.h" -#include "DocumentFragment.h" #include "DocumentType.h" #include "Element.h" #include "Event.h" #include "EventListener.h" -#include "EventNames.h" -#include "EventTarget.h" +#include "ExceptionCodeDescription.h" #include "FrameTree.h" #include "HTMLElement.h" #include "HTMLFrameOwnerElement.h" #include "HTMLNames.h" +#include "HTMLScriptElement.h" +#include "HTMLStyleElement.h" #include "HTMLTemplateElement.h" #include "HitTestResult.h" -#include "IdentifiersFactory.h" +#include "InspectorClient.h" +#include "InspectorController.h" #include "InspectorHistory.h" #include "InspectorNodeFinder.h" #include "InspectorOverlay.h" #include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" #include "IntRect.h" +#include "JSDOMBindingSecurity.h" #include "JSEventListener.h" #include "JSNode.h" #include "MainFrame.h" @@ -79,23 +79,26 @@ #include "NodeList.h" #include "Page.h" #include "Pasteboard.h" +#include "PseudoElement.h" #include "RenderStyle.h" #include "RenderStyleConstants.h" #include "ScriptState.h" -#include "Settings.h" #include "ShadowRoot.h" #include "StyleProperties.h" #include "StyleResolver.h" #include "StyleSheetList.h" #include "Text.h" +#include "TextNodeTraversal.h" +#include "Timer.h" #include "XPathResult.h" #include "htmlediting.h" #include "markup.h" +#include <inspector/IdentifiersFactory.h> #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> -#include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/Vector.h> +#include <pal/crypto/CryptoDigest.h> +#include <runtime/JSCInlines.h> +#include <wtf/text/Base64.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> @@ -108,23 +111,19 @@ using namespace HTMLNames; static const size_t maxTextSize = 10000; static const UChar ellipsisUChar[] = { 0x2026, 0 }; -static Color parseColor(const RefPtr<InspectorObject>* colorObject) +static Color parseColor(const InspectorObject* colorObject) { - if (!colorObject || !(*colorObject)) + if (!colorObject) return Color::transparent; - int r; - int g; - int b; - bool success = (*colorObject)->getNumber("r", &r); - success |= (*colorObject)->getNumber("g", &g); - success |= (*colorObject)->getNumber("b", &b); - if (!success) + int r = 0; + int g = 0; + int b = 0; + if (!colorObject->getInteger("r", r) || !colorObject->getInteger("g", g) || !colorObject->getInteger("b", b)) return Color::transparent; - double a; - success = (*colorObject)->getNumber("a", &a); - if (!success) + double a = 1.0; + if (!colorObject->getDouble("a", a)) return Color(r, g, b); // Clamp alpha to the [0..1] range. @@ -136,22 +135,22 @@ static Color parseColor(const RefPtr<InspectorObject>* colorObject) return Color(r, g, b, static_cast<int>(a * 255)); } -static Color parseConfigColor(const String& fieldName, InspectorObject* configObject) +static Color parseConfigColor(const String& fieldName, const InspectorObject* configObject) { - const RefPtr<InspectorObject> colorObject = configObject->getObject(fieldName); - return parseColor(&colorObject); + RefPtr<InspectorObject> colorObject; + configObject->getObject(fieldName, colorObject); + + return parseColor(colorObject.get()); } -static bool parseQuad(const RefPtr<InspectorArray>& quadArray, FloatQuad* quad) +static bool parseQuad(const InspectorArray& quadArray, FloatQuad* quad) { - if (!quadArray) - return false; const size_t coordinatesInQuad = 8; double coordinates[coordinatesInQuad]; - if (quadArray->length() != coordinatesInQuad) + if (quadArray.length() != coordinatesInQuad) return false; for (size_t i = 0; i < coordinatesInQuad; ++i) { - if (!quadArray->get(i)->asNumber(coordinates + i)) + if (!quadArray.get(i)->asDouble(*(coordinates + i))) return false; } quad->setP1(FloatPoint(coordinates[0], coordinates[1])); @@ -168,17 +167,17 @@ public: RevalidateStyleAttributeTask(InspectorDOMAgent*); void scheduleFor(Element*); void reset() { m_timer.stop(); } - void timerFired(Timer<RevalidateStyleAttributeTask>&); + void timerFired(); private: InspectorDOMAgent* m_domAgent; - Timer<RevalidateStyleAttributeTask> m_timer; + Timer m_timer; HashSet<RefPtr<Element>> m_elements; }; RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent) : m_domAgent(domAgent) - , m_timer(this, &RevalidateStyleAttributeTask::timerFired) + , m_timer(*this, &RevalidateStyleAttributeTask::timerFired) { } @@ -189,37 +188,38 @@ void RevalidateStyleAttributeTask::scheduleFor(Element* element) m_timer.startOneShot(0); } -void RevalidateStyleAttributeTask::timerFired(Timer<RevalidateStyleAttributeTask>&) +void RevalidateStyleAttributeTask::timerFired() { // The timer is stopped on m_domAgent destruction, so this method will never be called after m_domAgent has been destroyed. Vector<Element*> elements; - for (HashSet<RefPtr<Element>>::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it) - elements.append(it->get()); + for (auto& element : m_elements) + elements.append(element.get()); m_domAgent->styleAttributeInvalidated(elements); m_elements.clear(); } -String InspectorDOMAgent::toErrorString(const ExceptionCode& ec) +String InspectorDOMAgent::toErrorString(ExceptionCode ec) { if (ec) { ExceptionCodeDescription description(ec); return description.name; } - return ""; + return emptyString(); } -InspectorDOMAgent::InspectorDOMAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay) - : InspectorAgentBase(ASCIILiteral("DOM"), instrumentingAgents) +String InspectorDOMAgent::toErrorString(Exception&& exception) +{ + return ExceptionCodeDescription { exception.code() }.name; +} + +InspectorDOMAgent::InspectorDOMAgent(WebAgentContext& context, InspectorPageAgent* pageAgent, InspectorOverlay* overlay) + : InspectorAgentBase(ASCIILiteral("DOM"), context) + , m_injectedScriptManager(context.injectedScriptManager) + , m_frontendDispatcher(std::make_unique<Inspector::DOMFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::DOMBackendDispatcher::create(context.backendDispatcher, this)) , m_pageAgent(pageAgent) - , m_injectedScriptManager(injectedScriptManager) , m_overlay(overlay) - , m_domListener(0) - , m_lastNodeId(1) - , m_lastBackendNodeId(-1) - , m_searchingForNode(false) - , m_suppressAttributeModifiedEvent(false) - , m_documentRequested(false) { } @@ -229,34 +229,29 @@ InspectorDOMAgent::~InspectorDOMAgent() ASSERT(!m_searchingForNode); } -void InspectorDOMAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorDOMAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorDOMFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorDOMBackendDispatcher::create(backendDispatcher, this); - - m_history = adoptPtr(new InspectorHistory()); - m_domEditor = adoptPtr(new DOMEditor(m_history.get())); + m_history = std::make_unique<InspectorHistory>(); + m_domEditor = std::make_unique<DOMEditor>(*m_history); - m_instrumentingAgents->setInspectorDOMAgent(this); - m_document = m_pageAgent->mainFrame()->document(); + m_instrumentingAgents.setInspectorDOMAgent(this); + m_document = m_pageAgent->mainFrame().document(); if (m_nodeToFocus) focusNode(); } -void InspectorDOMAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorDOMAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - m_history.clear(); - m_domEditor.clear(); + m_history.reset(); + m_domEditor.reset(); + m_mousedOverNode = nullptr; - ErrorString error; - setSearchingForNode(&error, false, 0); - hideHighlight(&error); + ErrorString unused; + setSearchingForNode(unused, false, nullptr); + hideHighlight(unused); - m_instrumentingAgents->setInspectorDOMAgent(0); + m_instrumentingAgents.setInspectorDOMAgent(nullptr); m_documentRequested = false; reset(); } @@ -281,7 +276,7 @@ void InspectorDOMAgent::reset() discardBindings(); if (m_revalidateStyleAttrTask) m_revalidateStyleAttrTask->reset(); - m_document = 0; + m_document = nullptr; } void InspectorDOMAgent::setDOMListener(DOMListener* listener) @@ -289,20 +284,20 @@ void InspectorDOMAgent::setDOMListener(DOMListener* listener) m_domListener = listener; } -void InspectorDOMAgent::setDocument(Document* doc) +void InspectorDOMAgent::setDocument(Document* document) { - if (doc == m_document.get()) + if (document == m_document.get()) return; reset(); - m_document = doc; + m_document = document; if (!m_documentRequested) return; - // Immediately communicate 0 document or document that has finished loading. - if (!doc || !doc->parsing()) + // Immediately communicate null document or document that has finished loading. + if (!document || !document->parsing()) m_frontendDispatcher->documentUpdated(); } @@ -333,21 +328,23 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap) if (node->isFrameOwnerElement()) { const HTMLFrameOwnerElement* frameOwner = static_cast<const HTMLFrameOwnerElement*>(node); - Document* contentDocument = frameOwner->contentDocument(); - if (m_domListener) - m_domListener->didRemoveDocument(contentDocument); - if (contentDocument) + if (Document* contentDocument = frameOwner->contentDocument()) unbind(contentDocument, nodesMap); } - if (node->isElementNode()) { - if (ShadowRoot* root = toElement(node)->shadowRoot()) + if (is<Element>(*node)) { + Element& element = downcast<Element>(*node); + if (ShadowRoot* root = element.shadowRoot()) unbind(root, nodesMap); + if (PseudoElement* beforeElement = element.beforePseudoElement()) + unbind(beforeElement, nodesMap); + if (PseudoElement* afterElement = element.afterPseudoElement()) + unbind(afterElement, nodesMap); } nodesMap->remove(node); if (m_domListener) - m_domListener->didRemoveDOMNode(node); + m_domListener->didRemoveDOMNode(*node, id); bool childrenRequested = m_childrenRequested.contains(id); if (childrenRequested) { @@ -361,70 +358,78 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap) } } -Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId) +Node* InspectorDOMAgent::assertNode(ErrorString& errorString, int nodeId) { Node* node = nodeForId(nodeId); if (!node) { - *errorString = "Could not find node with given id"; + errorString = ASCIILiteral("Could not find node with given id"); return nullptr; } return node; } -Document* InspectorDOMAgent::assertDocument(ErrorString* errorString, int nodeId) +Document* InspectorDOMAgent::assertDocument(ErrorString& errorString, int nodeId) { Node* node = assertNode(errorString, nodeId); if (!node) return nullptr; - if (!node->isDocumentNode()) { - *errorString = "Document is not available"; + if (!is<Document>(*node)) { + errorString = ASCIILiteral("Document is not available"); return nullptr; } - return toDocument(node); + return downcast<Document>(node); } -Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId) +Element* InspectorDOMAgent::assertElement(ErrorString& errorString, int nodeId) { Node* node = assertNode(errorString, nodeId); if (!node) return nullptr; - if (!node->isElementNode()) { - *errorString = "Node is not an Element"; + if (!is<Element>(*node)) { + errorString = ASCIILiteral("Node is not an Element"); return nullptr; } - return toElement(node); + return downcast<Element>(node); } -Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId) +Node* InspectorDOMAgent::assertEditableNode(ErrorString& errorString, int nodeId) { Node* node = assertNode(errorString, nodeId); if (!node) return nullptr; - if (node->isInShadowTree()) { - *errorString = "Can not edit nodes from shadow trees"; + if (node->isInUserAgentShadowTree()) { + errorString = ASCIILiteral("Cannot edit nodes in user agent shadow trees"); + return nullptr; + } + if (node->isPseudoElement()) { + errorString = ASCIILiteral("Cannot edit pseudo elements"); return nullptr; } return node; } -Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int nodeId) +Element* InspectorDOMAgent::assertEditableElement(ErrorString& errorString, int nodeId) { Element* element = assertElement(errorString, nodeId); if (!element) return nullptr; - if (element->isInShadowTree()) { - *errorString = "Can not edit elements from shadow trees"; + if (element->isInUserAgentShadowTree()) { + errorString = ASCIILiteral("Cannot edit elements in user agent shadow trees"); + return nullptr; + } + if (element->isPseudoElement()) { + errorString = ASCIILiteral("Cannot edit pseudo elements"); return nullptr; } return element; } -void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<Inspector::TypeBuilder::DOM::Node>& root) +void InspectorDOMAgent::getDocument(ErrorString& errorString, RefPtr<Inspector::Protocol::DOM::Node>& root) { m_documentRequested = true; if (!m_document) { - *errorString = "Document is not available"; + errorString = ASCIILiteral("Document is not available"); return; } @@ -459,8 +464,8 @@ void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth) return; } - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodeMap); - m_frontendDispatcher->setChildNodes(nodeId, children.release()); + auto children = buildArrayForContainerChildren(node, depth, nodeMap); + m_frontendDispatcher->setChildNodes(nodeId, WTFMove(children)); } void InspectorDOMAgent::discardBindings() @@ -473,13 +478,13 @@ void InspectorDOMAgent::discardBindings() m_nodeGroupToBackendIdMap.clear(); } -int InspectorDOMAgent::pushNodeToFrontend(ErrorString* errorString, int documentNodeId, Node* nodeToPush) +int InspectorDOMAgent::pushNodeToFrontend(ErrorString& errorString, int documentNodeId, Node* nodeToPush) { Document* document = assertDocument(errorString, documentNodeId); if (!document) return 0; if (&nodeToPush->document() != document) { - *errorString = "Node is not part of the document with given id"; + errorString = ASCIILiteral("Node is not part of the document with given id"); return 0; } @@ -497,7 +502,7 @@ Node* InspectorDOMAgent::nodeForId(int id) return 0; } -void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, const int* depth) +void InspectorDOMAgent::requestChildNodes(ErrorString& errorString, int nodeId, const int* depth) { int sanitizedDepth; @@ -508,54 +513,52 @@ void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, else if (*depth > 0) sanitizedDepth = *depth; else { - *errorString = "Please provide a positive integer as a depth or -1 for entire subtree"; + errorString = ASCIILiteral("Please provide a positive integer as a depth or -1 for entire subtree"); return; } pushChildNodesToFrontend(nodeId, sanitizedDepth); } -void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId) +void InspectorDOMAgent::querySelector(ErrorString& errorString, int nodeId, const String& selectors, int* elementId) { *elementId = 0; Node* node = assertNode(errorString, nodeId); if (!node) return; - if (!node->isContainerNode()) { + if (!is<ContainerNode>(*node)) { assertElement(errorString, nodeId); return; } - ExceptionCode ec = 0; - RefPtr<Element> element = toContainerNode(node)->querySelector(selectors, ec); - if (ec) { - *errorString = "DOM Error while querying"; + auto queryResult = downcast<ContainerNode>(*node).querySelector(selectors); + if (queryResult.hasException()) { + errorString = ASCIILiteral("DOM Error while querying"); return; } - if (element) - *elementId = pushNodePathToFrontend(element.get()); + if (auto* element = queryResult.releaseReturnValue()) + *elementId = pushNodePathToFrontend(element); } -void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<Inspector::TypeBuilder::Array<int>>& result) +void InspectorDOMAgent::querySelectorAll(ErrorString& errorString, int nodeId, const String& selectors, RefPtr<Inspector::Protocol::Array<int>>& result) { Node* node = assertNode(errorString, nodeId); if (!node) return; - if (!node->isContainerNode()) { + if (!is<ContainerNode>(*node)) { assertElement(errorString, nodeId); return; } - ExceptionCode ec = 0; - RefPtr<NodeList> nodes = toContainerNode(node)->querySelectorAll(selectors, ec); - if (ec) { - *errorString = "DOM Error while querying"; + auto queryResult = downcast<ContainerNode>(*node).querySelectorAll(selectors); + if (queryResult.hasException()) { + errorString = ASCIILiteral("DOM Error while querying"); return; } - result = Inspector::TypeBuilder::Array<int>::create(); - + auto nodes = queryResult.releaseReturnValue(); + result = Inspector::Protocol::Array<int>::create(); for (unsigned i = 0; i < nodes->length(); ++i) result->addItem(pushNodePathToFrontend(nodes->item(i))); } @@ -582,12 +585,12 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush) Node* parent = innerParentNode(node); if (!parent) { // Node being pushed is detached -> push subtree root. - OwnPtr<NodeToIdMap> newMap = adoptPtr(new NodeToIdMap); + auto newMap = std::make_unique<NodeToIdMap>(); danglingMap = newMap.get(); m_danglingNodeToIdMaps.append(newMap.release()); - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create(); + auto children = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create(); children->addItem(buildObjectForNode(node, 0, danglingMap)); - m_frontendDispatcher->setChildNodes(0, children); + m_frontendDispatcher->setChildNodes(0, WTFMove(children)); break; } else { path.append(parent); @@ -607,9 +610,9 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush) return map->get(nodeToPush); } -int InspectorDOMAgent::boundNodeId(Node* node) +int InspectorDOMAgent::boundNodeId(const Node* node) { - return m_documentNodeToIdMap.get(node); + return m_documentNodeToIdMap.get(const_cast<Node*>(node)); } BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String& nodeGroup) @@ -631,50 +634,49 @@ BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String& return id; } -void InspectorDOMAgent::releaseBackendNodeIds(ErrorString* errorString, const String& nodeGroup) +void InspectorDOMAgent::releaseBackendNodeIds(ErrorString& errorString, const String& nodeGroup) { if (m_nodeGroupToBackendIdMap.contains(nodeGroup)) { NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value; - for (NodeToBackendIdMap::iterator it = map.begin(); it != map.end(); ++it) - m_backendIdToNode.remove(it->value); + for (auto& backendId : map.values()) + m_backendIdToNode.remove(backendId); m_nodeGroupToBackendIdMap.remove(nodeGroup); return; } - *errorString = "Group name not found"; + errorString = ASCIILiteral("Group name not found"); } -void InspectorDOMAgent::setAttributeValue(ErrorString* errorString, int elementId, const String& name, const String& value) +void InspectorDOMAgent::setAttributeValue(ErrorString& errorString, int elementId, const String& name, const String& value) { Element* element = assertEditableElement(errorString, elementId); if (!element) return; - m_domEditor->setAttribute(element, name, value, errorString); + m_domEditor->setAttribute(*element, name, value, errorString); } -void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elementId, const String& text, const String* const name) +void InspectorDOMAgent::setAttributesAsText(ErrorString& errorString, int elementId, const String& text, const String* const name) { Element* element = assertEditableElement(errorString, elementId); if (!element) return; - RefPtr<HTMLElement> parsedElement = createHTMLElement(element->document(), spanTag); - ExceptionCode ec = 0; - parsedElement.get()->setInnerHTML("<span " + text + "></span>", ec); - if (ec) { - *errorString = InspectorDOMAgent::toErrorString(ec); + auto parsedElement = createHTMLElement(element->document(), spanTag); + auto result = parsedElement.get().setInnerHTML("<span " + text + "></span>"); + if (result.hasException()) { + errorString = toErrorString(result.releaseException()); return; } Node* child = parsedElement->firstChild(); if (!child) { - *errorString = "Could not parse value as attributes"; + errorString = ASCIILiteral("Could not parse value as attributes"); return; } - Element* childElement = toElement(child); + Element* childElement = downcast<Element>(child); if (!childElement->hasAttributes() && name) { - m_domEditor->removeAttribute(element, *name, errorString); + m_domEditor->removeAttribute(*element, *name, errorString); return; } @@ -682,24 +684,24 @@ void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elemen for (const Attribute& attribute : childElement->attributesIterator()) { // Add attribute pair foundOriginalAttribute = foundOriginalAttribute || (name && attribute.name().toString() == *name); - if (!m_domEditor->setAttribute(element, attribute.name().toString(), attribute.value(), errorString)) + if (!m_domEditor->setAttribute(*element, attribute.name().toString(), attribute.value(), errorString)) return; } if (!foundOriginalAttribute && name && !name->stripWhiteSpace().isEmpty()) - m_domEditor->removeAttribute(element, *name, errorString); + m_domEditor->removeAttribute(*element, *name, errorString); } -void InspectorDOMAgent::removeAttribute(ErrorString* errorString, int elementId, const String& name) +void InspectorDOMAgent::removeAttribute(ErrorString& errorString, int elementId, const String& name) { Element* element = assertEditableElement(errorString, elementId); if (!element) return; - m_domEditor->removeAttribute(element, name, errorString); + m_domEditor->removeAttribute(*element, name, errorString); } -void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId) +void InspectorDOMAgent::removeNode(ErrorString& errorString, int nodeId) { Node* node = assertEditableNode(errorString, nodeId); if (!node) @@ -707,49 +709,49 @@ void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId) ContainerNode* parentNode = node->parentNode(); if (!parentNode) { - *errorString = "Can not remove detached node"; + errorString = ASCIILiteral("Cannot remove detached node"); return; } - m_domEditor->removeChild(parentNode, node, errorString); + m_domEditor->removeChild(*parentNode, *node, errorString); } -void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const String& tagName, int* newId) +void InspectorDOMAgent::setNodeName(ErrorString& errorString, int nodeId, const String& tagName, int* newId) { *newId = 0; - Node* oldNode = nodeForId(nodeId); - if (!oldNode || !oldNode->isElementNode()) + RefPtr<Node> oldNode = nodeForId(nodeId); + if (!is<Element>(oldNode.get())) return; - ExceptionCode ec = 0; - RefPtr<Element> newElem = oldNode->document().createElement(tagName, ec); - if (ec) + auto createElementResult = oldNode->document().createElementForBindings(tagName); + if (createElementResult.hasException()) return; + auto newElement = createElementResult.releaseReturnValue(); // Copy over the original node's attributes. - newElem->cloneAttributesFromElement(*toElement(oldNode)); + newElement->cloneAttributesFromElement(downcast<Element>(*oldNode)); // Copy over the original node's children. - Node* child; + RefPtr<Node> child; while ((child = oldNode->firstChild())) { - if (!m_domEditor->insertBefore(newElem.get(), child, 0, errorString)) + if (!m_domEditor->insertBefore(newElement, *child, 0, errorString)) return; } // Replace the old node with the new node - ContainerNode* parent = oldNode->parentNode(); - if (!m_domEditor->insertBefore(parent, newElem.get(), oldNode->nextSibling(), errorString)) + RefPtr<ContainerNode> parent = oldNode->parentNode(); + if (!m_domEditor->insertBefore(*parent, newElement.copyRef(), oldNode->nextSibling(), errorString)) return; - if (!m_domEditor->removeChild(parent, oldNode, errorString)) + if (!m_domEditor->removeChild(*parent, *oldNode, errorString)) return; - *newId = pushNodePathToFrontend(newElem.get()); + *newId = pushNodePathToFrontend(newElement.ptr()); if (m_childrenRequested.contains(nodeId)) pushChildNodesToFrontend(*newId); } -void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::String* outerHTML) +void InspectorDOMAgent::getOuterHTML(ErrorString& errorString, int nodeId, WTF::String* outerHTML) { Node* node = assertNode(errorString, nodeId); if (!node) @@ -758,11 +760,10 @@ void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF:: *outerHTML = createMarkup(*node); } -void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML) +void InspectorDOMAgent::setOuterHTML(ErrorString& errorString, int nodeId, const String& outerHTML) { if (!nodeId) { - DOMPatchSupport domPatchSupport(m_domEditor.get(), m_document.get()); - domPatchSupport.patchDocument(outerHTML); + DOMPatchSupport { *m_domEditor, *m_document }.patchDocument(outerHTML); return; } @@ -771,17 +772,13 @@ void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const return; Document& document = node->document(); - if (!document.isHTMLDocument() && !document.isXHTMLDocument() -#if ENABLE(SVG) - && !document.isSVGDocument() -#endif - ) { - *errorString = "Not an HTML/XML document"; + if (!document.isHTMLDocument() && !document.isXMLDocument()) { + errorString = ASCIILiteral("Not an HTML/XML document"); return; } - Node* newNode = 0; - if (!m_domEditor->setOuterHTML(*node, outerHTML, &newNode, errorString)) + Node* newNode = nullptr; + if (!m_domEditor->setOuterHTML(*node, outerHTML, newNode, errorString)) return; if (!newNode) { @@ -796,23 +793,23 @@ void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const pushChildNodesToFrontend(newId); } -void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const String& value) +void InspectorDOMAgent::setNodeValue(ErrorString& errorString, int nodeId, const String& value) { Node* node = assertEditableNode(errorString, nodeId); if (!node) return; - if (node->nodeType() != Node::TEXT_NODE) { - *errorString = "Can only set value of text nodes"; + if (!is<Text>(*node)) { + errorString = ASCIILiteral("Can only set value of text nodes"); return; } - m_domEditor->replaceWholeText(toText(node), value, errorString); + m_domEditor->replaceWholeText(downcast<Text>(*node), value, errorString); } -void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::EventListener>>& listenersArray) +void InspectorDOMAgent::getEventListenersForNode(ErrorString& errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>>& listenersArray) { - listenersArray = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::EventListener>::create(); + listenersArray = Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>::create(); Node* node = assertNode(errorString, nodeId); if (!node) return; @@ -821,24 +818,19 @@ void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int n // Get Capturing Listeners (in this order) size_t eventInformationLength = eventInformation.size(); - for (size_t i = 0; i < eventInformationLength; ++i) { - const EventListenerInfo& info = eventInformation[i]; - const EventListenerVector& vector = info.eventListenerVector; - for (size_t j = 0; j < vector.size(); ++j) { - const RegisteredEventListener& listener = vector[j]; - if (listener.useCapture) - listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup)); + for (auto& info : eventInformation) { + for (auto& listener : info.eventListenerVector) { + if (listener->useCapture()) + listenersArray->addItem(buildObjectForEventListener(*listener, info.eventType, info.node, objectGroup)); } } // Get Bubbling Listeners (reverse order) for (size_t i = eventInformationLength; i; --i) { const EventListenerInfo& info = eventInformation[i - 1]; - const EventListenerVector& vector = info.eventListenerVector; - for (size_t j = 0; j < vector.size(); ++j) { - const RegisteredEventListener& listener = vector[j]; - if (!listener.useCapture) - listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup)); + for (auto& listener : info.eventListenerVector) { + if (!listener->useCapture()) + listenersArray->addItem(buildObjectForEventListener(*listener, info.eventType, info.node, objectGroup)); } } } @@ -861,49 +853,54 @@ void InspectorDOMAgent::getEventListeners(Node* node, Vector<EventListenerInfo>& if (!d) continue; // Get the list of event types this Node is concerned with - Vector<AtomicString> eventTypes = d->eventListenerMap.eventTypes(); - for (size_t j = 0; j < eventTypes.size(); ++j) { - AtomicString& type = eventTypes[j]; - const EventListenerVector& listeners = ancestor->getEventListeners(type); + for (auto& type : d->eventListenerMap.eventTypes()) { + auto& listeners = ancestor->eventListeners(type); EventListenerVector filteredListeners; - filteredListeners.reserveCapacity(listeners.size()); - for (size_t k = 0; k < listeners.size(); ++k) { - if (listeners[k].listener->type() == EventListener::JSEventListenerType) - filteredListeners.append(listeners[k]); + filteredListeners.reserveInitialCapacity(listeners.size()); + for (auto& listener : listeners) { + if (listener->callback().type() == EventListener::JSEventListenerType) + filteredListeners.uncheckedAppend(listener); } if (!filteredListeners.isEmpty()) - eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners)); + eventInformation.append(EventListenerInfo(ancestor, type, WTFMove(filteredListeners))); } } } -void InspectorDOMAgent::performSearch(ErrorString* errorString, const String& whitespaceTrimmedQuery, const RefPtr<InspectorArray>* nodeIds, String* searchId, int* resultCount) +void InspectorDOMAgent::getAccessibilityPropertiesForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::DOM::AccessibilityProperties>& axProperties) +{ + Node* node = assertNode(errorString, nodeId); + if (!node) + return; + + axProperties = buildObjectForAccessibilityProperties(node); +} + +void InspectorDOMAgent::performSearch(ErrorString& errorString, const String& whitespaceTrimmedQuery, const InspectorArray* nodeIds, String* searchId, int* resultCount) { // FIXME: Search works with node granularity - number of matches within node is not calculated. InspectorNodeFinder finder(whitespaceTrimmedQuery); if (nodeIds) { - const RefPtr<InspectorArray>& nodeIdsRef = *nodeIds; - for (unsigned i = 0; i < nodeIdsRef->length(); ++i) { - RefPtr<InspectorValue> nodeValue = nodeIdsRef->get(i); + for (auto& nodeValue : *nodeIds) { if (!nodeValue) { - *errorString = "Invalid nodeIds item."; + errorString = ASCIILiteral("Invalid nodeIds item."); return; } int nodeId = 0; - if (!nodeValue->asNumber(&nodeId)) { - *errorString = "Invalid nodeIds item type. Expecting integer types."; + if (!nodeValue->asInteger(nodeId)) { + errorString = ASCIILiteral("Invalid nodeIds item type. Expecting integer types."); return; } Node* node = assertNode(errorString, nodeId); if (!node) { // assertNode should have filled the errorString for us. - ASSERT(errorString->length()); + ASSERT(errorString.length()); return; } finder.performSearch(node); } - } else if (m_document) { + } else { // There's no need to iterate the frames tree because // the search helper will go inside the frame owner elements. finder.performSearch(m_document.get()); @@ -912,32 +909,32 @@ void InspectorDOMAgent::performSearch(ErrorString* errorString, const String& wh *searchId = IdentifiersFactory::createIdentifier(); auto& resultsVector = m_searchResults.add(*searchId, Vector<RefPtr<Node>>()).iterator->value; - for (auto iterator = finder.results().begin(); iterator != finder.results().end(); ++iterator) - resultsVector.append(*iterator); + for (auto& result : finder.results()) + resultsVector.append(result); *resultCount = resultsVector.size(); } -void InspectorDOMAgent::getSearchResults(ErrorString* errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::TypeBuilder::Array<int>>& nodeIds) +void InspectorDOMAgent::getSearchResults(ErrorString& errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::Protocol::Array<int>>& nodeIds) { SearchResults::iterator it = m_searchResults.find(searchId); if (it == m_searchResults.end()) { - *errorString = "No search session with given id found"; + errorString = ASCIILiteral("No search session with given id found"); return; } int size = it->value.size(); if (fromIndex < 0 || toIndex > size || fromIndex >= toIndex) { - *errorString = "Invalid search result range"; + errorString = ASCIILiteral("Invalid search result range"); return; } - nodeIds = Inspector::TypeBuilder::Array<int>::create(); + nodeIds = Inspector::Protocol::Array<int>::create(); for (int i = fromIndex; i < toIndex; ++i) nodeIds->addItem(pushNodePathToFrontend((it->value)[i].get())); } -void InspectorDOMAgent::discardSearchResults(ErrorString*, const String& searchId) +void InspectorDOMAgent::discardSearchResults(ErrorString&, const String& searchId) { m_searchResults.remove(searchId); } @@ -954,13 +951,13 @@ bool InspectorDOMAgent::handleMousePress() return false; } -bool InspectorDOMAgent::handleTouchEvent(Node* node) +bool InspectorDOMAgent::handleTouchEvent(Node& node) { if (!m_searchingForNode) return false; - if (node && m_inspectModeHighlightConfig) { - m_overlay->highlightNode(node, *m_inspectModeHighlightConfig); - inspect(node); + if (m_inspectModeHighlightConfig) { + m_overlay->highlightNode(&node, *m_inspectModeHighlightConfig); + inspect(&node); return true; } return false; @@ -968,14 +965,17 @@ bool InspectorDOMAgent::handleTouchEvent(Node* node) void InspectorDOMAgent::inspect(Node* inspectedNode) { - ErrorString error; + ErrorString unused; RefPtr<Node> node = inspectedNode; - setSearchingForNode(&error, false, 0); + setSearchingForNode(unused, false, nullptr); if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE) node = node->parentNode(); m_nodeToFocus = node; + if (!m_nodeToFocus) + return; + focusNode(); } @@ -987,130 +987,173 @@ void InspectorDOMAgent::focusNode() ASSERT(m_nodeToFocus); RefPtr<Node> node = m_nodeToFocus.get(); - m_nodeToFocus = 0; + m_nodeToFocus = nullptr; Frame* frame = node->document().frame(); if (!frame) return; JSC::ExecState* scriptState = mainWorldExecState(frame); - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); + InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(scriptState); if (injectedScript.hasNoValue()) return; - injectedScript.inspectObject(InspectorDOMAgent::nodeAsScriptValue(scriptState, node.get())); + injectedScript.inspectObject(nodeAsScriptValue(*scriptState, node.get())); } void InspectorDOMAgent::mouseDidMoveOverElement(const HitTestResult& result, unsigned) { + m_mousedOverNode = result.innerNode(); + if (!m_searchingForNode) return; - Node* node = result.innerNode(); + highlightMousedOverNode(); +} + +void InspectorDOMAgent::highlightMousedOverNode() +{ + Node* node = m_mousedOverNode.get(); while (node && node->nodeType() == Node::TEXT_NODE) node = node->parentNode(); if (node && m_inspectModeHighlightConfig) m_overlay->highlightNode(node, *m_inspectModeHighlightConfig); } -void InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, bool enabled, InspectorObject* highlightInspectorObject) +void InspectorDOMAgent::setSearchingForNode(ErrorString& errorString, bool enabled, const InspectorObject* highlightInspectorObject) { if (m_searchingForNode == enabled) return; + m_searchingForNode = enabled; + if (enabled) { m_inspectModeHighlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject); if (!m_inspectModeHighlightConfig) return; + highlightMousedOverNode(); } else hideHighlight(errorString); m_overlay->didSetSearchingForNode(m_searchingForNode); + + if (InspectorClient* client = m_pageAgent->page().inspectorController().inspectorClient()) + client->elementSelectionChanged(m_searchingForNode); } -PassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString* errorString, InspectorObject* highlightInspectorObject) +std::unique_ptr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString& errorString, const InspectorObject* highlightInspectorObject) { if (!highlightInspectorObject) { - *errorString = "Internal error: highlight configuration parameter is missing"; + errorString = ASCIILiteral("Internal error: highlight configuration parameter is missing"); return nullptr; } - OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig()); + auto highlightConfig = std::make_unique<HighlightConfig>(); bool showInfo = false; // Default: false (do not show a tooltip). - highlightInspectorObject->getBoolean("showInfo", &showInfo); + highlightInspectorObject->getBoolean("showInfo", showInfo); highlightConfig->showInfo = showInfo; - bool showRulers = false; // Default: false (do not show rulers). - highlightInspectorObject->getBoolean("showRulers", &showRulers); - highlightConfig->showRulers = showRulers; highlightConfig->content = parseConfigColor("contentColor", highlightInspectorObject); highlightConfig->contentOutline = parseConfigColor("contentOutlineColor", highlightInspectorObject); highlightConfig->padding = parseConfigColor("paddingColor", highlightInspectorObject); highlightConfig->border = parseConfigColor("borderColor", highlightInspectorObject); highlightConfig->margin = parseConfigColor("marginColor", highlightInspectorObject); - return highlightConfig.release(); + return highlightConfig; } -void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const RefPtr<InspectorObject>* highlightConfig) +void InspectorDOMAgent::setInspectModeEnabled(ErrorString& errorString, bool enabled, const InspectorObject* highlightConfig) { - setSearchingForNode(errorString, enabled, highlightConfig ? highlightConfig->get() : 0); + setSearchingForNode(errorString, enabled, highlightConfig ? highlightConfig : nullptr); } -void InspectorDOMAgent::highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates) +void InspectorDOMAgent::highlightRect(ErrorString&, int x, int y, int width, int height, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates) { - OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad(FloatRect(x, y, width, height))); - innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates); + auto quad = std::make_unique<FloatQuad>(FloatRect(x, y, width, height)); + innerHighlightQuad(WTFMove(quad), color, outlineColor, usePageCoordinates); } -void InspectorDOMAgent::highlightQuad(ErrorString* errorString, const RefPtr<InspectorArray>& quadArray, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates) +void InspectorDOMAgent::highlightQuad(ErrorString& errorString, const InspectorArray& quadArray, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates) { - OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad()); + auto quad = std::make_unique<FloatQuad>(); if (!parseQuad(quadArray, quad.get())) { - *errorString = "Invalid Quad format"; + errorString = ASCIILiteral("Invalid Quad format"); return; } - innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates); + innerHighlightQuad(WTFMove(quad), color, outlineColor, usePageCoordinates); } -void InspectorDOMAgent::innerHighlightQuad(PassOwnPtr<FloatQuad> quad, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates) +void InspectorDOMAgent::innerHighlightQuad(std::unique_ptr<FloatQuad> quad, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates) { - OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig()); + auto highlightConfig = std::make_unique<HighlightConfig>(); highlightConfig->content = parseColor(color); highlightConfig->contentOutline = parseColor(outlineColor); highlightConfig->usePageCoordinates = usePageCoordinates ? *usePageCoordinates : false; - m_overlay->highlightQuad(quad, *highlightConfig); + m_overlay->highlightQuad(WTFMove(quad), *highlightConfig); } -void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<InspectorObject>& highlightInspectorObject, const int* nodeId, const String* objectId) +void InspectorDOMAgent::highlightSelector(ErrorString& errorString, const InspectorObject& highlightInspectorObject, const String& selectorString, const String* frameId) { - Node* node = 0; - if (nodeId) { + RefPtr<Document> document; + + if (frameId) { + Frame* frame = m_pageAgent->frameForId(*frameId); + if (!frame) { + errorString = ASCIILiteral("No frame for given id found"); + return; + } + + document = frame->document(); + } else + document = m_document; + + if (!document) { + errorString = ASCIILiteral("Document could not be found"); + return; + } + + auto queryResult = document->querySelectorAll(selectorString); + // FIXME: <https://webkit.org/b/146161> Web Inspector: DOM.highlightSelector should work for "a:visited" + if (queryResult.hasException()) { + errorString = ASCIILiteral("DOM Error while querying"); + return; + } + + auto highlightConfig = highlightConfigFromInspectorObject(errorString, &highlightInspectorObject); + if (!highlightConfig) + return; + + m_overlay->highlightNodeList(queryResult.releaseReturnValue(), *highlightConfig); +} + +void InspectorDOMAgent::highlightNode(ErrorString& errorString, const InspectorObject& highlightInspectorObject, const int* nodeId, const String* objectId) +{ + Node* node = nullptr; + if (nodeId) node = assertNode(errorString, *nodeId); - } else if (objectId) { + else if (objectId) { node = nodeForObjectId(*objectId); if (!node) - *errorString = "Node for given objectId not found"; + errorString = ASCIILiteral("Node for given objectId not found"); } else - *errorString = "Either nodeId or objectId must be specified"; + errorString = ASCIILiteral("Either nodeId or objectId must be specified"); if (!node) return; - OwnPtr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject.get()); + std::unique_ptr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, &highlightInspectorObject); if (!highlightConfig) return; m_overlay->highlightNode(node, *highlightConfig); } -void InspectorDOMAgent::highlightFrame( - ErrorString*, - const String& frameId, - const RefPtr<InspectorObject>* color, - const RefPtr<InspectorObject>* outlineColor) +void InspectorDOMAgent::highlightFrame(ErrorString& errorString, const String& frameId, const InspectorObject* color, const InspectorObject* outlineColor) { - Frame* frame = m_pageAgent->frameForId(frameId); - if (frame && frame->ownerElement()) { - OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig()); + Frame* frame = m_pageAgent->assertFrame(errorString, frameId); + if (!frame) + return; + + if (frame->ownerElement()) { + auto highlightConfig = std::make_unique<HighlightConfig>(); highlightConfig->showInfo = true; // Always show tooltips for frames. highlightConfig->content = parseColor(color); highlightConfig->contentOutline = parseColor(outlineColor); @@ -1118,12 +1161,12 @@ void InspectorDOMAgent::highlightFrame( } } -void InspectorDOMAgent::hideHighlight(ErrorString*) +void InspectorDOMAgent::hideHighlight(ErrorString&) { m_overlay->hideHighlight(); } -void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId) +void InspectorDOMAgent::moveTo(ErrorString& errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId) { Node* node = assertEditableNode(errorString, nodeId); if (!node) @@ -1139,65 +1182,65 @@ void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetE if (!anchorNode) return; if (anchorNode->parentNode() != targetElement) { - *errorString = "Anchor node must be child of the target element"; + errorString = ASCIILiteral("Anchor node must be child of the target element"); return; } } - if (!m_domEditor->insertBefore(targetElement, node, anchorNode, errorString)) + if (!m_domEditor->insertBefore(*targetElement, *node, anchorNode, errorString)) return; *newNodeId = pushNodePathToFrontend(node); } -void InspectorDOMAgent::undo(ErrorString* errorString) +void InspectorDOMAgent::undo(ErrorString& errorString) { - ExceptionCode ec = 0; - m_history->undo(ec); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto result = m_history->undo(); + if (result.hasException()) + errorString = toErrorString(result.releaseException()); } -void InspectorDOMAgent::redo(ErrorString* errorString) +void InspectorDOMAgent::redo(ErrorString& errorString) { - ExceptionCode ec = 0; - m_history->redo(ec); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto result = m_history->redo(); + if (result.hasException()) + errorString = toErrorString(result.releaseException()); } -void InspectorDOMAgent::markUndoableState(ErrorString*) +void InspectorDOMAgent::markUndoableState(ErrorString&) { m_history->markUndoableState(); } -void InspectorDOMAgent::focus(ErrorString* errorString, int nodeId) +void InspectorDOMAgent::focus(ErrorString& errorString, int nodeId) { Element* element = assertElement(errorString, nodeId); if (!element) return; if (!element->isFocusable()) { - *errorString = "Element is not focusable"; + errorString = ASCIILiteral("Element is not focusable"); return; } element->focus(); } -void InspectorDOMAgent::resolveNode(ErrorString* errorString, int nodeId, const String* const objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) +void InspectorDOMAgent::resolveNode(ErrorString& errorString, int nodeId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result) { - String objectGroupName = objectGroup ? *objectGroup : ""; + String objectGroupName = objectGroup ? *objectGroup : emptyString(); Node* node = nodeForId(nodeId); if (!node) { - *errorString = "No node with given id found"; + errorString = ASCIILiteral("No node with given id found"); return; } - RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> object = resolveNode(node, objectGroupName); + RefPtr<Inspector::Protocol::Runtime::RemoteObject> object = resolveNode(node, objectGroupName); if (!object) { - *errorString = "Node with given id does not belong to the document"; + errorString = ASCIILiteral("Node with given id does not belong to the document"); return; } result = object; } -void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<String>>& result) +void InspectorDOMAgent::getAttributes(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::Array<String>>& result) { Element* element = assertElement(errorString, nodeId); if (!element) @@ -1206,7 +1249,7 @@ void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefP result = buildArrayForElementAttributes(element); } -void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* nodeId) +void InspectorDOMAgent::requestNode(ErrorString&, const String& objectId, int* nodeId) { Node* node = nodeForObjectId(objectId); if (node) @@ -1215,20 +1258,72 @@ void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* n *nodeId = 0; } -// static String InspectorDOMAgent::documentURLString(Document* document) { if (!document || document->url().isNull()) - return ""; + return emptyString(); return document->url().string(); } static String documentBaseURLString(Document* document) { - return document->completeURL("").string(); + return document->completeURL(emptyString()).string(); +} + +static bool pseudoElementType(PseudoId pseudoId, Inspector::Protocol::DOM::PseudoType* type) +{ + switch (pseudoId) { + case BEFORE: + *type = Inspector::Protocol::DOM::PseudoType::Before; + return true; + case AFTER: + *type = Inspector::Protocol::DOM::PseudoType::After; + return true; + default: + return false; + } +} + +static Inspector::Protocol::DOM::ShadowRootType shadowRootType(ShadowRootMode mode) +{ + switch (mode) { + case ShadowRootMode::UserAgent: + return Inspector::Protocol::DOM::ShadowRootType::UserAgent; + case ShadowRootMode::Closed: + return Inspector::Protocol::DOM::ShadowRootType::Closed; + case ShadowRootMode::Open: + return Inspector::Protocol::DOM::ShadowRootType::Open; + } + + ASSERT_NOT_REACHED(); + return Inspector::Protocol::DOM::ShadowRootType::UserAgent; +} + +static Inspector::Protocol::DOM::CustomElementState customElementState(const Element& element) +{ + if (element.isDefinedCustomElement()) + return Inspector::Protocol::DOM::CustomElementState::Custom; + if (element.isFailedCustomElement()) + return Inspector::Protocol::DOM::CustomElementState::Failed; + if (element.isUndefinedCustomElement() || element.isCustomElementUpgradeCandidate()) + return Inspector::Protocol::DOM::CustomElementState::Waiting; + return Inspector::Protocol::DOM::CustomElementState::Builtin; } -PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap) +static String computeContentSecurityPolicySHA256Hash(const Element& element) +{ + // FIXME: Compute the digest with respect to the raw bytes received from the page. + // See <https://bugs.webkit.org/show_bug.cgi?id=155184>. + TextEncoding documentEncoding = element.document().textEncoding(); + const TextEncoding& encodingToUse = documentEncoding.isValid() ? documentEncoding : UTF8Encoding(); + CString content = encodingToUse.encode(TextNodeTraversal::contentsAsString(element), EntitiesForUnencodables); + auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256); + cryptoDigest->addBytes(content.data(), content.length()); + Vector<uint8_t> digest = cryptoDigest->computeHash(); + return makeString("sha256-", base64Encode(digest.data(), digest.size())); +} + +Ref<Inspector::Protocol::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap) { int id = bind(node, nodesMap); String nodeName; @@ -1236,6 +1331,10 @@ PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForN String nodeValue; switch (node->nodeType()) { + case Node::PROCESSING_INSTRUCTION_NODE: + nodeName = node->nodeName(); + localName = node->localName(); + FALLTHROUGH; case Node::TEXT_NODE: case Node::COMMENT_NODE: case Node::CDATA_SECTION_NODE: @@ -1257,80 +1356,108 @@ PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForN break; } - RefPtr<Inspector::TypeBuilder::DOM::Node> value = Inspector::TypeBuilder::DOM::Node::create() + auto value = Inspector::Protocol::DOM::Node::create() .setNodeId(id) .setNodeType(static_cast<int>(node->nodeType())) .setNodeName(nodeName) .setLocalName(localName) - .setNodeValue(nodeValue); + .setNodeValue(nodeValue) + .release(); if (node->isContainerNode()) { int nodeCount = innerChildNodeCount(node); value->setChildNodeCount(nodeCount); - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodesMap); + Ref<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodesMap); if (children->length() > 0) - value->setChildren(children.release()); + value->setChildren(WTFMove(children)); } - if (node->isElementNode()) { - Element* element = toElement(node); - value->setAttributes(buildArrayForElementAttributes(element)); - if (node->isFrameOwnerElement()) { - HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node); - Frame* frame = frameOwner->contentFrame(); + if (is<Element>(*node)) { + Element& element = downcast<Element>(*node); + value->setAttributes(buildArrayForElementAttributes(&element)); + if (is<HTMLFrameOwnerElement>(element)) { + HTMLFrameOwnerElement& frameOwner = downcast<HTMLFrameOwnerElement>(element); + Frame* frame = frameOwner.contentFrame(); if (frame) value->setFrameId(m_pageAgent->frameId(frame)); - Document* doc = frameOwner->contentDocument(); - if (doc) - value->setContentDocument(buildObjectForNode(doc, 0, nodesMap)); + Document* document = frameOwner.contentDocument(); + if (document) + value->setContentDocument(buildObjectForNode(document, 0, nodesMap)); } - if (ShadowRoot* root = element->shadowRoot()) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> shadowRoots = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create(); + if (ShadowRoot* root = element.shadowRoot()) { + auto shadowRoots = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create(); shadowRoots->addItem(buildObjectForNode(root, 0, nodesMap)); - value->setShadowRoots(shadowRoots); + value->setShadowRoots(WTFMove(shadowRoots)); + } + + if (is<HTMLTemplateElement>(element)) + value->setTemplateContent(buildObjectForNode(&downcast<HTMLTemplateElement>(element).content(), 0, nodesMap)); + + if (is<HTMLStyleElement>(element) || (is<HTMLScriptElement>(element) && !element.hasAttributeWithoutSynchronization(HTMLNames::srcAttr))) + value->setContentSecurityPolicyHash(computeContentSecurityPolicySHA256Hash(element)); + + auto state = customElementState(element); + if (state != Inspector::Protocol::DOM::CustomElementState::Builtin) + value->setCustomElementState(state); + + if (element.pseudoId()) { + Inspector::Protocol::DOM::PseudoType pseudoType; + if (pseudoElementType(element.pseudoId(), &pseudoType)) + value->setPseudoType(pseudoType); + } else { + if (auto pseudoElements = buildArrayForPseudoElements(element, nodesMap)) + value->setPseudoElements(WTFMove(pseudoElements)); } -#if ENABLE(TEMPLATE_ELEMENT) - if (element->hasTagName(HTMLNames::templateTag)) - value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(element)->content(), 0, nodesMap)); -#endif + } else if (is<Document>(*node)) { + Document& document = downcast<Document>(*node); + value->setFrameId(m_pageAgent->frameId(document.frame())); + value->setDocumentURL(documentURLString(&document)); + value->setBaseURL(documentBaseURLString(&document)); + value->setXmlVersion(document.xmlVersion()); + } else if (is<DocumentType>(*node)) { + DocumentType& docType = downcast<DocumentType>(*node); + value->setPublicId(docType.publicId()); + value->setSystemId(docType.systemId()); + } else if (is<Attr>(*node)) { + Attr& attribute = downcast<Attr>(*node); + value->setName(attribute.name()); + value->setValue(attribute.value()); + } else if (is<ShadowRoot>(*node)) { + ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); + value->setShadowRootType(shadowRootType(shadowRoot.mode())); + } + + // Need to enable AX to get the computed role. + if (!WebCore::AXObjectCache::accessibilityEnabled()) + WebCore::AXObjectCache::enableAccessibility(); - } else if (node->isDocumentNode()) { - Document* document = toDocument(node); - value->setDocumentURL(documentURLString(document)); - value->setBaseURL(documentBaseURLString(document)); - value->setXmlVersion(document->xmlVersion()); - } else if (node->nodeType() == Node::DOCUMENT_TYPE_NODE) { - DocumentType* docType = toDocumentType(node); - value->setPublicId(docType->publicId()); - value->setSystemId(docType->systemId()); - value->setInternalSubset(docType->internalSubset()); - } else if (node->isAttributeNode()) { - Attr* attribute = toAttr(node); - value->setName(attribute->name()); - value->setValue(attribute->value()); + if (AXObjectCache* axObjectCache = node->document().axObjectCache()) { + if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node)) + value->setRole(axObject->computedRoleString()); } - return value.release(); + + return value; } -PassRefPtr<Inspector::TypeBuilder::Array<String>> InspectorDOMAgent::buildArrayForElementAttributes(Element* element) +Ref<Inspector::Protocol::Array<String>> InspectorDOMAgent::buildArrayForElementAttributes(Element* element) { - RefPtr<Inspector::TypeBuilder::Array<String>> attributesValue = Inspector::TypeBuilder::Array<String>::create(); + auto attributesValue = Inspector::Protocol::Array<String>::create(); // Go through all attributes and serialize them. if (!element->hasAttributes()) - return attributesValue.release(); + return attributesValue; for (const Attribute& attribute : element->attributesIterator()) { // Add attribute pair attributesValue->addItem(attribute.name().toString()); attributesValue->addItem(attribute.value()); } - return attributesValue.release(); + return attributesValue; } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap) +Ref<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create(); + auto children = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create(); if (depth == 0) { // Special-case the only text child - pretend that container's children have been requested. Node* firstChild = container->firstChild(); @@ -1338,7 +1465,7 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> Ins children->addItem(buildObjectForNode(firstChild, 0, nodesMap)); m_childrenRequested.add(bind(container, nodesMap)); } - return children.release(); + return children; } Node* child = innerFirstChild(container); @@ -1349,29 +1476,46 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> Ins children->addItem(buildObjectForNode(child, depth, nodesMap)); child = innerNextSibling(child); } - return children.release(); + return children; } -PassRefPtr<Inspector::TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId) +RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> InspectorDOMAgent::buildArrayForPseudoElements(const Element& element, NodeToIdMap* nodesMap) { - RefPtr<EventListener> eventListener = registeredEventListener.listener; + PseudoElement* beforeElement = element.beforePseudoElement(); + PseudoElement* afterElement = element.afterPseudoElement(); + if (!beforeElement && !afterElement) + return nullptr; + + auto pseudoElements = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create(); + if (beforeElement) + pseudoElements->addItem(buildObjectForNode(beforeElement, 0, nodesMap)); + if (afterElement) + pseudoElements->addItem(buildObjectForNode(afterElement, 0, nodesMap)); + return WTFMove(pseudoElements); +} + +Ref<Inspector::Protocol::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId) +{ + Ref<EventListener> eventListener = registeredEventListener.callback(); JSC::ExecState* state = nullptr; JSC::JSObject* handler = nullptr; String body; int lineNumber = 0; + int columnNumber = 0; String scriptID; String sourceName; - if (auto scriptListener = JSEventListener::cast(eventListener.get())) { + if (auto scriptListener = JSEventListener::cast(eventListener.ptr())) { JSC::JSLockHolder lock(scriptListener->isolatedWorld().vm()); state = execStateFromNode(scriptListener->isolatedWorld(), &node->document()); handler = scriptListener->jsFunction(&node->document()); - if (handler) { + if (handler && state) { body = handler->toString(state)->value(state); - if (auto function = JSC::jsDynamicCast<JSC::JSFunction*>(handler)) { - if (!function->isHostFunction()) { + if (auto function = jsDynamicDowncast<JSC::JSFunction*>(state->vm(), handler)) { + if (!function->isHostOrBuiltinFunction()) { if (auto executable = function->jsExecutable()) { - lineNumber = executable->lineNo() - 1; + lineNumber = executable->firstLine() - 1; + columnNumber = executable->startColumn() - 1; scriptID = executable->sourceID() == JSC::SourceProvider::nullID ? emptyString() : String::number(executable->sourceID()); sourceName = executable->sourceURL(); } @@ -1380,26 +1524,349 @@ PassRefPtr<Inspector::TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildO } } - RefPtr<Inspector::TypeBuilder::DOM::EventListener> value = Inspector::TypeBuilder::DOM::EventListener::create() + auto value = Inspector::Protocol::DOM::EventListener::create() .setType(eventType) - .setUseCapture(registeredEventListener.useCapture) + .setUseCapture(registeredEventListener.useCapture()) .setIsAttribute(eventListener->isAttribute()) .setNodeId(pushNodePathToFrontend(node)) - .setHandlerBody(body); + .setHandlerBody(body) + .release(); if (objectGroupId && handler && state) { - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(state); + InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(state); if (!injectedScript.hasNoValue()) - value->setHandler(injectedScript.wrapObject(Deprecated::ScriptValue(state->vm(), handler), *objectGroupId)); + value->setHandler(injectedScript.wrapObject(handler, *objectGroupId)); } if (!scriptID.isNull()) { - RefPtr<Inspector::TypeBuilder::Debugger::Location> location = Inspector::TypeBuilder::Debugger::Location::create() + auto location = Inspector::Protocol::Debugger::Location::create() .setScriptId(scriptID) - .setLineNumber(lineNumber); - value->setLocation(location.release()); + .setLineNumber(lineNumber) + .release(); + location->setColumnNumber(columnNumber); + value->setLocation(WTFMove(location)); if (!sourceName.isEmpty()) value->setSourceName(sourceName); } - return value.release(); + return value; +} + +void InspectorDOMAgent::processAccessibilityChildren(RefPtr<AccessibilityObject>&& axObject, RefPtr<Inspector::Protocol::Array<int>>&& childNodeIds) +{ + const auto& children = axObject->children(); + if (!children.size()) + return; + + if (!childNodeIds) + childNodeIds = Inspector::Protocol::Array<int>::create(); + + for (const auto& childObject : children) { + if (Node* childNode = childObject->node()) + childNodeIds->addItem(pushNodePathToFrontend(childNode)); + else + processAccessibilityChildren(childObject.copyRef(), childNodeIds.copyRef()); + } +} + +RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> InspectorDOMAgent::buildObjectForAccessibilityProperties(Node* node) +{ + ASSERT(node); + if (!node) + return nullptr; + + if (!WebCore::AXObjectCache::accessibilityEnabled()) + WebCore::AXObjectCache::enableAccessibility(); + + Node* activeDescendantNode = nullptr; + bool busy = false; + auto checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::False; + RefPtr<Inspector::Protocol::Array<int>> childNodeIds; + RefPtr<Inspector::Protocol::Array<int>> controlledNodeIds; + auto currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::False; + bool exists = false; + bool expanded = false; + bool disabled = false; + RefPtr<Inspector::Protocol::Array<int>> flowedNodeIds; + bool focused = false; + bool ignored = true; + bool ignoredByDefault = false; + auto invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False; + bool hidden = false; + String label; + bool liveRegionAtomic = false; + RefPtr<Inspector::Protocol::Array<String>> liveRegionRelevant; + auto liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Off; + Node* mouseEventNode = nullptr; + RefPtr<Inspector::Protocol::Array<int>> ownedNodeIds; + Node* parentNode = nullptr; + bool pressed = false; + bool readonly = false; + bool required = false; + String role; + bool selected = false; + RefPtr<Inspector::Protocol::Array<int>> selectedChildNodeIds; + bool supportsChecked = false; + bool supportsExpanded = false; + bool supportsLiveRegion = false; + bool supportsPressed = false; + bool supportsRequired = false; + bool supportsFocused = false; + bool isPopupButton = false; + int headingLevel = 0; + unsigned hierarchicalLevel = 0; + unsigned level = 0; + + if (AXObjectCache* axObjectCache = node->document().axObjectCache()) { + if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node)) { + + if (AccessibilityObject* activeDescendant = axObject->activeDescendant()) + activeDescendantNode = activeDescendant->node(); + + // An AX object is "busy" if it or any ancestor has aria-busy="true" set. + AccessibilityObject* current = axObject; + while (!busy && current) { + busy = current->isBusy(); + current = current->parentObject(); + } + + supportsChecked = axObject->supportsChecked(); + if (supportsChecked) { + int checkValue = axObject->checkboxOrRadioValue(); // Element using aria-checked. + if (checkValue == 1) + checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::True; + else if (checkValue == 2) + checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::Mixed; + else if (axObject->isChecked()) // Native checkbox. + checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::True; + } + + processAccessibilityChildren(axObject, WTFMove(childNodeIds)); + + Vector<Element*> controlledElements; + axObject->elementsFromAttribute(controlledElements, aria_controlsAttr); + if (controlledElements.size()) { + controlledNodeIds = Inspector::Protocol::Array<int>::create(); + for (Element* controlledElement : controlledElements) + controlledNodeIds->addItem(pushNodePathToFrontend(controlledElement)); + } + + switch (axObject->ariaCurrentState()) { + case ARIACurrentFalse: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::False; + break; + case ARIACurrentPage: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Page; + break; + case ARIACurrentStep: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Step; + break; + case ARIACurrentLocation: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Location; + break; + case ARIACurrentDate: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Date; + break; + case ARIACurrentTime: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Time; + break; + default: + case ARIACurrentTrue: + currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::True; + break; + } + + disabled = !axObject->isEnabled(); + exists = true; + + supportsExpanded = axObject->supportsExpanded(); + if (supportsExpanded) + expanded = axObject->isExpanded(); + + Vector<Element*> flowedElements; + axObject->elementsFromAttribute(flowedElements, aria_flowtoAttr); + if (flowedElements.size()) { + flowedNodeIds = Inspector::Protocol::Array<int>::create(); + for (Element* flowedElement : flowedElements) + flowedNodeIds->addItem(pushNodePathToFrontend(flowedElement)); + } + + if (is<Element>(*node)) { + supportsFocused = axObject->canSetFocusAttribute(); + if (supportsFocused) + focused = axObject->isFocused(); + } + + ignored = axObject->accessibilityIsIgnored(); + ignoredByDefault = axObject->accessibilityIsIgnoredByDefault(); + + String invalidValue = axObject->invalidStatus(); + if (invalidValue == "false") + invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False; + else if (invalidValue == "grammar") + invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::Grammar; + else if (invalidValue == "spelling") + invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::Spelling; + else // Future versions of ARIA may allow additional truthy values. Ex. format, order, or size. + invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::True; + + if (axObject->isARIAHidden() || axObject->isDOMHidden()) + hidden = true; + + label = axObject->computedLabel(); + + if (axObject->supportsARIALiveRegion()) { + supportsLiveRegion = true; + liveRegionAtomic = axObject->ariaLiveRegionAtomic(); + + String ariaRelevantAttrValue = axObject->ariaLiveRegionRelevant(); + if (!ariaRelevantAttrValue.isEmpty()) { + // FIXME: Pass enum values rather than strings once unblocked. http://webkit.org/b/133711 + String ariaRelevantAdditions = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Additions); + String ariaRelevantRemovals = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Removals); + String ariaRelevantText = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Text); + liveRegionRelevant = Inspector::Protocol::Array<String>::create(); + const SpaceSplitString& values = SpaceSplitString(ariaRelevantAttrValue, true); + // @aria-relevant="all" is exposed as ["additions","removals","text"], in order. + // This order is controlled in WebCore and expected in WebInspectorUI. + if (values.contains("all")) { + liveRegionRelevant->addItem(ariaRelevantAdditions); + liveRegionRelevant->addItem(ariaRelevantRemovals); + liveRegionRelevant->addItem(ariaRelevantText); + } else { + if (values.contains(ariaRelevantAdditions)) + liveRegionRelevant->addItem(ariaRelevantAdditions); + if (values.contains(ariaRelevantRemovals)) + liveRegionRelevant->addItem(ariaRelevantRemovals); + if (values.contains(ariaRelevantText)) + liveRegionRelevant->addItem(ariaRelevantText); + } + } + + String ariaLive = axObject->ariaLiveRegionStatus(); + if (ariaLive == "assertive") + liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Assertive; + else if (ariaLive == "polite") + liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Polite; + } + + if (is<AccessibilityNodeObject>(*axObject)) + mouseEventNode = downcast<AccessibilityNodeObject>(*axObject).mouseButtonListener(MouseButtonListenerResultFilter::IncludeBodyElement); + + if (axObject->supportsARIAOwns()) { + Vector<Element*> ownedElements; + axObject->elementsFromAttribute(ownedElements, aria_ownsAttr); + if (ownedElements.size()) { + ownedNodeIds = Inspector::Protocol::Array<int>::create(); + for (Element* ownedElement : ownedElements) + ownedNodeIds->addItem(pushNodePathToFrontend(ownedElement)); + } + } + + if (AccessibilityObject* parentObject = axObject->parentObjectUnignored()) + parentNode = parentObject->node(); + + supportsPressed = axObject->ariaPressedIsPresent(); + if (supportsPressed) + pressed = axObject->isPressed(); + + if (axObject->isTextControl()) + readonly = !axObject->canSetValueAttribute(); + + supportsRequired = axObject->supportsRequiredAttribute(); + if (supportsRequired) + required = axObject->isRequired(); + + role = axObject->computedRoleString(); + selected = axObject->isSelected(); + + AccessibilityObject::AccessibilityChildrenVector selectedChildren; + axObject->selectedChildren(selectedChildren); + if (selectedChildren.size()) { + selectedChildNodeIds = Inspector::Protocol::Array<int>::create(); + for (auto& selectedChildObject : selectedChildren) { + if (Node* selectedChildNode = selectedChildObject->node()) + selectedChildNodeIds->addItem(pushNodePathToFrontend(selectedChildNode)); + } + } + + headingLevel = axObject->headingLevel(); + hierarchicalLevel = axObject->hierarchicalLevel(); + + level = hierarchicalLevel ? hierarchicalLevel : headingLevel; + isPopupButton = axObject->isPopUpButton() || axObject->ariaHasPopup(); + } + } + + Ref<Inspector::Protocol::DOM::AccessibilityProperties> value = Inspector::Protocol::DOM::AccessibilityProperties::create() + .setExists(exists) + .setLabel(label) + .setRole(role) + .setNodeId(pushNodePathToFrontend(node)) + .release(); + + if (exists) { + if (activeDescendantNode) + value->setActiveDescendantNodeId(pushNodePathToFrontend(activeDescendantNode)); + if (busy) + value->setBusy(busy); + if (supportsChecked) + value->setChecked(checked); + if (childNodeIds) + value->setChildNodeIds(childNodeIds); + if (controlledNodeIds) + value->setControlledNodeIds(controlledNodeIds); + if (currentState != Inspector::Protocol::DOM::AccessibilityProperties::Current::False) + value->setCurrent(currentState); + if (disabled) + value->setDisabled(disabled); + if (supportsExpanded) + value->setExpanded(expanded); + if (flowedNodeIds) + value->setFlowedNodeIds(flowedNodeIds); + if (supportsFocused) + value->setFocused(focused); + if (ignored) + value->setIgnored(ignored); + if (ignoredByDefault) + value->setIgnoredByDefault(ignoredByDefault); + if (invalid != Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False) + value->setInvalid(invalid); + if (hidden) + value->setHidden(hidden); + if (supportsLiveRegion) { + value->setLiveRegionAtomic(liveRegionAtomic); + if (liveRegionRelevant->length()) + value->setLiveRegionRelevant(liveRegionRelevant); + value->setLiveRegionStatus(liveRegionStatus); + } + if (mouseEventNode) + value->setMouseEventNodeId(pushNodePathToFrontend(mouseEventNode)); + if (ownedNodeIds) + value->setOwnedNodeIds(ownedNodeIds); + if (parentNode) + value->setParentNodeId(pushNodePathToFrontend(parentNode)); + if (supportsPressed) + value->setPressed(pressed); + if (readonly) + value->setReadonly(readonly); + if (supportsRequired) + value->setRequired(required); + if (selected) + value->setSelected(selected); + if (selectedChildNodeIds) + value->setSelectedChildNodeIds(selectedChildNodeIds); + + // H1 -- H6 always have a headingLevel property that can be complimented by a hierarchicalLevel + // property when aria-level is set on the element, in which case we want to remain calling + // this value the "Heading Level" in the inspector. + // Also, we do not want it to say Hierarchy Level: 0 + if (headingLevel) + value->setHeadingLevel(level); + else if (level) + value->setHierarchyLevel(level); + if (isPopupButton) + value->setIsPopUpButton(isPopupButton); + } + + return WTFMove(value); } Node* InspectorDOMAgent::innerFirstChild(Node* node) @@ -1439,10 +1906,11 @@ unsigned InspectorDOMAgent::innerChildNodeCount(Node* node) Node* InspectorDOMAgent::innerParentNode(Node* node) { - if (node->isDocumentNode()) { - Document* document = toDocument(node); - return document->ownerElement(); - } + ASSERT(node); + if (is<Document>(*node)) + return downcast<Document>(*node).ownerElement(); + if (is<ShadowRoot>(*node)) + return downcast<ShadowRoot>(*node).host(); return node->parentNode(); } @@ -1462,7 +1930,7 @@ void InspectorDOMAgent::mainFrameDOMContentLoaded() void InspectorDOMAgent::didCommitLoad(Document* document) { - Element* frameOwner = document->ownerElement(); + RefPtr<Element> frameOwner = document->ownerElement(); if (!frameOwner) return; @@ -1471,25 +1939,25 @@ void InspectorDOMAgent::didCommitLoad(Document* document) return; // Re-add frame owner element together with its new children. - int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner)); + int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner.get())); m_frontendDispatcher->childNodeRemoved(parentId, frameOwnerId); - unbind(frameOwner, &m_documentNodeToIdMap); + unbind(frameOwner.get(), &m_documentNodeToIdMap); - RefPtr<Inspector::TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, &m_documentNodeToIdMap); - Node* previousSibling = innerPreviousSibling(frameOwner); + Ref<Inspector::Protocol::DOM::Node> value = buildObjectForNode(frameOwner.get(), 0, &m_documentNodeToIdMap); + Node* previousSibling = innerPreviousSibling(frameOwner.get()); int prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0; - m_frontendDispatcher->childNodeInserted(parentId, prevId, value.release()); + m_frontendDispatcher->childNodeInserted(parentId, prevId, WTFMove(value)); } -void InspectorDOMAgent::didInsertDOMNode(Node* node) +void InspectorDOMAgent::didInsertDOMNode(Node& node) { - if (isWhitespace(node)) + if (isWhitespace(&node)) return; // We could be attaching existing subtree. Forget the bindings. - unbind(node, &m_documentNodeToIdMap); + unbind(&node, &m_documentNodeToIdMap); - ContainerNode* parent = node->parentNode(); + ContainerNode* parent = node.parentNode(); if (!parent) return; @@ -1503,19 +1971,19 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node) m_frontendDispatcher->childNodeCountUpdated(parentId, innerChildNodeCount(parent)); } else { // Children have been requested -> return value of a new child. - Node* prevSibling = innerPreviousSibling(node); + Node* prevSibling = innerPreviousSibling(&node); int prevId = prevSibling ? m_documentNodeToIdMap.get(prevSibling) : 0; - RefPtr<Inspector::TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, &m_documentNodeToIdMap); - m_frontendDispatcher->childNodeInserted(parentId, prevId, value.release()); + Ref<Inspector::Protocol::DOM::Node> value = buildObjectForNode(&node, 0, &m_documentNodeToIdMap); + m_frontendDispatcher->childNodeInserted(parentId, prevId, WTFMove(value)); } } -void InspectorDOMAgent::didRemoveDOMNode(Node* node) +void InspectorDOMAgent::didRemoveDOMNode(Node& node) { - if (isWhitespace(node)) + if (isWhitespace(&node)) return; - ContainerNode* parent = node->parentNode(); + ContainerNode* parent = node.parentNode(); // If parent is not mapped yet -> ignore the event. if (!m_documentNodeToIdMap.contains(parent)) @@ -1528,23 +1996,23 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node) if (innerChildNodeCount(parent) == 1) m_frontendDispatcher->childNodeCountUpdated(parentId, 0); } else - m_frontendDispatcher->childNodeRemoved(parentId, m_documentNodeToIdMap.get(node)); - unbind(node, &m_documentNodeToIdMap); + m_frontendDispatcher->childNodeRemoved(parentId, m_documentNodeToIdMap.get(&node)); + unbind(&node, &m_documentNodeToIdMap); } -void InspectorDOMAgent::willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue) +void InspectorDOMAgent::willModifyDOMAttr(Element&, const AtomicString& oldValue, const AtomicString& newValue) { m_suppressAttributeModifiedEvent = (oldValue == newValue); } -void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& name, const AtomicString& value) +void InspectorDOMAgent::didModifyDOMAttr(Element& element, const AtomicString& name, const AtomicString& value) { bool shouldSuppressEvent = m_suppressAttributeModifiedEvent; m_suppressAttributeModifiedEvent = false; if (shouldSuppressEvent) return; - int id = boundNodeId(element); + int id = boundNodeId(&element); // If node is not mapped yet -> ignore the event. if (!id) return; @@ -1555,9 +2023,9 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& n m_frontendDispatcher->attributeModified(id, name, value); } -void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& name) +void InspectorDOMAgent::didRemoveDOMAttr(Element& element, const AtomicString& name) { - int id = boundNodeId(element); + int id = boundNodeId(&element); // If node is not mapped yet -> ignore the event. if (!id) return; @@ -1570,68 +2038,74 @@ void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& n void InspectorDOMAgent::styleAttributeInvalidated(const Vector<Element*>& elements) { - RefPtr<Inspector::TypeBuilder::Array<int>> nodeIds = Inspector::TypeBuilder::Array<int>::create(); - for (unsigned i = 0, size = elements.size(); i < size; ++i) { - Element* element = elements.at(i); + auto nodeIds = Inspector::Protocol::Array<int>::create(); + for (auto& element : elements) { int id = boundNodeId(element); // If node is not mapped yet -> ignore the event. if (!id) continue; if (m_domListener) - m_domListener->didModifyDOMAttr(element); + m_domListener->didModifyDOMAttr(*element); nodeIds->addItem(id); } - m_frontendDispatcher->inlineStyleInvalidated(nodeIds.release()); + m_frontendDispatcher->inlineStyleInvalidated(WTFMove(nodeIds)); } -void InspectorDOMAgent::characterDataModified(CharacterData* characterData) +void InspectorDOMAgent::characterDataModified(CharacterData& characterData) { - int id = m_documentNodeToIdMap.get(characterData); + int id = m_documentNodeToIdMap.get(&characterData); if (!id) { // Push text node if it is being created. didInsertDOMNode(characterData); return; } - m_frontendDispatcher->characterDataModified(id, characterData->data()); + m_frontendDispatcher->characterDataModified(id, characterData.data()); } -void InspectorDOMAgent::didInvalidateStyleAttr(Node* node) +void InspectorDOMAgent::didInvalidateStyleAttr(Node& node) { - int id = m_documentNodeToIdMap.get(node); + int id = m_documentNodeToIdMap.get(&node); // If node is not mapped yet -> ignore the event. if (!id) return; if (!m_revalidateStyleAttrTask) - m_revalidateStyleAttrTask = adoptPtr(new RevalidateStyleAttributeTask(this)); - m_revalidateStyleAttrTask->scheduleFor(toElement(node)); + m_revalidateStyleAttrTask = std::make_unique<RevalidateStyleAttributeTask>(this); + m_revalidateStyleAttrTask->scheduleFor(downcast<Element>(&node)); } -void InspectorDOMAgent::didPushShadowRoot(Element* host, ShadowRoot* root) +void InspectorDOMAgent::didPushShadowRoot(Element& host, ShadowRoot& root) { - int hostId = m_documentNodeToIdMap.get(host); + int hostId = m_documentNodeToIdMap.get(&host); if (hostId) - m_frontendDispatcher->shadowRootPushed(hostId, buildObjectForNode(root, 0, &m_documentNodeToIdMap)); + m_frontendDispatcher->shadowRootPushed(hostId, buildObjectForNode(&root, 0, &m_documentNodeToIdMap)); } -void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root) +void InspectorDOMAgent::willPopShadowRoot(Element& host, ShadowRoot& root) { - int hostId = m_documentNodeToIdMap.get(host); - int rootId = m_documentNodeToIdMap.get(root); + int hostId = m_documentNodeToIdMap.get(&host); + int rootId = m_documentNodeToIdMap.get(&root); if (hostId && rootId) m_frontendDispatcher->shadowRootPopped(hostId, rootId); } -void InspectorDOMAgent::frameDocumentUpdated(Frame* frame) +void InspectorDOMAgent::didChangeCustomElementState(Element& element) { - Document* document = frame->document(); + int elementId = m_documentNodeToIdMap.get(&element); + if (!elementId) + return; + + m_frontendDispatcher->customElementStateChanged(elementId, customElementState(element)); +} + +void InspectorDOMAgent::frameDocumentUpdated(Frame& frame) +{ + Document* document = frame.document(); if (!document) return; - Page* page = frame->page(); - ASSERT(page); - if (frame != &page->mainFrame()) + if (!frame.isMainFrame()) return; // Only update the main frame document, nested frame document updates are not required @@ -1639,6 +2113,36 @@ void InspectorDOMAgent::frameDocumentUpdated(Frame* frame) setDocument(document); } +void InspectorDOMAgent::pseudoElementCreated(PseudoElement& pseudoElement) +{ + Element* parent = pseudoElement.hostElement(); + if (!parent) + return; + + int parentId = m_documentNodeToIdMap.get(parent); + if (!parentId) + return; + + pushChildNodesToFrontend(parentId, 1); + m_frontendDispatcher->pseudoElementAdded(parentId, buildObjectForNode(&pseudoElement, 0, &m_documentNodeToIdMap)); +} + +void InspectorDOMAgent::pseudoElementDestroyed(PseudoElement& pseudoElement) +{ + int pseudoElementId = m_documentNodeToIdMap.get(&pseudoElement); + if (!pseudoElementId) + return; + + // If a PseudoElement is bound, its parent element must have been bound. + Element* parent = pseudoElement.hostElement(); + ASSERT(parent); + int parentId = m_documentNodeToIdMap.get(parent); + ASSERT(parentId); + + unbind(&pseudoElement, &m_documentNodeToIdMap); + m_frontendDispatcher->pseudoElementRemoved(parentId, pseudoElementId); +} + Node* InspectorDOMAgent::nodeForPath(const String& path) { // The path is of form "1,HTML,2,BODY,1,DIV" @@ -1647,7 +2151,7 @@ Node* InspectorDOMAgent::nodeForPath(const String& path) Node* node = m_document.get(); Vector<String> pathTokens; - path.split(",", false, pathTokens); + path.split(',', false, pathTokens); if (!pathTokens.size()) return 0; for (size_t i = 0; i < pathTokens.size() - 1; i += 2) { @@ -1672,67 +2176,67 @@ Node* InspectorDOMAgent::nodeForPath(const String& path) Node* InspectorDOMAgent::nodeForObjectId(const String& objectId) { - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); - Deprecated::ScriptValue value = injectedScript.findObjectById(objectId); - return InspectorDOMAgent::scriptValueAsNode(value); + InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId); + if (injectedScript.hasNoValue()) + return nullptr; + + return scriptValueAsNode(injectedScript.findObjectById(objectId)); } -void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString* errorString, const String& path, int* nodeId) +void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString& errorString, const String& path, int* nodeId) { if (Node* node = nodeForPath(path)) *nodeId = pushNodePathToFrontend(node); else - *errorString = "No node with given path found"; + errorString = ASCIILiteral("No node with given path found"); } -void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString* errorString, BackendNodeId backendNodeId, int* nodeId) +void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString& errorString, BackendNodeId backendNodeId, int* nodeId) { - if (!m_backendIdToNode.contains(backendNodeId)) { - *errorString = "No node with given backend id found"; + auto iterator = m_backendIdToNode.find(backendNodeId); + if (iterator == m_backendIdToNode.end()) { + errorString = ASCIILiteral("No node with given backend id found"); return; } - Node* node = m_backendIdToNode.get(backendNodeId).first; - String nodeGroup = m_backendIdToNode.get(backendNodeId).second; + Node* node = iterator->value.first; + String nodeGroup = iterator->value.second; + *nodeId = pushNodePathToFrontend(node); - if (nodeGroup == "") { - m_backendIdToNode.remove(backendNodeId); + if (nodeGroup.isEmpty()) { + m_backendIdToNode.remove(iterator); + // FIXME: We really do the following only when nodeGroup is the empty string? Seems wrong. + ASSERT(m_nodeGroupToBackendIdMap.contains(nodeGroup)); m_nodeGroupToBackendIdMap.find(nodeGroup)->value.remove(node); } } -PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup) +RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup) { - Frame* frame = node->document().frame(); + auto* frame = node->document().frame(); if (!frame) - return 0; + return nullptr; - JSC::ExecState* scriptState = mainWorldExecState(frame); - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); + auto& state = *mainWorldExecState(frame); + auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state); if (injectedScript.hasNoValue()) - return 0; + return nullptr; - return injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(scriptState, node), objectGroup); + return injectedScript.wrapObject(nodeAsScriptValue(state, node), objectGroup); } -Node* InspectorDOMAgent::scriptValueAsNode(Deprecated::ScriptValue value) +Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value) { - if (!value.isObject() || value.isNull()) + if (!value || !value.isObject()) return nullptr; - - return toNode(value.jsValue()); + return JSNode::toWrapped(*value.getObject()->vm(), value.getObject()); } -Deprecated::ScriptValue InspectorDOMAgent::nodeAsScriptValue(JSC::ExecState* state, Node* node) +JSC::JSValue InspectorDOMAgent::nodeAsScriptValue(JSC::ExecState& state, Node* node) { - if (!shouldAllowAccessToNode(state, node)) - return Deprecated::ScriptValue(state->vm(), JSC::jsNull()); - - JSC::JSLockHolder lock(state); - return Deprecated::ScriptValue(state->vm(), toJS(state, deprecatedGlobalObjectForPrototype(state), node)); + JSC::JSLockHolder lock(&state); + return toJS(&state, deprecatedGlobalObjectForPrototype(&state), BindingSecurity::checkSecurityForNode(state, node)); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorDOMAgent.h b/Source/WebCore/inspector/InspectorDOMAgent.h index 1345bcb83..89bc75ee2 100644 --- a/Source/WebCore/inspector/InspectorDOMAgent.h +++ b/Source/WebCore/inspector/InspectorDOMAgent.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,50 +27,45 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorDOMAgent_h -#define InspectorDOMAgent_h +#pragma once #include "EventTarget.h" -#include "InspectorOverlay.h" #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include "RenderLayer.h" -#include "Timer.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <inspector/InspectorValues.h> -#include <wtf/Deque.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> #include <wtf/text/AtomicString.h> -namespace Deprecated { -class ScriptValue; -} - namespace Inspector { class InjectedScriptManager; } -namespace WebCore { +namespace JSC { +class ExecState; +class JSValue; +} -class ContainerNode; +namespace WebCore { + +class AccessibilityObject; class CharacterData; class DOMEditor; class Document; class Element; class Event; +class Exception; +class FloatQuad; +class Frame; class InspectorHistory; class InspectorOverlay; class InspectorPageAgent; class HitTestResult; -class HTMLElement; -class InstrumentingAgents; -class NameNodeMap; class Node; +class PseudoElement; class RevalidateStyleAttributeTask; class ShadowRoot; @@ -79,13 +74,11 @@ struct HighlightConfig; typedef String ErrorString; typedef int BackendNodeId; -#if ENABLE(INSPECTOR) - struct EventListenerInfo { - EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector) + EventListenerInfo(Node* node, const AtomicString& eventType, EventListenerVector&& eventListenerVector) : node(node) , eventType(eventType) - , eventListenerVector(eventListenerVector) + , eventListenerVector(WTFMove(eventListenerVector)) { } @@ -94,97 +87,103 @@ struct EventListenerInfo { const EventListenerVector eventListenerVector; }; -class InspectorDOMAgent : public InspectorAgentBase, public Inspector::InspectorDOMBackendDispatcherHandler { +class InspectorDOMAgent final : public InspectorAgentBase, public Inspector::DOMBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorDOMAgent); + WTF_MAKE_FAST_ALLOCATED; public: struct DOMListener { - virtual ~DOMListener() - { - } - virtual void didRemoveDocument(Document*) = 0; - virtual void didRemoveDOMNode(Node*) = 0; - virtual void didModifyDOMAttr(Element*) = 0; + virtual ~DOMListener() { } + virtual void didRemoveDOMNode(Node&, int nodeId) = 0; + virtual void didModifyDOMAttr(Element&) = 0; }; - InspectorDOMAgent(InstrumentingAgents*, InspectorPageAgent*, Inspector::InjectedScriptManager*, InspectorOverlay*); - ~InspectorDOMAgent(); + InspectorDOMAgent(WebAgentContext&, InspectorPageAgent*, InspectorOverlay*); + virtual ~InspectorDOMAgent(); - static String toErrorString(const ExceptionCode&); + static String toErrorString(ExceptionCode); + static String toErrorString(Exception&&); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; Vector<Document*> documents(); void reset(); // Methods called from the frontend for DOM nodes inspection. - virtual void querySelector(ErrorString*, int nodeId, const String& selectors, int* elementId) override; - virtual void querySelectorAll(ErrorString*, int nodeId, const String& selectors, RefPtr<Inspector::TypeBuilder::Array<int>>& result) override; - virtual void getDocument(ErrorString*, RefPtr<Inspector::TypeBuilder::DOM::Node>& root) override; - virtual void requestChildNodes(ErrorString*, int nodeId, const int* depth) override; - virtual void setAttributeValue(ErrorString*, int elementId, const String& name, const String& value) override; - virtual void setAttributesAsText(ErrorString*, int elementId, const String& text, const String* name) override; - virtual void removeAttribute(ErrorString*, int elementId, const String& name) override; - virtual void removeNode(ErrorString*, int nodeId) override; - virtual void setNodeName(ErrorString*, int nodeId, const String& name, int* newId) override; - virtual void getOuterHTML(ErrorString*, int nodeId, WTF::String* outerHTML) override; - virtual void setOuterHTML(ErrorString*, int nodeId, const String& outerHTML) override; - virtual void setNodeValue(ErrorString*, int nodeId, const String& value) override; - virtual void getEventListenersForNode(ErrorString*, int nodeId, const WTF::String* objectGroup, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::EventListener>>& listenersArray) override; - virtual void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, const RefPtr<Inspector::InspectorArray>* nodeIds, String* searchId, int* resultCount) override; - virtual void getSearchResults(ErrorString*, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::TypeBuilder::Array<int>>&) override; - virtual void discardSearchResults(ErrorString*, const String& searchId) override; - virtual void resolveNode(ErrorString*, int nodeId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) override; - virtual void getAttributes(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::Array<String>>& result) override; - virtual void setInspectModeEnabled(ErrorString*, bool enabled, const RefPtr<Inspector::InspectorObject>* highlightConfig) override; - virtual void requestNode(ErrorString*, const String& objectId, int* nodeId) override; - virtual void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId) override; - virtual void pushNodeByBackendIdToFrontend(ErrorString*, BackendNodeId, int* nodeId) override; - virtual void releaseBackendNodeIds(ErrorString*, const String& nodeGroup) override; - virtual void hideHighlight(ErrorString*) override; - virtual void highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<Inspector::InspectorObject>* color, const RefPtr<Inspector::InspectorObject>* outlineColor, const bool* usePageCoordinates) override; - virtual void highlightQuad(ErrorString*, const RefPtr<Inspector::InspectorArray>& quad, const RefPtr<Inspector::InspectorObject>* color, const RefPtr<Inspector::InspectorObject>* outlineColor, const bool* usePageCoordinates) override; - virtual void highlightNode(ErrorString*, const RefPtr<Inspector::InspectorObject>& highlightConfig, const int* nodeId, const String* objectId) override; - virtual void highlightFrame(ErrorString*, const String& frameId, const RefPtr<Inspector::InspectorObject>* color, const RefPtr<Inspector::InspectorObject>* outlineColor) override; - - virtual void moveTo(ErrorString*, int nodeId, int targetNodeId, const int* anchorNodeId, int* newNodeId) override; - virtual void undo(ErrorString*) override; - virtual void redo(ErrorString*) override; - virtual void markUndoableState(ErrorString*) override; - virtual void focus(ErrorString*, int nodeId) override; + void querySelector(ErrorString&, int nodeId, const String& selectors, int* elementId) override; + void querySelectorAll(ErrorString&, int nodeId, const String& selectors, RefPtr<Inspector::Protocol::Array<int>>& result) override; + void getDocument(ErrorString&, RefPtr<Inspector::Protocol::DOM::Node>& root) override; + void requestChildNodes(ErrorString&, int nodeId, const int* const depth) override; + void setAttributeValue(ErrorString&, int elementId, const String& name, const String& value) override; + void setAttributesAsText(ErrorString&, int elementId, const String& text, const String* const name) override; + void removeAttribute(ErrorString&, int elementId, const String& name) override; + void removeNode(ErrorString&, int nodeId) override; + void setNodeName(ErrorString&, int nodeId, const String& name, int* newId) override; + void getOuterHTML(ErrorString&, int nodeId, WTF::String* outerHTML) override; + void setOuterHTML(ErrorString&, int nodeId, const String& outerHTML) override; + void setNodeValue(ErrorString&, int nodeId, const String& value) override; + void getEventListenersForNode(ErrorString&, int nodeId, const WTF::String* const objectGroup, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>>& listenersArray) override; + void getAccessibilityPropertiesForNode(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::DOM::AccessibilityProperties>& axProperties) override; + void performSearch(ErrorString&, const String& whitespaceTrimmedQuery, const Inspector::InspectorArray* nodeIds, String* searchId, int* resultCount) override; + void getSearchResults(ErrorString&, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::Protocol::Array<int>>&) override; + void discardSearchResults(ErrorString&, const String& searchId) override; + void resolveNode(ErrorString&, int nodeId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result) override; + void getAttributes(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::Array<String>>& result) override; + void setInspectModeEnabled(ErrorString&, bool enabled, const Inspector::InspectorObject* highlightConfig) override; + void requestNode(ErrorString&, const String& objectId, int* nodeId) override; + void pushNodeByPathToFrontend(ErrorString&, const String& path, int* nodeId) override; + void pushNodeByBackendIdToFrontend(ErrorString&, BackendNodeId, int* nodeId) override; + void releaseBackendNodeIds(ErrorString&, const String& nodeGroup) override; + void hideHighlight(ErrorString&) override; + void highlightRect(ErrorString&, int x, int y, int width, int height, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* const usePageCoordinates) override; + void highlightQuad(ErrorString&, const Inspector::InspectorArray& quad, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* const usePageCoordinates) override; + void highlightSelector(ErrorString&, const Inspector::InspectorObject& highlightConfig, const String& selectorString, const String* const frameId) override; + void highlightNode(ErrorString&, const Inspector::InspectorObject& highlightConfig, const int* const nodeId, const String* const objectId) override; + void highlightFrame(ErrorString&, const String& frameId, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor) override; + + void moveTo(ErrorString&, int nodeId, int targetNodeId, const int* const anchorNodeId, int* newNodeId) override; + void undo(ErrorString&) override; + void redo(ErrorString&) override; + void markUndoableState(ErrorString&) override; + void focus(ErrorString&, int nodeId) override; void getEventListeners(Node*, Vector<EventListenerInfo>& listenersArray, bool includeAncestors); - // Methods called from the InspectorInstrumentation. + + // InspectorInstrumentation + void didInsertDOMNode(Node&); + void didRemoveDOMNode(Node&); + void willModifyDOMAttr(Element&, const AtomicString& oldValue, const AtomicString& newValue); + void didModifyDOMAttr(Element&, const AtomicString& name, const AtomicString& value); + void didRemoveDOMAttr(Element&, const AtomicString& name); + void characterDataModified(CharacterData&); + void didInvalidateStyleAttr(Node&); + void didPushShadowRoot(Element& host, ShadowRoot&); + void willPopShadowRoot(Element& host, ShadowRoot&); + void didChangeCustomElementState(Element&); + bool handleTouchEvent(Node&); + void didCommitLoad(Document*); + void frameDocumentUpdated(Frame&); + void pseudoElementCreated(PseudoElement&); + void pseudoElementDestroyed(PseudoElement&); + + // Callbacks that don't directly correspond to an instrumentation entry point. void setDocument(Document*); void releaseDanglingNodes(); - void mainFrameDOMContentLoaded(); - void didCommitLoad(Document*); - void didInsertDOMNode(Node*); - void didRemoveDOMNode(Node*); - void willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue); - void didModifyDOMAttr(Element*, const AtomicString& name, const AtomicString& value); - void didRemoveDOMAttr(Element*, const AtomicString& name); void styleAttributeInvalidated(const Vector<Element*>& elements); - void characterDataModified(CharacterData*); - void didInvalidateStyleAttr(Node*); - void didPushShadowRoot(Element* host, ShadowRoot*); - void willPopShadowRoot(Element* host, ShadowRoot*); - void frameDocumentUpdated(Frame*); - int pushNodeToFrontend(ErrorString*, int documentNodeId, Node*); + int pushNodeToFrontend(ErrorString&, int documentNodeId, Node*); Node* nodeForId(int nodeId); - int boundNodeId(Node*); + int boundNodeId(const Node*); void setDOMListener(DOMListener*); BackendNodeId backendNodeIdForNode(Node*, const String& nodeGroup); static String documentURLString(Document*); - PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup); + RefPtr<Inspector::Protocol::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup); bool handleMousePress(); - bool handleTouchEvent(Node*); void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); void inspect(Node*); void focusNode(); @@ -200,79 +199,80 @@ public: static Node* innerParentNode(Node*); static bool isWhitespace(Node*); - Node* assertNode(ErrorString*, int nodeId); - Element* assertElement(ErrorString*, int nodeId); - Document* assertDocument(ErrorString*, int nodeId); + Node* assertNode(ErrorString&, int nodeId); + Element* assertElement(ErrorString&, int nodeId); + Document* assertDocument(ErrorString&, int nodeId); - static Node* scriptValueAsNode(Deprecated::ScriptValue); - static Deprecated::ScriptValue nodeAsScriptValue(JSC::ExecState*, Node*); + static Node* scriptValueAsNode(JSC::JSValue); + static JSC::JSValue nodeAsScriptValue(JSC::ExecState&, Node*); // Methods called from other agents. InspectorPageAgent* pageAgent() { return m_pageAgent; } private: - void setSearchingForNode(ErrorString*, bool enabled, Inspector::InspectorObject* highlightConfig); - PassOwnPtr<HighlightConfig> highlightConfigFromInspectorObject(ErrorString*, Inspector::InspectorObject* highlightInspectorObject); + void highlightMousedOverNode(); + void setSearchingForNode(ErrorString&, bool enabled, const Inspector::InspectorObject* highlightConfig); + std::unique_ptr<HighlightConfig> highlightConfigFromInspectorObject(ErrorString&, const Inspector::InspectorObject* highlightInspectorObject); // Node-related methods. typedef HashMap<RefPtr<Node>, int> NodeToIdMap; int bind(Node*, NodeToIdMap*); void unbind(Node*, NodeToIdMap*); - Node* assertEditableNode(ErrorString*, int nodeId); - Element* assertEditableElement(ErrorString*, int nodeId); + Node* assertEditableNode(ErrorString&, int nodeId); + Element* assertEditableElement(ErrorString&, int nodeId); int pushNodePathToFrontend(Node*); void pushChildNodesToFrontend(int nodeId, int depth = 1); bool hasBreakpoint(Node*, int type); void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value); - void descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, PassRefPtr<Inspector::InspectorObject> description); - - PassRefPtr<Inspector::TypeBuilder::DOM::Node> buildObjectForNode(Node*, int depth, NodeToIdMap*); - PassRefPtr<Inspector::TypeBuilder::Array<String>> buildArrayForElementAttributes(Element*); - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); - PassRefPtr<Inspector::TypeBuilder::DOM::EventListener> buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*, const String* objectGroupId); + Ref<Inspector::Protocol::DOM::Node> buildObjectForNode(Node*, int depth, NodeToIdMap*); + Ref<Inspector::Protocol::Array<String>> buildArrayForElementAttributes(Element*); + Ref<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> buildArrayForPseudoElements(const Element&, NodeToIdMap* nodesMap); + Ref<Inspector::Protocol::DOM::EventListener> buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*, const String* objectGroupId); + RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> buildObjectForAccessibilityProperties(Node*); + void processAccessibilityChildren(RefPtr<AccessibilityObject>&&, RefPtr<Inspector::Protocol::Array<int>>&&); + Node* nodeForPath(const String& path); Node* nodeForObjectId(const String& objectId); void discardBindings(); - void innerHighlightQuad(PassOwnPtr<FloatQuad>, const RefPtr<Inspector::InspectorObject>* color, const RefPtr<Inspector::InspectorObject>* outlineColor, const bool* usePageCoordinates); + void innerHighlightQuad(std::unique_ptr<FloatQuad>, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* usePageCoordinates); - InspectorPageAgent* m_pageAgent; - Inspector::InjectedScriptManager* m_injectedScriptManager; - InspectorOverlay* m_overlay; - std::unique_ptr<Inspector::InspectorDOMFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorDOMBackendDispatcher> m_backendDispatcher; - DOMListener* m_domListener; + Inspector::InjectedScriptManager& m_injectedScriptManager; + std::unique_ptr<Inspector::DOMFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::DOMBackendDispatcher> m_backendDispatcher; + InspectorPageAgent* m_pageAgent { nullptr }; + + InspectorOverlay* m_overlay { nullptr }; + DOMListener* m_domListener { nullptr }; NodeToIdMap m_documentNodeToIdMap; typedef HashMap<RefPtr<Node>, BackendNodeId> NodeToBackendIdMap; HashMap<String, NodeToBackendIdMap> m_nodeGroupToBackendIdMap; // Owns node mappings for dangling nodes. - Vector<OwnPtr<NodeToIdMap>> m_danglingNodeToIdMaps; + Vector<std::unique_ptr<NodeToIdMap>> m_danglingNodeToIdMaps; HashMap<int, Node*> m_idToNode; HashMap<int, NodeToIdMap*> m_idToNodesMap; HashSet<int> m_childrenRequested; HashMap<BackendNodeId, std::pair<Node*, String>> m_backendIdToNode; - int m_lastNodeId; - BackendNodeId m_lastBackendNodeId; + int m_lastNodeId { 1 }; + BackendNodeId m_lastBackendNodeId { -1 }; RefPtr<Document> m_document; typedef HashMap<String, Vector<RefPtr<Node>>> SearchResults; SearchResults m_searchResults; - OwnPtr<RevalidateStyleAttributeTask> m_revalidateStyleAttrTask; + std::unique_ptr<RevalidateStyleAttributeTask> m_revalidateStyleAttrTask; RefPtr<Node> m_nodeToFocus; - bool m_searchingForNode; - OwnPtr<HighlightConfig> m_inspectModeHighlightConfig; - OwnPtr<InspectorHistory> m_history; - OwnPtr<DOMEditor> m_domEditor; - bool m_suppressAttributeModifiedEvent; - bool m_documentRequested; + RefPtr<Node> m_mousedOverNode; + std::unique_ptr<HighlightConfig> m_inspectModeHighlightConfig; + std::unique_ptr<InspectorHistory> m_history; + std::unique_ptr<DOMEditor> m_domEditor; + bool m_searchingForNode { false }; + bool m_suppressAttributeModifiedEvent { false }; + bool m_documentRequested { false }; }; -#endif // ENABLE(INSPECTOR) - } // namespace WebCore - -#endif // !defined(InspectorDOMAgent_h) diff --git a/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp index 4a4b38f2b..00408a164 100644 --- a/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp +++ b/Source/WebCore/inspector/InspectorDOMDebuggerAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,15 +32,11 @@ #include "config.h" #include "InspectorDOMDebuggerAgent.h" -#if ENABLE(INSPECTOR) - #include "HTMLElement.h" #include "InspectorDOMAgent.h" -#include "InspectorInstrumentation.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" +#include <inspector/InspectorFrontendDispatchers.h> #include <inspector/InspectorValues.h> -#include <wtf/text/WTFString.h> namespace { @@ -62,12 +59,11 @@ using namespace Inspector; namespace WebCore { -InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent) - : InspectorAgentBase(ASCIILiteral("DOMDebugger"), instrumentingAgents) +InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(WebAgentContext& context, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent) + : InspectorAgentBase(ASCIILiteral("DOMDebugger"), context) + , m_backendDispatcher(Inspector::DOMDebuggerBackendDispatcher::create(context.backendDispatcher, this)) , m_domAgent(domAgent) , m_debuggerAgent(debuggerAgent) - , m_pauseInNextEventListener(false) - , m_pauseOnAllXHRsEnabled(false) { m_debuggerAgent->setListener(this); } @@ -75,13 +71,13 @@ InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(InstrumentingAgents* instru InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent() { ASSERT(!m_debuggerAgent); - ASSERT(!m_instrumentingAgents->inspectorDOMDebuggerAgent()); + ASSERT(!m_instrumentingAgents.inspectorDOMDebuggerAgent()); } // Browser debugger agent enabled only when JS debugger is enabled. void InspectorDOMDebuggerAgent::debuggerWasEnabled() { - m_instrumentingAgents->setInspectorDOMDebuggerAgent(this); + m_instrumentingAgents.setInspectorDOMDebuggerAgent(this); } void InspectorDOMDebuggerAgent::debuggerWasDisabled() @@ -89,31 +85,18 @@ void InspectorDOMDebuggerAgent::debuggerWasDisabled() disable(); } -void InspectorDOMDebuggerAgent::stepInto() -{ - m_pauseInNextEventListener = true; -} - -void InspectorDOMDebuggerAgent::didPause() -{ - m_pauseInNextEventListener = false; -} - void InspectorDOMDebuggerAgent::disable() { - m_instrumentingAgents->setInspectorDOMDebuggerAgent(nullptr); + m_instrumentingAgents.setInspectorDOMDebuggerAgent(nullptr); clear(); } -void InspectorDOMDebuggerAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, InspectorBackendDispatcher* backendDispatcher) +void InspectorDOMDebuggerAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_backendDispatcher = InspectorDOMDebuggerBackendDispatcher::create(backendDispatcher, this); } -void InspectorDOMDebuggerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorDOMDebuggerAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_backendDispatcher.clear(); - disable(); } @@ -128,71 +111,71 @@ void InspectorDOMDebuggerAgent::discardBindings() m_domBreakpoints.clear(); } -void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString& error, const String& eventName) { setBreakpoint(error, String(listenerEventCategoryType) + eventName); } -void InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(ErrorString& error, const String& eventName) { setBreakpoint(error, String(instrumentationEventCategoryType) + eventName); } -void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString& error, const String& eventName) { if (eventName.isEmpty()) { - *error = "Event name is empty"; + error = ASCIILiteral("Event name is empty"); return; } m_eventListenerBreakpoints.add(eventName); } -void InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(ErrorString& error, const String& eventName) { removeBreakpoint(error, String(listenerEventCategoryType) + eventName); } -void InspectorDOMDebuggerAgent::removeInstrumentationBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::removeInstrumentationBreakpoint(ErrorString& error, const String& eventName) { removeBreakpoint(error, String(instrumentationEventCategoryType) + eventName); } -void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString* error, const String& eventName) +void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString& error, const String& eventName) { if (eventName.isEmpty()) { - *error = "Event name is empty"; + error = ASCIILiteral("Event name is empty"); return; } m_eventListenerBreakpoints.remove(eventName); } -void InspectorDOMDebuggerAgent::didInvalidateStyleAttr(Node* node) +void InspectorDOMDebuggerAgent::didInvalidateStyleAttr(Node& node) { - if (hasBreakpoint(node, AttributeModified)) { - RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (hasBreakpoint(&node, AttributeModified)) { + Ref<InspectorObject> eventData = InspectorObject::create(); descriptionForDOMEvent(node, AttributeModified, false, eventData.get()); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::DOM, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::DOM, WTFMove(eventData)); } } -void InspectorDOMDebuggerAgent::didInsertDOMNode(Node* node) +void InspectorDOMDebuggerAgent::didInsertDOMNode(Node& node) { if (m_domBreakpoints.size()) { - uint32_t mask = m_domBreakpoints.get(InspectorDOMAgent::innerParentNode(node)); + uint32_t mask = m_domBreakpoints.get(InspectorDOMAgent::innerParentNode(&node)); uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask; if (inheritableTypesMask) - updateSubtreeBreakpoints(node, inheritableTypesMask, true); + updateSubtreeBreakpoints(&node, inheritableTypesMask, true); } } -void InspectorDOMDebuggerAgent::didRemoveDOMNode(Node* node) +void InspectorDOMDebuggerAgent::didRemoveDOMNode(Node& node) { if (m_domBreakpoints.size()) { // Remove subtree breakpoints. - m_domBreakpoints.remove(node); - Vector<Node*> stack(1, InspectorDOMAgent::innerFirstChild(node)); + m_domBreakpoints.remove(&node); + Vector<Node*> stack(1, InspectorDOMAgent::innerFirstChild(&node)); do { Node* node = stack.last(); stack.removeLast(); @@ -205,7 +188,7 @@ void InspectorDOMDebuggerAgent::didRemoveDOMNode(Node* node) } } -static int domTypeForName(ErrorString* errorString, const String& typeString) +static int domTypeForName(ErrorString& errorString, const String& typeString) { if (typeString == "subtree-modified") return SubtreeModified; @@ -213,22 +196,22 @@ static int domTypeForName(ErrorString* errorString, const String& typeString) return AttributeModified; if (typeString == "node-removed") return NodeRemoved; - *errorString = makeString("Unknown DOM breakpoint type: ", typeString); + errorString = makeString("Unknown DOM breakpoint type: ", typeString); return -1; } static String domTypeName(int type) { switch (type) { - case SubtreeModified: return "subtree-modified"; - case AttributeModified: return "attribute-modified"; - case NodeRemoved: return "node-removed"; + case SubtreeModified: return ASCIILiteral("subtree-modified"); + case AttributeModified: return ASCIILiteral("attribute-modified"); + case NodeRemoved: return ASCIILiteral("node-removed"); default: break; } - return ""; + return emptyString(); } -void InspectorDOMDebuggerAgent::setDOMBreakpoint(ErrorString* errorString, int nodeId, const String& typeString) +void InspectorDOMDebuggerAgent::setDOMBreakpoint(ErrorString& errorString, int nodeId, const String& typeString) { Node* node = m_domAgent->assertNode(errorString, nodeId); if (!node) @@ -246,7 +229,7 @@ void InspectorDOMDebuggerAgent::setDOMBreakpoint(ErrorString* errorString, int n } } -void InspectorDOMDebuggerAgent::removeDOMBreakpoint(ErrorString* errorString, int nodeId, const String& typeString) +void InspectorDOMDebuggerAgent::removeDOMBreakpoint(ErrorString& errorString, int nodeId, const String& typeString) { Node* node = m_domAgent->assertNode(errorString, nodeId); if (!node) @@ -268,52 +251,52 @@ void InspectorDOMDebuggerAgent::removeDOMBreakpoint(ErrorString* errorString, in } } -void InspectorDOMDebuggerAgent::willInsertDOMNode(Node* parent) +void InspectorDOMDebuggerAgent::willInsertDOMNode(Node& parent) { - if (hasBreakpoint(parent, SubtreeModified)) { - RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (hasBreakpoint(&parent, SubtreeModified)) { + Ref<InspectorObject> eventData = InspectorObject::create(); descriptionForDOMEvent(parent, SubtreeModified, true, eventData.get()); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::DOM, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::DOM, WTFMove(eventData)); } } -void InspectorDOMDebuggerAgent::willRemoveDOMNode(Node* node) +void InspectorDOMDebuggerAgent::willRemoveDOMNode(Node& node) { - Node* parentNode = InspectorDOMAgent::innerParentNode(node); - if (hasBreakpoint(node, NodeRemoved)) { - RefPtr<InspectorObject> eventData = InspectorObject::create(); + Node* parentNode = InspectorDOMAgent::innerParentNode(&node); + if (hasBreakpoint(&node, NodeRemoved)) { + Ref<InspectorObject> eventData = InspectorObject::create(); descriptionForDOMEvent(node, NodeRemoved, false, eventData.get()); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::DOM, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::DOM, WTFMove(eventData)); } else if (parentNode && hasBreakpoint(parentNode, SubtreeModified)) { - RefPtr<InspectorObject> eventData = InspectorObject::create(); + Ref<InspectorObject> eventData = InspectorObject::create(); descriptionForDOMEvent(node, SubtreeModified, false, eventData.get()); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::DOM, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::DOM, WTFMove(eventData)); } } -void InspectorDOMDebuggerAgent::willModifyDOMAttr(Element* element) +void InspectorDOMDebuggerAgent::willModifyDOMAttr(Element& element) { - if (hasBreakpoint(element, AttributeModified)) { - RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (hasBreakpoint(&element, AttributeModified)) { + Ref<InspectorObject> eventData = InspectorObject::create(); descriptionForDOMEvent(element, AttributeModified, false, eventData.get()); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::DOM, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::DOM, WTFMove(eventData)); } } -void InspectorDOMDebuggerAgent::descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, InspectorObject* description) +void InspectorDOMDebuggerAgent::descriptionForDOMEvent(Node& target, int breakpointType, bool insertion, InspectorObject& description) { - ASSERT(hasBreakpoint(target, breakpointType)); + ASSERT(hasBreakpoint(&target, breakpointType)); - Node* breakpointOwner = target; + Node* breakpointOwner = ⌖ if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) { // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint. // Target node may be unknown to frontend, so we need to push it first. - RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> targetNodeObject = m_domAgent->resolveNode(target, InspectorDebuggerAgent::backtraceObjectGroup); - description->setValue("targetNode", targetNodeObject); + RefPtr<Inspector::Protocol::Runtime::RemoteObject> targetNodeObject = m_domAgent->resolveNode(&target, InspectorDebuggerAgent::backtraceObjectGroup); + description.setValue("targetNode", targetNodeObject); // Find breakpoint owner node. if (!insertion) - breakpointOwner = InspectorDOMAgent::innerParentNode(target); + breakpointOwner = InspectorDOMAgent::innerParentNode(&target); ASSERT(breakpointOwner); while (!(m_domBreakpoints.get(breakpointOwner) & (1 << breakpointType))) { Node* parentNode = InspectorDOMAgent::innerParentNode(breakpointOwner); @@ -323,13 +306,13 @@ void InspectorDOMDebuggerAgent::descriptionForDOMEvent(Node* target, int breakpo } if (breakpointType == SubtreeModified) - description->setBoolean("insertion", insertion); + description.setBoolean("insertion", insertion); } int breakpointOwnerNodeId = m_domAgent->boundNodeId(breakpointOwner); ASSERT(breakpointOwnerNodeId); - description->setNumber("nodeId", breakpointOwnerNodeId); - description->setString("type", domTypeName(breakpointType)); + description.setInteger("nodeId", breakpointOwnerNodeId); + description.setString("type", domTypeName(breakpointType)); } bool InspectorDOMDebuggerAgent::hasBreakpoint(Node* node, int type) @@ -360,22 +343,21 @@ void InspectorDOMDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_t ro void InspectorDOMDebuggerAgent::pauseOnNativeEventIfNeeded(bool isDOMEvent, const String& eventName, bool synchronous) { String fullEventName = (isDOMEvent ? listenerEventCategoryType : instrumentationEventCategoryType) + eventName; - if (m_pauseInNextEventListener) - m_pauseInNextEventListener = false; - else { - if (!m_eventListenerBreakpoints.contains(fullEventName)) - return; - } - RefPtr<InspectorObject> eventData = InspectorObject::create(); - eventData->setString("eventName", fullEventName); + bool shouldPause = m_debuggerAgent->pauseOnNextStatementEnabled() || m_eventListenerBreakpoints.contains(fullEventName); + if (!shouldPause) + return; + + Ref<InspectorObject> eventData = InspectorObject::create(); + eventData->setString(ASCIILiteral("eventName"), fullEventName); + if (synchronous) - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::EventListener, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::EventListener, WTFMove(eventData)); else - m_debuggerAgent->schedulePauseOnNextStatement(InspectorDebuggerFrontendDispatcher::Reason::EventListener, eventData.release()); + m_debuggerAgent->schedulePauseOnNextStatement(Inspector::DebuggerFrontendDispatcher::Reason::EventListener, WTFMove(eventData)); } -void InspectorDOMDebuggerAgent::setXHRBreakpoint(ErrorString*, const String& url) +void InspectorDOMDebuggerAgent::setXHRBreakpoint(ErrorString&, const String& url) { if (url.isEmpty()) { m_pauseOnAllXHRsEnabled = true; @@ -385,7 +367,7 @@ void InspectorDOMDebuggerAgent::setXHRBreakpoint(ErrorString*, const String& url m_xhrBreakpoints.add(url); } -void InspectorDOMDebuggerAgent::removeXHRBreakpoint(ErrorString*, const String& url) +void InspectorDOMDebuggerAgent::removeXHRBreakpoint(ErrorString&, const String& url) { if (url.isEmpty()) { m_pauseOnAllXHRsEnabled = false; @@ -399,11 +381,11 @@ void InspectorDOMDebuggerAgent::willSendXMLHttpRequest(const String& url) { String breakpointURL; if (m_pauseOnAllXHRsEnabled) - breakpointURL = ""; + breakpointURL = emptyString(); else { - for (auto it = m_xhrBreakpoints.begin(), end = m_xhrBreakpoints.end(); it != end; ++it) { - if (url.contains(*it)) { - breakpointURL = *it; + for (auto& breakpoint : m_xhrBreakpoints) { + if (url.contains(breakpoint)) { + breakpointURL = breakpoint; break; } } @@ -412,18 +394,15 @@ void InspectorDOMDebuggerAgent::willSendXMLHttpRequest(const String& url) if (breakpointURL.isNull()) return; - RefPtr<InspectorObject> eventData = InspectorObject::create(); + Ref<InspectorObject> eventData = InspectorObject::create(); eventData->setString("breakpointURL", breakpointURL); eventData->setString("url", url); - m_debuggerAgent->breakProgram(InspectorDebuggerFrontendDispatcher::Reason::XHR, eventData.release()); + m_debuggerAgent->breakProgram(Inspector::DebuggerFrontendDispatcher::Reason::XHR, WTFMove(eventData)); } void InspectorDOMDebuggerAgent::clear() { m_domBreakpoints.clear(); - m_pauseInNextEventListener = false; } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h b/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h index ebe26650a..c10979577 100644 --- a/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h +++ b/Source/WebCore/inspector/InspectorDOMDebuggerAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,17 +29,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorDOMDebuggerAgent_h -#define InspectorDOMDebuggerAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" +#include <inspector/InspectorBackendDispatchers.h> #include <inspector/agents/InspectorDebuggerAgent.h> #include <wtf/HashMap.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/RefCounted.h> #include <wtf/text/WTFString.h> namespace Inspector { @@ -49,70 +45,64 @@ namespace WebCore { class Element; class InspectorDOMAgent; -class InstrumentingAgents; class Node; typedef String ErrorString; -class InspectorDOMDebuggerAgent : public InspectorAgentBase, public Inspector::InspectorDebuggerAgent::Listener, public Inspector::InspectorDOMDebuggerBackendDispatcherHandler { +class InspectorDOMDebuggerAgent final : public InspectorAgentBase, public Inspector::InspectorDebuggerAgent::Listener, public Inspector::DOMDebuggerBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorDOMDebuggerAgent); + WTF_MAKE_FAST_ALLOCATED; public: - InspectorDOMDebuggerAgent(InstrumentingAgents*, InspectorDOMAgent*, Inspector::InspectorDebuggerAgent*); + InspectorDOMDebuggerAgent(WebAgentContext&, InspectorDOMAgent*, Inspector::InspectorDebuggerAgent*); virtual ~InspectorDOMDebuggerAgent(); // DOMDebugger API - virtual void setXHRBreakpoint(ErrorString*, const String& url) override; - virtual void removeXHRBreakpoint(ErrorString*, const String& url) override; - virtual void setEventListenerBreakpoint(ErrorString*, const String& eventName) override; - virtual void removeEventListenerBreakpoint(ErrorString*, const String& eventName) override; - virtual void setInstrumentationBreakpoint(ErrorString*, const String& eventName) override; - virtual void removeInstrumentationBreakpoint(ErrorString*, const String& eventName) override; - virtual void setDOMBreakpoint(ErrorString*, int nodeId, const String& type) override; - virtual void removeDOMBreakpoint(ErrorString*, int nodeId, const String& type) override; - - // InspectorInstrumentation API - void willInsertDOMNode(Node* parent); - void didInvalidateStyleAttr(Node*); - void didInsertDOMNode(Node*); - void willRemoveDOMNode(Node*); - void didRemoveDOMNode(Node*); - void willModifyDOMAttr(Element*); + void setXHRBreakpoint(ErrorString&, const String& url) override; + void removeXHRBreakpoint(ErrorString&, const String& url) override; + void setEventListenerBreakpoint(ErrorString&, const String& eventName) override; + void removeEventListenerBreakpoint(ErrorString&, const String& eventName) override; + void setInstrumentationBreakpoint(ErrorString&, const String& eventName) override; + void removeInstrumentationBreakpoint(ErrorString&, const String& eventName) override; + void setDOMBreakpoint(ErrorString&, int nodeId, const String& type) override; + void removeDOMBreakpoint(ErrorString&, int nodeId, const String& type) override; + + // InspectorInstrumentation + void willInsertDOMNode(Node& parent); + void didInvalidateStyleAttr(Node&); + void didInsertDOMNode(Node&); + void willRemoveDOMNode(Node&); + void didRemoveDOMNode(Node&); + void willModifyDOMAttr(Element&); void willSendXMLHttpRequest(const String& url); void pauseOnNativeEventIfNeeded(bool isDOMEvent, const String& eventName, bool synchronous); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - virtual void discardAgent() override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; + void discardAgent() override; private: // Inspector::InspectorDebuggerAgent::Listener implementation. - virtual void debuggerWasEnabled() override; - virtual void debuggerWasDisabled() override; - virtual void stepInto() override; - virtual void didPause() override; + void debuggerWasEnabled() override; + void debuggerWasDisabled() override; void disable(); - void descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, Inspector::InspectorObject* description); + void descriptionForDOMEvent(Node& target, int breakpointType, bool insertion, Inspector::InspectorObject& description); void updateSubtreeBreakpoints(Node*, uint32_t rootMask, bool set); bool hasBreakpoint(Node*, int type); void discardBindings(); - void setBreakpoint(ErrorString*, const String& eventName); - void removeBreakpoint(ErrorString*, const String& eventName); + void setBreakpoint(ErrorString&, const String& eventName); + void removeBreakpoint(ErrorString&, const String& eventName); void clear(); - InspectorDOMAgent* m_domAgent; - Inspector::InspectorDebuggerAgent* m_debuggerAgent; - RefPtr<Inspector::InspectorDOMDebuggerBackendDispatcher> m_backendDispatcher; + RefPtr<Inspector::DOMDebuggerBackendDispatcher> m_backendDispatcher; + InspectorDOMAgent* m_domAgent { nullptr }; + Inspector::InspectorDebuggerAgent* m_debuggerAgent { nullptr }; + HashMap<Node*, uint32_t> m_domBreakpoints; HashSet<String> m_eventListenerBreakpoints; HashSet<String> m_xhrBreakpoints; - bool m_pauseInNextEventListener; - bool m_pauseOnAllXHRsEnabled; + bool m_pauseOnAllXHRsEnabled { false }; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorDOMDebuggerAgent_h) diff --git a/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp b/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp index 25c6fc071..611480cd3 100644 --- a/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp +++ b/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. * Copyright (C) 2013 Samsung Electronics. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -11,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -28,9 +29,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorDOMStorageAgent.h" #include "DOMWindow.h" @@ -40,106 +38,101 @@ #include "ExceptionCodeDescription.h" #include "Frame.h" #include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" #include "Page.h" -#include "PageGroup.h" #include "SecurityOrigin.h" +#include "SecurityOriginData.h" #include "Storage.h" -#include "StorageArea.h" #include "StorageNamespace.h" +#include "StorageNamespaceProvider.h" +#include "StorageType.h" #include "VoidCallback.h" +#include <inspector/InspectorFrontendDispatchers.h> #include <inspector/InspectorValues.h> -#include <wtf/Vector.h> using namespace Inspector; namespace WebCore { -InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent) - : InspectorAgentBase(ASCIILiteral("DOMStorage"), instrumentingAgents) +InspectorDOMStorageAgent::InspectorDOMStorageAgent(WebAgentContext& context, InspectorPageAgent* pageAgent) + : InspectorAgentBase(ASCIILiteral("DOMStorage"), context) + , m_frontendDispatcher(std::make_unique<Inspector::DOMStorageFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::DOMStorageBackendDispatcher::create(context.backendDispatcher, this)) , m_pageAgent(pageAgent) - , m_enabled(false) { - m_instrumentingAgents->setInspectorDOMStorageAgent(this); + m_instrumentingAgents.setInspectorDOMStorageAgent(this); } InspectorDOMStorageAgent::~InspectorDOMStorageAgent() { - m_instrumentingAgents->setInspectorDOMStorageAgent(nullptr); - m_instrumentingAgents = nullptr; + m_instrumentingAgents.setInspectorDOMStorageAgent(nullptr); } -void InspectorDOMStorageAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorDOMStorageAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorDOMStorageFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorDOMStorageBackendDispatcher::create(backendDispatcher, this); } -void InspectorDOMStorageAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorDOMStorageAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - disable(nullptr); + ErrorString unused; + disable(unused); } -void InspectorDOMStorageAgent::enable(ErrorString*) +void InspectorDOMStorageAgent::enable(ErrorString&) { m_enabled = true; } -void InspectorDOMStorageAgent::disable(ErrorString*) +void InspectorDOMStorageAgent::disable(ErrorString&) { m_enabled = false; } -void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>>& items) +void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString& errorString, const InspectorObject& storageId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Array<String>>>& items) { Frame* frame; RefPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame); if (!storageArea) { - if (errorString) - *errorString = "No StorageArea for given storageId"; + errorString = ASCIILiteral("No StorageArea for given storageId"); return; } - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>> storageItems = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>::create(); + auto storageItems = Inspector::Protocol::Array<Inspector::Protocol::Array<String>>::create(); for (unsigned i = 0; i < storageArea->length(); ++i) { String key = storageArea->key(i); String value = storageArea->item(key); - RefPtr<Inspector::TypeBuilder::Array<String>> entry = Inspector::TypeBuilder::Array<String>::create(); + auto entry = Inspector::Protocol::Array<String>::create(); entry->addItem(key); entry->addItem(value); - storageItems->addItem(entry.release()); + storageItems->addItem(WTFMove(entry)); } - items = storageItems.release(); + items = WTFMove(storageItems); } -void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key, const String& value) +void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString& errorString, const InspectorObject& storageId, const String& key, const String& value) { Frame* frame; - RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame); + RefPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame); if (!storageArea) { - *errorString = "Storage not found"; + errorString = ASCIILiteral("Storage not found"); return; } bool quotaException = false; storageArea->setItem(frame, key, value, quotaException); if (quotaException) - *errorString = ExceptionCodeDescription(QUOTA_EXCEEDED_ERR).name; + errorString = ExceptionCodeDescription(QUOTA_EXCEEDED_ERR).name; } -void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, const String& key) +void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString& errorString, const InspectorObject& storageId, const String& key) { Frame* frame; - RefPtr<StorageArea> storageArea = findStorageArea(nullptr, storageId, frame); + RefPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame); if (!storageArea) { - *errorString = "Storage not found"; + errorString = ASCIILiteral("Storage not found"); return; } @@ -153,24 +146,25 @@ String InspectorDOMStorageAgent::storageId(Storage* storage) ASSERT(document); DOMWindow* window = document->domWindow(); ASSERT(window); - RefPtr<SecurityOrigin> securityOrigin = document->securityOrigin(); + Ref<SecurityOrigin> securityOrigin = document->securityOrigin(); bool isLocalStorage = window->optionalLocalStorage() == storage; - return storageId(securityOrigin.get(), isLocalStorage)->toJSONString(); + return storageId(securityOrigin.ptr(), isLocalStorage)->toJSONString(); } -PassRefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage) +RefPtr<Inspector::Protocol::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage) { - return Inspector::TypeBuilder::DOMStorage::StorageId::create() + return Inspector::Protocol::DOMStorage::StorageId::create() .setSecurityOrigin(securityOrigin->toRawString()) - .setIsLocalStorage(isLocalStorage).release(); + .setIsLocalStorage(isLocalStorage) + .release(); } -void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page*) +void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin) { - if (!m_frontendDispatcher || !m_enabled) + if (!m_enabled) return; - RefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> id = storageId(securityOrigin, storageType == LocalStorage); + RefPtr<Inspector::Protocol::DOMStorage::StorageId> id = storageId(securityOrigin, storageType == StorageType::Local); if (key.isNull()) m_frontendDispatcher->domStorageItemsCleared(id); @@ -182,33 +176,28 @@ void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, con m_frontendDispatcher->domStorageItemUpdated(id, key, oldValue, newValue); } -PassRefPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<InspectorObject>& storageId, Frame*& targetFrame) +RefPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString& errorString, const InspectorObject& storageId, Frame*& targetFrame) { String securityOrigin; bool isLocalStorage = false; - bool success = storageId->getString("securityOrigin", &securityOrigin); + bool success = storageId.getString(ASCIILiteral("securityOrigin"), securityOrigin); if (success) - success = storageId->getBoolean("isLocalStorage", &isLocalStorage); + success = storageId.getBoolean(ASCIILiteral("isLocalStorage"), isLocalStorage); if (!success) { - if (errorString) - *errorString = "Invalid storageId format"; + errorString = ASCIILiteral("Invalid storageId format"); targetFrame = nullptr; return nullptr; } targetFrame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); if (!targetFrame) { - if (errorString) - *errorString = "Frame not found for the given security origin"; + errorString = ASCIILiteral("Frame not found for the given security origin"); return nullptr; } - Page* page = m_pageAgent->page(); - if (isLocalStorage) - return page->group().localStorage()->storageArea(targetFrame->document()->securityOrigin()); - return page->sessionStorage()->storageArea(targetFrame->document()->securityOrigin()); + if (!isLocalStorage) + return m_pageAgent->page().sessionStorage()->storageArea(SecurityOriginData::fromSecurityOrigin(targetFrame->document()->securityOrigin())); + return m_pageAgent->page().storageNamespaceProvider().localStorageArea(*targetFrame->document()); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorDOMStorageAgent.h b/Source/WebCore/inspector/InspectorDOMStorageAgent.h index 5ad2b7e11..7a96bf5e3 100644 --- a/Source/WebCore/inspector/InspectorDOMStorageAgent.h +++ b/Source/WebCore/inspector/InspectorDOMStorageAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,63 +27,58 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorDOMStorageAgent_h -#define InspectorDOMStorageAgent_h +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" #include "StorageArea.h" -#include <wtf/HashMap.h> -#include <wtf/PassOwnPtr.h> +#include <inspector/InspectorBackendDispatchers.h> #include <wtf/text/WTFString.h> namespace Inspector { -class InspectorArray; -class InspectorDOMStorageFrontendDispatcher; +class DOMStorageFrontendDispatcher; } namespace WebCore { class Frame; class InspectorPageAgent; -class InstrumentingAgents; class Page; class SecurityOrigin; class Storage; typedef String ErrorString; -class InspectorDOMStorageAgent : public InspectorAgentBase, public Inspector::InspectorDOMStorageBackendDispatcherHandler { +class InspectorDOMStorageAgent final : public InspectorAgentBase, public Inspector::DOMStorageBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; public: - InspectorDOMStorageAgent(InstrumentingAgents*, InspectorPageAgent*); - ~InspectorDOMStorageAgent(); + InspectorDOMStorageAgent(WebAgentContext&, InspectorPageAgent*); + virtual ~InspectorDOMStorageAgent(); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; // Called from the front-end. - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void getDOMStorageItems(ErrorString*, const RefPtr<Inspector::InspectorObject>& storageId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Array<String>>>& items) override; - virtual void setDOMStorageItem(ErrorString*, const RefPtr<Inspector::InspectorObject>& storageId, const String& key, const String& value) override; - virtual void removeDOMStorageItem(ErrorString*, const RefPtr<Inspector::InspectorObject>& storageId, const String& key) override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void getDOMStorageItems(ErrorString&, const Inspector::InspectorObject& storageId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Array<String>>>& items) override; + void setDOMStorageItem(ErrorString&, const Inspector::InspectorObject& storageId, const String& key, const String& value) override; + void removeDOMStorageItem(ErrorString&, const Inspector::InspectorObject& storageId, const String& key) override; // Called from the injected script. String storageId(Storage*); - PassRefPtr<Inspector::TypeBuilder::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage); + RefPtr<Inspector::Protocol::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage); - // Called from InspectorInstrumentation - void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*, Page*); + // InspectorInstrumentation + void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*); private: - PassRefPtr<StorageArea> findStorageArea(ErrorString*, const RefPtr<Inspector::InspectorObject>&, Frame*&); + RefPtr<StorageArea> findStorageArea(ErrorString&, const Inspector::InspectorObject&, Frame*&); - InspectorPageAgent* m_pageAgent; - std::unique_ptr<Inspector::InspectorDOMStorageFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorDOMStorageBackendDispatcher> m_backendDispatcher; - bool m_enabled; + std::unique_ptr<Inspector::DOMStorageFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::DOMStorageBackendDispatcher> m_backendDispatcher; + InspectorPageAgent* m_pageAgent { nullptr }; + + bool m_enabled { false }; }; } // namespace WebCore - -#endif // !defined(InspectorDOMStorageAgent_h) diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp index 2861ed570..509018617 100644 --- a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp +++ b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,16 +28,10 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE) - #include "InspectorDatabaseAgent.h" #include "Database.h" -#include "ExceptionCode.h" -#include "ExceptionCodePlaceholder.h" #include "InspectorDatabaseResource.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" #include "SQLError.h" #include "SQLResultSet.h" @@ -48,142 +43,137 @@ #include "SQLTransactionErrorCallback.h" #include "SQLValue.h" #include "VoidCallback.h" +#include <inspector/InspectorFrontendRouter.h> #include <inspector/InspectorValues.h> #include <wtf/Vector.h> -typedef Inspector::InspectorDatabaseBackendDispatcherHandler::ExecuteSQLCallback ExecuteSQLCallback; - using namespace Inspector; namespace WebCore { +using ExecuteSQLCallback = Inspector::DatabaseBackendDispatcherHandler::ExecuteSQLCallback; + namespace { -void reportTransactionFailed(ExecuteSQLCallback* requestCallback, SQLError* error) +void reportTransactionFailed(ExecuteSQLCallback& requestCallback, SQLError* error) { - RefPtr<Inspector::TypeBuilder::Database::Error> errorObject = Inspector::TypeBuilder::Database::Error::create() + auto errorObject = Inspector::Protocol::Database::Error::create() .setMessage(error->message()) - .setCode(error->code()); - requestCallback->sendSuccess(nullptr, nullptr, errorObject.release()); + .setCode(error->code()) + .release(); + requestCallback.sendSuccess(nullptr, nullptr, WTFMove(errorObject)); } -class StatementCallback : public SQLStatementCallback { +class StatementCallback final : public SQLStatementCallback { public: - static PassRefPtr<StatementCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback) + static Ref<StatementCallback> create(Ref<ExecuteSQLCallback>&& requestCallback) { - return adoptRef(new StatementCallback(requestCallback)); + return adoptRef(*new StatementCallback(WTFMove(requestCallback))); } - virtual ~StatementCallback() { } +private: + StatementCallback(Ref<ExecuteSQLCallback>&& requestCallback) + : m_requestCallback(WTFMove(requestCallback)) { } - virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet) override + bool handleEvent(SQLTransaction*, SQLResultSet* resultSet) final { - SQLResultSetRowList* rowList = resultSet->rows(); - - RefPtr<Inspector::TypeBuilder::Array<String>> columnNames = Inspector::TypeBuilder::Array<String>::create(); - const Vector<String>& columns = rowList->columnNames(); - for (size_t i = 0; i < columns.size(); ++i) - columnNames->addItem(columns[i]); - - RefPtr<Inspector::TypeBuilder::Array<InspectorValue>> values = Inspector::TypeBuilder::Array<InspectorValue>::create(); - const Vector<SQLValue>& data = rowList->values(); - for (size_t i = 0; i < data.size(); ++i) { - const SQLValue& value = rowList->values()[i]; - switch (value.type()) { - case SQLValue::StringValue: values->addItem(InspectorString::create(value.string())); break; - case SQLValue::NumberValue: values->addItem(InspectorBasicValue::create(value.number())); break; - case SQLValue::NullValue: values->addItem(InspectorValue::null()); break; - } + auto& rowList = resultSet->rows(); + + auto columnNames = Inspector::Protocol::Array<String>::create(); + for (auto& column : rowList.columnNames()) + columnNames->addItem(column); + + auto values = Inspector::Protocol::Array<InspectorValue>::create(); + for (auto& value : rowList.values()) { + auto inspectorValue = WTF::switchOn(value, + [] (const std::nullptr_t&) { return InspectorValue::null(); }, + [] (const String& string) { return InspectorValue::create(string); }, + [] (double number) { return InspectorValue::create(number); } + ); + values->addItem(WTFMove(inspectorValue)); } - m_requestCallback->sendSuccess(columnNames.release(), values.release(), nullptr); + m_requestCallback->sendSuccess(WTFMove(columnNames), WTFMove(values), nullptr); return true; } -private: - StatementCallback(PassRefPtr<ExecuteSQLCallback> requestCallback) - : m_requestCallback(requestCallback) { } - RefPtr<ExecuteSQLCallback> m_requestCallback; + Ref<ExecuteSQLCallback> m_requestCallback; }; -class StatementErrorCallback : public SQLStatementErrorCallback { +class StatementErrorCallback final : public SQLStatementErrorCallback { public: - static PassRefPtr<StatementErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback) + static Ref<StatementErrorCallback> create(Ref<ExecuteSQLCallback>&& requestCallback) { - return adoptRef(new StatementErrorCallback(requestCallback)); + return adoptRef(*new StatementErrorCallback(WTFMove(requestCallback))); } - virtual ~StatementErrorCallback() { } +private: + StatementErrorCallback(Ref<ExecuteSQLCallback>&& requestCallback) + : m_requestCallback(WTFMove(requestCallback)) { } - virtual bool handleEvent(SQLTransaction*, SQLError* error) override + bool handleEvent(SQLTransaction*, SQLError* error) final { - reportTransactionFailed(m_requestCallback.get(), error); - return true; + reportTransactionFailed(m_requestCallback.copyRef(), error); + return true; } -private: - StatementErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback) - : m_requestCallback(requestCallback) { } - RefPtr<ExecuteSQLCallback> m_requestCallback; + Ref<ExecuteSQLCallback> m_requestCallback; }; -class TransactionCallback : public SQLTransactionCallback { +class TransactionCallback final : public SQLTransactionCallback { public: - static PassRefPtr<TransactionCallback> create(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback) + static Ref<TransactionCallback> create(const String& sqlStatement, Ref<ExecuteSQLCallback>&& requestCallback) { - return adoptRef(new TransactionCallback(sqlStatement, requestCallback)); + return adoptRef(*new TransactionCallback(sqlStatement, WTFMove(requestCallback))); } - virtual ~TransactionCallback() { } +private: + TransactionCallback(const String& sqlStatement, Ref<ExecuteSQLCallback>&& requestCallback) + : m_sqlStatement(sqlStatement) + , m_requestCallback(WTFMove(requestCallback)) { } - virtual bool handleEvent(SQLTransaction* transaction) override + bool handleEvent(SQLTransaction* transaction) final { if (!m_requestCallback->isActive()) return true; - Vector<SQLValue> sqlValues; - RefPtr<SQLStatementCallback> callback(StatementCallback::create(m_requestCallback.get())); - RefPtr<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_requestCallback.get())); - transaction->executeSQL(m_sqlStatement, sqlValues, callback.release(), errorCallback.release(), IGNORE_EXCEPTION); + Ref<SQLStatementCallback> callback(StatementCallback::create(m_requestCallback.copyRef())); + Ref<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_requestCallback.copyRef())); + transaction->executeSql(m_sqlStatement, { }, WTFMove(callback), WTFMove(errorCallback)); return true; } -private: - TransactionCallback(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback) - : m_sqlStatement(sqlStatement) - , m_requestCallback(requestCallback) { } + String m_sqlStatement; - RefPtr<ExecuteSQLCallback> m_requestCallback; + Ref<ExecuteSQLCallback> m_requestCallback; }; -class TransactionErrorCallback : public SQLTransactionErrorCallback { +class TransactionErrorCallback final : public SQLTransactionErrorCallback { public: - static PassRefPtr<TransactionErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback) + static Ref<TransactionErrorCallback> create(Ref<ExecuteSQLCallback>&& requestCallback) { - return adoptRef(new TransactionErrorCallback(requestCallback)); + return adoptRef(*new TransactionErrorCallback(WTFMove(requestCallback))); } - virtual ~TransactionErrorCallback() { } +private: + TransactionErrorCallback(Ref<ExecuteSQLCallback>&& requestCallback) + : m_requestCallback(WTFMove(requestCallback)) { } - virtual bool handleEvent(SQLError* error) override + bool handleEvent(SQLError* error) final { reportTransactionFailed(m_requestCallback.get(), error); return true; } -private: - TransactionErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback) - : m_requestCallback(requestCallback) { } - RefPtr<ExecuteSQLCallback> m_requestCallback; + + Ref<ExecuteSQLCallback> m_requestCallback; }; -class TransactionSuccessCallback : public VoidCallback { +class TransactionSuccessCallback final : public VoidCallback { public: - static PassRefPtr<TransactionSuccessCallback> create() + static Ref<TransactionSuccessCallback> create() { - return adoptRef(new TransactionSuccessCallback()); + return adoptRef(*new TransactionSuccessCallback()); } - virtual ~TransactionSuccessCallback() { } - - virtual bool handleEvent() override { return false; } + bool handleEvent() final { return false; } private: TransactionSuccessCallback() { } @@ -191,17 +181,17 @@ private: } // namespace -void InspectorDatabaseAgent::didOpenDatabase(PassRefPtr<Database> database, const String& domain, const String& name, const String& version) +void InspectorDatabaseAgent::didOpenDatabase(RefPtr<Database>&& database, const String& domain, const String& name, const String& version) { - if (InspectorDatabaseResource* resource = findByFileName(database->fileName())) { - resource->setDatabase(database); + if (auto* resource = findByFileName(database->fileName())) { + resource->setDatabase(WTFMove(database)); return; } - RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version); - m_resources.set(resource->id(), resource); + auto resource = InspectorDatabaseResource::create(WTFMove(database), domain, name, version); + m_resources.add(resource->id(), resource.ptr()); // Resources are only bound while visible. - if (m_frontendDispatcher && m_enabled) + if (m_enabled) resource->bind(m_frontendDispatcher.get()); } @@ -210,115 +200,103 @@ void InspectorDatabaseAgent::clearResources() m_resources.clear(); } -InspectorDatabaseAgent::InspectorDatabaseAgent(InstrumentingAgents* instrumentingAgents) - : InspectorAgentBase(ASCIILiteral("Database"), instrumentingAgents) - , m_enabled(false) +InspectorDatabaseAgent::InspectorDatabaseAgent(WebAgentContext& context) + : InspectorAgentBase(ASCIILiteral("Database"), context) + , m_frontendDispatcher(std::make_unique<Inspector::DatabaseFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::DatabaseBackendDispatcher::create(context.backendDispatcher, this)) { - m_instrumentingAgents->setInspectorDatabaseAgent(this); + m_instrumentingAgents.setInspectorDatabaseAgent(this); } InspectorDatabaseAgent::~InspectorDatabaseAgent() { - m_instrumentingAgents->setInspectorDatabaseAgent(nullptr); + m_instrumentingAgents.setInspectorDatabaseAgent(nullptr); } -void InspectorDatabaseAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorDatabaseAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorDatabaseFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorDatabaseBackendDispatcher::create(backendDispatcher, this); } -void InspectorDatabaseAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorDatabaseAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - disable(nullptr); + ErrorString unused; + disable(unused); } -void InspectorDatabaseAgent::enable(ErrorString*) +void InspectorDatabaseAgent::enable(ErrorString&) { if (m_enabled) return; m_enabled = true; - DatabaseResourcesMap::iterator databasesEnd = m_resources.end(); - for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != databasesEnd; ++it) - it->value->bind(m_frontendDispatcher.get()); + for (auto& resource : m_resources.values()) + resource->bind(m_frontendDispatcher.get()); } -void InspectorDatabaseAgent::disable(ErrorString*) +void InspectorDatabaseAgent::disable(ErrorString&) { if (!m_enabled) return; m_enabled = false; } -void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString* error, const String& databaseId, RefPtr<Inspector::TypeBuilder::Array<String>>& names) +void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString& error, const String& databaseId, RefPtr<Inspector::Protocol::Array<String>>& names) { if (!m_enabled) { - *error = "Database agent is not enabled"; + error = ASCIILiteral("Database agent is not enabled"); return; } - names = Inspector::TypeBuilder::Array<String>::create(); + names = Inspector::Protocol::Array<String>::create(); - Database* database = databaseForId(databaseId); - if (database) { - Vector<String> tableNames = database->tableNames(); - unsigned length = tableNames.size(); - for (unsigned i = 0; i < length; ++i) - names->addItem(tableNames[i]); + if (auto* database = databaseForId(databaseId)) { + for (auto& tableName : database->tableNames()) + names->addItem(tableName); } } -void InspectorDatabaseAgent::executeSQL(ErrorString*, const String& databaseId, const String& query, PassRefPtr<ExecuteSQLCallback> prpRequestCallback) +void InspectorDatabaseAgent::executeSQL(ErrorString&, const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&& requestCallback) { - RefPtr<ExecuteSQLCallback> requestCallback = prpRequestCallback; - if (!m_enabled) { requestCallback->sendFailure("Database agent is not enabled"); return; } - Database* database = databaseForId(databaseId); + auto* database = databaseForId(databaseId); if (!database) { requestCallback->sendFailure("Database not found"); return; } - RefPtr<SQLTransactionCallback> callback(TransactionCallback::create(query, requestCallback.get())); - RefPtr<SQLTransactionErrorCallback> errorCallback(TransactionErrorCallback::create(requestCallback.get())); - RefPtr<VoidCallback> successCallback(TransactionSuccessCallback::create()); - database->transaction(callback.release(), errorCallback.release(), successCallback.release()); + database->transaction(TransactionCallback::create(query, requestCallback.copyRef()), + TransactionErrorCallback::create(requestCallback.copyRef()), + TransactionSuccessCallback::create()); } String InspectorDatabaseAgent::databaseId(Database* database) { - for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) { - if (it->value->database() == database) - return it->key; + for (auto& resource : m_resources) { + if (resource.value->database() == database) + return resource.key; } return String(); } InspectorDatabaseResource* InspectorDatabaseAgent::findByFileName(const String& fileName) { - for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) { - if (it->value->database()->fileName() == fileName) - return it->value.get(); + for (auto& resource : m_resources.values()) { + if (resource->database()->fileName() == fileName) + return resource.get(); } return nullptr; } Database* InspectorDatabaseAgent::databaseForId(const String& databaseId) { - DatabaseResourcesMap::iterator it = m_resources.find(databaseId); - if (it == m_resources.end()) + auto* resource = m_resources.get(databaseId); + if (!resource) return nullptr; - return it->value->database(); + return resource->database(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE) diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.h b/Source/WebCore/inspector/InspectorDatabaseAgent.h index 322960757..de3c78335 100644 --- a/Source/WebCore/inspector/InspectorDatabaseAgent.h +++ b/Source/WebCore/inspector/InspectorDatabaseAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,63 +27,52 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorDatabaseAgent_h -#define InspectorDatabaseAgent_h - -#if ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE) +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <wtf/HashMap.h> -#include <wtf/PassOwnPtr.h> #include <wtf/text/WTFString.h> -namespace Inspector { -class InspectorArray; -} - namespace WebCore { class Database; class InspectorDatabaseResource; -class InstrumentingAgents; typedef String ErrorString; -class InspectorDatabaseAgent : public InspectorAgentBase, public Inspector::InspectorDatabaseBackendDispatcherHandler { +class InspectorDatabaseAgent final : public InspectorAgentBase, public Inspector::DatabaseBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; public: - explicit InspectorDatabaseAgent(InstrumentingAgents*); - ~InspectorDatabaseAgent(); + explicit InspectorDatabaseAgent(WebAgentContext&); + virtual ~InspectorDatabaseAgent(); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; void clearResources(); // Called from the front-end. - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void getDatabaseTableNames(ErrorString*, const String& databaseId, RefPtr<Inspector::TypeBuilder::Array<String>>& names) override; - virtual void executeSQL(ErrorString*, const String& databaseId, const String& query, PassRefPtr<ExecuteSQLCallback>) override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void getDatabaseTableNames(ErrorString&, const String& databaseId, RefPtr<Inspector::Protocol::Array<String>>& names) override; + void executeSQL(ErrorString&, const String& databaseId, const String& query, Ref<ExecuteSQLCallback>&&) override; // Called from the injected script. String databaseId(Database*); - void didOpenDatabase(PassRefPtr<Database>, const String& domain, const String& name, const String& version); + void didOpenDatabase(RefPtr<Database>&&, const String& domain, const String& name, const String& version); private: Database* databaseForId(const String& databaseId); InspectorDatabaseResource* findByFileName(const String& fileName); - std::unique_ptr<Inspector::InspectorDatabaseFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorDatabaseBackendDispatcher> m_backendDispatcher; + std::unique_ptr<Inspector::DatabaseFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::DatabaseBackendDispatcher> m_backendDispatcher; + typedef HashMap<String, RefPtr<InspectorDatabaseResource>> DatabaseResourcesMap; DatabaseResourcesMap m_resources; - bool m_enabled; + bool m_enabled { false }; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) && ENABLE(SQL_DATABASE) - -#endif // !defined(InspectorDatabaseAgent_h) diff --git a/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h b/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h deleted file mode 100644 index b0ad7b345..000000000 --- a/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Copyright (C) 2011 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef InspectorDatabaseInstrumentation_h -#define InspectorDatabaseInstrumentation_h - -#include "Database.h" -#include "InspectorInstrumentation.h" -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -#if ENABLE(SQL_DATABASE) -inline void InspectorInstrumentation::didOpenDatabase(ScriptExecutionContext* context, PassRefPtr<Database> database, const String& domain, const String& name, const String& version) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didOpenDatabaseImpl(instrumentingAgents, database, domain, name, version); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(database); - UNUSED_PARAM(domain); - UNUSED_PARAM(name); - UNUSED_PARAM(version); -#endif -} -#endif - -} // namespace WebCore - -#endif // !defined(InspectorDatabaseInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorDatabaseResource.cpp b/Source/WebCore/inspector/InspectorDatabaseResource.cpp index 1badbdf3f..b88c16b7a 100644 --- a/Source/WebCore/inspector/InspectorDatabaseResource.cpp +++ b/Source/WebCore/inspector/InspectorDatabaseResource.cpp @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -29,13 +29,9 @@ */ #include "config.h" - -#if ENABLE(SQL_DATABASE) && ENABLE(INSPECTOR) - #include "InspectorDatabaseResource.h" #include "Database.h" -#include "InspectorWebFrontendDispatchers.h" #include <inspector/InspectorValues.h> using namespace Inspector; @@ -44,12 +40,12 @@ namespace WebCore { static int nextUnusedId = 1; -PassRefPtr<InspectorDatabaseResource> InspectorDatabaseResource::create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version) +Ref<InspectorDatabaseResource> InspectorDatabaseResource::create(RefPtr<Database>&& database, const String& domain, const String& name, const String& version) { - return adoptRef(new InspectorDatabaseResource(database, domain, name, version)); + return adoptRef(*new InspectorDatabaseResource(WTFMove(database), domain, name, version)); } -InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr<Database> database, const String& domain, const String& name, const String& version) +InspectorDatabaseResource::InspectorDatabaseResource(RefPtr<Database>&& database, const String& domain, const String& name, const String& version) : m_database(database) , m_id(String::number(nextUnusedId++)) , m_domain(domain) @@ -58,16 +54,15 @@ InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr<Database> databa { } -void InspectorDatabaseResource::bind(InspectorDatabaseFrontendDispatcher* databaseFrontendDispatcher) +void InspectorDatabaseResource::bind(Inspector::DatabaseFrontendDispatcher* databaseFrontendDispatcher) { - RefPtr<Inspector::TypeBuilder::Database::Database> jsonObject = Inspector::TypeBuilder::Database::Database::create() + auto jsonObject = Inspector::Protocol::Database::Database::create() .setId(m_id) .setDomain(m_domain) .setName(m_name) - .setVersion(m_version); - databaseFrontendDispatcher->addDatabase(jsonObject); + .setVersion(m_version) + .release(); + databaseFrontendDispatcher->addDatabase(WTFMove(jsonObject)); } } // namespace WebCore - -#endif // ENABLE(SQL_DATABASE) && ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorDatabaseResource.h b/Source/WebCore/inspector/InspectorDatabaseResource.h index ccd09c80c..e19241f72 100644 --- a/Source/WebCore/inspector/InspectorDatabaseResource.h +++ b/Source/WebCore/inspector/InspectorDatabaseResource.h @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -28,12 +28,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorDatabaseResource_h -#define InspectorDatabaseResource_h +#pragma once -#if ENABLE(SQL_DATABASE) && ENABLE(INSPECTOR) -#include "InspectorWebFrontendDispatchers.h" -#include <wtf/PassRefPtr.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> #include <wtf/text/WTFString.h> @@ -44,15 +41,15 @@ class Database; class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> { public: - static PassRefPtr<InspectorDatabaseResource> create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version); + static Ref<InspectorDatabaseResource> create(RefPtr<Database>&&, const String& domain, const String& name, const String& version); - void bind(Inspector::InspectorDatabaseFrontendDispatcher*); + void bind(Inspector::DatabaseFrontendDispatcher*); Database* database() { return m_database.get(); } - void setDatabase(PassRefPtr<Database> database) { m_database = database; } + void setDatabase(RefPtr<Database>&& database) { m_database = WTFMove(database); } String id() const { return m_id; } private: - InspectorDatabaseResource(PassRefPtr<Database>, const String& domain, const String& name, const String& version); + InspectorDatabaseResource(RefPtr<Database>&&, const String& domain, const String& name, const String& version); RefPtr<Database> m_database; String m_id; @@ -62,7 +59,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SQL_DATABASE) - -#endif // InspectorDatabaseResource_h diff --git a/Source/WebCore/inspector/InspectorForwarding.h b/Source/WebCore/inspector/InspectorForwarding.h deleted file mode 100644 index f68fcdc6a..000000000 --- a/Source/WebCore/inspector/InspectorForwarding.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All Rights Reserved. - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorForwarding_h -#define InspectorForwarding_h - -#include <inspector/InspectorFrontendChannel.h> - -namespace WebCore { -typedef Inspector::InspectorFrontendChannel InspectorFrontendChannel; -} - -#endif // !defined(InspectorForwarding_h) diff --git a/Source/WebCore/inspector/InspectorFrontendClient.h b/Source/WebCore/inspector/InspectorFrontendClient.h index 9b0b75d6e..4eeb38886 100644 --- a/Source/WebCore/inspector/InspectorFrontendClient.h +++ b/Source/WebCore/inspector/InspectorFrontendClient.h @@ -28,44 +28,46 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorFrontendClient_h -#define InspectorFrontendClient_h +#pragma once +#include "UserInterfaceLayoutDirection.h" #include <wtf/Forward.h> -#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { -class ContextMenuItem; -class Event; - class InspectorFrontendClient { public: - enum DockSide { - UNDOCKED = 0, - DOCKED_TO_RIGHT, - DOCKED_TO_BOTTOM + enum class DockSide { + Undocked = 0, + Right, + Left, + Bottom, }; virtual ~InspectorFrontendClient() { } - virtual void windowObjectCleared() = 0; + WEBCORE_EXPORT virtual void windowObjectCleared() = 0; virtual void frontendLoaded() = 0; + virtual void startWindowDrag() = 0; virtual void moveWindowBy(float x, float y) = 0; virtual String localizedStringsURL() = 0; + virtual unsigned inspectionLevel() const = 0; + virtual String backendCommandsURL() { return String(); }; + virtual String debuggableType() { return ASCIILiteral("web"); } virtual void bringToFront() = 0; virtual void closeWindow() = 0; - virtual void requestSetDockSide(DockSide) = 0; - virtual void changeAttachedWindowHeight(unsigned) = 0; - virtual void changeAttachedWindowWidth(unsigned) = 0; + virtual UserInterfaceLayoutDirection userInterfaceLayoutDirection() const = 0; - virtual void setToolbarHeight(unsigned) = 0; + WEBCORE_EXPORT virtual void requestSetDockSide(DockSide) = 0; + WEBCORE_EXPORT virtual void changeAttachedWindowHeight(unsigned) = 0; + WEBCORE_EXPORT virtual void changeAttachedWindowWidth(unsigned) = 0; - virtual void openInNewTab(const String& url) = 0; + WEBCORE_EXPORT virtual void openInNewTab(const String& url) = 0; virtual bool canSave() = 0; virtual void save(const WTF::String& url, const WTF::String& content, bool base64Encoded, bool forceSaveAs) = 0; @@ -73,11 +75,12 @@ public: virtual void inspectedURLChanged(const String&) = 0; - virtual void sendMessageToBackend(const String&) = 0; + virtual void pagePaused() { } + virtual void pageUnpaused() { } + + WEBCORE_EXPORT virtual void sendMessageToBackend(const String&) = 0; - virtual bool isUnderTest() = 0; + WEBCORE_EXPORT virtual bool isUnderTest() = 0; }; } // namespace WebCore - -#endif diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp index 4e85bc532..76670246a 100644 --- a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp +++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,9 +30,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorFrontendClientLocal.h" #include "Chrome.h" @@ -44,7 +42,6 @@ #include "InspectorController.h" #include "InspectorFrontendHost.h" #include "InspectorPageAgent.h" -#include "InspectorWebBackendDispatchers.h" #include "MainFrame.h" #include "Page.h" #include "ScriptController.h" @@ -54,10 +51,9 @@ #include "Timer.h" #include "UserGestureIndicator.h" #include "WindowFeatures.h" -#include <bindings/ScriptValue.h> +#include <inspector/InspectorBackendDispatchers.h> #include <wtf/Deque.h> #include <wtf/text/CString.h> -#include <wtf/text/WTFString.h> using namespace Inspector; @@ -67,20 +63,21 @@ static const char* inspectorAttachedHeightSetting = "inspectorAttachedHeight"; static const unsigned defaultAttachedHeight = 300; static const float minimumAttachedHeight = 250.0f; static const float maximumAttachedHeightRatio = 0.75f; -static const float minimumAttachedWidth = 750.0f; +static const float minimumAttachedWidth = 500.0f; static const float minimumAttachedInspectedWidth = 320.0f; -class InspectorBackendDispatchTask { +class InspectorBackendDispatchTask : public RefCounted<InspectorBackendDispatchTask> { WTF_MAKE_FAST_ALLOCATED; public: - InspectorBackendDispatchTask(InspectorController* inspectorController) - : m_inspectorController(inspectorController) - , m_timer(this, &InspectorBackendDispatchTask::timerFired) + static Ref<InspectorBackendDispatchTask> create(InspectorController* inspectedPageController) { + return adoptRef(*new InspectorBackendDispatchTask(inspectedPageController)); } void dispatch(const String& message) { + ASSERT_ARG(message, !message.isEmpty()); + m_messages.append(message); if (!m_timer.isActive()) m_timer.startOneShot(0); @@ -90,20 +87,34 @@ public: { m_messages.clear(); m_timer.stop(); + m_inspectedPageController = nullptr; } - void timerFired(Timer<InspectorBackendDispatchTask>&) + void timerFired() { - if (!m_messages.isEmpty()) { - // Dispatch can lead to the timer destruction -> schedule the next shot first. + ASSERT(m_inspectedPageController); + + // Dispatching a message can possibly close the frontend and destroy + // the owning frontend client, so keep a protector reference here. + Ref<InspectorBackendDispatchTask> protectedThis(*this); + + if (!m_messages.isEmpty()) + m_inspectedPageController->dispatchMessageFromFrontend(m_messages.takeFirst()); + + if (!m_messages.isEmpty() && m_inspectedPageController) m_timer.startOneShot(0); - m_inspectorController->dispatchMessageFromFrontend(m_messages.takeFirst()); - } } private: - InspectorController* m_inspectorController; - Timer<InspectorBackendDispatchTask> m_timer; + InspectorBackendDispatchTask(InspectorController* inspectedPageController) + : m_inspectedPageController(inspectedPageController) + , m_timer(*this, &InspectorBackendDispatchTask::timerFired) + { + ASSERT_ARG(inspectedPageController, inspectedPageController); + } + + InspectorController* m_inspectedPageController { nullptr }; + Timer m_timer; Deque<String> m_messages; }; @@ -116,23 +127,23 @@ void InspectorFrontendClientLocal::Settings::setProperty(const String&, const St { } -InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage, PassOwnPtr<Settings> settings) - : m_inspectorController(inspectorController) +InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectedPageController, Page* frontendPage, std::unique_ptr<Settings> settings) + : m_inspectedPageController(inspectedPageController) , m_frontendPage(frontendPage) - , m_settings(settings) - , m_frontendLoaded(false) - , m_dockSide(UNDOCKED) + , m_settings(WTFMove(settings)) + , m_dockSide(DockSide::Undocked) + , m_dispatchTask(InspectorBackendDispatchTask::create(inspectedPageController)) { m_frontendPage->settings().setAllowFileAccessFromFileURLs(true); - m_dispatchTask = adoptPtr(new InspectorBackendDispatchTask(inspectorController)); } InspectorFrontendClientLocal::~InspectorFrontendClientLocal() { if (m_frontendHost) m_frontendHost->disconnectClient(); - m_frontendPage = 0; - m_inspectorController = 0; + m_frontendPage = nullptr; + m_inspectedPageController = nullptr; + m_dispatchTask->reset(); } void InspectorFrontendClientLocal::windowObjectCleared() @@ -140,28 +151,32 @@ void InspectorFrontendClientLocal::windowObjectCleared() if (m_frontendHost) m_frontendHost->disconnectClient(); - JSC::ExecState* frontendExecState = execStateFromPage(debuggerWorld(), m_frontendPage); m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage); - ScriptGlobalObject::set(frontendExecState, "InspectorFrontendHost", m_frontendHost.get()); + ScriptGlobalObject::set(*execStateFromPage(debuggerWorld(), m_frontendPage), "InspectorFrontendHost", *m_frontendHost); } void InspectorFrontendClientLocal::frontendLoaded() { // Call setDockingUnavailable before bringToFront. If we display the inspector window via bringToFront first it causes // the call to canAttachWindow to return the wrong result on Windows. - // Calling bringToFront first causes the visibleHeight of the inspected page to always return 0 immediately after. + // Calling bringToFront first causes the visibleHeight of the inspected page to always return 0 immediately after. // Thus if we call canAttachWindow first we can avoid this problem. This change does not cause any regressions on Mac. setDockingUnavailable(!canAttachWindow()); bringToFront(); m_frontendLoaded = true; - for (Vector<String>::iterator it = m_evaluateOnLoad.begin(); it != m_evaluateOnLoad.end(); ++it) - evaluateOnLoad(*it); + for (auto& evaluate : m_evaluateOnLoad) + evaluateOnLoad(evaluate); m_evaluateOnLoad.clear(); } +UserInterfaceLayoutDirection InspectorFrontendClientLocal::userInterfaceLayoutDirection() const +{ + return m_frontendPage->userInterfaceLayoutDirection(); +} + void InspectorFrontendClientLocal::requestSetDockSide(DockSide dockSide) { - if (dockSide == UNDOCKED) { + if (dockSide == DockSide::Undocked) { detachWindow(); setAttachedWindow(dockSide); } else if (canAttachWindow()) { @@ -173,17 +188,17 @@ void InspectorFrontendClientLocal::requestSetDockSide(DockSide dockSide) bool InspectorFrontendClientLocal::canAttachWindow() { // Don't allow attaching to another inspector -- two inspectors in one window is too much! - bool isInspectorPage = m_inspectorController->hasInspectorFrontendClient(); + bool isInspectorPage = m_inspectedPageController->inspectionLevel() > 0; if (isInspectorPage) return false; // If we are already attached, allow attaching again to allow switching sides. - if (m_dockSide != UNDOCKED) + if (m_dockSide != DockSide::Undocked) return true; // Don't allow the attach if the window would be too small to accommodate the minimum inspector size. - unsigned inspectedPageHeight = m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight(); - unsigned inspectedPageWidth = m_inspectorController->inspectedPage().mainFrame().view()->visibleWidth(); + unsigned inspectedPageHeight = m_inspectedPageController->inspectedPage().mainFrame().view()->visibleHeight(); + unsigned inspectedPageWidth = m_inspectedPageController->inspectedPage().mainFrame().view()->visibleWidth(); unsigned maximumAttachedHeight = inspectedPageHeight * maximumAttachedHeightRatio; return minimumAttachedHeight <= maximumAttachedHeight && minimumAttachedWidth <= inspectedPageWidth; } @@ -195,7 +210,7 @@ void InspectorFrontendClientLocal::setDockingUnavailable(bool unavailable) void InspectorFrontendClientLocal::changeAttachedWindowHeight(unsigned height) { - unsigned totalHeight = m_frontendPage->mainFrame().view()->visibleHeight() + m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight(); + unsigned totalHeight = m_frontendPage->mainFrame().view()->visibleHeight() + m_inspectedPageController->inspectedPage().mainFrame().view()->visibleHeight(); unsigned attachedHeight = constrainedAttachedWindowHeight(height, totalHeight); m_settings->setProperty(inspectorAttachedHeightSetting, String::number(attachedHeight)); setAttachedWindowHeight(attachedHeight); @@ -203,20 +218,20 @@ void InspectorFrontendClientLocal::changeAttachedWindowHeight(unsigned height) void InspectorFrontendClientLocal::changeAttachedWindowWidth(unsigned width) { - unsigned totalWidth = m_frontendPage->mainFrame().view()->visibleWidth() + m_inspectorController->inspectedPage().mainFrame().view()->visibleWidth(); + unsigned totalWidth = m_frontendPage->mainFrame().view()->visibleWidth() + m_inspectedPageController->inspectedPage().mainFrame().view()->visibleWidth(); unsigned attachedWidth = constrainedAttachedWindowWidth(width, totalWidth); setAttachedWindowWidth(attachedWidth); } void InspectorFrontendClientLocal::openInNewTab(const String& url) { - UserGestureIndicator indicator(DefinitelyProcessingUserGesture); - Frame& mainFrame = m_inspectorController->inspectedPage().mainFrame(); - FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank"); + UserGestureIndicator indicator(ProcessingUserGesture); + Frame& mainFrame = m_inspectedPageController->inspectedPage().mainFrame(); + FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow); bool created; WindowFeatures windowFeatures; - RefPtr<Frame> frame = WebCore::createWindow(&mainFrame, &mainFrame, request, windowFeatures, created); + RefPtr<Frame> frame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created); if (!frame) return; @@ -224,7 +239,9 @@ void InspectorFrontendClientLocal::openInNewTab(const String& url) frame->page()->setOpenedByDOM(); // FIXME: Why does one use mainFrame and the other frame? - frame->loader().changeLocation(mainFrame.document()->securityOrigin(), frame->document()->completeURL(url), "", false, false); + ResourceRequest resourceRequest(frame->document()->completeURL(url)); + FrameLoadRequest frameRequest(mainFrame.document()->securityOrigin(), resourceRequest, "_self", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow); + frame->loader().changeLocation(frameRequest); } void InspectorFrontendClientLocal::moveWindowBy(float x, float y) @@ -238,13 +255,16 @@ void InspectorFrontendClientLocal::setAttachedWindow(DockSide dockSide) { const char* side = "undocked"; switch (dockSide) { - case UNDOCKED: + case DockSide::Undocked: side = "undocked"; break; - case DOCKED_TO_RIGHT: + case DockSide::Right: side = "right"; break; - case DOCKED_TO_BOTTOM: + case DockSide::Left: + side = "left"; + break; + case DockSide::Bottom: side = "bottom"; break; } @@ -256,7 +276,7 @@ void InspectorFrontendClientLocal::setAttachedWindow(DockSide dockSide) void InspectorFrontendClientLocal::restoreAttachedWindowHeight() { - unsigned inspectedPageHeight = m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight(); + unsigned inspectedPageHeight = m_inspectedPageController->inspectedPage().mainFrame().view()->visibleHeight(); String value = m_settings->getProperty(inspectorAttachedHeightSetting); unsigned preferredHeight = value.isEmpty() ? defaultAttachedHeight : value.toUInt(); @@ -319,7 +339,7 @@ void InspectorFrontendClientLocal::showResources() void InspectorFrontendClientLocal::showMainResourceForFrame(Frame* frame) { - String frameId = m_inspectorController->pageAgent()->frameId(frame); + String frameId = m_inspectedPageController->pageAgent()->frameId(frame); evaluateOnLoad(String::format("[\"showMainResourceForFrame\", \"%s\"]", frameId.ascii().data())); } @@ -340,23 +360,34 @@ void InspectorFrontendClientLocal::sendMessageToBackend(const String& message) bool InspectorFrontendClientLocal::isUnderTest() { - return m_inspectorController->isUnderTest(); + return m_inspectedPageController->isUnderTest(); +} + +unsigned InspectorFrontendClientLocal::inspectionLevel() const +{ + return m_inspectedPageController->inspectionLevel() + 1; } bool InspectorFrontendClientLocal::evaluateAsBoolean(const String& expression) { - Deprecated::ScriptValue value = m_frontendPage->mainFrame().script().executeScript(expression); - return value.toString(mainWorldExecState(&m_frontendPage->mainFrame())) == "true"; + auto& state = *mainWorldExecState(&m_frontendPage->mainFrame()); + return m_frontendPage->mainFrame().script().executeScript(expression).toWTFString(&state) == "true"; } void InspectorFrontendClientLocal::evaluateOnLoad(const String& expression) { if (m_frontendLoaded) - m_frontendPage->mainFrame().script().executeScript("InspectorFrontendAPI.dispatch(" + expression + ")"); + m_frontendPage->mainFrame().script().executeScript("if (InspectorFrontendAPI) InspectorFrontendAPI.dispatch(" + expression + ")"); else m_evaluateOnLoad.append(expression); } -} // namespace WebCore +Page* InspectorFrontendClientLocal::inspectedPage() const +{ + if (!m_inspectedPageController) + return nullptr; -#endif + return &m_inspectedPageController->inspectedPage(); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.h b/Source/WebCore/inspector/InspectorFrontendClientLocal.h index b654f7087..ce6a54a68 100644 --- a/Source/WebCore/inspector/InspectorFrontendClientLocal.h +++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,8 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorFrontendClientLocal_h -#define InspectorFrontendClientLocal_h +#pragma once #include "InspectorFrontendClient.h" #include <wtf/Forward.h> @@ -47,7 +47,7 @@ class Page; class InspectorFrontendClientLocal : public InspectorFrontendClient { WTF_MAKE_NONCOPYABLE(InspectorFrontendClientLocal); WTF_MAKE_FAST_ALLOCATED; public: - class Settings { + class WEBCORE_EXPORT Settings { public: Settings() { } virtual ~Settings() { } @@ -55,75 +55,79 @@ public: virtual void setProperty(const String& name, const String& value); }; - InspectorFrontendClientLocal(InspectorController*, Page*, PassOwnPtr<Settings>); - virtual ~InspectorFrontendClientLocal(); - - virtual void windowObjectCleared(); - virtual void frontendLoaded(); + WEBCORE_EXPORT InspectorFrontendClientLocal(InspectorController* inspectedPageController, Page* frontendPage, std::unique_ptr<Settings>); + WEBCORE_EXPORT virtual ~InspectorFrontendClientLocal(); - virtual void moveWindowBy(float x, float y); + WEBCORE_EXPORT void windowObjectCleared() final; + WEBCORE_EXPORT void frontendLoaded() override; - virtual void requestSetDockSide(DockSide); - virtual void changeAttachedWindowHeight(unsigned); - virtual void changeAttachedWindowWidth(unsigned); - virtual void openInNewTab(const String& url); - virtual bool canSave() { return false; } - virtual void save(const String&, const String&, bool, bool) { } - virtual void append(const String&, const String&) { } + void startWindowDrag() override { } + WEBCORE_EXPORT void moveWindowBy(float x, float y) final; + + WEBCORE_EXPORT UserInterfaceLayoutDirection userInterfaceLayoutDirection() const final; + + WEBCORE_EXPORT void requestSetDockSide(DockSide) final; + WEBCORE_EXPORT void changeAttachedWindowHeight(unsigned) final; + WEBCORE_EXPORT void changeAttachedWindowWidth(unsigned) final; + WEBCORE_EXPORT void openInNewTab(const String& url) final; + bool canSave() override { return false; } + void save(const String&, const String&, bool, bool) override { } + void append(const String&, const String&) override { } virtual void attachWindow(DockSide) = 0; virtual void detachWindow() = 0; - virtual void sendMessageToBackend(const String& message); + WEBCORE_EXPORT void sendMessageToBackend(const String& message) final; - virtual bool isUnderTest(); + WEBCORE_EXPORT bool isUnderTest() final; + WEBCORE_EXPORT unsigned inspectionLevel() const final; - bool canAttachWindow(); - void setDockingUnavailable(bool); + WEBCORE_EXPORT bool canAttachWindow(); + WEBCORE_EXPORT void setDockingUnavailable(bool); - static unsigned constrainedAttachedWindowHeight(unsigned preferredHeight, unsigned totalWindowHeight); - static unsigned constrainedAttachedWindowWidth(unsigned preferredWidth, unsigned totalWindowWidth); + WEBCORE_EXPORT static unsigned constrainedAttachedWindowHeight(unsigned preferredHeight, unsigned totalWindowHeight); + WEBCORE_EXPORT static unsigned constrainedAttachedWindowWidth(unsigned preferredWidth, unsigned totalWindowWidth); // Direct Frontend API - bool isDebuggingEnabled(); - void setDebuggingEnabled(bool); + WEBCORE_EXPORT bool isDebuggingEnabled(); + WEBCORE_EXPORT void setDebuggingEnabled(bool); - bool isTimelineProfilingEnabled(); - void setTimelineProfilingEnabled(bool); + WEBCORE_EXPORT bool isTimelineProfilingEnabled(); + WEBCORE_EXPORT void setTimelineProfilingEnabled(bool); - bool isProfilingJavaScript(); - void startProfilingJavaScript(); - void stopProfilingJavaScript(); + WEBCORE_EXPORT bool isProfilingJavaScript(); + WEBCORE_EXPORT void startProfilingJavaScript(); + WEBCORE_EXPORT void stopProfilingJavaScript(); - void showConsole(); + WEBCORE_EXPORT void showConsole(); - void showMainResourceForFrame(Frame*); - - void showResources(); + WEBCORE_EXPORT void showMainResourceForFrame(Frame*); - void setAttachedWindow(DockSide); + WEBCORE_EXPORT void showResources(); + WEBCORE_EXPORT void setAttachedWindow(DockSide); + + WEBCORE_EXPORT Page* inspectedPage() const; + Page* frontendPage() const { return m_frontendPage; } protected: virtual void setAttachedWindowHeight(unsigned) = 0; virtual void setAttachedWindowWidth(unsigned) = 0; - void restoreAttachedWindowHeight(); + WEBCORE_EXPORT void restoreAttachedWindowHeight(); private: bool evaluateAsBoolean(const String& expression); void evaluateOnLoad(const String& expression); friend class FrontendMenuProvider; - InspectorController* m_inspectorController; - Page* m_frontendPage; + InspectorController* m_inspectedPageController { nullptr }; + Page* m_frontendPage { nullptr }; // TODO(yurys): this ref shouldn't be needed. RefPtr<InspectorFrontendHost> m_frontendHost; - OwnPtr<InspectorFrontendClientLocal::Settings> m_settings; - bool m_frontendLoaded; + std::unique_ptr<InspectorFrontendClientLocal::Settings> m_settings; + bool m_frontendLoaded { false }; DockSide m_dockSide; Vector<String> m_evaluateOnLoad; - OwnPtr<InspectorBackendDispatchTask> m_dispatchTask; + Ref<InspectorBackendDispatchTask> m_dispatchTask; }; } // namespace WebCore - -#endif diff --git a/Source/WebCore/inspector/InspectorFrontendHost.cpp b/Source/WebCore/inspector/InspectorFrontendHost.cpp index 06057bf3d..564f14ec1 100644 --- a/Source/WebCore/inspector/InspectorFrontendHost.cpp +++ b/Source/WebCore/inspector/InspectorFrontendHost.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007-2017 Apple Inc. All rights reserved. * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -28,30 +28,25 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorFrontendHost.h" #include "ContextMenu.h" -#include "ContextMenuItem.h" #include "ContextMenuController.h" +#include "ContextMenuItem.h" #include "ContextMenuProvider.h" #include "DOMWrapperWorld.h" -#include "Element.h" +#include "Document.h" +#include "Editor.h" #include "Event.h" -#include "FrameLoader.h" +#include "FocusController.h" #include "HitTestResult.h" -#include "HTMLFrameOwnerElement.h" #include "InspectorFrontendClient.h" #include "JSMainThreadExecState.h" #include "MainFrame.h" #include "MouseEvent.h" +#include "Node.h" #include "Page.h" #include "Pasteboard.h" -#include "ResourceError.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" #include "ScriptGlobalObject.h" #include "ScriptState.h" #include "Sound.h" @@ -66,14 +61,14 @@ namespace WebCore { #if ENABLE(CONTEXT_MENUS) class FrontendMenuProvider : public ContextMenuProvider { public: - static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, Deprecated::ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items) + static Ref<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, Deprecated::ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items) { - return adoptRef(new FrontendMenuProvider(frontendHost, frontendApiObject, items)); + return adoptRef(*new FrontendMenuProvider(frontendHost, frontendApiObject, items)); } void disconnect() { - m_frontendApiObject = Deprecated::ScriptObject(); + m_frontendApiObject = { }; m_frontendHost = nullptr; } @@ -90,17 +85,17 @@ private: contextMenuCleared(); } - virtual void populateContextMenu(ContextMenu* menu) override + void populateContextMenu(ContextMenu* menu) override { - for (size_t i = 0; i < m_items.size(); ++i) - menu->appendItem(m_items[i]); + for (auto& item : m_items) + menu->appendItem(item); } - virtual void contextMenuItemSelected(ContextMenuItem* item) override + void contextMenuItemSelected(ContextMenuAction action, const String&) override { if (m_frontendHost) { - UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); - int itemNumber = item->action() - ContextMenuItemBaseCustomTag; + UserGestureIndicator gestureIndicator(ProcessingUserGesture); + int itemNumber = action - ContextMenuItemBaseCustomTag; Deprecated::ScriptFunctionCall function(m_frontendApiObject, "contextMenuItemSelected", WebCore::functionCallHandlerFromAnyThread); function.appendArgument(itemNumber); @@ -108,7 +103,7 @@ private: } } - virtual void contextMenuCleared() override + void contextMenuCleared() override { if (m_frontendHost) { Deprecated::ScriptFunctionCall function(m_frontendApiObject, "contextMenuCleared", WebCore::functionCallHandlerFromAnyThread); @@ -160,11 +155,13 @@ void InspectorFrontendHost::requestSetDockSide(const String& side) if (!m_client) return; if (side == "undocked") - m_client->requestSetDockSide(InspectorFrontendClient::UNDOCKED); + m_client->requestSetDockSide(InspectorFrontendClient::DockSide::Undocked); else if (side == "right") - m_client->requestSetDockSide(InspectorFrontendClient::DOCKED_TO_RIGHT); + m_client->requestSetDockSide(InspectorFrontendClient::DockSide::Right); + else if (side == "left") + m_client->requestSetDockSide(InspectorFrontendClient::DockSide::Left); else if (side == "bottom") - m_client->requestSetDockSide(InspectorFrontendClient::DOCKED_TO_BOTTOM); + m_client->requestSetDockSide(InspectorFrontendClient::DockSide::Bottom); } void InspectorFrontendHost::closeWindow() @@ -181,15 +178,32 @@ void InspectorFrontendHost::bringToFront() m_client->bringToFront(); } +void InspectorFrontendHost::inspectedURLChanged(const String& newURL) +{ + if (m_client) + m_client->inspectedURLChanged(newURL); +} + void InspectorFrontendHost::setZoomFactor(float zoom) { - m_frontendPage->mainFrame().setPageAndTextZoomFactors(zoom, 1); + if (m_frontendPage) + m_frontendPage->mainFrame().setPageAndTextZoomFactors(zoom, 1); } -void InspectorFrontendHost::inspectedURLChanged(const String& newURL) +float InspectorFrontendHost::zoomFactor() { - if (m_client) - m_client->inspectedURLChanged(newURL); + if (m_frontendPage) + return m_frontendPage->mainFrame().pageZoomFactor(); + + return 1.0; +} + +String InspectorFrontendHost::userInterfaceLayoutDirection() +{ + if (m_client && m_client->userInterfaceLayoutDirection() == UserInterfaceLayoutDirection::RTL) + return ASCIILiteral("rtl"); + + return ASCIILiteral("ltr"); } void InspectorFrontendHost::setAttachedWindowHeight(unsigned height) @@ -204,10 +218,10 @@ void InspectorFrontendHost::setAttachedWindowWidth(unsigned width) m_client->changeAttachedWindowWidth(width); } -void InspectorFrontendHost::setToolbarHeight(unsigned height) +void InspectorFrontendHost::startWindowDrag() { if (m_client) - m_client->setToolbarHeight(height); + m_client->startWindowDrag(); } void InspectorFrontendHost::moveWindowBy(float x, float y) const @@ -218,12 +232,50 @@ void InspectorFrontendHost::moveWindowBy(float x, float y) const String InspectorFrontendHost::localizedStringsURL() { - return m_client ? m_client->localizedStringsURL() : ""; + return m_client ? m_client->localizedStringsURL() : String(); +} + +String InspectorFrontendHost::backendCommandsURL() +{ + return m_client ? m_client->backendCommandsURL() : String(); } String InspectorFrontendHost::debuggableType() { - return ASCIILiteral("web"); + return m_client ? m_client->debuggableType() : String(); +} + +unsigned InspectorFrontendHost::inspectionLevel() +{ + return m_client ? m_client->inspectionLevel() : 1; +} + +String InspectorFrontendHost::platform() +{ +#if PLATFORM(MAC) || PLATFORM(IOS) + return ASCIILiteral("mac"); +#elif OS(WINDOWS) + return ASCIILiteral("windows"); +#elif OS(LINUX) + return ASCIILiteral("linux"); +#elif OS(FREEBSD) + return ASCIILiteral("freebsd"); +#elif OS(OPENBSD) + return ASCIILiteral("openbsd"); +#elif OS(SOLARIS) + return ASCIILiteral("solaris"); +#else + return ASCIILiteral("unknown"); +#endif +} + +String InspectorFrontendHost::port() +{ +#if PLATFORM(GTK) + return ASCIILiteral("gtk"); +#else + return ASCIILiteral("unknown"); +#endif } void InspectorFrontendHost::copyText(const String& text) @@ -231,8 +283,22 @@ void InspectorFrontendHost::copyText(const String& text) Pasteboard::createForCopyAndPaste()->writePlainText(text, Pasteboard::CannotSmartReplace); } +void InspectorFrontendHost::killText(const String& text, bool shouldPrependToKillRing, bool shouldStartNewSequence) +{ + if (!m_frontendPage) + return; + + Editor& editor = m_frontendPage->focusController().focusedOrMainFrame().editor(); + editor.setStartNewKillRingSequence(shouldStartNewSequence); + Editor::KillRingInsertionMode insertionMode = shouldPrependToKillRing ? Editor::KillRingInsertionMode::PrependText : Editor::KillRingInsertionMode::AppendText; + editor.addTextToKillRing(text, insertionMode); +} + void InspectorFrontendHost::openInNewTab(const String& url) { + if (WebCore::protocolIsJavaScript(url)) + return; + if (m_client) m_client->openInNewTab(url); } @@ -267,72 +333,56 @@ void InspectorFrontendHost::sendMessageToBackend(const String& message) } #if ENABLE(CONTEXT_MENUS) + void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items) { if (!event) return; ASSERT(m_frontendPage); - JSC::ExecState* frontendExecState = execStateFromPage(debuggerWorld(), m_frontendPage); - Deprecated::ScriptObject frontendApiObject; - if (!ScriptGlobalObject::get(frontendExecState, "InspectorFrontendAPI", frontendApiObject)) { + auto& state = *execStateFromPage(debuggerWorld(), m_frontendPage); + JSC::JSObject* frontendApiObject; + if (!ScriptGlobalObject::get(state, "InspectorFrontendAPI", frontendApiObject)) { ASSERT_NOT_REACHED(); return; } - RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, frontendApiObject, items); - m_frontendPage->contextMenuController().showContextMenu(event, menuProvider); - m_menuProvider = menuProvider.get(); + auto menuProvider = FrontendMenuProvider::create(this, { &state, frontendApiObject }, items); + m_menuProvider = menuProvider.ptr(); + m_frontendPage->contextMenuController().showContextMenu(*event, menuProvider); } + #endif void InspectorFrontendHost::dispatchEventAsContextMenuEvent(Event* event) { #if ENABLE(CONTEXT_MENUS) && USE(ACCESSIBILITY_CONTEXT_MENUS) - if (!event || !event->isMouseEvent()) + if (!is<MouseEvent>(event)) return; Frame* frame = event->target()->toNode()->document().frame(); - MouseEvent* mouseEvent = toMouseEvent(event); - IntPoint mousePoint = IntPoint(mouseEvent->clientX(), mouseEvent->clientY()); + MouseEvent& mouseEvent = downcast<MouseEvent>(*event); + IntPoint mousePoint = IntPoint(mouseEvent.clientX(), mouseEvent.clientY()); - m_frontendPage->contextMenuController().showContextMenuAt(frame, mousePoint); + m_frontendPage->contextMenuController().showContextMenuAt(*frame, mousePoint); #else UNUSED_PARAM(event); #endif } -String InspectorFrontendHost::loadResourceSynchronously(const String& url) -{ - ResourceRequest request(url); - request.setHTTPMethod("GET"); - - Vector<char> data; - ResourceError error; - ResourceResponse response; - m_frontendPage->mainFrame().loader().loadResourceSynchronously(request, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, error, response, data); - return String::fromUTF8(data.data(), data.size()); -} - bool InspectorFrontendHost::isUnderTest() { return m_client && m_client->isUnderTest(); } -void InspectorFrontendHost::beep() -{ - systemBeep(); -} - -bool InspectorFrontendHost::canSaveAs() +void InspectorFrontendHost::unbufferedLog(const String& message) { - return false; + // This is used only for debugging inspector tests. + WTFLogAlways("%s", message.utf8().data()); } -bool InspectorFrontendHost::canInspectWorkers() +void InspectorFrontendHost::beep() { - return false; + systemBeep(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorFrontendHost.h b/Source/WebCore/inspector/InspectorFrontendHost.h index 9dc67b0c7..b6af405e6 100644 --- a/Source/WebCore/inspector/InspectorFrontendHost.h +++ b/Source/WebCore/inspector/InspectorFrontendHost.h @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -26,10 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorFrontendHost_h -#define InspectorFrontendHost_h +#pragma once -#include "ConsoleTypes.h" #include "ContextMenu.h" #include "ContextMenuProvider.h" #include <wtf/RefCounted.h> @@ -46,31 +44,41 @@ class Page; class InspectorFrontendHost : public RefCounted<InspectorFrontendHost> { public: - static PassRefPtr<InspectorFrontendHost> create(InspectorFrontendClient* client, Page* frontendPage) + static Ref<InspectorFrontendHost> create(InspectorFrontendClient* client, Page* frontendPage) { - return adoptRef(new InspectorFrontendHost(client, frontendPage)); + return adoptRef(*new InspectorFrontendHost(client, frontendPage)); } - ~InspectorFrontendHost(); - void disconnectClient(); + WEBCORE_EXPORT ~InspectorFrontendHost(); + WEBCORE_EXPORT void disconnectClient(); void loaded(); void requestSetDockSide(const String&); void closeWindow(); void bringToFront(); - void setZoomFactor(float); void inspectedURLChanged(const String&); + void setZoomFactor(float); + float zoomFactor(); + + String userInterfaceLayoutDirection(); + void setAttachedWindowHeight(unsigned); void setAttachedWindowWidth(unsigned); - void setToolbarHeight(unsigned); + void startWindowDrag(); void moveWindowBy(float x, float y) const; String localizedStringsURL(); + String backendCommandsURL(); String debuggableType(); + unsigned inspectionLevel(); + + String platform(); + String port(); void copyText(const String& text); + void killText(const String& text, bool shouldPrependToKillRing, bool shouldStartNewSequence); void openInNewTab(const String& url); bool canSave(); void save(const String& url, const String& content, bool base64Encoded, bool forceSaveAs); @@ -84,20 +92,16 @@ public: void sendMessageToBackend(const String& message); void dispatchEventAsContextMenuEvent(Event*); - String loadResourceSynchronously(const String& url); - bool isUnderTest(); + void unbufferedLog(const String& message); void beep(); - bool canInspectWorkers(); - bool canSaveAs(); - private: #if ENABLE(CONTEXT_MENUS) friend class FrontendMenuProvider; #endif - InspectorFrontendHost(InspectorFrontendClient*, Page* frontendPage); + WEBCORE_EXPORT InspectorFrontendHost(InspectorFrontendClient*, Page* frontendPage); InspectorFrontendClient* m_client; Page* m_frontendPage; @@ -107,5 +111,3 @@ private: }; } // namespace WebCore - -#endif // !defined(InspectorFrontendHost_h) diff --git a/Source/WebCore/inspector/InspectorFrontendHost.idl b/Source/WebCore/inspector/InspectorFrontendHost.idl index b18fa10e5..0fe5feb78 100644 --- a/Source/WebCore/inspector/InspectorFrontendHost.idl +++ b/Source/WebCore/inspector/InspectorFrontendHost.idl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007-2017 Apple Inc. All rights reserved. * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> * Copyright (C) 2009 Google Inc. All rights reserved. * @@ -31,51 +31,49 @@ */ [ + ImplementationLacksVTable, NoInterfaceObject, - Conditional=INSPECTOR, - ImplementationLacksVTable ] interface InspectorFrontendHost { void loaded(); void closeWindow(); void bringToFront(); - void setZoomFactor(float zoom); void inspectedURLChanged(DOMString newURL); + void setZoomFactor(unrestricted float zoom); + float zoomFactor(); + + DOMString userInterfaceLayoutDirection(); + void requestSetDockSide(DOMString side); void setAttachedWindowHeight(unsigned long height); void setAttachedWindowWidth(unsigned long width); - void setToolbarHeight(float height); - void moveWindowBy(float x, float y); + void startWindowDrag(); + void moveWindowBy(unrestricted float x, unrestricted float y); DOMString localizedStringsURL(); + DOMString backendCommandsURL(); DOMString debuggableType(); + unsigned long inspectionLevel(); void copyText(DOMString text); + void killText(DOMString text, boolean shouldPrependToKillRing, boolean shouldStartNewSequence); void openInNewTab(DOMString url); boolean canSave(); void save(DOMString url, DOMString content, boolean base64Encoded, boolean forceSaveAs); void append(DOMString url, DOMString content); void close(DOMString url); - [Custom] DOMString platform(); - [Custom] DOMString port(); + DOMString platform(); + DOMString port(); + [Custom] void showContextMenu(MouseEvent event, any items); - void dispatchEventAsContextMenuEvent(Event event); + void dispatchEventAsContextMenuEvent(Event? event); void sendMessageToBackend(DOMString message); - - [Custom] void recordActionTaken(unsigned long actionCode); - [Custom] void recordPanelShown(unsigned long panelCode); - [Custom] void recordSettingChanged(unsigned long settingChanged); - - DOMString loadResourceSynchronously(DOMString url); + void unbufferedLog(DOMString message); boolean isUnderTest(); void beep(); - - // Deprecated - boolean canInspectWorkers(); - boolean canSaveAs(); }; diff --git a/Source/WebCore/inspector/InspectorHeapProfilerAgent.cpp b/Source/WebCore/inspector/InspectorHeapProfilerAgent.cpp deleted file mode 100644 index ccfe2f89d..000000000 --- a/Source/WebCore/inspector/InspectorHeapProfilerAgent.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "InspectorHeapProfilerAgent.h" - -#if ENABLE(INSPECTOR) - -#include "CommandLineAPIHost.h" -#include "InstrumentingAgents.h" -#include "PageInjectedScriptManager.h" -#include "ScriptProfiler.h" -#include <inspector/InjectedScript.h> - -using namespace Inspector; - -namespace WebCore { - -static const char* const UserInitiatedProfileNameHeap = "org.webkit.profiles.user-initiated"; - -InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InstrumentingAgents* instrumentingAgents, PageInjectedScriptManager* injectedScriptManager) - : InspectorAgentBase(ASCIILiteral("HeapProfiler"), instrumentingAgents) - , m_injectedScriptManager(injectedScriptManager) - , m_nextUserInitiatedHeapSnapshotNumber(1) - , m_profileHeadersRequested(false) -{ - m_instrumentingAgents->setInspectorHeapProfilerAgent(this); -} - -InspectorHeapProfilerAgent::~InspectorHeapProfilerAgent() -{ - m_instrumentingAgents->setInspectorHeapProfilerAgent(nullptr); -} - -void InspectorHeapProfilerAgent::resetState() -{ - m_snapshots.clear(); - m_nextUserInitiatedHeapSnapshotNumber = 1; - resetFrontendProfiles(); - - if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) - commandLineAPIHost->clearInspectedObjects(); -} - -void InspectorHeapProfilerAgent::resetFrontendProfiles() -{ - if (!m_frontendDispatcher) - return; - if (!m_profileHeadersRequested) - return; - if (m_snapshots.isEmpty()) - m_frontendDispatcher->resetProfiles(); -} - -void InspectorHeapProfilerAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) -{ - m_frontendDispatcher = std::make_unique<InspectorHeapProfilerFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorHeapProfilerBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorHeapProfilerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) -{ - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - m_profileHeadersRequested = false; -} - -void InspectorHeapProfilerAgent::collectGarbage(WebCore::ErrorString*) -{ - ScriptProfiler::collectGarbage(); -} - -PassRefPtr<Inspector::TypeBuilder::HeapProfiler::ProfileHeader> InspectorHeapProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot) -{ - RefPtr<Inspector::TypeBuilder::HeapProfiler::ProfileHeader> header = Inspector::TypeBuilder::HeapProfiler::ProfileHeader::create() - .setUid(snapshot.uid()) - .setTitle(snapshot.title()); - header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId()); - return header.release(); -} - -void InspectorHeapProfilerAgent::hasHeapProfiler(ErrorString*, bool* result) -{ - *result = ScriptProfiler::hasHeapProfiler(); -} - -void InspectorHeapProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::HeapProfiler::ProfileHeader>>& headers) -{ - m_profileHeadersRequested = true; - headers = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::HeapProfiler::ProfileHeader>::create(); - - IdToHeapSnapshotMap::iterator snapshotsEnd = m_snapshots.end(); - for (IdToHeapSnapshotMap::iterator it = m_snapshots.begin(); it != snapshotsEnd; ++it) - headers->addItem(createSnapshotHeader(*it->value)); -} - -void InspectorHeapProfilerAgent::getHeapSnapshot(ErrorString* errorString, int rawUid) -{ - class OutputStream : public ScriptHeapSnapshot::OutputStream { - public: - OutputStream(InspectorHeapProfilerFrontendDispatcher* frontend, unsigned uid) - : m_frontendDispatcher(frontend), m_uid(uid) { } - void Write(const String& chunk) override { m_frontendDispatcher->addHeapSnapshotChunk(m_uid, chunk); } - void Close() override { m_frontendDispatcher->finishHeapSnapshot(m_uid); } - private: - InspectorHeapProfilerFrontendDispatcher* m_frontendDispatcher; - int m_uid; - }; - - unsigned uid = static_cast<unsigned>(rawUid); - IdToHeapSnapshotMap::iterator it = m_snapshots.find(uid); - if (it == m_snapshots.end()) { - *errorString = "Profile wasn't found"; - return; - } - RefPtr<ScriptHeapSnapshot> snapshot = it->value; - if (m_frontendDispatcher) { - OutputStream stream(m_frontendDispatcher.get(), uid); - snapshot->writeJSON(&stream); - } -} - -void InspectorHeapProfilerAgent::removeProfile(ErrorString*, int rawUid) -{ - unsigned uid = static_cast<unsigned>(rawUid); - if (m_snapshots.contains(uid)) - m_snapshots.remove(uid); -} - -void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* reportProgress) -{ - class HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress { - public: - explicit HeapSnapshotProgress(InspectorHeapProfilerFrontendDispatcher* frontend) - : m_frontendDispatcher(frontend) { } - void Start(int totalWork) override - { - m_totalWork = totalWork; - } - void Worked(int workDone) override - { - if (m_frontendDispatcher) - m_frontendDispatcher->reportHeapSnapshotProgress(workDone, m_totalWork); - } - void Done() override { } - bool isCanceled() { return false; } - private: - InspectorHeapProfilerFrontendDispatcher* m_frontendDispatcher; - int m_totalWork; - }; - - String title = makeString(UserInitiatedProfileNameHeap, '.', String::number(m_nextUserInitiatedHeapSnapshotNumber)); - ++m_nextUserInitiatedHeapSnapshotNumber; - - HeapSnapshotProgress progress(reportProgress && *reportProgress ? m_frontendDispatcher.get() : nullptr); - RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, &progress); - if (snapshot) { - m_snapshots.add(snapshot->uid(), snapshot); - if (m_frontendDispatcher) - m_frontendDispatcher->addProfileHeader(createSnapshotHeader(*snapshot)); - } -} - -void InspectorHeapProfilerAgent::getObjectByHeapObjectId(ErrorString* error, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) -{ - bool ok; - unsigned id = heapSnapshotObjectId.toUInt(&ok); - if (!ok) { - *error = "Invalid heap snapshot object id"; - return; - } - Deprecated::ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id); - if (heapObject.hasNoValue()) { - *error = "Object is not available"; - return; - } - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState()); - if (injectedScript.hasNoValue()) { - *error = "Object is not available. Inspected context is gone"; - return; - } - result = injectedScript.wrapObject(heapObject, objectGroup ? *objectGroup : ""); - if (!result) - *error = "Failed to wrap object"; -} - -void InspectorHeapProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId) -{ - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); - if (injectedScript.hasNoValue()) { - *errorString = "Inspected context has gone"; - return; - } - Deprecated::ScriptValue value = injectedScript.findObjectById(objectId); - if (value.hasNoValue() || value.isUndefined()) { - *errorString = "Object with given id not found"; - return; - } - unsigned id = ScriptProfiler::getHeapObjectId(value); - *heapSnapshotObjectId = String::number(id); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorHeapProfilerAgent.h b/Source/WebCore/inspector/InspectorHeapProfilerAgent.h deleted file mode 100644 index e417c3cb0..000000000 --- a/Source/WebCore/inspector/InspectorHeapProfilerAgent.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorHeapProfilerAgent_h -#define InspectorHeapProfilerAgent_h - -#if ENABLE(INSPECTOR) - -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { - -class PageInjectedScriptManager; -class ScriptHeapSnapshot; -class ScriptProfile; - -typedef String ErrorString; - -class InspectorHeapProfilerAgent : public InspectorAgentBase, public Inspector::InspectorHeapProfilerBackendDispatcherHandler { - WTF_MAKE_NONCOPYABLE(InspectorHeapProfilerAgent); WTF_MAKE_FAST_ALLOCATED; -public: - InspectorHeapProfilerAgent(InstrumentingAgents*, PageInjectedScriptManager*); - virtual ~InspectorHeapProfilerAgent(); - - virtual void collectGarbage(ErrorString*) override; - virtual void clearProfiles(ErrorString*) override { resetState(); } - void resetState(); - - virtual void hasHeapProfiler(ErrorString*, bool*) override; - - virtual void getProfileHeaders(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::HeapProfiler::ProfileHeader>>&) override; - virtual void getHeapSnapshot(ErrorString*, int uid) override; - virtual void removeProfile(ErrorString*, int uid) override; - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - virtual void takeHeapSnapshot(ErrorString*, const bool* reportProgress) override; - - virtual void getObjectByHeapObjectId(ErrorString*, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) override; - virtual void getHeapObjectId(ErrorString*, const String& objectId, String* heapSnapshotObjectId) override; - -private: - typedef HashMap<unsigned, RefPtr<ScriptHeapSnapshot>> IdToHeapSnapshotMap; - - void resetFrontendProfiles(); - - PassRefPtr<Inspector::TypeBuilder::HeapProfiler::ProfileHeader> createSnapshotHeader(const ScriptHeapSnapshot&); - - PageInjectedScriptManager* m_injectedScriptManager; - std::unique_ptr<Inspector::InspectorHeapProfilerFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorHeapProfilerBackendDispatcher> m_backendDispatcher; - unsigned m_nextUserInitiatedHeapSnapshotNumber; - IdToHeapSnapshotMap m_snapshots; - bool m_profileHeadersRequested; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorHeapProfilerAgent_h) diff --git a/Source/WebCore/inspector/InspectorHistory.cpp b/Source/WebCore/inspector/InspectorHistory.cpp index bcfef4a4b..2c0816e81 100644 --- a/Source/WebCore/inspector/InspectorHistory.cpp +++ b/Source/WebCore/inspector/InspectorHistory.cpp @@ -29,119 +29,84 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorHistory.h" -#include "ExceptionCodePlaceholder.h" #include "Node.h" namespace WebCore { -namespace { - class UndoableStateMark : public InspectorHistory::Action { public: - UndoableStateMark() : InspectorHistory::Action("[UndoableState]") { } - - virtual bool perform(ExceptionCode&) override { return true; } - - virtual bool undo(ExceptionCode&) override { return true; } - - virtual bool redo(ExceptionCode&) override { return true; } + UndoableStateMark() + : Action("[UndoableState]") + { + } - virtual bool isUndoableStateMark() override { return true; } +private: + ExceptionOr<void> perform() final { return { }; } + ExceptionOr<void> undo() final { return { }; } + ExceptionOr<void> redo() final { return { }; } + bool isUndoableStateMark() final { return true; } }; -} - -InspectorHistory::Action::Action(const String& name) : m_name(name) -{ -} - -InspectorHistory::Action::~Action() -{ -} - -String InspectorHistory::Action::toString() +ExceptionOr<void> InspectorHistory::perform(std::unique_ptr<Action> action) { - return m_name; -} - -bool InspectorHistory::Action::isUndoableStateMark() -{ - return false; -} - -String InspectorHistory::Action::mergeId() -{ - return ""; -} - -void InspectorHistory::Action::merge(PassOwnPtr<Action>) -{ -} - -InspectorHistory::InspectorHistory() : m_afterLastActionIndex(0) { } - -InspectorHistory::~InspectorHistory() { } - -bool InspectorHistory::perform(PassOwnPtr<Action> action, ExceptionCode& ec) -{ - if (!action->perform(ec)) - return false; + auto performResult = action->perform(); + if (performResult.hasException()) + return performResult.releaseException(); if (!action->mergeId().isEmpty() && m_afterLastActionIndex > 0 && action->mergeId() == m_history[m_afterLastActionIndex - 1]->mergeId()) - m_history[m_afterLastActionIndex - 1]->merge(action); + m_history[m_afterLastActionIndex - 1]->merge(WTFMove(action)); else { m_history.resize(m_afterLastActionIndex); - m_history.append(action); + m_history.append(WTFMove(action)); ++m_afterLastActionIndex; } - return true; + return { }; } void InspectorHistory::markUndoableState() { - perform(adoptPtr(new UndoableStateMark()), IGNORE_EXCEPTION); + perform(std::make_unique<UndoableStateMark>()); } -bool InspectorHistory::undo(ExceptionCode& ec) +ExceptionOr<void> InspectorHistory::undo() { while (m_afterLastActionIndex > 0 && m_history[m_afterLastActionIndex - 1]->isUndoableStateMark()) --m_afterLastActionIndex; while (m_afterLastActionIndex > 0) { Action* action = m_history[m_afterLastActionIndex - 1].get(); - if (!action->undo(ec)) { + auto undoResult = action->undo(); + if (undoResult.hasException()) { reset(); - return false; + return undoResult.releaseException(); } --m_afterLastActionIndex; if (action->isUndoableStateMark()) break; } - return true; + return { }; } -bool InspectorHistory::redo(ExceptionCode& ec) +ExceptionOr<void> InspectorHistory::redo() { while (m_afterLastActionIndex < m_history.size() && m_history[m_afterLastActionIndex]->isUndoableStateMark()) ++m_afterLastActionIndex; while (m_afterLastActionIndex < m_history.size()) { Action* action = m_history[m_afterLastActionIndex].get(); - if (!action->redo(ec)) { + auto redoResult = action->redo(); + if (redoResult.hasException()) { reset(); - return false; + return redoResult.releaseException(); } ++m_afterLastActionIndex; if (action->isUndoableStateMark()) break; } - return true; + return { }; } void InspectorHistory::reset() @@ -151,5 +116,3 @@ void InspectorHistory::reset() } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorHistory.h b/Source/WebCore/inspector/InspectorHistory.h index 7224a393e..318fca376 100644 --- a/Source/WebCore/inspector/InspectorHistory.h +++ b/Source/WebCore/inspector/InspectorHistory.h @@ -28,63 +28,53 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorHistory_h -#define InspectorHistory_h +#pragma once -#include "ExceptionCode.h" - -#include <wtf/OwnPtr.h> +#include "ExceptionOr.h" #include <wtf/Vector.h> -#include <wtf/text/WTFString.h> namespace WebCore { -class ContainerNode; -class Element; -class Node; - -#if ENABLE(INSPECTOR) - -class InspectorHistory { +class InspectorHistory final { WTF_MAKE_NONCOPYABLE(InspectorHistory); WTF_MAKE_FAST_ALLOCATED; public: class Action { WTF_MAKE_FAST_ALLOCATED; public: - Action(const String& name); - virtual ~Action(); - virtual String toString(); + explicit Action(const String& name) + : m_name { name } + { + } + + virtual ~Action() = default; + virtual String toString() { return m_name; } - virtual String mergeId(); - virtual void merge(PassOwnPtr<Action>); + virtual String mergeId() { return emptyString(); } + virtual void merge(std::unique_ptr<Action>) { }; - virtual bool perform(ExceptionCode&) = 0; + virtual ExceptionOr<void> perform() = 0; - virtual bool undo(ExceptionCode&) = 0; - virtual bool redo(ExceptionCode&) = 0; + virtual ExceptionOr<void> undo() = 0; + virtual ExceptionOr<void> redo() = 0; + + virtual bool isUndoableStateMark() { return false; } - virtual bool isUndoableStateMark(); private: String m_name; }; - InspectorHistory(); - virtual ~InspectorHistory(); + InspectorHistory() = default; - bool perform(PassOwnPtr<Action>, ExceptionCode&); + ExceptionOr<void> perform(std::unique_ptr<Action>); void markUndoableState(); - bool undo(ExceptionCode&); - bool redo(ExceptionCode&); + ExceptionOr<void> undo(); + ExceptionOr<void> redo(); void reset(); private: - Vector<OwnPtr<Action>> m_history; - size_t m_afterLastActionIndex; + Vector<std::unique_ptr<Action>> m_history; + size_t m_afterLastActionIndex { 0 }; }; -#endif // ENABLE(INSPECTOR) - } // namespace WebCore - -#endif // !defined(InspectorHistory_h) diff --git a/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp b/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp index af3c598f7..ef3d268d0 100644 --- a/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp +++ b/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,25 +30,23 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE) - #include "InspectorIndexedDBAgent.h" +#if ENABLE(INDEXED_DATABASE) + #include "DOMStringList.h" #include "DOMWindow.h" #include "DOMWindowIndexedDatabase.h" #include "Document.h" #include "Event.h" #include "EventListener.h" +#include "EventNames.h" #include "EventTarget.h" -#include "ExceptionCode.h" #include "Frame.h" +#include "IDBBindingUtilities.h" #include "IDBCursor.h" #include "IDBCursorWithValue.h" #include "IDBDatabase.h" -#include "IDBDatabaseCallbacks.h" -#include "IDBDatabaseMetadata.h" #include "IDBFactory.h" #include "IDBIndex.h" #include "IDBKey.h" @@ -55,32 +54,35 @@ #include "IDBKeyRange.h" #include "IDBObjectStore.h" #include "IDBOpenDBRequest.h" -#include "IDBPendingTransactionMonitor.h" #include "IDBRequest.h" #include "IDBTransaction.h" #include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" +#include "ScriptState.h" #include "SecurityOrigin.h" +#include <heap/HeapInlines.h> #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <inspector/InspectorFrontendRouter.h> #include <inspector/InspectorValues.h> +#include <wtf/NeverDestroyed.h> #include <wtf/Vector.h> -using Inspector::TypeBuilder::Array; -using Inspector::TypeBuilder::IndexedDB::DatabaseWithObjectStores; -using Inspector::TypeBuilder::IndexedDB::DataEntry; -using Inspector::TypeBuilder::IndexedDB::Key; -using Inspector::TypeBuilder::IndexedDB::KeyPath; -using Inspector::TypeBuilder::IndexedDB::KeyRange; -using Inspector::TypeBuilder::IndexedDB::ObjectStore; -using Inspector::TypeBuilder::IndexedDB::ObjectStoreIndex; - -typedef Inspector::InspectorBackendDispatcher::CallbackBase RequestCallback; -typedef Inspector::InspectorIndexedDBBackendDispatcherHandler::RequestDatabaseNamesCallback RequestDatabaseNamesCallback; -typedef Inspector::InspectorIndexedDBBackendDispatcherHandler::RequestDatabaseCallback RequestDatabaseCallback; -typedef Inspector::InspectorIndexedDBBackendDispatcherHandler::RequestDataCallback RequestDataCallback; -typedef Inspector::InspectorIndexedDBBackendDispatcherHandler::ClearObjectStoreCallback ClearObjectStoreCallback; +using Inspector::Protocol::Array; +using Inspector::Protocol::IndexedDB::DatabaseWithObjectStores; +using Inspector::Protocol::IndexedDB::DataEntry; +using Inspector::Protocol::IndexedDB::Key; +using Inspector::Protocol::IndexedDB::KeyPath; +using Inspector::Protocol::IndexedDB::KeyRange; +using Inspector::Protocol::IndexedDB::ObjectStore; +using Inspector::Protocol::IndexedDB::ObjectStoreIndex; + +typedef Inspector::BackendDispatcher::CallbackBase RequestCallback; +typedef Inspector::IndexedDBBackendDispatcherHandler::RequestDatabaseNamesCallback RequestDatabaseNamesCallback; +typedef Inspector::IndexedDBBackendDispatcherHandler::RequestDatabaseCallback RequestDatabaseCallback; +typedef Inspector::IndexedDBBackendDispatcherHandler::RequestDataCallback RequestDataCallback; +typedef Inspector::IndexedDBBackendDispatcherHandler::ClearObjectStoreCallback ClearObjectStoreCallback; using namespace Inspector; @@ -88,283 +90,220 @@ namespace WebCore { namespace { -class GetDatabaseNamesCallback : public EventListener { - WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback); -public: - static PassRefPtr<GetDatabaseNamesCallback> create(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin) - { - return adoptRef(new GetDatabaseNamesCallback(requestCallback, securityOrigin)); - } - - virtual ~GetDatabaseNamesCallback() { } - - virtual bool operator==(const EventListener& other) override - { - return this == &other; - } - - virtual void handleEvent(ScriptExecutionContext*, Event* event) override - { - if (!m_requestCallback->isActive()) - return; - if (event->type() != eventNames().successEvent) { - m_requestCallback->sendFailure("Unexpected event type."); - return; - } - - IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target()); - ExceptionCode ec = 0; - RefPtr<IDBAny> requestResult = idbRequest->result(ec); - if (ec) { - m_requestCallback->sendFailure("Could not get result in callback."); - return; - } - if (requestResult->type() != IDBAny::DOMStringListType) { - m_requestCallback->sendFailure("Unexpected result type."); - return; - } - - RefPtr<DOMStringList> databaseNamesList = requestResult->domStringList(); - RefPtr<Inspector::TypeBuilder::Array<String>> databaseNames = Inspector::TypeBuilder::Array<String>::create(); - for (size_t i = 0; i < databaseNamesList->length(); ++i) - databaseNames->addItem(databaseNamesList->item(i)); - m_requestCallback->sendSuccess(databaseNames.release()); - } - -private: - GetDatabaseNamesCallback(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin) - : EventListener(EventListener::CPPEventListenerType) - , m_requestCallback(requestCallback) - , m_securityOrigin(securityOrigin) { } - RefPtr<RequestDatabaseNamesCallback> m_requestCallback; - String m_securityOrigin; -}; - class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> { public: ExecutableWithDatabase(ScriptExecutionContext* context) : m_context(context) { } - virtual ~ExecutableWithDatabase() { }; + virtual ~ExecutableWithDatabase() { } void start(IDBFactory*, SecurityOrigin*, const String& databaseName); - virtual void execute(PassRefPtr<IDBDatabase>) = 0; - virtual RequestCallback* requestCallback() = 0; - ScriptExecutionContext* context() { return m_context; }; + virtual void execute(IDBDatabase&) = 0; + virtual RequestCallback& requestCallback() = 0; + ScriptExecutionContext* context() const { return m_context; } private: ScriptExecutionContext* m_context; }; -class OpenDatabaseCallback : public EventListener { +class OpenDatabaseCallback final : public EventListener { public: - static PassRefPtr<OpenDatabaseCallback> create(ExecutableWithDatabase* executableWithDatabase) + static Ref<OpenDatabaseCallback> create(ExecutableWithDatabase& executableWithDatabase) { - return adoptRef(new OpenDatabaseCallback(executableWithDatabase)); + return adoptRef(*new OpenDatabaseCallback(executableWithDatabase)); } - virtual ~OpenDatabaseCallback() { } - - virtual bool operator==(const EventListener& other) override + bool operator==(const EventListener& other) const final { return this == &other; } - virtual void handleEvent(ScriptExecutionContext*, Event* event) override + void handleEvent(ScriptExecutionContext*, Event* event) final { if (event->type() != eventNames().successEvent) { - m_executableWithDatabase->requestCallback()->sendFailure("Unexpected event type."); + m_executableWithDatabase->requestCallback().sendFailure("Unexpected event type."); return; } - IDBOpenDBRequest* idbOpenDBRequest = static_cast<IDBOpenDBRequest*>(event->target()); - ExceptionCode ec = 0; - RefPtr<IDBAny> requestResult = idbOpenDBRequest->result(ec); - if (ec) { - m_executableWithDatabase->requestCallback()->sendFailure("Could not get result in callback."); + auto& request = static_cast<IDBOpenDBRequest&>(*event->target()); + + auto result = request.result(); + if (result.hasException()) { + m_executableWithDatabase->requestCallback().sendFailure("Could not get result in callback."); return; } - if (requestResult->type() != IDBAny::IDBDatabaseType) { - m_executableWithDatabase->requestCallback()->sendFailure("Unexpected result type."); + + auto resultValue = result.releaseReturnValue(); + if (!resultValue || !WTF::holds_alternative<RefPtr<IDBDatabase>>(resultValue.value())) { + m_executableWithDatabase->requestCallback().sendFailure("Unexpected result type."); return; } - RefPtr<IDBDatabase> idbDatabase = requestResult->idbDatabase(); - m_executableWithDatabase->execute(idbDatabase); - IDBPendingTransactionMonitor::deactivateNewTransactions(); - idbDatabase->close(); + auto databaseResult = WTF::get<RefPtr<IDBDatabase>>(resultValue.value()); + m_executableWithDatabase->execute(*databaseResult); + databaseResult->close(); } private: - OpenDatabaseCallback(ExecutableWithDatabase* executableWithDatabase) + OpenDatabaseCallback(ExecutableWithDatabase& executableWithDatabase) : EventListener(EventListener::CPPEventListenerType) , m_executableWithDatabase(executableWithDatabase) { } - RefPtr<ExecutableWithDatabase> m_executableWithDatabase; + Ref<ExecutableWithDatabase> m_executableWithDatabase; }; void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, const String& databaseName) { - RefPtr<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this); - ExceptionCode ec = 0; - RefPtr<IDBOpenDBRequest> idbOpenDBRequest = idbFactory->open(context(), databaseName, ec); - if (ec) { - requestCallback()->sendFailure("Could not open database."); + if (!context()) { + requestCallback().sendFailure("Could not open database."); + return; + } + + auto result = idbFactory->open(*context(), databaseName, std::nullopt); + if (result.hasException()) { + requestCallback().sendFailure("Could not open database."); return; } - idbOpenDBRequest->addEventListener(eventNames().successEvent, callback, false); + + result.releaseReturnValue()->addEventListener(eventNames().successEvent, OpenDatabaseCallback::create(*this), false); } -static PassRefPtr<IDBTransaction> transactionForDatabase(ScriptExecutionContext* scriptExecutionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly()) + +static RefPtr<KeyPath> keyPathFromIDBKeyPath(const std::optional<IDBKeyPath>& idbKeyPath) { - ExceptionCode ec = 0; - RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(scriptExecutionContext, objectStoreName, mode, ec); - if (ec) - return nullptr; - return idbTransaction; + if (!idbKeyPath) + return KeyPath::create().setType(KeyPath::Type::Null).release(); + + auto visitor = WTF::makeVisitor([](const String& string) { + RefPtr<KeyPath> keyPath = KeyPath::create().setType(KeyPath::Type::String).release(); + keyPath->setString(string); + return keyPath; + }, [](const Vector<String>& vector) { + auto array = Inspector::Protocol::Array<String>::create(); + for (auto& string : vector) + array->addItem(string); + RefPtr<KeyPath> keyPath = KeyPath::create().setType(KeyPath::Type::Array).release(); + keyPath->setArray(WTFMove(array)); + return keyPath; + }); + return WTF::visit(visitor, idbKeyPath.value()); } -static PassRefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName) +static RefPtr<IDBTransaction> transactionForDatabase(IDBDatabase* idbDatabase, const String& objectStoreName, IDBTransactionMode mode = IDBTransactionMode::Readonly) { - ExceptionCode ec = 0; - RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectStoreName, ec); - if (ec) + auto result = idbDatabase->transaction(objectStoreName, mode); + if (result.hasException()) return nullptr; - return idbObjectStore; + return result.releaseReturnValue(); } -static PassRefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName) +static RefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName) { - ExceptionCode ec = 0; - RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, ec); - if (ec) + auto result = idbTransaction->objectStore(objectStoreName); + if (result.hasException()) return nullptr; - return idbIndex; + return result.releaseReturnValue(); } -#if !PLATFORM(MAC) -static PassRefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath) +static RefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName) { - RefPtr<KeyPath> keyPath; - switch (idbKeyPath.type()) { - case IDBKeyPath::NullType: - keyPath = KeyPath::create().setType(KeyPath::Type::Null); - break; - case IDBKeyPath::StringType: - keyPath = KeyPath::create().setType(KeyPath::Type::String); - keyPath->setString(idbKeyPath.string()); - break; - case IDBKeyPath::ArrayType: { - keyPath = KeyPath::create().setType(KeyPath::Type::Array); - RefPtr<Inspector::TypeBuilder::Array<String>> array = Inspector::TypeBuilder::Array<String>::create(); - const Vector<String>& stringArray = idbKeyPath.array(); - for (size_t i = 0; i < stringArray.size(); ++i) - array->addItem(stringArray[i]); - keyPath->setArray(array); - break; - } - default: - ASSERT_NOT_REACHED(); - } - - return keyPath.release(); + auto index = idbObjectStore->index(indexName); + if (index.hasException()) + return nullptr; + return index.releaseReturnValue(); } -#endif // !PLATFORM(MAC) -class DatabaseLoader : public ExecutableWithDatabase { +class DatabaseLoader final : public ExecutableWithDatabase { public: - static PassRefPtr<DatabaseLoader> create(ScriptExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback) + static Ref<DatabaseLoader> create(ScriptExecutionContext* context, Ref<RequestDatabaseCallback>&& requestCallback) { - return adoptRef(new DatabaseLoader(context, requestCallback)); + return adoptRef(*new DatabaseLoader(context, WTFMove(requestCallback))); } virtual ~DatabaseLoader() { } - virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) override + void execute(IDBDatabase& database) override { -#if PLATFORM(MAC) - ASSERT_UNUSED(prpDatabase, prpDatabase); -#else - RefPtr<IDBDatabase> idbDatabase = prpDatabase; - if (!requestCallback()->isActive()) + if (!requestCallback().isActive()) return; - - const IDBDatabaseMetadata databaseMetadata = idbDatabase->metadata(); - - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::IndexedDB::ObjectStore>> objectStores = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::IndexedDB::ObjectStore>::create(); - - for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = databaseMetadata.objectStores.begin(); it != databaseMetadata.objectStores.end(); ++it) { - const IDBObjectStoreMetadata& objectStoreMetadata = it->value; - - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::IndexedDB::ObjectStoreIndex>> indexes = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::IndexedDB::ObjectStoreIndex>::create(); - - for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectStoreMetadata.indexes.begin(); it != objectStoreMetadata.indexes.end(); ++it) { - const IDBIndexMetadata& indexMetadata = it->value; - - RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create() - .setName(indexMetadata.name) - .setKeyPath(keyPathFromIDBKeyPath(indexMetadata.keyPath)) - .setUnique(indexMetadata.unique) - .setMultiEntry(indexMetadata.multiEntry); - indexes->addItem(objectStoreIndex); + + auto& databaseInfo = database.info(); + auto objectStores = Inspector::Protocol::Array<Inspector::Protocol::IndexedDB::ObjectStore>::create(); + auto objectStoreNames = databaseInfo.objectStoreNames(); + for (auto& name : objectStoreNames) { + auto* objectStoreInfo = databaseInfo.infoForExistingObjectStore(name); + if (!objectStoreInfo) + continue; + + auto indexes = Inspector::Protocol::Array<Inspector::Protocol::IndexedDB::ObjectStoreIndex>::create(); + + for (auto& indexInfo : objectStoreInfo->indexMap().values()) { + auto objectStoreIndex = ObjectStoreIndex::create() + .setName(indexInfo.name()) + .setKeyPath(keyPathFromIDBKeyPath(indexInfo.keyPath())) + .setUnique(indexInfo.unique()) + .setMultiEntry(indexInfo.multiEntry()) + .release(); + indexes->addItem(WTFMove(objectStoreIndex)); } - - RefPtr<ObjectStore> objectStore = ObjectStore::create() - .setName(objectStoreMetadata.name) - .setKeyPath(keyPathFromIDBKeyPath(objectStoreMetadata.keyPath)) - .setAutoIncrement(objectStoreMetadata.autoIncrement) - .setIndexes(indexes); - objectStores->addItem(objectStore); + + auto objectStore = ObjectStore::create() + .setName(objectStoreInfo->name()) + .setKeyPath(keyPathFromIDBKeyPath(objectStoreInfo->keyPath())) + .setAutoIncrement(objectStoreInfo->autoIncrement()) + .setIndexes(WTFMove(indexes)) + .release(); + objectStores->addItem(WTFMove(objectStore)); } - RefPtr<DatabaseWithObjectStores> result = DatabaseWithObjectStores::create() - .setName(databaseMetadata.name) - .setIntVersion(databaseMetadata.version) - .setVersion(String::number(databaseMetadata.version)) - .setObjectStores(objectStores); - - m_requestCallback->sendSuccess(result); -#endif // PLATFORM(MAC) + + auto result = DatabaseWithObjectStores::create() + .setName(databaseInfo.name()) + .setVersion(databaseInfo.version()) + .setObjectStores(WTFMove(objectStores)) + .release(); + m_requestCallback->sendSuccess(WTFMove(result)); } - virtual RequestCallback* requestCallback() override { return m_requestCallback.get(); } + RequestCallback& requestCallback() override { return m_requestCallback.get(); } private: - DatabaseLoader(ScriptExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback) + DatabaseLoader(ScriptExecutionContext* context, Ref<RequestDatabaseCallback>&& requestCallback) : ExecutableWithDatabase(context) - , m_requestCallback(requestCallback) { } - RefPtr<RequestDatabaseCallback> m_requestCallback; + , m_requestCallback(WTFMove(requestCallback)) { } + Ref<RequestDatabaseCallback> m_requestCallback; }; -static PassRefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key) +static RefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key) { - RefPtr<IDBKey> idbKey; - String type; - if (!key->getString("type", &type)) + if (!key->getString("type", type)) return nullptr; - DEFINE_STATIC_LOCAL(String, number, (ASCIILiteral("number"))); - DEFINE_STATIC_LOCAL(String, string, (ASCIILiteral("string"))); - DEFINE_STATIC_LOCAL(String, date, (ASCIILiteral("date"))); - DEFINE_STATIC_LOCAL(String, array, (ASCIILiteral("array"))); + static NeverDestroyed<const String> numberType(ASCIILiteral("number")); + static NeverDestroyed<const String> stringType(ASCIILiteral("string")); + static NeverDestroyed<const String> dateType(ASCIILiteral("date")); + static NeverDestroyed<const String> arrayType(ASCIILiteral("array")); - if (type == number) { + RefPtr<IDBKey> idbKey; + if (type == numberType) { double number; - if (!key->getNumber("number", &number)) + if (!key->getDouble("number", number)) return nullptr; idbKey = IDBKey::createNumber(number); - } else if (type == string) { + } else if (type == stringType) { String string; - if (!key->getString("string", &string)) + if (!key->getString("string", string)) return nullptr; idbKey = IDBKey::createString(string); - } else if (type == date) { + } else if (type == dateType) { double date; - if (!key->getNumber("date", &date)) + if (!key->getDouble("date", date)) return nullptr; idbKey = IDBKey::createDate(date); - } else if (type == array) { - IDBKey::KeyArray keyArray; - RefPtr<InspectorArray> array = key->getArray("array"); + } else if (type == arrayType) { + Vector<RefPtr<IDBKey>> keyArray; + RefPtr<InspectorArray> array; + if (!key->getArray("array", array)) + return nullptr; for (size_t i = 0; i < array->length(); ++i) { RefPtr<InspectorValue> value = array->get(i); RefPtr<InspectorObject> object; - if (!value->asObject(&object)) + if (!value->asObject(object)) return nullptr; keyArray.append(idbKeyFromInspectorObject(object.get())); } @@ -372,80 +311,77 @@ static PassRefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key) } else return nullptr; - return idbKey.release(); + return idbKey; } -static PassRefPtr<IDBKeyRange> idbKeyRangeFromKeyRange(InspectorObject* keyRange) +static RefPtr<IDBKeyRange> idbKeyRangeFromKeyRange(const InspectorObject* keyRange) { - RefPtr<InspectorObject> lower = keyRange->getObject("lower"); - RefPtr<IDBKey> idbLower = lower ? idbKeyFromInspectorObject(lower.get()) : nullptr; - if (lower && !idbLower) - return nullptr; + RefPtr<IDBKey> idbLower; + RefPtr<InspectorObject> lower; + if (keyRange->getObject(ASCIILiteral("lower"), lower)) { + idbLower = idbKeyFromInspectorObject(lower.get()); + if (!idbLower) + return nullptr; + } - RefPtr<InspectorObject> upper = keyRange->getObject("upper"); - RefPtr<IDBKey> idbUpper = upper ? idbKeyFromInspectorObject(upper.get()) : nullptr; - if (upper && !idbUpper) - return nullptr; + RefPtr<IDBKey> idbUpper; + RefPtr<InspectorObject> upper; + if (keyRange->getObject(ASCIILiteral("upper"), upper)) { + idbUpper = idbKeyFromInspectorObject(upper.get()); + if (!idbUpper) + return nullptr; + } bool lowerOpen; - if (!keyRange->getBoolean("lowerOpen", &lowerOpen)) + if (!keyRange->getBoolean(ASCIILiteral("lowerOpen"), lowerOpen)) return nullptr; - IDBKeyRange::LowerBoundType lowerBoundType = lowerOpen ? IDBKeyRange::LowerBoundOpen : IDBKeyRange::LowerBoundClosed; bool upperOpen; - if (!keyRange->getBoolean("upperOpen", &upperOpen)) + if (!keyRange->getBoolean(ASCIILiteral("upperOpen"), upperOpen)) return nullptr; - IDBKeyRange::UpperBoundType upperBoundType = upperOpen ? IDBKeyRange::UpperBoundOpen : IDBKeyRange::UpperBoundClosed; - RefPtr<IDBKeyRange> idbKeyRange = IDBKeyRange::create(idbLower, idbUpper, lowerBoundType, upperBoundType); - return idbKeyRange.release(); + return IDBKeyRange::create(WTFMove(idbLower), WTFMove(idbUpper), lowerOpen, upperOpen); } -class DataLoader; - -class OpenCursorCallback : public EventListener { +class OpenCursorCallback final : public EventListener { public: - static PassRefPtr<OpenCursorCallback> create(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize) + static Ref<OpenCursorCallback> create(InjectedScript injectedScript, Ref<RequestDataCallback>&& requestCallback, int skipCount, unsigned pageSize) { - return adoptRef(new OpenCursorCallback(injectedScript, requestCallback, skipCount, pageSize)); + return adoptRef(*new OpenCursorCallback(injectedScript, WTFMove(requestCallback), skipCount, pageSize)); } virtual ~OpenCursorCallback() { } - virtual bool operator==(const EventListener& other) override + bool operator==(const EventListener& other) const override { return this == &other; } - virtual void handleEvent(ScriptExecutionContext*, Event* event) override + void handleEvent(ScriptExecutionContext* context, Event* event) override { if (event->type() != eventNames().successEvent) { m_requestCallback->sendFailure("Unexpected event type."); return; } - IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target()); - ExceptionCode ec = 0; - RefPtr<IDBAny> requestResult = idbRequest->result(ec); - if (ec) { + auto& request = static_cast<IDBRequest&>(*event->target()); + + auto result = request.result(); + if (result.hasException()) { m_requestCallback->sendFailure("Could not get result in callback."); return; } - if (requestResult->type() == IDBAny::ScriptValueType) { + + auto resultValue = result.releaseReturnValue(); + if (!resultValue || !WTF::holds_alternative<RefPtr<IDBCursor>>(resultValue.value())) { end(false); return; } - if (requestResult->type() != IDBAny::IDBCursorWithValueType) { - m_requestCallback->sendFailure("Unexpected result type."); - return; - } - RefPtr<IDBCursorWithValue> idbCursor = requestResult->idbCursorWithValue(); + auto cursor = WTF::get<RefPtr<IDBCursor>>(resultValue.value()); if (m_skipCount) { - ExceptionCode ec = 0; - idbCursor->advance(m_skipCount, ec); - if (ec) + if (cursor->advance(m_skipCount).hasException()) m_requestCallback->sendFailure("Could not advance cursor."); m_skipCount = 0; return; @@ -457,97 +393,116 @@ public: } // Continue cursor before making injected script calls, otherwise transaction might be finished. - idbCursor->continueFunction(nullptr, ec); - if (ec) { + if (cursor->continueFunction(nullptr).hasException()) { m_requestCallback->sendFailure("Could not continue cursor."); return; } - RefPtr<DataEntry> dataEntry = DataEntry::create() - .setKey(m_injectedScript.wrapObject(idbCursor->key(), String())) - .setPrimaryKey(m_injectedScript.wrapObject(idbCursor->primaryKey(), String())) - .setValue(m_injectedScript.wrapObject(idbCursor->value(), String())); - m_result->addItem(dataEntry); + auto* state = context ? context->execState() : nullptr; + if (!state) + return; + auto dataEntry = DataEntry::create() + .setKey(m_injectedScript.wrapObject(cursor->key(), String(), true)) + .setPrimaryKey(m_injectedScript.wrapObject(cursor->primaryKey(), String(), true)) + .setValue(m_injectedScript.wrapObject(cursor->value(), String(), true)) + .release(); + m_result->addItem(WTFMove(dataEntry)); } void end(bool hasMore) { if (!m_requestCallback->isActive()) return; - m_requestCallback->sendSuccess(m_result.release(), hasMore); + m_requestCallback->sendSuccess(WTFMove(m_result), hasMore); } private: - OpenCursorCallback(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize) + OpenCursorCallback(InjectedScript injectedScript, Ref<RequestDataCallback>&& requestCallback, int skipCount, unsigned pageSize) : EventListener(EventListener::CPPEventListenerType) , m_injectedScript(injectedScript) - , m_requestCallback(requestCallback) + , m_requestCallback(WTFMove(requestCallback)) + , m_result(Array<DataEntry>::create()) , m_skipCount(skipCount) , m_pageSize(pageSize) { - m_result = Array<DataEntry>::create(); } InjectedScript m_injectedScript; - RefPtr<RequestDataCallback> m_requestCallback; + Ref<RequestDataCallback> m_requestCallback; + Ref<Array<DataEntry>> m_result; int m_skipCount; unsigned m_pageSize; - RefPtr<Array<DataEntry>> m_result; }; -class DataLoader : public ExecutableWithDatabase { +class DataLoader final : public ExecutableWithDatabase { public: - static PassRefPtr<DataLoader> create(ScriptExecutionContext* context, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize) + static Ref<DataLoader> create(ScriptExecutionContext* context, Ref<RequestDataCallback>&& requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, RefPtr<IDBKeyRange>&& idbKeyRange, int skipCount, unsigned pageSize) { - return adoptRef(new DataLoader(context, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize)); + return adoptRef(*new DataLoader(context, WTFMove(requestCallback), injectedScript, objectStoreName, indexName, WTFMove(idbKeyRange), skipCount, pageSize)); } virtual ~DataLoader() { } - virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) override + void execute(IDBDatabase& database) override { - RefPtr<IDBDatabase> idbDatabase = prpDatabase; - if (!requestCallback()->isActive()) + if (!requestCallback().isActive()) return; - RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), m_objectStoreName); + + auto idbTransaction = transactionForDatabase(&database, m_objectStoreName); if (!idbTransaction) { m_requestCallback->sendFailure("Could not get transaction"); return; } - RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName); + + auto idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName); if (!idbObjectStore) { m_requestCallback->sendFailure("Could not get object store"); return; } - RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback, m_skipCount, m_pageSize); - - ExceptionCode ec = 0; + TransactionActivator activator(idbTransaction.get()); RefPtr<IDBRequest> idbRequest; + auto* exec = context() ? context()->execState() : nullptr; if (!m_indexName.isEmpty()) { - RefPtr<IDBIndex> idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName); + auto idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName); if (!idbIndex) { m_requestCallback->sendFailure("Could not get index"); return; } - idbRequest = idbIndex->openCursor(context(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), ec); - } else - idbRequest = idbObjectStore->openCursor(context(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), ec); - idbRequest->addEventListener(eventNames().successEvent, openCursorCallback, false); + if (exec) { + auto result = idbIndex->openCursor(*exec, m_idbKeyRange.get(), IDBCursorDirection::Next); + if (!result.hasException()) + idbRequest = result.releaseReturnValue(); + } + } else { + if (exec) { + auto result = idbObjectStore->openCursor(*exec, m_idbKeyRange.get(), IDBCursorDirection::Next); + if (!result.hasException()) + idbRequest = result.releaseReturnValue(); + } + } + + if (!idbRequest) { + m_requestCallback->sendFailure("Could not open cursor to populate database data"); + return; + } + + auto openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback.copyRef(), m_skipCount, m_pageSize); + idbRequest->addEventListener(eventNames().successEvent, WTFMove(openCursorCallback), false); } - virtual RequestCallback* requestCallback() override { return m_requestCallback.get(); } - DataLoader(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize) + RequestCallback& requestCallback() override { return m_requestCallback.get(); } + DataLoader(ScriptExecutionContext* scriptExecutionContext, Ref<RequestDataCallback>&& requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, RefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize) : ExecutableWithDatabase(scriptExecutionContext) - , m_requestCallback(requestCallback) + , m_requestCallback(WTFMove(requestCallback)) , m_injectedScript(injectedScript) , m_objectStoreName(objectStoreName) , m_indexName(indexName) - , m_idbKeyRange(idbKeyRange) + , m_idbKeyRange(WTFMove(idbKeyRange)) , m_skipCount(skipCount) , m_pageSize(pageSize) { } - RefPtr<RequestDataCallback> m_requestCallback; + Ref<RequestDataCallback> m_requestCallback; InjectedScript m_injectedScript; String m_objectStoreName; String m_indexName; @@ -558,9 +513,10 @@ public: } // namespace -InspectorIndexedDBAgent::InspectorIndexedDBAgent(InstrumentingAgents* instrumentingAgents, InjectedScriptManager* injectedScriptManager, InspectorPageAgent* pageAgent) - : InspectorAgentBase(ASCIILiteral("IndexedDB"), instrumentingAgents) - , m_injectedScriptManager(injectedScriptManager) +InspectorIndexedDBAgent::InspectorIndexedDBAgent(WebAgentContext& context, InspectorPageAgent* pageAgent) + : InspectorAgentBase(ASCIILiteral("IndexedDB"), context) + , m_injectedScriptManager(context.injectedScriptManager) + , m_backendDispatcher(Inspector::IndexedDBBackendDispatcher::create(context.backendDispatcher, this)) , m_pageAgent(pageAgent) { } @@ -569,122 +525,129 @@ InspectorIndexedDBAgent::~InspectorIndexedDBAgent() { } -void InspectorIndexedDBAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, InspectorBackendDispatcher* backendDispatcher) +void InspectorIndexedDBAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_backendDispatcher = InspectorIndexedDBBackendDispatcher::create(backendDispatcher, this); } -void InspectorIndexedDBAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorIndexedDBAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_backendDispatcher.clear(); - - disable(nullptr); + ErrorString unused; + disable(unused); } -void InspectorIndexedDBAgent::enable(ErrorString*) +void InspectorIndexedDBAgent::enable(ErrorString&) { } -void InspectorIndexedDBAgent::disable(ErrorString*) +void InspectorIndexedDBAgent::disable(ErrorString&) { } -static Document* assertDocument(ErrorString* errorString, Frame* frame) +static Document* assertDocument(ErrorString& errorString, Frame* frame) { Document* document = frame ? frame->document() : nullptr; - if (!document) - *errorString = "No document for given frame found"; - + errorString = ASCIILiteral("No document for given frame found"); return document; } -static IDBFactory* assertIDBFactory(ErrorString* errorString, Document* document) +static IDBFactory* assertIDBFactory(ErrorString& errorString, Document* document) { DOMWindow* domWindow = document->domWindow(); if (!domWindow) { - *errorString = "No IndexedDB factory for given frame found"; + errorString = ASCIILiteral("No IndexedDB factory for given frame found"); return nullptr; } - IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(domWindow); + IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(*domWindow); if (!idbFactory) - *errorString = "No IndexedDB factory for given frame found"; + errorString = ASCIILiteral("No IndexedDB factory for given frame found"); return idbFactory; } -void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString* errorString, const String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback> requestCallback) +void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString& errorString, const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&& requestCallback) { Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); Document* document = assertDocument(errorString, frame); if (!document) return; + + auto& openingOrigin = document->securityOrigin(); + + auto& topOrigin = document->topOrigin(); + IDBFactory* idbFactory = assertIDBFactory(errorString, document); if (!idbFactory) return; - ExceptionCode ec = 0; - RefPtr<IDBRequest> idbRequest = idbFactory->getDatabaseNames(document, ec); - if (ec) { - requestCallback->sendFailure("Could not obtain database names."); - return; - } - idbRequest->addEventListener(eventNames().successEvent, GetDatabaseNamesCallback::create(requestCallback, document->securityOrigin()->toRawString()), false); + RefPtr<RequestDatabaseNamesCallback> callback = WTFMove(requestCallback); + idbFactory->getAllDatabaseNames(topOrigin, openingOrigin, [callback](auto& databaseNames) { + if (!callback->isActive()) + return; + + Ref<Inspector::Protocol::Array<String>> databaseNameArray = Inspector::Protocol::Array<String>::create(); + for (auto& databaseName : databaseNames) + databaseNameArray->addItem(databaseName); + + callback->sendSuccess(WTFMove(databaseNameArray)); + }); } -void InspectorIndexedDBAgent::requestDatabase(ErrorString* errorString, const String& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCallback> requestCallback) +void InspectorIndexedDBAgent::requestDatabase(ErrorString& errorString, const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&& requestCallback) { Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); Document* document = assertDocument(errorString, frame); if (!document) return; + IDBFactory* idbFactory = assertIDBFactory(errorString, document); if (!idbFactory) return; - RefPtr<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, requestCallback); - databaseLoader->start(idbFactory, document->securityOrigin(), databaseName); + Ref<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, WTFMove(requestCallback)); + databaseLoader->start(idbFactory, &document->securityOrigin(), databaseName); } -void InspectorIndexedDBAgent::requestData(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const RefPtr<InspectorObject>* keyRange, PassRefPtr<RequestDataCallback> requestCallback) +void InspectorIndexedDBAgent::requestData(ErrorString& errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const InspectorObject* keyRange, Ref<RequestDataCallback>&& requestCallback) { Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); Document* document = assertDocument(errorString, frame); if (!document) return; + IDBFactory* idbFactory = assertIDBFactory(errorString, document); if (!idbFactory) return; - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldExecState(frame)); + InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(mainWorldExecState(frame)); - RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRange->get()) : nullptr; + RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRange) : nullptr; if (keyRange && !idbKeyRange) { - *errorString = "Can not parse key range."; + errorString = ASCIILiteral("Can not parse key range."); return; } - RefPtr<DataLoader> dataLoader = DataLoader::create(document, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize); - dataLoader->start(idbFactory, document->securityOrigin(), databaseName); + Ref<DataLoader> dataLoader = DataLoader::create(document, WTFMove(requestCallback), injectedScript, objectStoreName, indexName, WTFMove(idbKeyRange), skipCount, pageSize); + dataLoader->start(idbFactory, &document->securityOrigin(), databaseName); } -class ClearObjectStoreListener : public EventListener { +class ClearObjectStoreListener final : public EventListener { WTF_MAKE_NONCOPYABLE(ClearObjectStoreListener); public: - static PassRefPtr<ClearObjectStoreListener> create(PassRefPtr<ClearObjectStoreCallback> requestCallback) + static Ref<ClearObjectStoreListener> create(Ref<ClearObjectStoreCallback> requestCallback) { - return adoptRef(new ClearObjectStoreListener(requestCallback)); + return adoptRef(*new ClearObjectStoreListener(WTFMove(requestCallback))); } virtual ~ClearObjectStoreListener() { } - virtual bool operator==(const EventListener& other) override + bool operator==(const EventListener& other) const override { return this == &other; } - virtual void handleEvent(ScriptExecutionContext*, Event* event) override + void handleEvent(ScriptExecutionContext*, Event* event) override { if (!m_requestCallback->isActive()) return; @@ -696,63 +659,68 @@ public: m_requestCallback->sendSuccess(); } private: - ClearObjectStoreListener(PassRefPtr<ClearObjectStoreCallback> requestCallback) + ClearObjectStoreListener(Ref<ClearObjectStoreCallback>&& requestCallback) : EventListener(EventListener::CPPEventListenerType) - , m_requestCallback(requestCallback) + , m_requestCallback(WTFMove(requestCallback)) { } - RefPtr<ClearObjectStoreCallback> m_requestCallback; + Ref<ClearObjectStoreCallback> m_requestCallback; }; - -class ClearObjectStore : public ExecutableWithDatabase { +class ClearObjectStore final : public ExecutableWithDatabase { public: - static PassRefPtr<ClearObjectStore> create(ScriptExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback) + static Ref<ClearObjectStore> create(ScriptExecutionContext* context, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& requestCallback) { - return adoptRef(new ClearObjectStore(context, objectStoreName, requestCallback)); + return adoptRef(*new ClearObjectStore(context, objectStoreName, WTFMove(requestCallback))); } - ClearObjectStore(ScriptExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback) + ClearObjectStore(ScriptExecutionContext* context, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& requestCallback) : ExecutableWithDatabase(context) , m_objectStoreName(objectStoreName) - , m_requestCallback(requestCallback) + , m_requestCallback(WTFMove(requestCallback)) { } - virtual void execute(PassRefPtr<IDBDatabase> prpDatabase) override + void execute(IDBDatabase& database) override { - RefPtr<IDBDatabase> idbDatabase = prpDatabase; - if (!requestCallback()->isActive()) + if (!requestCallback().isActive()) return; - RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), m_objectStoreName, IDBTransaction::modeReadWrite()); + + auto idbTransaction = transactionForDatabase(&database, m_objectStoreName, IDBTransactionMode::Readwrite); if (!idbTransaction) { m_requestCallback->sendFailure("Could not get transaction"); return; } - RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName); + + auto idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName); if (!idbObjectStore) { m_requestCallback->sendFailure("Could not get object store"); return; } - ExceptionCode ec = 0; - RefPtr<IDBRequest> idbRequest = idbObjectStore->clear(context(), ec); - ASSERT(!ec); - if (ec) { - m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), ec)); - return; + TransactionActivator activator(idbTransaction.get()); + RefPtr<IDBRequest> idbRequest; + if (auto* exec = context() ? context()->execState() : nullptr) { + auto result = idbObjectStore->clear(*exec); + ASSERT(!result.hasException()); + if (result.hasException()) { + m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), result.releaseException().code())); + return; + } + idbRequest = result.releaseReturnValue(); } - idbTransaction->addEventListener(eventNames().completeEvent, ClearObjectStoreListener::create(m_requestCallback), false); + + idbTransaction->addEventListener(eventNames().completeEvent, ClearObjectStoreListener::create(m_requestCallback.copyRef()), false); } - virtual RequestCallback* requestCallback() override { return m_requestCallback.get(); } + RequestCallback& requestCallback() override { return m_requestCallback.get(); } private: const String m_objectStoreName; - RefPtr<ClearObjectStoreCallback> m_requestCallback; + Ref<ClearObjectStoreCallback> m_requestCallback; }; -void InspectorIndexedDBAgent::clearObjectStore(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback) +void InspectorIndexedDBAgent::clearObjectStore(ErrorString& errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, Ref<ClearObjectStoreCallback>&& requestCallback) { Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); Document* document = assertDocument(errorString, frame); @@ -762,10 +730,9 @@ void InspectorIndexedDBAgent::clearObjectStore(ErrorString* errorString, const S if (!idbFactory) return; - RefPtr<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, requestCallback); - clearObjectStore->start(idbFactory, document->securityOrigin(), databaseName); + Ref<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, WTFMove(requestCallback)); + clearObjectStore->start(idbFactory, &document->securityOrigin(), databaseName); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE) +#endif // ENABLE(INDEXED_DATABASE) diff --git a/Source/WebCore/inspector/InspectorIndexedDBAgent.h b/Source/WebCore/inspector/InspectorIndexedDBAgent.h index d071a004f..8ec4c017c 100644 --- a/Source/WebCore/inspector/InspectorIndexedDBAgent.h +++ b/Source/WebCore/inspector/InspectorIndexedDBAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,14 +29,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorIndexedDBAgent_h -#define InspectorIndexedDBAgent_h +#pragma once -#if ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE) +#if ENABLE(INDEXED_DATABASE) #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include <wtf/PassOwnPtr.h> +#include <inspector/InspectorBackendDispatchers.h> #include <wtf/text/WTFString.h> namespace Inspector { @@ -48,29 +47,29 @@ class InspectorPageAgent; typedef String ErrorString; -class InspectorIndexedDBAgent : public InspectorAgentBase, public Inspector::InspectorIndexedDBBackendDispatcherHandler { +class InspectorIndexedDBAgent final : public InspectorAgentBase, public Inspector::IndexedDBBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; public: - InspectorIndexedDBAgent(InstrumentingAgents*, Inspector::InjectedScriptManager*, InspectorPageAgent*); - ~InspectorIndexedDBAgent(); + InspectorIndexedDBAgent(WebAgentContext&, InspectorPageAgent*); + virtual ~InspectorIndexedDBAgent(); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; // Called from the front-end. - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void requestDatabaseNames(ErrorString*, const String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback>) override; - virtual void requestDatabase(ErrorString*, const String& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCallback>) override; - virtual void requestData(ErrorString*, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const RefPtr<Inspector::InspectorObject>* keyRange, PassRefPtr<RequestDataCallback>) override; - virtual void clearObjectStore(ErrorString*, const String& in_securityOrigin, const String& in_databaseName, const String& in_objectStoreName, PassRefPtr<ClearObjectStoreCallback>) override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void requestDatabaseNames(ErrorString&, const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&&) override; + void requestDatabase(ErrorString&, const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&&) override; + void requestData(ErrorString&, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const Inspector::InspectorObject* keyRange, Ref<RequestDataCallback>&&) override; + void clearObjectStore(ErrorString&, const String& in_securityOrigin, const String& in_databaseName, const String& in_objectStoreName, Ref<ClearObjectStoreCallback>&&) override; private: - Inspector::InjectedScriptManager* m_injectedScriptManager; - InspectorPageAgent* m_pageAgent; - RefPtr<Inspector::InspectorIndexedDBBackendDispatcher> m_backendDispatcher; + Inspector::InjectedScriptManager& m_injectedScriptManager; + RefPtr<Inspector::IndexedDBBackendDispatcher> m_backendDispatcher; + InspectorPageAgent* m_pageAgent { nullptr }; }; } // namespace WebCore -#endif // ENABLE(INSPECTOR) && ENABLE(INDEXED_DATABASE) -#endif // !defined(InspectorIndexedDBAgent_h) +#endif // ENABLE(INDEXED_DATABASE) diff --git a/Source/WebCore/inspector/InspectorInputAgent.cpp b/Source/WebCore/inspector/InspectorInputAgent.cpp deleted file mode 100644 index c45a04030..000000000 --- a/Source/WebCore/inspector/InspectorInputAgent.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorInputAgent.h" - -#include "Chrome.h" -#include "EventHandler.h" -#include "FrameView.h" -#include "IntPoint.h" -#include "IntRect.h" -#include "IntSize.h" -#include "MainFrame.h" -#include "Page.h" -#include "PlatformEvent.h" -#include "PlatformKeyboardEvent.h" -#include "PlatformMouseEvent.h" - -#include <wtf/CurrentTime.h> -#include <wtf/text/WTFString.h> - -using namespace Inspector; - -namespace WebCore { - -InspectorInputAgent::InspectorInputAgent(InstrumentingAgents* instrumentingAgents, Page* page) - : InspectorAgentBase(ASCIILiteral("Input"), instrumentingAgents) - , m_page(page) -{ -} - -InspectorInputAgent::~InspectorInputAgent() -{ -} - -void InspectorInputAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, InspectorBackendDispatcher* backendDispatcher) -{ - m_backendDispatcher = InspectorInputBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorInputAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) -{ - m_backendDispatcher.clear(); -} - -void InspectorInputAgent::dispatchKeyEvent(ErrorString* error, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const int* macCharCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey) -{ - PlatformEvent::Type convertedType; - if (type == "keyDown") - convertedType = PlatformEvent::KeyDown; - else if (type == "keyUp") - convertedType = PlatformEvent::KeyUp; - else if (type == "char") - convertedType = PlatformEvent::Char; - else if (type == "rawKeyDown") - convertedType = PlatformEvent::RawKeyDown; - else { - *error = "Unrecognized type: " + type; - return; - } - - PlatformKeyboardEvent event( - convertedType, - text ? *text : "", - unmodifiedText ? *unmodifiedText : "", - keyIdentifier ? *keyIdentifier : "", - windowsVirtualKeyCode ? *windowsVirtualKeyCode : 0, - nativeVirtualKeyCode ? *nativeVirtualKeyCode : 0, - macCharCode ? *macCharCode : 0, - autoRepeat ? *autoRepeat : false, - isKeypad ? *isKeypad : false, - isSystemKey ? *isSystemKey : false, - static_cast<PlatformEvent::Modifiers>(modifiers ? *modifiers : 0), - timestamp ? *timestamp : currentTime()); - m_page->mainFrame().eventHandler().keyEvent(event); -} - -void InspectorInputAgent::dispatchMouseEvent(ErrorString* error, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount) -{ - PlatformEvent::Type convertedType; - if (type == "mousePressed") - convertedType = PlatformEvent::MousePressed; - else if (type == "mouseReleased") - convertedType = PlatformEvent::MouseReleased; - else if (type == "mouseMoved") - convertedType = PlatformEvent::MouseMoved; - else { - *error = "Unrecognized type: " + type; - return; - } - - int convertedModifiers = modifiers ? *modifiers : 0; - - MouseButton convertedButton = NoButton; - if (button) { - if (*button == "left") - convertedButton = LeftButton; - else if (*button == "middle") - convertedButton = MiddleButton; - else if (*button == "right") - convertedButton = RightButton; - else if (*button != "none") { - *error = "Unrecognized button: " + *button; - return; - } - } - - // Some platforms may have flipped coordinate systems, but the given coordinates - // assume the origin is in the top-left of the window. Convert. - IntPoint convertedPoint = m_page->mainFrame().view()->convertToContainingWindow(IntPoint(x, y)); - IntPoint globalPoint = m_page->chrome().rootViewToScreen(IntRect(IntPoint(x, y), IntSize(0, 0))).location(); - - PlatformMouseEvent event( - convertedPoint, - globalPoint, - convertedButton, - convertedType, - clickCount ? *clickCount : 0, - convertedModifiers & PlatformEvent::ShiftKey, - convertedModifiers & PlatformEvent::CtrlKey, - convertedModifiers & PlatformEvent::AltKey, - convertedModifiers & PlatformEvent::MetaKey, - timestamp ? *timestamp : currentTime()); - - EventHandler& eventHandler = m_page->mainFrame().eventHandler(); - switch (convertedType) { - case PlatformEvent::MousePressed: - eventHandler.handleMousePressEvent(event); - break; - case PlatformEvent::MouseReleased: - eventHandler.handleMouseReleaseEvent(event); - break; - case PlatformEvent::MouseMoved: - eventHandler.handleMouseMoveEvent(event); - break; - default: - *error = "Unhandled type: " + type; - } -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorInputAgent.h b/Source/WebCore/inspector/InspectorInputAgent.h deleted file mode 100644 index f152af645..000000000 --- a/Source/WebCore/inspector/InspectorInputAgent.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorInputAgent_h -#define InspectorInputAgent_h - -#if ENABLE(INSPECTOR) - -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { -class Page; - -typedef String ErrorString; - -class InspectorInputAgent : public InspectorAgentBase, public Inspector::InspectorInputBackendDispatcherHandler { - WTF_MAKE_NONCOPYABLE(InspectorInputAgent); -public: - InspectorInputAgent(InstrumentingAgents*, Page*); - ~InspectorInputAgent(); - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - // Methods called from the frontend for simulating input. - virtual void dispatchKeyEvent(ErrorString*, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const int* macCharCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey) override; - virtual void dispatchMouseEvent(ErrorString*, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount) override; - -private: - Page* m_page; - RefPtr<Inspector::InspectorInputBackendDispatcher> m_backendDispatcher; -}; - -#endif // ENABLE(INSPECTOR) - -} // namespace WebCore - -#endif // !defined(InspectorInputAgent_h) diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp index df1357227..87f0d93ff 100644 --- a/Source/WebCore/inspector/InspectorInstrumentation.cpp +++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. +* Copyright (C) 2014-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,12 +32,6 @@ #include "config.h" #include "InspectorInstrumentation.h" -#if ENABLE(INSPECTOR) - -#include "CSSRule.h" -#include "CSSStyleRule.h" -#include "ConsoleAPITypes.h" -#include "ConsoleTypes.h" #include "DOMWindow.h" #include "DOMWrapperWorld.h" #include "Database.h" @@ -45,38 +40,37 @@ #include "EventDispatcher.h" #include "InspectorApplicationCacheAgent.h" #include "InspectorCSSAgent.h" -#include "InspectorCanvasAgent.h" -#include "InspectorConsoleAgent.h" #include "InspectorDOMAgent.h" #include "InspectorDOMDebuggerAgent.h" #include "InspectorDOMStorageAgent.h" #include "InspectorDatabaseAgent.h" -#include "InspectorHeapProfilerAgent.h" #include "InspectorLayerTreeAgent.h" +#include "InspectorMemoryAgent.h" +#include "InspectorNetworkAgent.h" #include "InspectorPageAgent.h" -#include "InspectorProfilerAgent.h" -#include "InspectorResourceAgent.h" #include "InspectorTimelineAgent.h" #include "InspectorWorkerAgent.h" #include "InstrumentingAgents.h" #include "MainFrame.h" #include "PageDebuggerAgent.h" +#include "PageHeapAgent.h" #include "PageRuntimeAgent.h" #include "RenderObject.h" #include "RenderView.h" -#include "ScriptArguments.h" -#include "ScriptCallStack.h" #include "ScriptController.h" -#include "ScriptProfile.h" -#include "StyleResolver.h" -#include "StyleRule.h" -#include "WorkerGlobalScope.h" -#include "WorkerRuntimeAgent.h" -#include "WorkerThread.h" -#include "XMLHttpRequest.h" +#include "WebConsoleAgent.h" +#include "WebSocketFrame.h" +#include <inspector/ConsoleMessage.h> +#include <inspector/ScriptArguments.h> +#include <inspector/ScriptCallStack.h> #include <inspector/agents/InspectorDebuggerAgent.h> +#include <runtime/ConsoleTypes.h> #include <wtf/StdLibExtras.h> -#include <wtf/text/CString.h> + +#if ENABLE(WEB_REPLAY) +#include "InspectorReplayAgent.h" +#include "ReplayController.h" +#endif using namespace Inspector; @@ -89,276 +83,312 @@ static const char* const setTimerEventName = "setTimer"; static const char* const clearTimerEventName = "clearTimer"; static const char* const timerFiredEventName = "timerFired"; +enum AsyncCallType { + AsyncCallTypeRequestAnimationFrame, + AsyncCallTypeTimer, +}; + namespace { -static HashSet<InstrumentingAgents*>* instrumentingAgentsSet = nullptr; +static HashSet<InstrumentingAgents*>* s_instrumentingAgentsSet = nullptr; } int InspectorInstrumentation::s_frontendCounter = 0; +static void didScheduleAsyncCall(InstrumentingAgents& instrumentingAgents, AsyncCallType type, int callbackId, ScriptExecutionContext& context, bool singleShot) +{ + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) { + JSC::ExecState* scriptState = context.execState(); + if (!scriptState) + return; + + debuggerAgent->didScheduleAsyncCall(scriptState, type, callbackId, singleShot); + } +} + static Frame* frameForScriptExecutionContext(ScriptExecutionContext* context) { Frame* frame = nullptr; - if (context->isDocument()) - frame = toDocument(context)->frame(); + if (is<Document>(*context)) + frame = downcast<Document>(*context).frame(); + return frame; +} + +static Frame* frameForScriptExecutionContext(ScriptExecutionContext& context) +{ + Frame* frame = nullptr; + if (is<Document>(context)) + frame = downcast<Document>(context).frame(); return frame; } -void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, DOMWrapperWorld& world) +void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, DOMWrapperWorld& world) { - InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent(); + InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent(); if (pageAgent) - pageAgent->didClearWindowObjectInWorld(frame, world); - if (PageDebuggerAgent* debuggerAgent = instrumentingAgents->pageDebuggerAgent()) { - if (pageAgent && &world == &mainThreadNormalWorld() && frame == pageAgent->mainFrame()) + pageAgent->didClearWindowObjectInWorld(&frame, world); + if (PageDebuggerAgent* debuggerAgent = instrumentingAgents.pageDebuggerAgent()) { + if (pageAgent && &world == &mainThreadNormalWorld() && &frame == &pageAgent->mainFrame()) debuggerAgent->didClearMainFrameWindowObject(); } - if (PageRuntimeAgent* pageRuntimeAgent = instrumentingAgents->pageRuntimeAgent()) { + if (PageRuntimeAgent* pageRuntimeAgent = instrumentingAgents.pageRuntimeAgent()) { if (&world == &mainThreadNormalWorld()) pageRuntimeAgent->didCreateMainWorldContext(frame); } } -bool InspectorInstrumentation::isDebuggerPausedImpl(InstrumentingAgents* instrumentingAgents) +bool InspectorInstrumentation::isDebuggerPausedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) return debuggerAgent->isPaused(); return false; } -void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* parent) +void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& parent) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->willInsertDOMNode(parent); } -void InspectorInstrumentation::didInsertDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* node) +void InspectorInstrumentation::didInsertDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didInsertDOMNode(node); - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->didInsertDOMNode(node); } -void InspectorInstrumentation::willRemoveDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* node) +void InspectorInstrumentation::willRemoveDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->willRemoveDOMNode(node); } -void InspectorInstrumentation::didRemoveDOMNodeImpl(InstrumentingAgents* instrumentingAgents, Node* node) +void InspectorInstrumentation::didRemoveDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->didRemoveDOMNode(node); - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didRemoveDOMNode(node); } -void InspectorInstrumentation::willModifyDOMAttrImpl(InstrumentingAgents* instrumentingAgents, Element* element, const AtomicString& oldValue, const AtomicString& newValue) +void InspectorInstrumentation::willModifyDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& oldValue, const AtomicString& newValue) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->willModifyDOMAttr(element); - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->willModifyDOMAttr(element, oldValue, newValue); } -void InspectorInstrumentation::didModifyDOMAttrImpl(InstrumentingAgents* instrumentingAgents, Element* element, const AtomicString& name, const AtomicString& value) +void InspectorInstrumentation::didModifyDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& name, const AtomicString& value) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didModifyDOMAttr(element, name, value); } -void InspectorInstrumentation::didRemoveDOMAttrImpl(InstrumentingAgents* instrumentingAgents, Element* element, const AtomicString& name) +void InspectorInstrumentation::didRemoveDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& name) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didRemoveDOMAttr(element, name); } -void InspectorInstrumentation::didInvalidateStyleAttrImpl(InstrumentingAgents* instrumentingAgents, Node* node) +void InspectorInstrumentation::didInvalidateStyleAttrImpl(InstrumentingAgents& instrumentingAgents, Node& node) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didInvalidateStyleAttr(node); - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->didInvalidateStyleAttr(node); } -void InspectorInstrumentation::frameWindowDiscardedImpl(InstrumentingAgents* instrumentingAgents, DOMWindow* window) +void InspectorInstrumentation::documentDetachedImpl(InstrumentingAgents& instrumentingAgents, Document& document) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) + cssAgent->documentDetached(document); +} + +void InspectorInstrumentation::frameWindowDiscardedImpl(InstrumentingAgents& instrumentingAgents, DOMWindow* window) +{ + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) consoleAgent->frameWindowDiscarded(window); } -void InspectorInstrumentation::mediaQueryResultChangedImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::mediaQueryResultChangedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) cssAgent->mediaQueryResultChanged(); } -void InspectorInstrumentation::didPushShadowRootImpl(InstrumentingAgents* instrumentingAgents, Element* host, ShadowRoot* root) +void InspectorInstrumentation::activeStyleSheetsUpdatedImpl(InstrumentingAgents& instrumentingAgents, Document& document) +{ + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) + cssAgent->activeStyleSheetsUpdated(document); +} + +void InspectorInstrumentation::didPushShadowRootImpl(InstrumentingAgents& instrumentingAgents, Element& host, ShadowRoot& root) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->didPushShadowRoot(host, root); } -void InspectorInstrumentation::willPopShadowRootImpl(InstrumentingAgents* instrumentingAgents, Element* host, ShadowRoot* root) +void InspectorInstrumentation::willPopShadowRootImpl(InstrumentingAgents& instrumentingAgents, Element& host, ShadowRoot& root) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->willPopShadowRoot(host, root); } -void InspectorInstrumentation::didCreateNamedFlowImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow) +void InspectorInstrumentation::didChangeCustomElementStateImpl(InstrumentingAgents& instrumentingAgents, Element& element) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) - cssAgent->didCreateNamedFlow(document, namedFlow); + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) + domAgent->didChangeCustomElementState(element); } -void InspectorInstrumentation::willRemoveNamedFlowImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow) +void InspectorInstrumentation::pseudoElementCreatedImpl(InstrumentingAgents& instrumentingAgents, PseudoElement& pseudoElement) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) - cssAgent->willRemoveNamedFlow(document, namedFlow); + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) + domAgent->pseudoElementCreated(pseudoElement); +} + +void InspectorInstrumentation::pseudoElementDestroyedImpl(InstrumentingAgents& instrumentingAgents, PseudoElement& pseudoElement) +{ + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) + domAgent->pseudoElementDestroyed(pseudoElement); + if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent()) + layerTreeAgent->pseudoElementDestroyed(pseudoElement); } -void InspectorInstrumentation::didUpdateRegionLayoutImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow) +void InspectorInstrumentation::didCreateNamedFlowImpl(InstrumentingAgents& instrumentingAgents, Document* document, WebKitNamedFlow& namedFlow) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) - cssAgent->didUpdateRegionLayout(document, namedFlow); + if (!document) + return; + + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) + cssAgent->didCreateNamedFlow(*document, namedFlow); +} + +void InspectorInstrumentation::willRemoveNamedFlowImpl(InstrumentingAgents& instrumentingAgents, Document* document, WebKitNamedFlow& namedFlow) +{ + if (!document) + return; + + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) + cssAgent->willRemoveNamedFlow(*document, namedFlow); } -void InspectorInstrumentation::didChangeRegionOversetImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow) +void InspectorInstrumentation::didChangeRegionOversetImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) cssAgent->didChangeRegionOverset(document, namedFlow); } -void InspectorInstrumentation::didRegisterNamedFlowContentElementImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow, Node* contentElement, Node* nextContentElement) +void InspectorInstrumentation::didRegisterNamedFlowContentElementImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow, Node& contentElement, Node* nextContentElement) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) cssAgent->didRegisterNamedFlowContentElement(document, namedFlow, contentElement, nextContentElement); } -void InspectorInstrumentation::didUnregisterNamedFlowContentElementImpl(InstrumentingAgents* instrumentingAgents, Document* document, WebKitNamedFlow* namedFlow, Node* contentElement) +void InspectorInstrumentation::didUnregisterNamedFlowContentElementImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow, Node& contentElement) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) cssAgent->didUnregisterNamedFlowContentElement(document, namedFlow, contentElement); } -void InspectorInstrumentation::mouseDidMoveOverElementImpl(InstrumentingAgents* instrumentingAgents, const HitTestResult& result, unsigned modifierFlags) +void InspectorInstrumentation::mouseDidMoveOverElementImpl(InstrumentingAgents& instrumentingAgents, const HitTestResult& result, unsigned modifierFlags) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->mouseDidMoveOverElement(result, modifierFlags); } -void InspectorInstrumentation::didScrollImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::didScrollImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->didScroll(); } -bool InspectorInstrumentation::handleTouchEventImpl(InstrumentingAgents* instrumentingAgents, Node* node) +bool InspectorInstrumentation::handleTouchEventImpl(InstrumentingAgents& instrumentingAgents, Node& node) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) return domAgent->handleTouchEvent(node); return false; } -bool InspectorInstrumentation::handleMousePressImpl(InstrumentingAgents* instrumentingAgents) +bool InspectorInstrumentation::handleMousePressImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) return domAgent->handleMousePress(); return false; } -bool InspectorInstrumentation::forcePseudoStateImpl(InstrumentingAgents* instrumentingAgents, Element* element, CSSSelector::PseudoType pseudoState) +bool InspectorInstrumentation::forcePseudoStateImpl(InstrumentingAgents& instrumentingAgents, const Element& element, CSSSelector::PseudoClassType pseudoState) { - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) return cssAgent->forcePseudoState(element, pseudoState); return false; } -void InspectorInstrumentation::characterDataModifiedImpl(InstrumentingAgents* instrumentingAgents, CharacterData* characterData) +void InspectorInstrumentation::characterDataModifiedImpl(InstrumentingAgents& instrumentingAgents, CharacterData& characterData) { - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->characterDataModified(characterData); } -void InspectorInstrumentation::willSendXMLHttpRequestImpl(InstrumentingAgents* instrumentingAgents, const String& url) +void InspectorInstrumentation::willSendXMLHttpRequestImpl(InstrumentingAgents& instrumentingAgents, const String& url) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) domDebuggerAgent->willSendXMLHttpRequest(url); } -void InspectorInstrumentation::didScheduleResourceRequestImpl(InstrumentingAgents* instrumentingAgents, const String& url, Frame* frame) -{ - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didScheduleResourceRequest(url, frame); -} - -void InspectorInstrumentation::didInstallTimerImpl(InstrumentingAgents* instrumentingAgents, int timerId, int timeout, bool singleShot, ScriptExecutionContext* context) +void InspectorInstrumentation::didInstallTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, std::chrono::milliseconds timeout, bool singleShot, ScriptExecutionContext& context) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, setTimerEventName, true); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + didScheduleAsyncCall(instrumentingAgents, AsyncCallTypeTimer, timerId, context, singleShot); + + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didInstallTimer(timerId, timeout, singleShot, frameForScriptExecutionContext(context)); } -void InspectorInstrumentation::didRemoveTimerImpl(InstrumentingAgents* instrumentingAgents, int timerId, ScriptExecutionContext* context) +void InspectorInstrumentation::didRemoveTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, ScriptExecutionContext& context) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, clearTimerEventName, true); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) + debuggerAgent->didCancelAsyncCall(AsyncCallTypeTimer, timerId); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didRemoveTimer(timerId, frameForScriptExecutionContext(context)); } -InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InstrumentingAgents* instrumentingAgents, const String& scriptName, int scriptLine, ScriptExecutionContext* context) +InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InstrumentingAgents& instrumentingAgents, const String& scriptName, int scriptLine, ScriptExecutionContext* context) { int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { timelineAgent->willCallFunction(scriptName, scriptLine, frameForScriptExecutionContext(context)); timelineAgentId = timelineAgent->id(); } return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } -void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentationCookie& cookie) -{ - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didCallFunction(); -} - -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchXHRReadyStateChangeEventImpl(InstrumentingAgents* instrumentingAgents, XMLHttpRequest* request, ScriptExecutionContext* context) -{ - int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); - if (timelineAgent && request->hasEventListeners(eventNames().readystatechangeEvent)) { - timelineAgent->willDispatchXHRReadyStateChangeEvent(request->url().string(), request->readyState(), frameForScriptExecutionContext(context)); - timelineAgentId = timelineAgent->id(); - } - return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); -} - -void InspectorInstrumentation::didDispatchXHRReadyStateChangeEventImpl(const InspectorInstrumentationCookie& cookie) +void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentationCookie& cookie, ScriptExecutionContext* context) { if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didDispatchXHRReadyStateChangeEvent(); + timelineAgent->didCallFunction(frameForScriptExecutionContext(context)); } -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, bool hasEventListeners, Document* document) +InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents& instrumentingAgents, Document& document, const Event& event, bool hasEventListeners) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); + InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent(); if (timelineAgent && hasEventListeners) { - timelineAgent->willDispatchEvent(event, document->frame()); + timelineAgent->willDispatchEvent(event, document.frame()); timelineAgentId = timelineAgent->id(); } +#if ENABLE(WEB_REPLAY) + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->willDispatchEvent(event, document.frame()); +#endif return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } -InspectorInstrumentationCookie InspectorInstrumentation::willHandleEventImpl(InstrumentingAgents* instrumentingAgents, Event* event) -{ - pauseOnNativeEventIfNeeded(instrumentingAgents, true, event->type(), false); - return InspectorInstrumentationCookie(instrumentingAgents, 0); -} - -void InspectorInstrumentation::didHandleEventImpl(const InspectorInstrumentationCookie& cookie) +void InspectorInstrumentation::willHandleEventImpl(InstrumentingAgents& instrumentingAgents, const Event& event) { - cancelPauseOnNativeEvent(cookie.instrumentingAgents()); + pauseOnNativeEventIfNeeded(instrumentingAgents, true, event.type(), false); } void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentationCookie& cookie) @@ -367,14 +397,18 @@ void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentati timelineAgent->didDispatchEvent(); } -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window) +InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InstrumentingAgents& instrumentingAgents, const Event& event, DOMWindow& window) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); - if (timelineAgent && window->hasEventListeners(event.type())) { - timelineAgent->willDispatchEvent(event, window ? window->frame() : nullptr); + InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent(); + if (timelineAgent && window.hasEventListeners(event.type())) { + timelineAgent->willDispatchEvent(event, window.frame()); timelineAgentId = timelineAgent->id(); } +#if ENABLE(WEB_REPLAY) + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->willDispatchEvent(event, window.frame()); +#endif return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } @@ -384,40 +418,31 @@ void InspectorInstrumentation::didDispatchEventOnWindowImpl(const InspectorInstr timelineAgent->didDispatchEvent(); } -InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InstrumentingAgents* instrumentingAgents, const String& url, int lineNumber, Frame* frame) +InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& url, int lineNumber) { int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { timelineAgent->willEvaluateScript(url, lineNumber, frame); timelineAgentId = timelineAgent->id(); } return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } -void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentationCookie& cookie) +void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentationCookie& cookie, Frame& frame) { if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didEvaluateScript(); -} - -void InspectorInstrumentation::scriptsEnabledImpl(InstrumentingAgents* instrumentingAgents, bool isEnabled) -{ - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) - pageAgent->scriptsEnabled(isEnabled); + timelineAgent->didEvaluateScript(frame); } -void InspectorInstrumentation::didCreateIsolatedContextImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, JSC::ExecState* scriptState, SecurityOrigin* origin) -{ - if (PageRuntimeAgent* runtimeAgent = instrumentingAgents->pageRuntimeAgent()) - runtimeAgent->didCreateIsolatedContext(frame, scriptState, origin); -} - -InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InstrumentingAgents* instrumentingAgents, int timerId, ScriptExecutionContext* context) +InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, ScriptExecutionContext& context) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, timerFiredEventName, false); + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) + debuggerAgent->willDispatchAsyncCall(AsyncCallTypeTimer, timerId); + int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { timelineAgent->willFireTimer(timerId, frameForScriptExecutionContext(context)); timelineAgentId = timelineAgent->id(); } @@ -426,29 +451,29 @@ InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(Instr void InspectorInstrumentation::didFireTimerImpl(const InspectorInstrumentationCookie& cookie) { - cancelPauseOnNativeEvent(cookie.instrumentingAgents()); - + if (InspectorDebuggerAgent* debuggerAgent = cookie.instrumentingAgents()->inspectorDebuggerAgent()) + debuggerAgent->didDispatchAsyncCall(); if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didFireTimer(); } -void InspectorInstrumentation::didInvalidateLayoutImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::didInvalidateLayoutImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didInvalidateLayout(frame); } -InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { timelineAgent->willLayout(frame); timelineAgentId = timelineAgent->id(); } return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } -void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCookie& cookie, RenderObject* root) +void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCookie& cookie, RenderObject& root) { if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didLayout(root); @@ -457,353 +482,314 @@ void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCooki pageAgent->didLayout(); } -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchXHRLoadEventImpl(InstrumentingAgents* instrumentingAgents, XMLHttpRequest* request, ScriptExecutionContext* context) +void InspectorInstrumentation::willCompositeImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); - if (timelineAgent && request->hasEventListeners(eventNames().loadEvent)) { - timelineAgent->willDispatchXHRLoadEvent(request->url(), frameForScriptExecutionContext(context)); - timelineAgentId = timelineAgent->id(); - } - return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->willComposite(frame); } -void InspectorInstrumentation::didDispatchXHRLoadEventImpl(const InspectorInstrumentationCookie& cookie) +void InspectorInstrumentation::didCompositeImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didDispatchXHRLoadEvent(); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->didComposite(); } -void InspectorInstrumentation::willPaintImpl(InstrumentingAgents* instrumentingAgents, RenderObject* renderer) +void InspectorInstrumentation::willPaintImpl(InstrumentingAgents& instrumentingAgents, RenderObject& renderer) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->willPaint(&renderer->frame()); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->willPaint(renderer.frame()); } -void InspectorInstrumentation::didPaintImpl(InstrumentingAgents* instrumentingAgents, RenderObject* renderer, GraphicsContext* context, const LayoutRect& rect) +void InspectorInstrumentation::didPaintImpl(InstrumentingAgents& instrumentingAgents, RenderObject& renderer, const LayoutRect& rect) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didPaint(renderer, rect); - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) - pageAgent->didPaint(context, rect); -} -void InspectorInstrumentation::willScrollLayerImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) -{ - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->willScroll(frame); -} - -void InspectorInstrumentation::didScrollLayerImpl(InstrumentingAgents* instrumentingAgents) -{ - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didScroll(); + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) + pageAgent->didPaint(renderer, rect); } -InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InstrumentingAgents& instrumentingAgents, Document& document) { int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { - timelineAgent->willRecalculateStyle(frame); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { + timelineAgent->willRecalculateStyle(document.frame()); timelineAgentId = timelineAgent->id(); } - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->willRecalculateStyle(); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->willRecalculateStyle(); return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); } void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrumentationCookie& cookie) { + if (!cookie.isValid()) + return; + + InstrumentingAgents& instrumentingAgents = *cookie.instrumentingAgents(); + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didRecalculateStyle(); - InstrumentingAgents* instrumentingAgents = cookie.instrumentingAgents(); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didRecalculateStyle(); - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didRecalculateStyle(); + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->didRecalculateStyle(); } -void InspectorInstrumentation::didScheduleStyleRecalculationImpl(InstrumentingAgents* instrumentingAgents, Document* document) +void InspectorInstrumentation::didScheduleStyleRecalculationImpl(InstrumentingAgents& instrumentingAgents, Document& document) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didScheduleStyleRecalculation(document->frame()); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didScheduleStyleRecalculation(document); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->didScheduleStyleRecalculation(document.frame()); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didScheduleStyleRecalculation(document); } -void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents* instrumentingAgents, String* media) +void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, String& media) { - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->applyEmulatedMedia(media); } -void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse) +void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->willSendResourceRequest(identifier, request, loader->frame()); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->willSendRequest(identifier, loader, request, redirectResponse); + if (!loader) + return; + + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->willSendRequest(identifier, *loader, request, redirectResponse); } -void InspectorInstrumentation::continueAfterPingLoaderImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response) +void InspectorInstrumentation::continueAfterPingLoaderImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response) { willSendRequestImpl(instrumentingAgents, identifier, loader, request, response); } -void InspectorInstrumentation::markResourceAsCachedImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier) +void InspectorInstrumentation::markResourceAsCachedImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->markResourceAsCached(identifier); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->markResourceAsCached(identifier); } -void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InstrumentingAgents* instrumentingAgents, DocumentLoader* loader, CachedResource* cachedResource) +void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader* loader, CachedResource* cachedResource) { - if (!instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) + if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled()) + return; + + if (!loader || !cachedResource) return; - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource); -} - -InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceDataImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, Frame* frame, int length) -{ - int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { - timelineAgent->willReceiveResourceData(identifier, frame, length); - timelineAgentId = timelineAgent->id(); - } - return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); -} - -void InspectorInstrumentation::didReceiveResourceDataImpl(const InspectorInstrumentationCookie& cookie) -{ - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didReceiveResourceData(); -} -InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponseImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const ResourceResponse& response, Frame* frame) -{ - int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); - if (timelineAgent) { - timelineAgent->willReceiveResourceResponse(identifier, response, frame); - timelineAgentId = timelineAgent->id(); - } - return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didLoadResourceFromMemoryCache(*loader, *cachedResource); } -void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorInstrumentationCookie& cookie, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) +void InspectorInstrumentation::didReceiveResourceResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) { - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didReceiveResourceResponse(); if (!loader) return; - InstrumentingAgents* instrumentingAgents = cookie.instrumentingAgents(); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveResponse(identifier, loader, response, resourceLoader); - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->didReceiveResponse(identifier, response); // This should come AFTER resource notification, front-end relies on this. -} -void InspectorInstrumentation::didReceiveResourceResponseButCanceledImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) -{ - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(frame, identifier, r); - InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, r, nullptr); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveResponse(identifier, *loader, response, resourceLoader); + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->didReceiveResponse(identifier, response); // This should come AFTER resource notification, front-end relies on this. } -void InspectorInstrumentation::continueAfterXFrameOptionsDeniedImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) +void InspectorInstrumentation::didReceiveThreadableLoaderResponseImpl(InstrumentingAgents& instrumentingAgents, DocumentThreadableLoader& documentThreadableLoader, unsigned long identifier) { - didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveThreadableLoaderResponse(identifier, documentThreadableLoader); } -void InspectorInstrumentation::continueWithPolicyDownloadImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) +void InspectorInstrumentation::didReceiveDataImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) { - didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveData(identifier, data, dataLength, encodedDataLength); } -void InspectorInstrumentation::continueWithPolicyIgnoreImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) +void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, double finishTime) { - didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); -} + if (!loader) + return; -void InspectorInstrumentation::didReceiveDataImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) -{ - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveData(identifier, data, dataLength, encodedDataLength); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didFinishLoading(identifier, *loader, finishTime); } -void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, double finishTime) +void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceError& error) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didFinishLoadingResource(identifier, false, finishTime, loader->frame()); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didFinishLoading(identifier, loader, finishTime); -} + if (!loader) + return; -void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceError& error) -{ - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didFinishLoadingResource(identifier, true, 0, loader->frame()); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didFailLoading(identifier, loader, error); - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didFailLoading(identifier, *loader, error); + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) consoleAgent->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this. } -void InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClientImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, ThreadableLoaderClient* client) -{ - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->documentThreadableLoaderStartedLoadingForClient(identifier, client); -} - -void InspectorInstrumentation::willLoadXHRImpl(InstrumentingAgents* instrumentingAgents, ThreadableLoaderClient* client, const String& method, const URL& url, bool async, PassRefPtr<FormData> formData, const HTTPHeaderMap& headers, bool includeCredentials) +void InspectorInstrumentation::didFinishXHRLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->willLoadXHR(client, method, url, async, formData, headers, includeCredentials); -} - -void InspectorInstrumentation::didFailXHRLoadingImpl(InstrumentingAgents* instrumentingAgents, ThreadableLoaderClient* client) -{ - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didFailXHRLoading(client); -} - -void InspectorInstrumentation::didFinishXHRLoadingImpl(InstrumentingAgents* instrumentingAgents, ThreadableLoaderClient* client, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) -{ - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) consoleAgent->didFinishXHRLoading(identifier, url, sendURL, sendLineNumber, sendColumnNumber); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didFinishXHRLoading(client, identifier, sourceString); -} - -void InspectorInstrumentation::didReceiveXHRResponseImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier) -{ - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveXHRResponse(identifier); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) { + if (decodedText) + networkAgent->didFinishXHRLoading(identifier, *decodedText); + } } -void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->willLoadXHRSynchronously(); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->willLoadXHRSynchronously(); } -void InspectorInstrumentation::didLoadXHRSynchronouslyImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::didLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didLoadXHRSynchronously(); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didLoadXHRSynchronously(); } -void InspectorInstrumentation::scriptImportedImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const String& sourceString) +void InspectorInstrumentation::scriptImportedImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const String& sourceString) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->setInitialScriptContent(identifier, sourceString); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->setInitialScriptContent(identifier, sourceString); } -void InspectorInstrumentation::scriptExecutionBlockedByCSPImpl(InstrumentingAgents* instrumentingAgents, const String& directiveText) +void InspectorInstrumentation::scriptExecutionBlockedByCSPImpl(InstrumentingAgents& instrumentingAgents, const String& directiveText) { - if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) debuggerAgent->scriptExecutionBlockedByCSP(directiveText); } -void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier) +void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveScriptResponse(identifier); + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveScriptResponse(identifier); } -void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didMarkDOMContentEvent(frame); - - if (&frame->page()->mainFrame() != frame) + if (!frame.isMainFrame()) return; - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->mainFrameDOMContentLoaded(); - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->domContentEventFired(); } -void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame* frame) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didMarkLoadEvent(frame); - - if (&frame->page()->mainFrame() != frame) + if (!frame || !frame->isMainFrame()) return; - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->loadEventFired(); } -void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent()) - canvasAgent->frameDetached(frame); - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) pageAgent->frameDetached(frame); + +#if ENABLE(WEB_REPLAY) + if (!frame.isMainFrame()) + return; + + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->frameDetached(frame); +#endif } -void InspectorInstrumentation::didCommitLoadImpl(InstrumentingAgents* instrumentingAgents, Page* page, DocumentLoader* loader) +void InspectorInstrumentation::didCommitLoadImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, DocumentLoader* loader) { - if (!instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) + if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled()) + return; + + if (!frame.page()) + return; + + if (!loader) return; - if (loader->frame()->isMainFrame()) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) + ASSERT(loader->frame() == &frame); + + if (frame.isMainFrame()) { + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) consoleAgent->reset(); - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->mainFrameNavigated(loader); - if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) - profilerAgent->resetState(); - if (InspectorHeapProfilerAgent* heapProfilerAgent = instrumentingAgents->inspectorHeapProfilerAgent()) - heapProfilerAgent->resetState(); - if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent()) + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->mainFrameNavigated(*loader); + + if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent()) cssAgent->reset(); -#if ENABLE(SQL_DATABASE) - if (InspectorDatabaseAgent* databaseAgent = instrumentingAgents->inspectorDatabaseAgent()) + + if (InspectorDatabaseAgent* databaseAgent = instrumentingAgents.inspectorDatabaseAgent()) databaseAgent->clearResources(); -#endif - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) - domAgent->setDocument(page->mainFrame().document()); -#if USE(ACCELERATED_COMPOSITING) - if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents->inspectorLayerTreeAgent()) + + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) + domAgent->setDocument(frame.document()); + + if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent()) layerTreeAgent->reset(); -#endif + + if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent()) + pageDebuggerAgent->mainFrameNavigated(); + + if (PageHeapAgent* pageHeapAgent = instrumentingAgents.pageHeapAgent()) + pageHeapAgent->mainFrameNavigated(); } - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) - domAgent->didCommitLoad(loader->frame()->document()); - if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent()) - canvasAgent->frameNavigated(loader->frame()); - if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent()) - pageAgent->frameNavigated(loader); + + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) + domAgent->didCommitLoad(frame.document()); + + if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent()) + pageAgent->frameNavigated(frame); + + if (frame.isMainFrame()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->mainFrameNavigated(); + } + +#if ENABLE(WEB_REPLAY) + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->frameNavigated(frame); +#endif } -void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - if (!instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) + if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled()) return; - if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent()) + if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent()) domAgent->frameDocumentUpdated(frame); } -void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents* instrumentingAgents, DocumentLoader* loader) +void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader) { - if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent()) + if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent()) inspectorPageAgent->loaderDetachedFromFrame(loader); } void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { + if (frame.isMainFrame()) { + if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent()) + pageDebuggerAgent->mainFrameStartedLoading(); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent()) + timelineAgent->mainFrameStartedLoading(); + } + if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent()) inspectorPageAgent->frameStartedLoading(frame); } void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { + if (frame.isMainFrame()) { + if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent()) + pageDebuggerAgent->mainFrameStoppedLoading(); + } + if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent()) inspectorPageAgent->frameStoppedLoading(frame); } @@ -820,261 +806,283 @@ void InspectorInstrumentation::frameClearedScheduledNavigationImpl(Instrumenting inspectorPageAgent->frameClearedScheduledNavigation(frame); } -InspectorInstrumentationCookie InspectorInstrumentation::willRunJavaScriptDialogImpl(InstrumentingAgents* instrumentingAgents, const String& message) -{ - if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent()) - inspectorPageAgent->willRunJavaScriptDialog(message); - return InspectorInstrumentationCookie(instrumentingAgents, 0); -} - -void InspectorInstrumentation::didRunJavaScriptDialogImpl(const InspectorInstrumentationCookie& cookie) -{ - if (InspectorPageAgent* inspectorPageAgent = cookie.instrumentingAgents()->inspectorPageAgent()) - inspectorPageAgent->didRunJavaScriptDialog(); -} - -void InspectorInstrumentation::willDestroyCachedResourceImpl(CachedResource* cachedResource) +void InspectorInstrumentation::willDestroyCachedResourceImpl(CachedResource& cachedResource) { - if (!instrumentingAgentsSet) + if (!s_instrumentingAgentsSet) return; - HashSet<InstrumentingAgents*>::iterator end = instrumentingAgentsSet->end(); - for (HashSet<InstrumentingAgents*>::iterator it = instrumentingAgentsSet->begin(); it != end; ++it) { - InstrumentingAgents* instrumentingAgents = *it; - if (InspectorResourceAgent* inspectorResourceAgent = instrumentingAgents->inspectorResourceAgent()) - inspectorResourceAgent->willDestroyCachedResource(cachedResource); - } -} -InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTMLImpl(InstrumentingAgents* instrumentingAgents, unsigned startLine, Frame* frame) -{ - int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { - timelineAgent->willWriteHTML(startLine, frame); - timelineAgentId = timelineAgent->id(); + for (auto* instrumentingAgent : *s_instrumentingAgentsSet) { + if (InspectorNetworkAgent* inspectorNetworkAgent = instrumentingAgent->inspectorNetworkAgent()) + inspectorNetworkAgent->willDestroyCachedResource(cachedResource); } - return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId); -} - -void InspectorInstrumentation::didWriteHTMLImpl(const InspectorInstrumentationCookie& cookie, unsigned endLine) -{ - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) - timelineAgent->didWriteHTML(endLine); } // JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes. static bool isConsoleAssertMessage(MessageSource source, MessageType type) { - return source == ConsoleAPIMessageSource && type == AssertMessageType; + return source == MessageSource::ConsoleAPI && type == MessageType::Assert; } -// FIXME: Drop this once we no longer generate stacks outside of Inspector. -void InspectorInstrumentation::addMessageToConsoleImpl(InstrumentingAgents* instrumentingAgents, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier) +void InspectorInstrumentation::addMessageToConsoleImpl(InstrumentingAgents& instrumentingAgents, std::unique_ptr<ConsoleMessage> message) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->addMessageToConsole(source, type, level, message, callStack, requestIdentifier); + MessageSource source = message->source(); + MessageType type = message->type(); + String messageText = message->message(); + + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->addMessageToConsole(WTFMove(message)); // FIXME: This should just pass the message on to the debugger agent. JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes. - if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) { + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) { if (isConsoleAssertMessage(source, type)) - debuggerAgent->handleConsoleAssert(); + debuggerAgent->handleConsoleAssert(messageText); } } -void InspectorInstrumentation::addMessageToConsoleImpl(InstrumentingAgents* instrumentingAgents, MessageSource source, MessageType type, MessageLevel level, const String& message, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier) +void InspectorInstrumentation::consoleCountImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* state, Ref<ScriptArguments>&& arguments) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->addMessageToConsole(source, type, level, message, state, arguments, requestIdentifier); - // FIXME: This should just pass the message on to the debugger agent. JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes. - if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) { - if (isConsoleAssertMessage(source, type)) - debuggerAgent->handleConsoleAssert(); - } + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->count(state, WTFMove(arguments)); } -void InspectorInstrumentation::addMessageToConsoleImpl(InstrumentingAgents* instrumentingAgents, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier) +void InspectorInstrumentation::takeHeapSnapshotImpl(InstrumentingAgents& instrumentingAgents, const String& title) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->addMessageToConsole(source, type, level, message, scriptID, lineNumber, columnNumber, state, requestIdentifier); + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->takeHeapSnapshot(title); } -void InspectorInstrumentation::consoleCountImpl(InstrumentingAgents* instrumentingAgents, JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments) +void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& title) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->count(state, arguments); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) + timelineAgent->time(frame, title); + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->startTiming(title); } -void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const String& title) +void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, const String& title) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->time(frame, title); - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) consoleAgent->startTiming(title); } -void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const String& title, PassRefPtr<ScriptCallStack> stack) +void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& title, Ref<ScriptCallStack>&& stack) { - if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) - consoleAgent->stopTiming(title, stack); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->stopTiming(title, WTFMove(stack)); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->timeEnd(frame, title); } -void InspectorInstrumentation::consoleTimeStampImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, PassRefPtr<ScriptArguments> arguments) +void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, const String& title, Ref<ScriptCallStack>&& stack) +{ + if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent()) + consoleAgent->stopTiming(title, WTFMove(stack)); +} + +void InspectorInstrumentation::consoleTimeStampImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, Ref<ScriptArguments>&& arguments) { - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { String message; arguments->getFirstArgumentAsString(message); timelineAgent->didTimeStamp(frame, message); } } -void InspectorInstrumentation::addStartProfilingMessageToConsoleImpl(InstrumentingAgents* instrumentingAgents, const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL) +void InspectorInstrumentation::startProfilingImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* exec, const String& title) { - if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) - profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, columnNumber, sourceURL); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent()) + timelineAgent->startFromConsole(exec, title); } -void InspectorInstrumentation::addProfileImpl(InstrumentingAgents* instrumentingAgents, RefPtr<ScriptProfile> profile, PassRefPtr<ScriptCallStack> callStack) +void InspectorInstrumentation::stopProfilingImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* exec, const String& title) { - if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) { - const ScriptCallFrame& lastCaller = callStack->at(0); - profilerAgent->addProfile(profile, lastCaller.lineNumber(), lastCaller.columnNumber(), lastCaller.sourceURL()); - } + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent()) + timelineAgent->stopFromConsole(exec, title); } -String InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(InstrumentingAgents* instrumentingAgents, bool incrementProfileNumber) +void InspectorInstrumentation::didOpenDatabaseImpl(InstrumentingAgents& instrumentingAgents, RefPtr<Database>&& database, const String& domain, const String& name, const String& version) { - if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) - return profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber); - return ""; + if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled()) + return; + if (InspectorDatabaseAgent* dbAgent = instrumentingAgents.inspectorDatabaseAgent()) + dbAgent->didOpenDatabase(WTFMove(database), domain, name, version); } -bool InspectorInstrumentation::profilerEnabledImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin) { - if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) - return profilerAgent->enabled(); + if (InspectorDOMStorageAgent* domStorageAgent = instrumentingAgents.inspectorDOMStorageAgent()) + domStorageAgent->didDispatchDOMStorageEvent(key, oldValue, newValue, storageType, securityOrigin); +} + +bool InspectorInstrumentation::shouldWaitForDebuggerOnStartImpl(InstrumentingAgents& instrumentingAgents) +{ + if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent()) + return workerAgent->shouldWaitForDebuggerOnStart(); return false; } -#if ENABLE(SQL_DATABASE) -void InspectorInstrumentation::didOpenDatabaseImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<Database> database, const String& domain, const String& name, const String& version) +void InspectorInstrumentation::workerStartedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy, const URL& url) +{ + if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent()) + workerAgent->workerStarted(proxy, url); +} + +void InspectorInstrumentation::workerTerminatedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy) +{ + if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent()) + workerAgent->workerTerminated(proxy); +} + +#if ENABLE(WEB_SOCKETS) +void InspectorInstrumentation::didCreateWebSocketImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const URL& requestURL) { - if (!instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) + if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled()) return; - if (InspectorDatabaseAgent* dbAgent = instrumentingAgents->inspectorDatabaseAgent()) - dbAgent->didOpenDatabase(database, domain, name, version); + + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didCreateWebSocket(identifier, requestURL); +} + +void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const ResourceRequest& request) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->willSendWebSocketHandshakeRequest(identifier, request); +} + +void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const ResourceResponse& response) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveWebSocketHandshakeResponse(identifier, response); +} + +void InspectorInstrumentation::didCloseWebSocketImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didCloseWebSocket(identifier); +} + +void InspectorInstrumentation::didReceiveWebSocketFrameImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveWebSocketFrame(identifier, frame); +} + +void InspectorInstrumentation::didReceiveWebSocketFrameErrorImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const String& errorMessage) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didReceiveWebSocketFrameError(identifier, errorMessage); +} + +void InspectorInstrumentation::didSendWebSocketFrameImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame) +{ + if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) + networkAgent->didSendWebSocketFrame(identifier, frame); } #endif -void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents* instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page* page) +#if ENABLE(WEB_REPLAY) +void InspectorInstrumentation::sessionCreatedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session) { - if (InspectorDOMStorageAgent* domStorageAgent = instrumentingAgents->inspectorDOMStorageAgent()) - domStorageAgent->didDispatchDOMStorageEvent(key, oldValue, newValue, storageType, securityOrigin, page); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->sessionCreated(WTFMove(session)); } -bool InspectorInstrumentation::shouldPauseDedicatedWorkerOnStartImpl(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::sessionLoadedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session) { - if (InspectorWorkerAgent* workerAgent = instrumentingAgents->inspectorWorkerAgent()) - return workerAgent->shouldPauseDedicatedWorkerOnStart(); - return false; + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->sessionLoaded(WTFMove(session)); } -void InspectorInstrumentation::didStartWorkerGlobalScopeImpl(InstrumentingAgents* instrumentingAgents, WorkerGlobalScopeProxy* workerGlobalScopeProxy, const URL& url) +void InspectorInstrumentation::sessionModifiedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session) { - if (InspectorWorkerAgent* workerAgent = instrumentingAgents->inspectorWorkerAgent()) - workerAgent->didStartWorkerGlobalScope(workerGlobalScopeProxy, url); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->sessionModified(WTFMove(session)); } -void InspectorInstrumentation::willEvaluateWorkerScript(WorkerGlobalScope* workerGlobalScope, int workerThreadStartMode) +void InspectorInstrumentation::segmentCreatedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment) { - if (workerThreadStartMode != PauseWorkerGlobalScopeOnStart) - return; - InstrumentingAgents* instrumentingAgents = instrumentationForWorkerGlobalScope(workerGlobalScope); - if (!instrumentingAgents) - return; - if (WorkerRuntimeAgent* runtimeAgent = instrumentingAgents->workerRuntimeAgent()) - runtimeAgent->pauseWorkerGlobalScope(workerGlobalScope); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->segmentCreated(WTFMove(segment)); } -void InspectorInstrumentation::workerGlobalScopeTerminatedImpl(InstrumentingAgents* instrumentingAgents, WorkerGlobalScopeProxy* proxy) +void InspectorInstrumentation::segmentCompletedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment) { - if (InspectorWorkerAgent* workerAgent = instrumentingAgents->inspectorWorkerAgent()) - workerAgent->workerGlobalScopeTerminated(proxy); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->segmentCompleted(WTFMove(segment)); } -#if ENABLE(WEB_SOCKETS) -void InspectorInstrumentation::didCreateWebSocketImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const URL& requestURL, const URL&, const String& protocol, Document* document) +void InspectorInstrumentation::segmentLoadedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment) { - if (!instrumentingAgents->inspectorEnvironment().developerExtrasEnabled()) - return; - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didCreateWebSocket(identifier, requestURL); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didCreateWebSocket(identifier, requestURL, protocol, document->frame()); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->segmentLoaded(WTFMove(segment)); } -void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const ResourceRequest& request, Document* document) +void InspectorInstrumentation::segmentUnloadedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->willSendWebSocketHandshakeRequest(identifier, document->frame()); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->segmentUnloaded(); } -void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const ResourceResponse& response, Document* document) +void InspectorInstrumentation::captureStartedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didReceiveWebSocketHandshakeResponse(identifier, document->frame()); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->captureStarted(); } -void InspectorInstrumentation::didCloseWebSocketImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, Document* document) +void InspectorInstrumentation::captureStoppedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didCloseWebSocket(identifier); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) - timelineAgent->didDestroyWebSocket(identifier, document->frame()); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->captureStopped(); } -void InspectorInstrumentation::didReceiveWebSocketFrameImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame) +void InspectorInstrumentation::playbackStartedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveWebSocketFrame(identifier, frame); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->playbackStarted(); } -void InspectorInstrumentation::didReceiveWebSocketFrameErrorImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const String& errorMessage) + +void InspectorInstrumentation::playbackPausedImpl(InstrumentingAgents& instrumentingAgents, const ReplayPosition& position) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didReceiveWebSocketFrameError(identifier, errorMessage); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->playbackPaused(position); } -void InspectorInstrumentation::didSendWebSocketFrameImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame) + +void InspectorInstrumentation::playbackHitPositionImpl(InstrumentingAgents& instrumentingAgents, const ReplayPosition& position) +{ + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->playbackHitPosition(position); +} + +void InspectorInstrumentation::playbackFinishedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) - resourceAgent->didSendWebSocketFrame(identifier, frame); + if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent()) + replayAgent->playbackFinished(); } #endif -void InspectorInstrumentation::networkStateChangedImpl(InstrumentingAgents* instrumentingAgents) +#if ENABLE(RESOURCE_USAGE) +void InspectorInstrumentation::didHandleMemoryPressureImpl(InstrumentingAgents& instrumentingAgents, Critical critical) { - if (InspectorApplicationCacheAgent* applicationCacheAgent = instrumentingAgents->inspectorApplicationCacheAgent()) - applicationCacheAgent->networkStateChanged(); + if (InspectorMemoryAgent* memoryAgent = instrumentingAgents.inspectorMemoryAgent()) + memoryAgent->didHandleMemoryPressure(critical); } +#endif -void InspectorInstrumentation::updateApplicationCacheStatusImpl(InstrumentingAgents* instrumentingAgents, Frame* frame) +void InspectorInstrumentation::networkStateChangedImpl(InstrumentingAgents& instrumentingAgents) { - if (InspectorApplicationCacheAgent* applicationCacheAgent = instrumentingAgents->inspectorApplicationCacheAgent()) - applicationCacheAgent->updateApplicationCacheStatus(frame); + if (InspectorApplicationCacheAgent* applicationCacheAgent = instrumentingAgents.inspectorApplicationCacheAgent()) + applicationCacheAgent->networkStateChanged(); } -bool InspectorInstrumentation::canvasAgentEnabled(ScriptExecutionContext* scriptExecutionContext) +void InspectorInstrumentation::updateApplicationCacheStatusImpl(InstrumentingAgents& instrumentingAgents, Frame& frame) { - InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext); - return instrumentingAgents && instrumentingAgents->inspectorCanvasAgent(); + if (auto* applicationCacheAgent = instrumentingAgents.inspectorApplicationCacheAgent()) + applicationCacheAgent->updateApplicationCacheStatus(&frame); } bool InspectorInstrumentation::consoleAgentEnabled(ScriptExecutionContext* scriptExecutionContext) { InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext); - InspectorConsoleAgent* consoleAgent = instrumentingAgents ? instrumentingAgents->inspectorConsoleAgent() : nullptr; + InspectorConsoleAgent* consoleAgent = instrumentingAgents ? instrumentingAgents->webConsoleAgent() : nullptr; return consoleAgent && consoleAgent->enabled(); } @@ -1084,40 +1092,51 @@ bool InspectorInstrumentation::timelineAgentEnabled(ScriptExecutionContext* scri return instrumentingAgents && instrumentingAgents->inspectorTimelineAgent(); } -void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InstrumentingAgents* instrumentingAgents, bool isDOMEvent, const String& eventName, bool synchronous) +bool InspectorInstrumentation::replayAgentEnabled(ScriptExecutionContext* scriptExecutionContext) { - if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent()) - domDebuggerAgent->pauseOnNativeEventIfNeeded(isDOMEvent, eventName, synchronous); +#if ENABLE(WEB_REPLAY) + InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext); + return instrumentingAgents && instrumentingAgents->inspectorReplayAgent(); +#else + UNUSED_PARAM(scriptExecutionContext); + return false; +#endif } -void InspectorInstrumentation::cancelPauseOnNativeEvent(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InstrumentingAgents& instrumentingAgents, bool isDOMEvent, const String& eventName, bool synchronous) { - if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) - debuggerAgent->cancelPauseOnNextStatement(); + if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent()) + domDebuggerAgent->pauseOnNativeEventIfNeeded(isDOMEvent, eventName, synchronous); } -void InspectorInstrumentation::didRequestAnimationFrameImpl(InstrumentingAgents* instrumentingAgents, int callbackId, Frame* frame) +void InspectorInstrumentation::didRequestAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, requestAnimationFrameEventName, true); + didScheduleAsyncCall(instrumentingAgents, AsyncCallTypeRequestAnimationFrame, callbackId, *frame->document(), true); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didRequestAnimationFrame(callbackId, frame); } -void InspectorInstrumentation::didCancelAnimationFrameImpl(InstrumentingAgents* instrumentingAgents, int callbackId, Frame* frame) +void InspectorInstrumentation::didCancelAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, cancelAnimationFrameEventName, true); - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) + debuggerAgent->didCancelAsyncCall(AsyncCallTypeRequestAnimationFrame, callbackId); + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) timelineAgent->didCancelAnimationFrame(callbackId, frame); } -InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameImpl(InstrumentingAgents* instrumentingAgents, int callbackId, Frame* frame) +InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame) { pauseOnNativeEventIfNeeded(instrumentingAgents, false, animationFrameFiredEventName, false); + if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) + debuggerAgent->willDispatchAsyncCall(AsyncCallTypeRequestAnimationFrame, callbackId); + int timelineAgentId = 0; - if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent()) { + if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) { timelineAgent->willFireAnimationFrame(callbackId, frame); timelineAgentId = timelineAgent->id(); } @@ -1126,84 +1145,58 @@ InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameI void InspectorInstrumentation::didFireAnimationFrameImpl(const InspectorInstrumentationCookie& cookie) { + if (InspectorDebuggerAgent* debuggerAgent = cookie.instrumentingAgents()->inspectorDebuggerAgent()) + debuggerAgent->didDispatchAsyncCall(); if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didFireAnimationFrame(); } -void InspectorInstrumentation::registerInstrumentingAgents(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::registerInstrumentingAgents(InstrumentingAgents& instrumentingAgents) { - if (!instrumentingAgentsSet) - instrumentingAgentsSet = new HashSet<InstrumentingAgents*>(); - instrumentingAgentsSet->add(instrumentingAgents); + if (!s_instrumentingAgentsSet) + s_instrumentingAgentsSet = new HashSet<InstrumentingAgents*>(); + + s_instrumentingAgentsSet->add(&instrumentingAgents); } -void InspectorInstrumentation::unregisterInstrumentingAgents(InstrumentingAgents* instrumentingAgents) +void InspectorInstrumentation::unregisterInstrumentingAgents(InstrumentingAgents& instrumentingAgents) { - if (!instrumentingAgentsSet) + if (!s_instrumentingAgentsSet) return; - instrumentingAgentsSet->remove(instrumentingAgents); - if (instrumentingAgentsSet->isEmpty()) { - delete instrumentingAgentsSet; - instrumentingAgentsSet = nullptr; + + s_instrumentingAgentsSet->remove(&instrumentingAgents); + if (s_instrumentingAgentsSet->isEmpty()) { + delete s_instrumentingAgentsSet; + s_instrumentingAgentsSet = nullptr; } } InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie) { - if (!cookie.instrumentingAgents()) + if (!cookie.isValid()) return nullptr; + InspectorTimelineAgent* timelineAgent = cookie.instrumentingAgents()->inspectorTimelineAgent(); if (timelineAgent && cookie.hasMatchingTimelineAgentId(timelineAgent->id())) return timelineAgent; return nullptr; } -InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForPage(Page* page) +InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForRenderer(RenderObject& renderer) { - if (!page) - return nullptr; - return instrumentationForPage(page); + return instrumentingAgentsForFrame(renderer.frame()); } -InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForRenderer(RenderObject* renderer) +void InspectorInstrumentation::layerTreeDidChangeImpl(InstrumentingAgents& instrumentingAgents) { - return instrumentingAgentsForFrame(&renderer->frame()); -} - -InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope) -{ - if (!workerGlobalScope) - return nullptr; - return instrumentationForWorkerGlobalScope(workerGlobalScope); -} - -InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForNonDocumentContext(ScriptExecutionContext* context) -{ - if (context->isWorkerGlobalScope()) - return instrumentationForWorkerGlobalScope(static_cast<WorkerGlobalScope*>(context)); - return nullptr; -} - -#if USE(ACCELERATED_COMPOSITING) -void InspectorInstrumentation::layerTreeDidChangeImpl(InstrumentingAgents* instrumentingAgents) -{ - if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents->inspectorLayerTreeAgent()) + if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent()) layerTreeAgent->layerTreeDidChange(); } -void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents* instrumentingAgents, const RenderLayer* renderLayer) +void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& instrumentingAgents, const RenderLayer& renderLayer) { - if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents->inspectorLayerTreeAgent()) + if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent()) layerTreeAgent->renderLayerDestroyed(renderLayer); } -void InspectorInstrumentation::pseudoElementDestroyedImpl(InstrumentingAgents* instrumentingAgents, PseudoElement* pseudoElement) -{ - if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents->inspectorLayerTreeAgent()) - layerTreeAgent->pseudoElementDestroyed(pseudoElement); -} -#endif - } // namespace WebCore - -#endif // !ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h index 13d622455..9a99e9963 100644 --- a/Source/WebCore/inspector/InspectorInstrumentation.h +++ b/Source/WebCore/inspector/InspectorInstrumentation.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. +* Copyright (C) 2014-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,217 +29,208 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorInstrumentation_h -#define InspectorInstrumentation_h +#pragma once #include "CSSSelector.h" -#include "ConsoleAPITypes.h" -#include "ConsoleTypes.h" +#include "DocumentThreadableLoader.h" #include "Element.h" #include "FormData.h" #include "Frame.h" #include "HitTestResult.h" +#include "InspectorController.h" #include "InspectorInstrumentationCookie.h" +#include "MemoryPressureHandler.h" #include "Page.h" #include "ScriptExecutionContext.h" -#include "ScriptState.h" #include "StorageArea.h" -#include "WebSocketFrame.h" +#include "WorkerGlobalScope.h" +#include "WorkerInspectorController.h" #include <wtf/RefPtr.h> -namespace Deprecated { -class ScriptObject; +#if ENABLE(WEB_REPLAY) +#include "ReplaySession.h" +#include "ReplaySessionSegment.h" +#endif + + +namespace Inspector { +class ConsoleMessage; +class ScriptArguments; +class ScriptCallStack; } namespace WebCore { -class CSSRule; class CachedResource; class CharacterData; class DOMWindow; class DOMWrapperWorld; class Database; class Document; -class Element; class DocumentLoader; -class DocumentStyleSheetCollection; -class GraphicsContext; class HTTPHeaderMap; -class InspectorCSSAgent; -class InspectorCSSOMWrappers; -class InspectorInstrumentation; class InspectorTimelineAgent; class InstrumentingAgents; -class URL; class Node; class PseudoElement; class RenderLayer; -class RenderLayerBacking; class RenderObject; class ResourceRequest; class ResourceResponse; -class ScriptArguments; -class ScriptCallStack; -class ScriptExecutionContext; -class ScriptProfile; class SecurityOrigin; class ShadowRoot; -class StorageArea; -class StyleResolver; -class StyleRule; -class ThreadableLoaderClient; -class WorkerGlobalScope; -class WorkerGlobalScopeProxy; -class XMLHttpRequest; +class URL; +class WebKitNamedFlow; +class WorkerInspectorProxy; + +enum class StorageType; + +struct ReplayPosition; +struct WebSocketFrame; #define FAST_RETURN_IF_NO_FRONTENDS(value) if (LIKELY(!hasFrontends())) return value; class InspectorInstrumentation { public: - static void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld&); + static void didClearWindowObjectInWorld(Frame&, DOMWrapperWorld&); static bool isDebuggerPaused(Frame*); - static void willInsertDOMNode(Document*, Node* parent); - static void didInsertDOMNode(Document*, Node*); - static void willRemoveDOMNode(Document*, Node*); - static void didRemoveDOMNode(Document*, Node*); - static void willModifyDOMAttr(Document*, Element*, const AtomicString& oldValue, const AtomicString& newValue); - static void didModifyDOMAttr(Document*, Element*, const AtomicString& name, const AtomicString& value); - static void didRemoveDOMAttr(Document*, Element*, const AtomicString& name); - static void characterDataModified(Document*, CharacterData*); - static void didInvalidateStyleAttr(Document*, Node*); - static void frameWindowDiscarded(Frame*, DOMWindow*); - static void mediaQueryResultChanged(Document*); - static void didPushShadowRoot(Element* host, ShadowRoot*); - static void willPopShadowRoot(Element* host, ShadowRoot*); - static void didCreateNamedFlow(Document*, WebKitNamedFlow*); - static void willRemoveNamedFlow(Document*, WebKitNamedFlow*); - static void didUpdateRegionLayout(Document*, WebKitNamedFlow*); - static void didChangeRegionOverset(Document*, WebKitNamedFlow*); - static void didRegisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement, Node* nextContentElement = nullptr); - static void didUnregisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement); - - static void mouseDidMoveOverElement(Page*, const HitTestResult&, unsigned modifierFlags); - static bool handleMousePress(Page*); - static bool handleTouchEvent(Page*, Node*); - static bool forcePseudoState(Element*, CSSSelector::PseudoType); + static void willInsertDOMNode(Document&, Node& parent); + static void didInsertDOMNode(Document&, Node&); + static void willRemoveDOMNode(Document&, Node&); + static void didRemoveDOMNode(Document&, Node&); + static void willModifyDOMAttr(Document&, Element&, const AtomicString& oldValue, const AtomicString& newValue); + static void didModifyDOMAttr(Document&, Element&, const AtomicString& name, const AtomicString& value); + static void didRemoveDOMAttr(Document&, Element&, const AtomicString& name); + static void characterDataModified(Document&, CharacterData&); + static void didInvalidateStyleAttr(Document&, Node&); + static void documentDetached(Document&); + static void frameWindowDiscarded(Frame&, DOMWindow*); + static void mediaQueryResultChanged(Document&); + static void activeStyleSheetsUpdated(Document&); + static void didPushShadowRoot(Element& host, ShadowRoot&); + static void willPopShadowRoot(Element& host, ShadowRoot&); + static void didChangeCustomElementState(Element&); + static void pseudoElementCreated(Page*, PseudoElement&); + static void pseudoElementDestroyed(Page*, PseudoElement&); + static void didCreateNamedFlow(Document*, WebKitNamedFlow&); + static void willRemoveNamedFlow(Document*, WebKitNamedFlow&); + static void didChangeRegionOverset(Document&, WebKitNamedFlow&); + static void didRegisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement, Node* nextContentElement = nullptr); + static void didUnregisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement); + + static void mouseDidMoveOverElement(Page&, const HitTestResult&, unsigned modifierFlags); + static bool handleMousePress(Frame&); + static bool handleTouchEvent(Frame&, Node&); + static bool forcePseudoState(const Element&, CSSSelector::PseudoClassType); static void willSendXMLHttpRequest(ScriptExecutionContext*, const String& url); - static void didScheduleResourceRequest(Document*, const String& url); - static void didInstallTimer(ScriptExecutionContext*, int timerId, int timeout, bool singleShot); - static void didRemoveTimer(ScriptExecutionContext*, int timerId); + static void didInstallTimer(ScriptExecutionContext&, int timerId, std::chrono::milliseconds timeout, bool singleShot); + static void didRemoveTimer(ScriptExecutionContext&, int timerId); static InspectorInstrumentationCookie willCallFunction(ScriptExecutionContext*, const String& scriptName, int scriptLine); - static void didCallFunction(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext*, XMLHttpRequest*); - static void didDispatchXHRReadyStateChangeEvent(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event&, bool hasEventListeners); + static void didCallFunction(const InspectorInstrumentationCookie&, ScriptExecutionContext*); + static InspectorInstrumentationCookie willDispatchEvent(Document&, const Event&, bool hasEventListeners); static void didDispatchEvent(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willHandleEvent(ScriptExecutionContext*, Event*); - static void didHandleEvent(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event& event, DOMWindow* window); + static void willHandleEvent(ScriptExecutionContext*, const Event&); + static InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event&, DOMWindow&); static void didDispatchEventOnWindow(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willEvaluateScript(Frame*, const String& url, int lineNumber); - static void didEvaluateScript(const InspectorInstrumentationCookie&); - static void scriptsEnabled(Page*, bool isEnabled); - static void didCreateIsolatedContext(Frame*, JSC::ExecState*, SecurityOrigin*); - static InspectorInstrumentationCookie willFireTimer(ScriptExecutionContext*, int timerId); + static InspectorInstrumentationCookie willEvaluateScript(Frame&, const String& url, int lineNumber); + static void didEvaluateScript(const InspectorInstrumentationCookie&, Frame&); + static InspectorInstrumentationCookie willFireTimer(ScriptExecutionContext&, int timerId); static void didFireTimer(const InspectorInstrumentationCookie&); - static void didInvalidateLayout(Frame*); - static InspectorInstrumentationCookie willLayout(Frame*); - static void didLayout(const InspectorInstrumentationCookie&, RenderObject*); - static void didScroll(Page*); - static InspectorInstrumentationCookie willDispatchXHRLoadEvent(ScriptExecutionContext*, XMLHttpRequest*); - static void didDispatchXHRLoadEvent(const InspectorInstrumentationCookie&); - static void willScrollLayer(Frame*); - static void didScrollLayer(Frame*); - static void willPaint(RenderObject*); - static void didPaint(RenderObject*, GraphicsContext*, const LayoutRect&); - static void willComposite(Page*); - static void didComposite(Page*); - static InspectorInstrumentationCookie willRecalculateStyle(Document*); + static void didInvalidateLayout(Frame&); + static InspectorInstrumentationCookie willLayout(Frame&); + static void didLayout(const InspectorInstrumentationCookie&, RenderObject&); + static void didScroll(Page&); + static void willComposite(Frame&); + static void didComposite(Frame&); + static void willPaint(RenderObject&); + static void didPaint(RenderObject&, const LayoutRect&); + static InspectorInstrumentationCookie willRecalculateStyle(Document&); static void didRecalculateStyle(const InspectorInstrumentationCookie&); - static void didScheduleStyleRecalculation(Document*); + static void didScheduleStyleRecalculation(Document&); - static void applyEmulatedMedia(Frame*, String*); + static void applyEmulatedMedia(Frame&, String&); static void willSendRequest(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse); - static void continueAfterPingLoader(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&); - static void markResourceAsCached(Page*, unsigned long identifier); - static void didLoadResourceFromMemoryCache(Page*, DocumentLoader*, CachedResource*); - static InspectorInstrumentationCookie willReceiveResourceData(Frame*, unsigned long identifier, int length); - static void didReceiveResourceData(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willReceiveResourceResponse(Frame*, unsigned long identifier, const ResourceResponse&); - static void didReceiveResourceResponse(const InspectorInstrumentationCookie&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*); - static void continueAfterXFrameOptionsDenied(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void continueWithPolicyDownload(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void continueWithPolicyIgnore(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); + static void continueAfterPingLoader(Frame&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&); + static void markResourceAsCached(Page&, unsigned long identifier); + static void didLoadResourceFromMemoryCache(Page&, DocumentLoader*, CachedResource*); + static void didReceiveResourceResponse(Frame&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*); + static void didReceiveThreadableLoaderResponse(DocumentThreadableLoader&, unsigned long identifier); static void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength); static void didFinishLoading(Frame*, DocumentLoader*, unsigned long identifier, double finishTime); static void didFailLoading(Frame*, DocumentLoader*, unsigned long identifier, const ResourceError&); - static void documentThreadableLoaderStartedLoadingForClient(ScriptExecutionContext*, unsigned long identifier, ThreadableLoaderClient*); - static void willLoadXHR(ScriptExecutionContext*, ThreadableLoaderClient*, const String&, const URL&, bool, PassRefPtr<FormData>, const HTTPHeaderMap&, bool); - static void didFailXHRLoading(ScriptExecutionContext*, ThreadableLoaderClient*); - static void didFinishXHRLoading(ScriptExecutionContext*, ThreadableLoaderClient*, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); - static void didReceiveXHRResponse(ScriptExecutionContext*, unsigned long identifier); + static void continueAfterXFrameOptionsDenied(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&); + static void continueWithPolicyDownload(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&); + static void continueWithPolicyIgnore(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&); + + static void didFinishXHRLoading(ScriptExecutionContext*, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); static void willLoadXHRSynchronously(ScriptExecutionContext*); static void didLoadXHRSynchronously(ScriptExecutionContext*); - static void scriptImported(ScriptExecutionContext*, unsigned long identifier, const String& sourceString); + static void scriptImported(ScriptExecutionContext&, unsigned long identifier, const String& sourceString); static void scriptExecutionBlockedByCSP(ScriptExecutionContext*, const String& directiveText); static void didReceiveScriptResponse(ScriptExecutionContext*, unsigned long identifier); - static void domContentLoadedEventFired(Frame*); + static void domContentLoadedEventFired(Frame&); static void loadEventFired(Frame*); - static void frameDetachedFromParent(Frame*); - static void didCommitLoad(Frame*, DocumentLoader*); - static void frameDocumentUpdated(Frame*); - static void loaderDetachedFromFrame(Frame*, DocumentLoader*); + static void frameDetachedFromParent(Frame&); + static void didCommitLoad(Frame&, DocumentLoader*); + static void frameDocumentUpdated(Frame&); + static void loaderDetachedFromFrame(Frame&, DocumentLoader&); static void frameStartedLoading(Frame&); static void frameStoppedLoading(Frame&); static void frameScheduledNavigation(Frame&, double delay); static void frameClearedScheduledNavigation(Frame&); - static InspectorInstrumentationCookie willRunJavaScriptDialog(Page*, const String& message); - static void didRunJavaScriptDialog(const InspectorInstrumentationCookie&); - static void willDestroyCachedResource(CachedResource*); - - static InspectorInstrumentationCookie willWriteHTML(Document*, unsigned startLine); - static void didWriteHTML(const InspectorInstrumentationCookie&, unsigned endLine); - - // FIXME: Remove once we no longer generate stacks outside of Inspector. - static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0); - static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, JSC::ExecState*, PassRefPtr<ScriptArguments>, unsigned long requestIdentifier = 0); - static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0); - - // FIXME: Convert to ScriptArguments to match non-worker context. - static void addMessageToConsole(WorkerGlobalScope*, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0); - static void addMessageToConsole(WorkerGlobalScope*, MessageSource, MessageType, MessageLevel, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0); - - static void consoleCount(Page*, JSC::ExecState*, PassRefPtr<ScriptArguments>); - static void startConsoleTiming(Frame*, const String& title); - static void stopConsoleTiming(Frame*, const String& title, PassRefPtr<ScriptCallStack>); - static void consoleTimeStamp(Frame*, PassRefPtr<ScriptArguments>); + static void willDestroyCachedResource(CachedResource&); + + static void addMessageToConsole(Page&, std::unique_ptr<Inspector::ConsoleMessage>); + static void addMessageToConsole(WorkerGlobalScope&, std::unique_ptr<Inspector::ConsoleMessage>); + + static void consoleCount(Page&, JSC::ExecState*, Ref<Inspector::ScriptArguments>&&); + static void consoleCount(WorkerGlobalScope&, JSC::ExecState*, Ref<Inspector::ScriptArguments>&&); + static void takeHeapSnapshot(Frame&, const String& title); + static void startConsoleTiming(Frame&, const String& title); + static void startConsoleTiming(WorkerGlobalScope&, const String& title); + static void stopConsoleTiming(Frame&, const String& title, Ref<Inspector::ScriptCallStack>&&); + static void stopConsoleTiming(WorkerGlobalScope&, const String& title, Ref<Inspector::ScriptCallStack>&&); + static void consoleTimeStamp(Frame&, Ref<Inspector::ScriptArguments>&&); + static void startProfiling(Page&, JSC::ExecState*, const String& title); + static void stopProfiling(Page&, JSC::ExecState*, const String& title); static void didRequestAnimationFrame(Document*, int callbackId); static void didCancelAnimationFrame(Document*, int callbackId); static InspectorInstrumentationCookie willFireAnimationFrame(Document*, int callbackId); static void didFireAnimationFrame(const InspectorInstrumentationCookie&); - static void addStartProfilingMessageToConsole(Page*, const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - static void addProfile(Page*, RefPtr<ScriptProfile>, PassRefPtr<ScriptCallStack>); - static String getCurrentUserInitiatedProfileName(Page*, bool incrementProfileNumber); - static bool profilerEnabled(Page*); + static void didOpenDatabase(ScriptExecutionContext*, RefPtr<Database>&&, const String& domain, const String& name, const String& version); -#if ENABLE(SQL_DATABASE) - static void didOpenDatabase(ScriptExecutionContext*, PassRefPtr<Database>, const String& domain, const String& name, const String& version); -#endif + static void didDispatchDOMStorageEvent(Page&, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*); + + static bool shouldWaitForDebuggerOnStart(ScriptExecutionContext&); + static void workerStarted(ScriptExecutionContext&, WorkerInspectorProxy*, const URL&); + static void workerTerminated(ScriptExecutionContext&, WorkerInspectorProxy*); - static void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*, Page*); +#if ENABLE(WEB_REPLAY) + static void sessionCreated(Page&, RefPtr<ReplaySession>&&); + static void sessionLoaded(Page&, RefPtr<ReplaySession>&&); + static void sessionModified(Page&, RefPtr<ReplaySession>&&); - static bool shouldPauseDedicatedWorkerOnStart(ScriptExecutionContext*); - static void didStartWorkerGlobalScope(ScriptExecutionContext*, WorkerGlobalScopeProxy*, const URL&); - static void workerGlobalScopeTerminated(ScriptExecutionContext*, WorkerGlobalScopeProxy*); - static void willEvaluateWorkerScript(WorkerGlobalScope*, int workerThreadStartMode); + static void segmentCreated(Page&, RefPtr<ReplaySessionSegment>&&); + static void segmentCompleted(Page&, RefPtr<ReplaySessionSegment>&&); + static void segmentLoaded(Page&, RefPtr<ReplaySessionSegment>&&); + static void segmentUnloaded(Page&); + + static void captureStarted(Page&); + static void captureStopped(Page&); + + static void playbackStarted(Page&); + static void playbackPaused(Page&, const ReplayPosition&); + static void playbackHitPosition(Page&, const ReplayPosition&); + static void playbackFinished(Page&); +#endif #if ENABLE(WEB_SOCKETS) - static void didCreateWebSocket(Document*, unsigned long identifier, const URL& requestURL, const URL& documentURL, const String& protocol); + static void didCreateWebSocket(Document*, unsigned long identifier, const URL& requestURL); static void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const ResourceRequest&); static void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const ResourceResponse&); static void didCloseWebSocket(Document*, unsigned long identifier); @@ -247,1666 +239,1116 @@ public: static void didReceiveWebSocketFrameError(Document*, unsigned long identifier, const String& errorMessage); #endif - static Deprecated::ScriptObject wrapCanvas2DRenderingContextForInstrumentation(Document*, const Deprecated::ScriptObject&); -#if ENABLE(WEBGL) - static Deprecated::ScriptObject wrapWebGLRenderingContextForInstrumentation(Document*, const Deprecated::ScriptObject&); +#if ENABLE(RESOURCE_USAGE) + static void didHandleMemoryPressure(Page&, Critical); #endif - static void networkStateChanged(Page*); + static void networkStateChanged(Page&); static void updateApplicationCacheStatus(Frame*); -#if ENABLE(INSPECTOR) + static void layerTreeDidChange(Page*); + static void renderLayerDestroyed(Page*, const RenderLayer&); + static void frontendCreated() { s_frontendCounter += 1; } static void frontendDeleted() { s_frontendCounter -= 1; } static bool hasFrontends() { return s_frontendCounter; } - static bool canvasAgentEnabled(ScriptExecutionContext*); static bool consoleAgentEnabled(ScriptExecutionContext*); static bool timelineAgentEnabled(ScriptExecutionContext*); -#else - static bool hasFrontends() { return false; } - static bool canvasAgentEnabled(ScriptExecutionContext*) { return false; } - static bool consoleAgentEnabled(ScriptExecutionContext*) { return false; } - static bool runtimeAgentEnabled(Frame*) { return false; } - static bool timelineAgentEnabled(ScriptExecutionContext*) { return false; } -#endif + static bool replayAgentEnabled(ScriptExecutionContext*); - static void registerInstrumentingAgents(InstrumentingAgents*); - static void unregisterInstrumentingAgents(InstrumentingAgents*); + static InstrumentingAgents* instrumentingAgentsForPage(Page*); -#if USE(ACCELERATED_COMPOSITING) - static void layerTreeDidChange(Page*); - static void renderLayerDestroyed(Page*, const RenderLayer*); - static void pseudoElementDestroyed(Page*, PseudoElement*); -#endif + static void registerInstrumentingAgents(InstrumentingAgents&); + static void unregisterInstrumentingAgents(InstrumentingAgents&); private: -#if ENABLE(INSPECTOR) - static void didClearWindowObjectInWorldImpl(InstrumentingAgents*, Frame*, DOMWrapperWorld&); - static bool isDebuggerPausedImpl(InstrumentingAgents*); - - static void willInsertDOMNodeImpl(InstrumentingAgents*, Node* parent); - static void didInsertDOMNodeImpl(InstrumentingAgents*, Node*); - static void willRemoveDOMNodeImpl(InstrumentingAgents*, Node*); - static void didRemoveDOMNodeImpl(InstrumentingAgents*, Node*); - static void willModifyDOMAttrImpl(InstrumentingAgents*, Element*, const AtomicString& oldValue, const AtomicString& newValue); - static void didModifyDOMAttrImpl(InstrumentingAgents*, Element*, const AtomicString& name, const AtomicString& value); - static void didRemoveDOMAttrImpl(InstrumentingAgents*, Element*, const AtomicString& name); - static void characterDataModifiedImpl(InstrumentingAgents*, CharacterData*); - static void didInvalidateStyleAttrImpl(InstrumentingAgents*, Node*); - static void frameWindowDiscardedImpl(InstrumentingAgents*, DOMWindow*); - static void mediaQueryResultChangedImpl(InstrumentingAgents*); - static void didPushShadowRootImpl(InstrumentingAgents*, Element* host, ShadowRoot*); - static void willPopShadowRootImpl(InstrumentingAgents*, Element* host, ShadowRoot*); - static void didCreateNamedFlowImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*); - static void willRemoveNamedFlowImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*); - static void didUpdateRegionLayoutImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*); - static void didChangeRegionOversetImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*); - static void didRegisterNamedFlowContentElementImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*, Node* contentElement, Node* nextContentElement = nullptr); - static void didUnregisterNamedFlowContentElementImpl(InstrumentingAgents*, Document*, WebKitNamedFlow*, Node* contentElement); - - static void mouseDidMoveOverElementImpl(InstrumentingAgents*, const HitTestResult&, unsigned modifierFlags); - static bool handleTouchEventImpl(InstrumentingAgents*, Node*); - static bool handleMousePressImpl(InstrumentingAgents*); - static bool forcePseudoStateImpl(InstrumentingAgents*, Element*, CSSSelector::PseudoType); - - static void willSendXMLHttpRequestImpl(InstrumentingAgents*, const String& url); - static void didScheduleResourceRequestImpl(InstrumentingAgents*, const String& url, Frame*); - static void didInstallTimerImpl(InstrumentingAgents*, int timerId, int timeout, bool singleShot, ScriptExecutionContext*); - static void didRemoveTimerImpl(InstrumentingAgents*, int timerId, ScriptExecutionContext*); - - static InspectorInstrumentationCookie willCallFunctionImpl(InstrumentingAgents*, const String& scriptName, int scriptLine, ScriptExecutionContext*); - static void didCallFunctionImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEventImpl(InstrumentingAgents*, XMLHttpRequest*, ScriptExecutionContext*); - static void didDispatchXHRReadyStateChangeEventImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents*, const Event&, bool hasEventListeners, Document*); - static InspectorInstrumentationCookie willHandleEventImpl(InstrumentingAgents*, Event*); - static void didHandleEventImpl(const InspectorInstrumentationCookie&); + static void didClearWindowObjectInWorldImpl(InstrumentingAgents&, Frame&, DOMWrapperWorld&); + static bool isDebuggerPausedImpl(InstrumentingAgents&); + + static void willInsertDOMNodeImpl(InstrumentingAgents&, Node& parent); + static void didInsertDOMNodeImpl(InstrumentingAgents&, Node&); + static void willRemoveDOMNodeImpl(InstrumentingAgents&, Node&); + static void didRemoveDOMNodeImpl(InstrumentingAgents&, Node&); + static void willModifyDOMAttrImpl(InstrumentingAgents&, Element&, const AtomicString& oldValue, const AtomicString& newValue); + static void didModifyDOMAttrImpl(InstrumentingAgents&, Element&, const AtomicString& name, const AtomicString& value); + static void didRemoveDOMAttrImpl(InstrumentingAgents&, Element&, const AtomicString& name); + static void characterDataModifiedImpl(InstrumentingAgents&, CharacterData&); + static void didInvalidateStyleAttrImpl(InstrumentingAgents&, Node&); + static void documentDetachedImpl(InstrumentingAgents&, Document&); + static void frameWindowDiscardedImpl(InstrumentingAgents&, DOMWindow*); + static void mediaQueryResultChangedImpl(InstrumentingAgents&); + static void activeStyleSheetsUpdatedImpl(InstrumentingAgents&, Document&); + static void didPushShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&); + static void willPopShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&); + static void didChangeCustomElementStateImpl(InstrumentingAgents&, Element&); + static void pseudoElementCreatedImpl(InstrumentingAgents&, PseudoElement&); + static void pseudoElementDestroyedImpl(InstrumentingAgents&, PseudoElement&); + static void didCreateNamedFlowImpl(InstrumentingAgents&, Document*, WebKitNamedFlow&); + static void willRemoveNamedFlowImpl(InstrumentingAgents&, Document*, WebKitNamedFlow&); + static void didChangeRegionOversetImpl(InstrumentingAgents&, Document&, WebKitNamedFlow&); + static void didRegisterNamedFlowContentElementImpl(InstrumentingAgents&, Document&, WebKitNamedFlow&, Node& contentElement, Node* nextContentElement = nullptr); + static void didUnregisterNamedFlowContentElementImpl(InstrumentingAgents&, Document&, WebKitNamedFlow&, Node& contentElement); + + static void mouseDidMoveOverElementImpl(InstrumentingAgents&, const HitTestResult&, unsigned modifierFlags); + static bool handleMousePressImpl(InstrumentingAgents&); + static bool handleTouchEventImpl(InstrumentingAgents&, Node&); + static bool forcePseudoStateImpl(InstrumentingAgents&, const Element&, CSSSelector::PseudoClassType); + + static void willSendXMLHttpRequestImpl(InstrumentingAgents&, const String& url); + static void didInstallTimerImpl(InstrumentingAgents&, int timerId, std::chrono::milliseconds timeout, bool singleShot, ScriptExecutionContext&); + static void didRemoveTimerImpl(InstrumentingAgents&, int timerId, ScriptExecutionContext&); + + static InspectorInstrumentationCookie willCallFunctionImpl(InstrumentingAgents&, const String& scriptName, int scriptLine, ScriptExecutionContext*); + static void didCallFunctionImpl(const InspectorInstrumentationCookie&, ScriptExecutionContext*); + static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents&, Document&, const Event&, bool hasEventListeners); + static void willHandleEventImpl(InstrumentingAgents&, const Event&); static void didDispatchEventImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InstrumentingAgents*, const Event&, DOMWindow*); + static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InstrumentingAgents&, const Event&, DOMWindow&); static void didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willEvaluateScriptImpl(InstrumentingAgents*, const String& url, int lineNumber, Frame*); - static void didEvaluateScriptImpl(const InspectorInstrumentationCookie&); - static void scriptsEnabledImpl(InstrumentingAgents*, bool isEnabled); - static void didCreateIsolatedContextImpl(InstrumentingAgents*, Frame*, JSC::ExecState*, SecurityOrigin*); - static InspectorInstrumentationCookie willFireTimerImpl(InstrumentingAgents*, int timerId, ScriptExecutionContext*); + static InspectorInstrumentationCookie willEvaluateScriptImpl(InstrumentingAgents&, Frame&, const String& url, int lineNumber); + static void didEvaluateScriptImpl(const InspectorInstrumentationCookie&, Frame&); + static InspectorInstrumentationCookie willFireTimerImpl(InstrumentingAgents&, int timerId, ScriptExecutionContext&); static void didFireTimerImpl(const InspectorInstrumentationCookie&); - static void didInvalidateLayoutImpl(InstrumentingAgents*, Frame*); - static InspectorInstrumentationCookie willLayoutImpl(InstrumentingAgents*, Frame*); - static void didLayoutImpl(const InspectorInstrumentationCookie&, RenderObject*); - static void didScrollImpl(InstrumentingAgents*); - static InspectorInstrumentationCookie willDispatchXHRLoadEventImpl(InstrumentingAgents*, XMLHttpRequest*, ScriptExecutionContext*); - static void didDispatchXHRLoadEventImpl(const InspectorInstrumentationCookie&); - static void willScrollLayerImpl(InstrumentingAgents*, Frame*); - static void didScrollLayerImpl(InstrumentingAgents*); - static void willPaintImpl(InstrumentingAgents*, RenderObject*); - static void didPaintImpl(InstrumentingAgents*, RenderObject*, GraphicsContext*, const LayoutRect&); - static InspectorInstrumentationCookie willRecalculateStyleImpl(InstrumentingAgents*, Frame*); + static void didInvalidateLayoutImpl(InstrumentingAgents&, Frame&); + static InspectorInstrumentationCookie willLayoutImpl(InstrumentingAgents&, Frame&); + static void didLayoutImpl(const InspectorInstrumentationCookie&, RenderObject&); + static void didScrollImpl(InstrumentingAgents&); + static void willCompositeImpl(InstrumentingAgents&, Frame&); + static void didCompositeImpl(InstrumentingAgents&); + static void willPaintImpl(InstrumentingAgents&, RenderObject&); + static void didPaintImpl(InstrumentingAgents&, RenderObject&, const LayoutRect&); + static InspectorInstrumentationCookie willRecalculateStyleImpl(InstrumentingAgents&, Document&); static void didRecalculateStyleImpl(const InspectorInstrumentationCookie&); - static void didScheduleStyleRecalculationImpl(InstrumentingAgents*, Document*); - - static void applyEmulatedMediaImpl(InstrumentingAgents*, String*); - static void willSendRequestImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse); - static void continueAfterPingLoaderImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&); - static void markResourceAsCachedImpl(InstrumentingAgents*, unsigned long identifier); - static void didLoadResourceFromMemoryCacheImpl(InstrumentingAgents*, DocumentLoader*, CachedResource*); - static InspectorInstrumentationCookie willReceiveResourceDataImpl(InstrumentingAgents*, unsigned long identifier, Frame*, int length); - static void didReceiveResourceDataImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willReceiveResourceResponseImpl(InstrumentingAgents*, unsigned long identifier, const ResourceResponse&, Frame*); - static void didReceiveResourceResponseImpl(const InspectorInstrumentationCookie&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*); - static void didReceiveResourceResponseButCanceledImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void continueAfterXFrameOptionsDeniedImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void continueWithPolicyDownloadImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void continueWithPolicyIgnoreImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&); - static void didReceiveDataImpl(InstrumentingAgents*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength); - static void didFinishLoadingImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, double finishTime); - static void didFailLoadingImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, const ResourceError&); - static void documentThreadableLoaderStartedLoadingForClientImpl(InstrumentingAgents*, unsigned long identifier, ThreadableLoaderClient*); - static void willLoadXHRImpl(InstrumentingAgents*, ThreadableLoaderClient*, const String&, const URL&, bool, PassRefPtr<FormData>, const HTTPHeaderMap&, bool); - static void didFailXHRLoadingImpl(InstrumentingAgents*, ThreadableLoaderClient*); - static void didFinishXHRLoadingImpl(InstrumentingAgents*, ThreadableLoaderClient*, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); - static void didReceiveXHRResponseImpl(InstrumentingAgents*, unsigned long identifier); - static void willLoadXHRSynchronouslyImpl(InstrumentingAgents*); - static void didLoadXHRSynchronouslyImpl(InstrumentingAgents*); - static void scriptImportedImpl(InstrumentingAgents*, unsigned long identifier, const String& sourceString); - static void scriptExecutionBlockedByCSPImpl(InstrumentingAgents*, const String& directiveText); - static void didReceiveScriptResponseImpl(InstrumentingAgents*, unsigned long identifier); - static void domContentLoadedEventFiredImpl(InstrumentingAgents*, Frame*); - static void loadEventFiredImpl(InstrumentingAgents*, Frame*); - static void frameDetachedFromParentImpl(InstrumentingAgents*, Frame*); - static void didCommitLoadImpl(InstrumentingAgents*, Page*, DocumentLoader*); - static void frameDocumentUpdatedImpl(InstrumentingAgents*, Frame*); - static void loaderDetachedFromFrameImpl(InstrumentingAgents*, DocumentLoader*); + static void didScheduleStyleRecalculationImpl(InstrumentingAgents&, Document&); + + static void applyEmulatedMediaImpl(InstrumentingAgents&, String&); + static void willSendRequestImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse); + static void continueAfterPingLoaderImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&); + static void markResourceAsCachedImpl(InstrumentingAgents&, unsigned long identifier); + static void didLoadResourceFromMemoryCacheImpl(InstrumentingAgents&, DocumentLoader*, CachedResource*); + static void didReceiveResourceResponseImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*); + static void didReceiveThreadableLoaderResponseImpl(InstrumentingAgents&, DocumentThreadableLoader&, unsigned long identifier); + static void didReceiveDataImpl(InstrumentingAgents&, unsigned long identifier, const char* data, int dataLength, int encodedDataLength); + static void didFinishLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, double finishTime); + static void didFailLoadingImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceError&); + static void didFinishXHRLoadingImpl(InstrumentingAgents&, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); + static void willLoadXHRSynchronouslyImpl(InstrumentingAgents&); + static void didLoadXHRSynchronouslyImpl(InstrumentingAgents&); + static void scriptImportedImpl(InstrumentingAgents&, unsigned long identifier, const String& sourceString); + static void scriptExecutionBlockedByCSPImpl(InstrumentingAgents&, const String& directiveText); + static void didReceiveScriptResponseImpl(InstrumentingAgents&, unsigned long identifier); + static void domContentLoadedEventFiredImpl(InstrumentingAgents&, Frame&); + static void loadEventFiredImpl(InstrumentingAgents&, Frame*); + static void frameDetachedFromParentImpl(InstrumentingAgents&, Frame&); + static void didCommitLoadImpl(InstrumentingAgents&, Frame&, DocumentLoader*); + static void frameDocumentUpdatedImpl(InstrumentingAgents&, Frame&); + static void loaderDetachedFromFrameImpl(InstrumentingAgents&, DocumentLoader&); static void frameStartedLoadingImpl(InstrumentingAgents&, Frame&); static void frameStoppedLoadingImpl(InstrumentingAgents&, Frame&); static void frameScheduledNavigationImpl(InstrumentingAgents&, Frame&, double delay); static void frameClearedScheduledNavigationImpl(InstrumentingAgents&, Frame&); - static InspectorInstrumentationCookie willRunJavaScriptDialogImpl(InstrumentingAgents*, const String& message); - static void didRunJavaScriptDialogImpl(const InspectorInstrumentationCookie&); - static void willDestroyCachedResourceImpl(CachedResource*); + static void willDestroyCachedResourceImpl(CachedResource&); + + static void addMessageToConsoleImpl(InstrumentingAgents&, std::unique_ptr<Inspector::ConsoleMessage>); - static InspectorInstrumentationCookie willWriteHTMLImpl(InstrumentingAgents*, unsigned startLine, Frame*); - static void didWriteHTMLImpl(const InspectorInstrumentationCookie&, unsigned endLine); + static void consoleCountImpl(InstrumentingAgents&, JSC::ExecState*, Ref<Inspector::ScriptArguments>&&); + static void takeHeapSnapshotImpl(InstrumentingAgents&, const String& title); + static void startConsoleTimingImpl(InstrumentingAgents&, Frame&, const String& title); + static void startConsoleTimingImpl(InstrumentingAgents&, const String& title); + static void stopConsoleTimingImpl(InstrumentingAgents&, Frame&, const String& title, Ref<Inspector::ScriptCallStack>&&); + static void stopConsoleTimingImpl(InstrumentingAgents&, const String& title, Ref<Inspector::ScriptCallStack>&&); + static void consoleTimeStampImpl(InstrumentingAgents&, Frame&, Ref<Inspector::ScriptArguments>&&); - static void addMessageToConsoleImpl(InstrumentingAgents*, MessageSource, MessageType, MessageLevel, const String& message, JSC::ExecState*, PassRefPtr<ScriptArguments>, unsigned long requestIdentifier); - static void addMessageToConsoleImpl(InstrumentingAgents*, MessageSource, MessageType, MessageLevel, const String& message, const String& scriptID, unsigned lineNumber, unsigned columnNumber, JSC::ExecState*, unsigned long requestIdentifier); + static void didRequestAnimationFrameImpl(InstrumentingAgents&, int callbackId, Frame*); + static void didCancelAnimationFrameImpl(InstrumentingAgents&, int callbackId, Frame*); + static InspectorInstrumentationCookie willFireAnimationFrameImpl(InstrumentingAgents&, int callbackId, Frame*); + static void didFireAnimationFrameImpl(const InspectorInstrumentationCookie&); - // FIXME: Remove once we no longer generate stacks outside of Inspector. - static void addMessageToConsoleImpl(InstrumentingAgents*, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier); + static void startProfilingImpl(InstrumentingAgents&, JSC::ExecState*, const String& title); + static void stopProfilingImpl(InstrumentingAgents&, JSC::ExecState*, const String& title); - static void consoleCountImpl(InstrumentingAgents*, JSC::ExecState*, PassRefPtr<ScriptArguments>); - static void startConsoleTimingImpl(InstrumentingAgents*, Frame*, const String& title); - static void stopConsoleTimingImpl(InstrumentingAgents*, Frame*, const String& title, PassRefPtr<ScriptCallStack>); - static void consoleTimeStampImpl(InstrumentingAgents*, Frame*, PassRefPtr<ScriptArguments>); + static void didOpenDatabaseImpl(InstrumentingAgents&, RefPtr<Database>&&, const String& domain, const String& name, const String& version); - static void didRequestAnimationFrameImpl(InstrumentingAgents*, int callbackId, Frame*); - static void didCancelAnimationFrameImpl(InstrumentingAgents*, int callbackId, Frame*); - static InspectorInstrumentationCookie willFireAnimationFrameImpl(InstrumentingAgents*, int callbackId, Frame*); - static void didFireAnimationFrameImpl(const InspectorInstrumentationCookie&); + static void didDispatchDOMStorageEventImpl(InstrumentingAgents&, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*); - static void addStartProfilingMessageToConsoleImpl(InstrumentingAgents*, const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - static void addProfileImpl(InstrumentingAgents*, RefPtr<ScriptProfile>, PassRefPtr<ScriptCallStack>); - static String getCurrentUserInitiatedProfileNameImpl(InstrumentingAgents*, bool incrementProfileNumber); - static bool profilerEnabledImpl(InstrumentingAgents*); + static bool shouldWaitForDebuggerOnStartImpl(InstrumentingAgents&); + static void workerStartedImpl(InstrumentingAgents&, WorkerInspectorProxy*, const URL&); + static void workerTerminatedImpl(InstrumentingAgents&, WorkerInspectorProxy*); -#if ENABLE(SQL_DATABASE) - static void didOpenDatabaseImpl(InstrumentingAgents*, PassRefPtr<Database>, const String& domain, const String& name, const String& version); -#endif +#if ENABLE(WEB_REPLAY) + static void sessionCreatedImpl(InstrumentingAgents&, RefPtr<ReplaySession>&&); + static void sessionLoadedImpl(InstrumentingAgents&, RefPtr<ReplaySession>&&); + static void sessionModifiedImpl(InstrumentingAgents&, RefPtr<ReplaySession>&&); - static void didDispatchDOMStorageEventImpl(InstrumentingAgents*, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*, Page*); + static void segmentCreatedImpl(InstrumentingAgents&, RefPtr<ReplaySessionSegment>&&); + static void segmentCompletedImpl(InstrumentingAgents&, RefPtr<ReplaySessionSegment>&&); + static void segmentLoadedImpl(InstrumentingAgents&, RefPtr<ReplaySessionSegment>&&); + static void segmentUnloadedImpl(InstrumentingAgents&); - static bool shouldPauseDedicatedWorkerOnStartImpl(InstrumentingAgents*); - static void didStartWorkerGlobalScopeImpl(InstrumentingAgents*, WorkerGlobalScopeProxy*, const URL&); - static void workerGlobalScopeTerminatedImpl(InstrumentingAgents*, WorkerGlobalScopeProxy*); + static void captureStartedImpl(InstrumentingAgents&); + static void captureStoppedImpl(InstrumentingAgents&); + + static void playbackStartedImpl(InstrumentingAgents&); + static void playbackPausedImpl(InstrumentingAgents&, const ReplayPosition&); + static void playbackHitPositionImpl(InstrumentingAgents&, const ReplayPosition&); + static void playbackFinishedImpl(InstrumentingAgents&); +#endif #if ENABLE(WEB_SOCKETS) - static void didCreateWebSocketImpl(InstrumentingAgents*, unsigned long identifier, const URL& requestURL, const URL& documentURL, const String& protocol, Document*); - static void willSendWebSocketHandshakeRequestImpl(InstrumentingAgents*, unsigned long identifier, const ResourceRequest&, Document*); - static void didReceiveWebSocketHandshakeResponseImpl(InstrumentingAgents*, unsigned long identifier, const ResourceResponse&, Document*); - static void didCloseWebSocketImpl(InstrumentingAgents*, unsigned long identifier, Document*); - static void didReceiveWebSocketFrameImpl(InstrumentingAgents*, unsigned long identifier, const WebSocketFrame&); - static void didSendWebSocketFrameImpl(InstrumentingAgents*, unsigned long identifier, const WebSocketFrame&); - static void didReceiveWebSocketFrameErrorImpl(InstrumentingAgents*, unsigned long identifier, const String&); + static void didCreateWebSocketImpl(InstrumentingAgents&, unsigned long identifier, const URL& requestURL); + static void willSendWebSocketHandshakeRequestImpl(InstrumentingAgents&, unsigned long identifier, const ResourceRequest&); + static void didReceiveWebSocketHandshakeResponseImpl(InstrumentingAgents&, unsigned long identifier, const ResourceResponse&); + static void didCloseWebSocketImpl(InstrumentingAgents&, unsigned long identifier); + static void didReceiveWebSocketFrameImpl(InstrumentingAgents&, unsigned long identifier, const WebSocketFrame&); + static void didSendWebSocketFrameImpl(InstrumentingAgents&, unsigned long identifier, const WebSocketFrame&); + static void didReceiveWebSocketFrameErrorImpl(InstrumentingAgents&, unsigned long identifier, const String&); #endif - static void networkStateChangedImpl(InstrumentingAgents*); - static void updateApplicationCacheStatusImpl(InstrumentingAgents*, Frame*); +#if ENABLE(RESOURCE_USAGE) + static void didHandleMemoryPressureImpl(InstrumentingAgents&, Critical); +#endif - static InstrumentingAgents* instrumentingAgentsForPage(Page*); + static void networkStateChangedImpl(InstrumentingAgents&); + static void updateApplicationCacheStatusImpl(InstrumentingAgents&, Frame&); + + static void layerTreeDidChangeImpl(InstrumentingAgents&); + static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&); + + static InstrumentingAgents& instrumentingAgentsForPage(Page&); + static InstrumentingAgents& instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope&); + + static InstrumentingAgents* instrumentingAgentsForFrame(Frame&); static InstrumentingAgents* instrumentingAgentsForFrame(Frame*); static InstrumentingAgents* instrumentingAgentsForContext(ScriptExecutionContext*); + static InstrumentingAgents* instrumentingAgentsForContext(ScriptExecutionContext&); + static InstrumentingAgents* instrumentingAgentsForDocument(Document&); static InstrumentingAgents* instrumentingAgentsForDocument(Document*); - static InstrumentingAgents* instrumentingAgentsForRenderer(RenderObject*); - + static InstrumentingAgents* instrumentingAgentsForRenderer(RenderObject&); static InstrumentingAgents* instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope*); - static InstrumentingAgents* instrumentingAgentsForNonDocumentContext(ScriptExecutionContext*); - static void pauseOnNativeEventIfNeeded(InstrumentingAgents*, bool isDOMEvent, const String& eventName, bool synchronous); - static void cancelPauseOnNativeEvent(InstrumentingAgents*); static InspectorTimelineAgent* retrieveTimelineAgent(const InspectorInstrumentationCookie&); -#if USE(ACCELERATED_COMPOSITING) - static void layerTreeDidChangeImpl(InstrumentingAgents*); - static void renderLayerDestroyedImpl(InstrumentingAgents*, const RenderLayer*); - static void pseudoElementDestroyedImpl(InstrumentingAgents*, PseudoElement*); -#endif + static void pauseOnNativeEventIfNeeded(InstrumentingAgents&, bool isDOMEvent, const String& eventName, bool synchronous); - static int s_frontendCounter; -#endif + WEBCORE_EXPORT static int s_frontendCounter; }; -inline void InspectorInstrumentation::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld& world) +inline void InspectorInstrumentation::didClearWindowObjectInWorld(Frame& frame, DOMWrapperWorld& world) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didClearWindowObjectInWorldImpl(instrumentingAgents, frame, world); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(world); -#endif + didClearWindowObjectInWorldImpl(*instrumentingAgents, frame, world); } inline bool InspectorInstrumentation::isDebuggerPaused(Frame* frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(false); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return isDebuggerPausedImpl(instrumentingAgents); -#else - UNUSED_PARAM(frame); -#endif + return isDebuggerPausedImpl(*instrumentingAgents); return false; } -inline void InspectorInstrumentation::willInsertDOMNode(Document* document, Node* parent) +inline void InspectorInstrumentation::willInsertDOMNode(Document& document, Node& parent) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - willInsertDOMNodeImpl(instrumentingAgents, parent); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(parent); -#endif + willInsertDOMNodeImpl(*instrumentingAgents, parent); } -inline void InspectorInstrumentation::didInsertDOMNode(Document* document, Node* node) +inline void InspectorInstrumentation::didInsertDOMNode(Document& document, Node& node) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didInsertDOMNodeImpl(instrumentingAgents, node); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(node); -#endif + didInsertDOMNodeImpl(*instrumentingAgents, node); } -inline void InspectorInstrumentation::willRemoveDOMNode(Document* document, Node* node) +inline void InspectorInstrumentation::willRemoveDOMNode(Document& document, Node& node) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - willRemoveDOMNodeImpl(instrumentingAgents, node); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(node); -#endif + willRemoveDOMNodeImpl(*instrumentingAgents, node); } -inline void InspectorInstrumentation::didRemoveDOMNode(Document* document, Node* node) +inline void InspectorInstrumentation::didRemoveDOMNode(Document& document, Node& node) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didRemoveDOMNodeImpl(instrumentingAgents, node); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(node); -#endif + didRemoveDOMNodeImpl(*instrumentingAgents, node); } -inline void InspectorInstrumentation::willModifyDOMAttr(Document* document, Element* element, const AtomicString& oldValue, const AtomicString& newValue) +inline void InspectorInstrumentation::willModifyDOMAttr(Document& document, Element& element, const AtomicString& oldValue, const AtomicString& newValue) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - willModifyDOMAttrImpl(instrumentingAgents, element, oldValue, newValue); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(element); - UNUSED_PARAM(oldValue); - UNUSED_PARAM(newValue); -#endif + willModifyDOMAttrImpl(*instrumentingAgents, element, oldValue, newValue); } -inline void InspectorInstrumentation::didModifyDOMAttr(Document* document, Element* element, const AtomicString& name, const AtomicString& value) +inline void InspectorInstrumentation::didModifyDOMAttr(Document& document, Element& element, const AtomicString& name, const AtomicString& value) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didModifyDOMAttrImpl(instrumentingAgents, element, name, value); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(element); - UNUSED_PARAM(name); - UNUSED_PARAM(value); -#endif + didModifyDOMAttrImpl(*instrumentingAgents, element, name, value); } -inline void InspectorInstrumentation::didRemoveDOMAttr(Document* document, Element* element, const AtomicString& name) +inline void InspectorInstrumentation::didRemoveDOMAttr(Document& document, Element& element, const AtomicString& name) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didRemoveDOMAttrImpl(instrumentingAgents, element, name); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(element); - UNUSED_PARAM(name); -#endif + didRemoveDOMAttrImpl(*instrumentingAgents, element, name); } -inline void InspectorInstrumentation::didInvalidateStyleAttr(Document* document, Node* node) +inline void InspectorInstrumentation::didInvalidateStyleAttr(Document& document, Node& node) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didInvalidateStyleAttrImpl(instrumentingAgents, node); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(node); -#endif + didInvalidateStyleAttrImpl(*instrumentingAgents, node); +} + +inline void InspectorInstrumentation::documentDetached(Document& document) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) + documentDetachedImpl(*instrumentingAgents, document); } -inline void InspectorInstrumentation::frameWindowDiscarded(Frame* frame, DOMWindow* domWindow) +inline void InspectorInstrumentation::frameWindowDiscarded(Frame& frame, DOMWindow* domWindow) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - frameWindowDiscardedImpl(instrumentingAgents, domWindow); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(domWindow); -#endif + frameWindowDiscardedImpl(*instrumentingAgents, domWindow); } -inline void InspectorInstrumentation::mediaQueryResultChanged(Document* document) +inline void InspectorInstrumentation::mediaQueryResultChanged(Document& document) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - mediaQueryResultChangedImpl(instrumentingAgents); -#else - UNUSED_PARAM(document); -#endif + mediaQueryResultChangedImpl(*instrumentingAgents); } -inline void InspectorInstrumentation::didPushShadowRoot(Element* host, ShadowRoot* root) +inline void InspectorInstrumentation::activeStyleSheetsUpdated(Document& document) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&host->document())) - didPushShadowRootImpl(instrumentingAgents, host, root); -#else - UNUSED_PARAM(host); - UNUSED_PARAM(root); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) + activeStyleSheetsUpdatedImpl(*instrumentingAgents, document); } -inline void InspectorInstrumentation::willPopShadowRoot(Element* host, ShadowRoot* root) +inline void InspectorInstrumentation::didPushShadowRoot(Element& host, ShadowRoot& root) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&host->document())) - willPopShadowRootImpl(instrumentingAgents, host, root); -#else - UNUSED_PARAM(host); - UNUSED_PARAM(root); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(host.document())) + didPushShadowRootImpl(*instrumentingAgents, host, root); } -inline void InspectorInstrumentation::didCreateNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +inline void InspectorInstrumentation::willPopShadowRoot(Element& host, ShadowRoot& root) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didCreateNamedFlowImpl(instrumentingAgents, document, namedFlow); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(host.document())) + willPopShadowRootImpl(*instrumentingAgents, host, root); +} + +inline void InspectorInstrumentation::didChangeCustomElementState(Element& element) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(element.document())) + didChangeCustomElementStateImpl(*instrumentingAgents, element); +} + +inline void InspectorInstrumentation::pseudoElementCreated(Page* page, PseudoElement& pseudoElement) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) + pseudoElementCreatedImpl(*instrumentingAgents, pseudoElement); +} + +inline void InspectorInstrumentation::pseudoElementDestroyed(Page* page, PseudoElement& pseudoElement) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) + pseudoElementDestroyedImpl(*instrumentingAgents, pseudoElement); } -inline void InspectorInstrumentation::willRemoveNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +inline void InspectorInstrumentation::didCreateNamedFlow(Document* document, WebKitNamedFlow& namedFlow) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - willRemoveNamedFlowImpl(instrumentingAgents, document, namedFlow); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); -#endif + didCreateNamedFlowImpl(*instrumentingAgents, document, namedFlow); } -inline void InspectorInstrumentation::didUpdateRegionLayout(Document* document, WebKitNamedFlow* namedFlow) +inline void InspectorInstrumentation::willRemoveNamedFlow(Document* document, WebKitNamedFlow& namedFlow) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didUpdateRegionLayoutImpl(instrumentingAgents, document, namedFlow); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); -#endif + willRemoveNamedFlowImpl(*instrumentingAgents, document, namedFlow); } -inline void InspectorInstrumentation::didChangeRegionOverset(Document* document, WebKitNamedFlow* namedFlow) +inline void InspectorInstrumentation::didChangeRegionOverset(Document& document, WebKitNamedFlow& namedFlow) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didChangeRegionOversetImpl(instrumentingAgents, document, namedFlow); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); -#endif + didChangeRegionOversetImpl(*instrumentingAgents, document, namedFlow); } -inline void InspectorInstrumentation::didRegisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement, Node* nextContentElement) +inline void InspectorInstrumentation::didRegisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement, Node* nextContentElement) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didRegisterNamedFlowContentElementImpl(instrumentingAgents, document, namedFlow, contentElement, nextContentElement); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); - UNUSED_PARAM(contentElement); - UNUSED_PARAM(nextContentElement); -#endif + didRegisterNamedFlowContentElementImpl(*instrumentingAgents, document, namedFlow, contentElement, nextContentElement); } -inline void InspectorInstrumentation::didUnregisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement) +inline void InspectorInstrumentation::didUnregisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didUnregisterNamedFlowContentElementImpl(instrumentingAgents, document, namedFlow, contentElement); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(namedFlow); - UNUSED_PARAM(contentElement); -#endif + didUnregisterNamedFlowContentElementImpl(*instrumentingAgents, document, namedFlow, contentElement); } -inline void InspectorInstrumentation::mouseDidMoveOverElement(Page* page, const HitTestResult& result, unsigned modifierFlags) +inline void InspectorInstrumentation::mouseDidMoveOverElement(Page& page, const HitTestResult& result, unsigned modifierFlags) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - mouseDidMoveOverElementImpl(instrumentingAgents, result, modifierFlags); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(result); - UNUSED_PARAM(modifierFlags); -#endif + mouseDidMoveOverElementImpl(instrumentingAgentsForPage(page), result, modifierFlags); } -inline bool InspectorInstrumentation::handleTouchEvent(Page* page, Node* node) +inline bool InspectorInstrumentation::handleTouchEvent(Frame& frame, Node& node) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(false); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return handleTouchEventImpl(instrumentingAgents, node); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(node); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + return handleTouchEventImpl(*instrumentingAgents, node); return false; } -inline bool InspectorInstrumentation::handleMousePress(Page* page) +inline bool InspectorInstrumentation::handleMousePress(Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(false); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return handleMousePressImpl(instrumentingAgents); -#else - UNUSED_PARAM(page); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + return handleMousePressImpl(*instrumentingAgents); return false; } -inline bool InspectorInstrumentation::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoState) +inline bool InspectorInstrumentation::forcePseudoState(const Element& element, CSSSelector::PseudoClassType pseudoState) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(false); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&element->document())) - return forcePseudoStateImpl(instrumentingAgents, element, pseudoState); -#else - UNUSED_PARAM(element); - UNUSED_PARAM(pseudoState); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(element.document())) + return forcePseudoStateImpl(*instrumentingAgents, element, pseudoState); return false; } -inline void InspectorInstrumentation::characterDataModified(Document* document, CharacterData* characterData) +inline void InspectorInstrumentation::characterDataModified(Document& document, CharacterData& characterData) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - characterDataModifiedImpl(instrumentingAgents, characterData); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(characterData); -#endif + characterDataModifiedImpl(*instrumentingAgents, characterData); } inline void InspectorInstrumentation::willSendXMLHttpRequest(ScriptExecutionContext* context, const String& url) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - willSendXMLHttpRequestImpl(instrumentingAgents, url); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(url); -#endif + willSendXMLHttpRequestImpl(*instrumentingAgents, url); } -inline void InspectorInstrumentation::didScheduleResourceRequest(Document* document, const String& url) +inline void InspectorInstrumentation::didInstallTimer(ScriptExecutionContext& context, int timerId, std::chrono::milliseconds timeout, bool singleShot) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didScheduleResourceRequestImpl(instrumentingAgents, url, document->frame()); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(url); -#endif -} - -inline void InspectorInstrumentation::didInstallTimer(ScriptExecutionContext* context, int timerId, int timeout, bool singleShot) -{ -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didInstallTimerImpl(instrumentingAgents, timerId, timeout, singleShot, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(timerId); - UNUSED_PARAM(timeout); - UNUSED_PARAM(singleShot); -#endif + didInstallTimerImpl(*instrumentingAgents, timerId, timeout, singleShot, context); } -inline void InspectorInstrumentation::didRemoveTimer(ScriptExecutionContext* context, int timerId) +inline void InspectorInstrumentation::didRemoveTimer(ScriptExecutionContext& context, int timerId) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didRemoveTimerImpl(instrumentingAgents, timerId, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(timerId); -#endif + didRemoveTimerImpl(*instrumentingAgents, timerId, context); } inline InspectorInstrumentationCookie InspectorInstrumentation::willCallFunction(ScriptExecutionContext* context, const String& scriptName, int scriptLine) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return willCallFunctionImpl(instrumentingAgents, scriptName, scriptLine, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(scriptName); - UNUSED_PARAM(scriptLine); -#endif + return willCallFunctionImpl(*instrumentingAgents, scriptName, scriptLine, context); return InspectorInstrumentationCookie(); } - -inline void InspectorInstrumentation::didCallFunction(const InspectorInstrumentationCookie& cookie) +inline void InspectorInstrumentation::didCallFunction(const InspectorInstrumentationCookie& cookie, ScriptExecutionContext* context) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) - didCallFunctionImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif + didCallFunctionImpl(cookie, context); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext* context, XMLHttpRequest* request) +inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document& document, const Event& event, bool hasEventListeners) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return willDispatchXHRReadyStateChangeEventImpl(instrumentingAgents, request, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(request); -#endif - return InspectorInstrumentationCookie(); -} - -inline void InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(const InspectorInstrumentationCookie& cookie) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didDispatchXHRReadyStateChangeEventImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif -} - -inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, bool hasEventListeners) -{ -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - return willDispatchEventImpl(instrumentingAgents, event, hasEventListeners, document); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(event); - UNUSED_PARAM(hasEventListeners); -#endif + return willDispatchEventImpl(*instrumentingAgents, document, event, hasEventListeners); return InspectorInstrumentationCookie(); } inline void InspectorInstrumentation::didDispatchEvent(const InspectorInstrumentationCookie& cookie) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didDispatchEventImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif -} - -inline InspectorInstrumentationCookie InspectorInstrumentation::willHandleEvent(ScriptExecutionContext* context, Event* event) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return willHandleEventImpl(instrumentingAgents, event); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(event); -#endif - return InspectorInstrumentationCookie(); } -inline void InspectorInstrumentation::didHandleEvent(const InspectorInstrumentationCookie& cookie) +inline void InspectorInstrumentation::willHandleEvent(ScriptExecutionContext* context, const Event& event) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didHandleEventImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) + return willHandleEventImpl(*instrumentingAgents, event); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindow(Frame* frame, const Event& event, DOMWindow* window) +inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindow(Frame* frame, const Event& event, DOMWindow& window) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return willDispatchEventOnWindowImpl(instrumentingAgents, event, window); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(event); - UNUSED_PARAM(window); -#endif + return willDispatchEventOnWindowImpl(*instrumentingAgents, event, window); return InspectorInstrumentationCookie(); } inline void InspectorInstrumentation::didDispatchEventOnWindow(const InspectorInstrumentationCookie& cookie) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didDispatchEventOnWindowImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif } -inline InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScript(Frame* frame, const String& url, int lineNumber) +inline InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScript(Frame& frame, const String& url, int lineNumber) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return willEvaluateScriptImpl(instrumentingAgents, url, lineNumber, frame); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(url); - UNUSED_PARAM(lineNumber); -#endif + return willEvaluateScriptImpl(*instrumentingAgents, frame, url, lineNumber); return InspectorInstrumentationCookie(); } -inline void InspectorInstrumentation::didEvaluateScript(const InspectorInstrumentationCookie& cookie) +inline void InspectorInstrumentation::didEvaluateScript(const InspectorInstrumentationCookie& cookie, Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) - didEvaluateScriptImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif -} - -inline void InspectorInstrumentation::scriptsEnabled(Page* page, bool isEnabled) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return scriptsEnabledImpl(instrumentingAgents, isEnabled); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(isEnabled); -#endif + didEvaluateScriptImpl(cookie, frame); } -inline void InspectorInstrumentation::didCreateIsolatedContext(Frame* frame, JSC::ExecState* scriptState, SecurityOrigin* origin) +inline InspectorInstrumentationCookie InspectorInstrumentation::willFireTimer(ScriptExecutionContext& context, int timerId) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return didCreateIsolatedContextImpl(instrumentingAgents, frame, scriptState, origin); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(scriptState); - UNUSED_PARAM(origin); -#endif -} - -inline InspectorInstrumentationCookie InspectorInstrumentation::willFireTimer(ScriptExecutionContext* context, int timerId) -{ -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return willFireTimerImpl(instrumentingAgents, timerId, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(timerId); -#endif + return willFireTimerImpl(*instrumentingAgents, timerId, context); return InspectorInstrumentationCookie(); } inline void InspectorInstrumentation::didFireTimer(const InspectorInstrumentationCookie& cookie) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didFireTimerImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif } -inline void InspectorInstrumentation::didInvalidateLayout(Frame* frame) +inline void InspectorInstrumentation::didInvalidateLayout(Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didInvalidateLayoutImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + didInvalidateLayoutImpl(*instrumentingAgents, frame); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willLayout(Frame* frame) +inline InspectorInstrumentationCookie InspectorInstrumentation::willLayout(Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return willLayoutImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + return willLayoutImpl(*instrumentingAgents, frame); return InspectorInstrumentationCookie(); } -inline void InspectorInstrumentation::didLayout(const InspectorInstrumentationCookie& cookie, RenderObject* root) +inline void InspectorInstrumentation::didLayout(const InspectorInstrumentationCookie& cookie, RenderObject& root) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didLayoutImpl(cookie, root); -#else - UNUSED_PARAM(cookie); - UNUSED_PARAM(root); -#endif } -inline void InspectorInstrumentation::didScroll(Page* page) +inline void InspectorInstrumentation::didScroll(Page& page) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - didScrollImpl(instrumentingAgents); -#else - UNUSED_PARAM(page); -#endif + didScrollImpl(instrumentingAgentsForPage(page)); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchXHRLoadEvent(ScriptExecutionContext* context, XMLHttpRequest* request) +inline void InspectorInstrumentation::willComposite(Frame& frame) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return willDispatchXHRLoadEventImpl(instrumentingAgents, request, context); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(request); -#endif - return InspectorInstrumentationCookie(); -} - -inline void InspectorInstrumentation::didDispatchXHRLoadEvent(const InspectorInstrumentationCookie& cookie) -{ -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didDispatchXHRLoadEventImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + willCompositeImpl(*instrumentingAgents, frame); } -inline void InspectorInstrumentation::willPaint(RenderObject* renderer) +inline void InspectorInstrumentation::didComposite(Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderer(renderer)) - return willPaintImpl(instrumentingAgents, renderer); -#else - UNUSED_PARAM(renderer); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + didCompositeImpl(*instrumentingAgents); } -inline void InspectorInstrumentation::didPaint(RenderObject* renderer, GraphicsContext* context, const LayoutRect& rect) +inline void InspectorInstrumentation::willPaint(RenderObject& renderer) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderer(renderer)) - didPaintImpl(instrumentingAgents, renderer, context, rect); -#else - UNUSED_PARAM(renderer); - UNUSED_PARAM(context); - UNUSED_PARAM(rect); -#endif + return willPaintImpl(*instrumentingAgents, renderer); } -inline void InspectorInstrumentation::willScrollLayer(Frame* frame) +inline void InspectorInstrumentation::didPaint(RenderObject& renderer, const LayoutRect& rect) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - willScrollLayerImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif -} - -inline void InspectorInstrumentation::didScrollLayer(Frame* frame) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didScrollLayerImpl(instrumentingAgents); -#else - UNUSED_PARAM(frame); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderer(renderer)) + didPaintImpl(*instrumentingAgents, renderer, rect); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyle(Document* document) +inline InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyle(Document& document) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - return willRecalculateStyleImpl(instrumentingAgents, document->frame()); -#else - UNUSED_PARAM(document); -#endif + return willRecalculateStyleImpl(*instrumentingAgents, document); return InspectorInstrumentationCookie(); } inline void InspectorInstrumentation::didRecalculateStyle(const InspectorInstrumentationCookie& cookie) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didRecalculateStyleImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif } -inline void InspectorInstrumentation::didScheduleStyleRecalculation(Document* document) +inline void InspectorInstrumentation::didScheduleStyleRecalculation(Document& document) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didScheduleStyleRecalculationImpl(instrumentingAgents, document); -#else - UNUSED_PARAM(document); -#endif + didScheduleStyleRecalculationImpl(*instrumentingAgents, document); } -inline void InspectorInstrumentation::applyEmulatedMedia(Frame* frame, String* media) +inline void InspectorInstrumentation::applyEmulatedMedia(Frame& frame, String& media) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - applyEmulatedMediaImpl(instrumentingAgents, media); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(media); -#endif + applyEmulatedMediaImpl(*instrumentingAgents, media); } inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - willSendRequestImpl(instrumentingAgents, identifier, loader, request, redirectResponse); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(identifier); - UNUSED_PARAM(loader); - UNUSED_PARAM(request); - UNUSED_PARAM(redirectResponse); -#endif + willSendRequestImpl(*instrumentingAgents, identifier, loader, request, redirectResponse); } -inline void InspectorInstrumentation::continueAfterPingLoader(Frame* frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response) +inline void InspectorInstrumentation::continueAfterPingLoader(Frame& frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - InspectorInstrumentation::continueAfterPingLoaderImpl(instrumentingAgents, identifier, loader, request, response); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(identifier); - UNUSED_PARAM(loader); - UNUSED_PARAM(request); - UNUSED_PARAM(response); -#endif + InspectorInstrumentation::continueAfterPingLoaderImpl(*instrumentingAgents, identifier, loader, request, response); } -inline void InspectorInstrumentation::markResourceAsCached(Page* page, unsigned long identifier) +inline void InspectorInstrumentation::markResourceAsCached(Page& page, unsigned long identifier) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - markResourceAsCachedImpl(instrumentingAgents, identifier); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(identifier); -#endif + markResourceAsCachedImpl(instrumentingAgentsForPage(page), identifier); } -inline void InspectorInstrumentation::didLoadResourceFromMemoryCache(Page* page, DocumentLoader* loader, CachedResource* resource) +inline void InspectorInstrumentation::didLoadResourceFromMemoryCache(Page& page, DocumentLoader* loader, CachedResource* resource) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - didLoadResourceFromMemoryCacheImpl(instrumentingAgents, loader, resource); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(loader); - UNUSED_PARAM(resource); -#endif + didLoadResourceFromMemoryCacheImpl(instrumentingAgentsForPage(page), loader, resource); } -inline InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceData(Frame* frame, unsigned long identifier, int length) +inline void InspectorInstrumentation::didReceiveResourceResponse(Frame& frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return willReceiveResourceDataImpl(instrumentingAgents, identifier, frame, length); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(identifier); - UNUSED_PARAM(length); -#endif - return InspectorInstrumentationCookie(); + didReceiveResourceResponseImpl(*instrumentingAgents, identifier, loader, response, resourceLoader); } -inline void InspectorInstrumentation::didReceiveResourceData(const InspectorInstrumentationCookie& cookie) +inline void InspectorInstrumentation::didReceiveThreadableLoaderResponse(DocumentThreadableLoader& documentThreadableLoader, unsigned long identifier) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didReceiveResourceDataImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(documentThreadableLoader.document())) + didReceiveThreadableLoaderResponseImpl(*instrumentingAgents, documentThreadableLoader, identifier); } - -inline InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponse(Frame* frame, unsigned long identifier, const ResourceResponse& response) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - return willReceiveResourceResponseImpl(instrumentingAgents, identifier, response, frame); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(identifier); - UNUSED_PARAM(response); -#endif - return InspectorInstrumentationCookie(); -} - -inline void InspectorInstrumentation::didReceiveResourceResponse(const InspectorInstrumentationCookie& cookie, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) -{ -#if ENABLE(INSPECTOR) - // Call this unconditionally so that we're able to log to console with no front-end attached. - if (cookie.isValid()) - didReceiveResourceResponseImpl(cookie, identifier, loader, response, resourceLoader); -#else - UNUSED_PARAM(cookie); - UNUSED_PARAM(identifier); - UNUSED_PARAM(loader); - UNUSED_PARAM(response); - UNUSED_PARAM(resourceLoader); -#endif -} - -inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - InspectorInstrumentation::continueAfterXFrameOptionsDeniedImpl(frame, loader, identifier, r); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); - UNUSED_PARAM(identifier); - UNUSED_PARAM(r); -#endif -} - -inline void InspectorInstrumentation::continueWithPolicyDownload(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - InspectorInstrumentation::continueWithPolicyDownloadImpl(frame, loader, identifier, r); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); - UNUSED_PARAM(identifier); - UNUSED_PARAM(r); -#endif -} - -inline void InspectorInstrumentation::continueWithPolicyIgnore(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - InspectorInstrumentation::continueWithPolicyIgnoreImpl(frame, loader, identifier, r); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); - UNUSED_PARAM(identifier); - UNUSED_PARAM(r); -#endif -} - + inline void InspectorInstrumentation::didReceiveData(Frame* frame, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didReceiveDataImpl(instrumentingAgents, identifier, data, dataLength, encodedDataLength); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(identifier); - UNUSED_PARAM(data); - UNUSED_PARAM(dataLength); - UNUSED_PARAM(encodedDataLength); -#endif + didReceiveDataImpl(*instrumentingAgents, identifier, data, dataLength, encodedDataLength); } inline void InspectorInstrumentation::didFinishLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier, double finishTime) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didFinishLoadingImpl(instrumentingAgents, identifier, loader, finishTime); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); - UNUSED_PARAM(identifier); - UNUSED_PARAM(finishTime); -#endif + didFinishLoadingImpl(*instrumentingAgents, identifier, loader, finishTime); } inline void InspectorInstrumentation::didFailLoading(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceError& error) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didFailLoadingImpl(instrumentingAgents, identifier, loader, error); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); - UNUSED_PARAM(identifier); - UNUSED_PARAM(error); -#endif + didFailLoadingImpl(*instrumentingAgents, identifier, loader, error); } -inline void InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(ScriptExecutionContext* context, unsigned long identifier, ThreadableLoaderClient* client) +inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(Frame& frame, unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - documentThreadableLoaderStartedLoadingForClientImpl(instrumentingAgents, identifier, client); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(identifier); - UNUSED_PARAM(client); -#endif -} - -inline void InspectorInstrumentation::willLoadXHR(ScriptExecutionContext* context, ThreadableLoaderClient* client, const String& method, const URL& url, bool async, PassRefPtr<FormData> formData, const HTTPHeaderMap& headers, bool includeCredentials) -{ -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - willLoadXHRImpl(instrumentingAgents, client, method, url, async, formData, headers, includeCredentials); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(client); - UNUSED_PARAM(method); - UNUSED_PARAM(url); - UNUSED_PARAM(async); - UNUSED_PARAM(formData); - UNUSED_PARAM(headers); - UNUSED_PARAM(includeCredentials); -#endif + // Treat the same as didReceiveResponse. + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + didReceiveResourceResponseImpl(*instrumentingAgents, identifier, &loader, response, nullptr); } -inline void InspectorInstrumentation::didFailXHRLoading(ScriptExecutionContext* context, ThreadableLoaderClient* client) +inline void InspectorInstrumentation::continueWithPolicyDownload(Frame& frame, unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didFailXHRLoadingImpl(instrumentingAgents, client); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(client); -#endif + // Treat the same as didReceiveResponse. + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + didReceiveResourceResponseImpl(*instrumentingAgents, identifier, &loader, response, nullptr); } - -inline void InspectorInstrumentation::didFinishXHRLoading(ScriptExecutionContext* context, ThreadableLoaderClient* client, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) +inline void InspectorInstrumentation::continueWithPolicyIgnore(Frame& frame, unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didFinishXHRLoadingImpl(instrumentingAgents, client, identifier, sourceString, url, sendURL, sendLineNumber, sendColumnNumber); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(client); - UNUSED_PARAM(identifier); - UNUSED_PARAM(sourceString); - UNUSED_PARAM(url); - UNUSED_PARAM(sendURL); - UNUSED_PARAM(sendLineNumber); -#endif + // Treat the same as didReceiveResponse. + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + didReceiveResourceResponseImpl(*instrumentingAgents, identifier, &loader, response, nullptr); } -inline void InspectorInstrumentation::didReceiveXHRResponse(ScriptExecutionContext* context, unsigned long identifier) +inline void InspectorInstrumentation::didFinishXHRLoading(ScriptExecutionContext* context, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didReceiveXHRResponseImpl(instrumentingAgents, identifier); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(identifier); -#endif + didFinishXHRLoadingImpl(*instrumentingAgents, identifier, decodedText, url, sendURL, sendLineNumber, sendColumnNumber); } inline void InspectorInstrumentation::willLoadXHRSynchronously(ScriptExecutionContext* context) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - willLoadXHRSynchronouslyImpl(instrumentingAgents); -#else - UNUSED_PARAM(context); -#endif + willLoadXHRSynchronouslyImpl(*instrumentingAgents); } inline void InspectorInstrumentation::didLoadXHRSynchronously(ScriptExecutionContext* context) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didLoadXHRSynchronouslyImpl(instrumentingAgents); -#else - UNUSED_PARAM(context); -#endif + didLoadXHRSynchronouslyImpl(*instrumentingAgents); } -inline void InspectorInstrumentation::scriptImported(ScriptExecutionContext* context, unsigned long identifier, const String& sourceString) +inline void InspectorInstrumentation::scriptImported(ScriptExecutionContext& context, unsigned long identifier, const String& sourceString) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - scriptImportedImpl(instrumentingAgents, identifier, sourceString); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(identifier); - UNUSED_PARAM(sourceString); -#endif + scriptImportedImpl(*instrumentingAgents, identifier, sourceString); } inline void InspectorInstrumentation::scriptExecutionBlockedByCSP(ScriptExecutionContext* context, const String& directiveText) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - scriptExecutionBlockedByCSPImpl(instrumentingAgents, directiveText); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(directiveText); -#endif + scriptExecutionBlockedByCSPImpl(*instrumentingAgents, directiveText); } inline void InspectorInstrumentation::didReceiveScriptResponse(ScriptExecutionContext* context, unsigned long identifier) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didReceiveScriptResponseImpl(instrumentingAgents, identifier); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(identifier); -#endif + didReceiveScriptResponseImpl(*instrumentingAgents, identifier); } -inline void InspectorInstrumentation::domContentLoadedEventFired(Frame* frame) +inline void InspectorInstrumentation::domContentLoadedEventFired(Frame& frame) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - domContentLoadedEventFiredImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + domContentLoadedEventFiredImpl(*instrumentingAgents, frame); } inline void InspectorInstrumentation::loadEventFired(Frame* frame) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - loadEventFiredImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + loadEventFiredImpl(*instrumentingAgents, frame); } -inline void InspectorInstrumentation::frameDetachedFromParent(Frame* frame) +inline void InspectorInstrumentation::frameDetachedFromParent(Frame& frame) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - frameDetachedFromParentImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + frameDetachedFromParentImpl(*instrumentingAgents, frame); } -inline void InspectorInstrumentation::didCommitLoad(Frame* frame, DocumentLoader* loader) +inline void InspectorInstrumentation::didCommitLoad(Frame& frame, DocumentLoader* loader) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - didCommitLoadImpl(instrumentingAgents, frame->page(), loader); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); -#endif + didCommitLoadImpl(*instrumentingAgents, frame, loader); } -inline void InspectorInstrumentation::frameDocumentUpdated(Frame* frame) +inline void InspectorInstrumentation::frameDocumentUpdated(Frame& frame) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - frameDocumentUpdatedImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + frameDocumentUpdatedImpl(*instrumentingAgents, frame); } -inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame* frame, DocumentLoader* loader) +inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame& frame, DocumentLoader& loader) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - loaderDetachedFromFrameImpl(instrumentingAgents, loader); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(loader); -#endif + loaderDetachedFromFrameImpl(*instrumentingAgents, loader); } inline void InspectorInstrumentation::frameStartedLoading(Frame& frame) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(&frame)) + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) frameStartedLoadingImpl(*instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif } inline void InspectorInstrumentation::frameStoppedLoading(Frame& frame) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(&frame)) + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) frameStoppedLoadingImpl(*instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif } inline void InspectorInstrumentation::frameScheduledNavigation(Frame& frame, double delay) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(&frame)) + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) frameScheduledNavigationImpl(*instrumentingAgents, frame, delay); -#else - UNUSED_PARAM(frame); - UNUSED_PARAM(delay); -#endif } inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame& frame) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(&frame)) + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) frameClearedScheduledNavigationImpl(*instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif -} - -inline InspectorInstrumentationCookie InspectorInstrumentation::willRunJavaScriptDialog(Page* page, const String& message) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - return willRunJavaScriptDialogImpl(instrumentingAgents, message); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(message); -#endif - return InspectorInstrumentationCookie(); } -inline void InspectorInstrumentation::didRunJavaScriptDialog(const InspectorInstrumentationCookie& cookie) +inline void InspectorInstrumentation::willDestroyCachedResource(CachedResource& cachedResource) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didRunJavaScriptDialogImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif -} - -inline void InspectorInstrumentation::willDestroyCachedResource(CachedResource* cachedResource) -{ -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); willDestroyCachedResourceImpl(cachedResource); -#else - UNUSED_PARAM(cachedResource); -#endif -} - -inline InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTML(Document* document, unsigned startLine) -{ -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - return willWriteHTMLImpl(instrumentingAgents, startLine, document->frame()); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(startLine); -#endif - return InspectorInstrumentationCookie(); } -inline void InspectorInstrumentation::didWriteHTML(const InspectorInstrumentationCookie& cookie, unsigned endLine) +inline void InspectorInstrumentation::didOpenDatabase(ScriptExecutionContext* context, RefPtr<Database>&& database, const String& domain, const String& name, const String& version) { -#if ENABLE(INSPECTOR) - FAST_RETURN_IF_NO_FRONTENDS(void()); - if (cookie.isValid()) - didWriteHTMLImpl(cookie, endLine); -#else - UNUSED_PARAM(cookie); - UNUSED_PARAM(endLine); -#endif + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) + didOpenDatabaseImpl(*instrumentingAgents, WTFMove(database), domain, name, version); } -inline void InspectorInstrumentation::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin, Page* page) +inline void InspectorInstrumentation::didDispatchDOMStorageEvent(Page& page, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - didDispatchDOMStorageEventImpl(instrumentingAgents, key, oldValue, newValue, storageType, securityOrigin, page); -#else - UNUSED_PARAM(key); - UNUSED_PARAM(oldValue); - UNUSED_PARAM(newValue); - UNUSED_PARAM(storageType); - UNUSED_PARAM(securityOrigin); - UNUSED_PARAM(page); -#endif // ENABLE(INSPECTOR) + didDispatchDOMStorageEventImpl(instrumentingAgentsForPage(page), key, oldValue, newValue, storageType, securityOrigin); } -inline bool InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(ScriptExecutionContext* context) +inline bool InspectorInstrumentation::shouldWaitForDebuggerOnStart(ScriptExecutionContext& context) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(false); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - return shouldPauseDedicatedWorkerOnStartImpl(instrumentingAgents); -#else - UNUSED_PARAM(context); -#endif + return shouldWaitForDebuggerOnStartImpl(*instrumentingAgents); return false; } -inline void InspectorInstrumentation::didStartWorkerGlobalScope(ScriptExecutionContext* context, WorkerGlobalScopeProxy* proxy, const URL& url) +inline void InspectorInstrumentation::workerStarted(ScriptExecutionContext& context, WorkerInspectorProxy* proxy, const URL& url) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - didStartWorkerGlobalScopeImpl(instrumentingAgents, proxy, url); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(proxy); - UNUSED_PARAM(url); -#endif + workerStartedImpl(*instrumentingAgents, proxy, url); } -inline void InspectorInstrumentation::workerGlobalScopeTerminated(ScriptExecutionContext* context, WorkerGlobalScopeProxy* proxy) +inline void InspectorInstrumentation::workerTerminated(ScriptExecutionContext& context, WorkerInspectorProxy* proxy) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) - workerGlobalScopeTerminatedImpl(instrumentingAgents, proxy); -#else - UNUSED_PARAM(context); - UNUSED_PARAM(proxy); -#endif + workerTerminatedImpl(*instrumentingAgents, proxy); } #if ENABLE(WEB_SOCKETS) -inline void InspectorInstrumentation::didCreateWebSocket(Document* document, unsigned long identifier, const URL& requestURL, const URL& documentURL, const String& protocol) +inline void InspectorInstrumentation::didCreateWebSocket(Document* document, unsigned long identifier, const URL& requestURL) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didCreateWebSocketImpl(instrumentingAgents, identifier, requestURL, documentURL, protocol, document); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(requestURL); - UNUSED_PARAM(documentURL); - UNUSED_PARAM(protocol); -#endif + didCreateWebSocketImpl(*instrumentingAgents, identifier, requestURL); } inline void InspectorInstrumentation::willSendWebSocketHandshakeRequest(Document* document, unsigned long identifier, const ResourceRequest& request) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - willSendWebSocketHandshakeRequestImpl(instrumentingAgents, identifier, request, document); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(request); -#endif + willSendWebSocketHandshakeRequestImpl(*instrumentingAgents, identifier, request); } inline void InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(Document* document, unsigned long identifier, const ResourceResponse& response) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didReceiveWebSocketHandshakeResponseImpl(instrumentingAgents, identifier, response, document); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(response); -#endif + didReceiveWebSocketHandshakeResponseImpl(*instrumentingAgents, identifier, response); } inline void InspectorInstrumentation::didCloseWebSocket(Document* document, unsigned long identifier) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didCloseWebSocketImpl(instrumentingAgents, identifier, document); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); -#endif + didCloseWebSocketImpl(*instrumentingAgents, identifier); } + inline void InspectorInstrumentation::didReceiveWebSocketFrame(Document* document, unsigned long identifier, const WebSocketFrame& frame) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didReceiveWebSocketFrameImpl(instrumentingAgents, identifier, frame); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(frame); -#endif + didReceiveWebSocketFrameImpl(*instrumentingAgents, identifier, frame); } + inline void InspectorInstrumentation::didReceiveWebSocketFrameError(Document* document, unsigned long identifier, const String& errorMessage) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didReceiveWebSocketFrameErrorImpl(instrumentingAgents, identifier, errorMessage); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(errorMessage); -#endif + didReceiveWebSocketFrameErrorImpl(*instrumentingAgents, identifier, errorMessage); } + inline void InspectorInstrumentation::didSendWebSocketFrame(Document* document, unsigned long identifier, const WebSocketFrame& frame) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didSendWebSocketFrameImpl(instrumentingAgents, identifier, frame); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(identifier); - UNUSED_PARAM(frame); -#endif + didSendWebSocketFrameImpl(*instrumentingAgents, identifier, frame); } -#endif +#endif // ENABLE(WEB_SOCKETS) -inline void InspectorInstrumentation::networkStateChanged(Page* page) +#if ENABLE(WEB_REPLAY) +inline void InspectorInstrumentation::sessionCreated(Page& page, RefPtr<ReplaySession>&& session) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - networkStateChangedImpl(instrumentingAgents); -#else - UNUSED_PARAM(page); + sessionCreatedImpl(instrumentingAgentsForPage(page), WTFMove(session)); +} + +inline void InspectorInstrumentation::sessionLoaded(Page& page, RefPtr<ReplaySession>&& session) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + sessionLoadedImpl(instrumentingAgentsForPage(page), WTFMove(session)); +} + +inline void InspectorInstrumentation::sessionModified(Page& page, RefPtr<ReplaySession>&& session) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + sessionModifiedImpl(instrumentingAgentsForPage(page), WTFMove(session)); +} + +inline void InspectorInstrumentation::segmentCreated(Page& page, RefPtr<ReplaySessionSegment>&& segment) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + segmentCreatedImpl(instrumentingAgentsForPage(page), WTFMove(segment)); +} + +inline void InspectorInstrumentation::segmentCompleted(Page& page, RefPtr<ReplaySessionSegment>&& segment) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + segmentCompletedImpl(instrumentingAgentsForPage(page), WTFMove(segment)); +} + +inline void InspectorInstrumentation::segmentLoaded(Page& page, RefPtr<ReplaySessionSegment>&& segment) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + segmentLoadedImpl(instrumentingAgentsForPage(page), WTFMove(segment)); +} + +inline void InspectorInstrumentation::segmentUnloaded(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + segmentUnloadedImpl(instrumentingAgentsForPage(page)); +} + +inline void InspectorInstrumentation::captureStarted(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + captureStartedImpl(instrumentingAgentsForPage(page)); +} + +inline void InspectorInstrumentation::captureStopped(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + captureStoppedImpl(instrumentingAgentsForPage(page)); +} + +inline void InspectorInstrumentation::playbackStarted(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + playbackStartedImpl(instrumentingAgentsForPage(page)); +} + +inline void InspectorInstrumentation::playbackPaused(Page& page, const ReplayPosition& position) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + playbackPausedImpl(instrumentingAgentsForPage(page), position); +} + +inline void InspectorInstrumentation::playbackFinished(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + playbackFinishedImpl(instrumentingAgentsForPage(page)); +} + +inline void InspectorInstrumentation::playbackHitPosition(Page& page, const ReplayPosition& position) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + playbackHitPositionImpl(instrumentingAgentsForPage(page), position); +} +#endif // ENABLE(WEB_REPLAY) + +#if ENABLE(RESOURCE_USAGE) +inline void InspectorInstrumentation::didHandleMemoryPressure(Page& page, Critical critical) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + didHandleMemoryPressureImpl(instrumentingAgentsForPage(page), critical); +} #endif + +inline void InspectorInstrumentation::networkStateChanged(Page& page) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + networkStateChangedImpl(instrumentingAgentsForPage(page)); } inline void InspectorInstrumentation::updateApplicationCacheStatus(Frame* frame) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (auto* instrumentingAgents = instrumentingAgentsForFrame(frame)) + updateApplicationCacheStatusImpl(*instrumentingAgents, *frame); +} + +inline void InspectorInstrumentation::addMessageToConsole(Page& page, std::unique_ptr<Inspector::ConsoleMessage> message) +{ + addMessageToConsoleImpl(instrumentingAgentsForPage(page), WTFMove(message)); +} + +inline void InspectorInstrumentation::addMessageToConsole(WorkerGlobalScope& workerGlobalScope, std::unique_ptr<Inspector::ConsoleMessage> message) +{ + addMessageToConsoleImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), WTFMove(message)); +} + +inline void InspectorInstrumentation::consoleCount(Page& page, JSC::ExecState* state, Ref<Inspector::ScriptArguments>&& arguments) +{ + consoleCountImpl(instrumentingAgentsForPage(page), state, WTFMove(arguments)); +} + +inline void InspectorInstrumentation::consoleCount(WorkerGlobalScope& workerGlobalScope, JSC::ExecState* state, Ref<Inspector::ScriptArguments>&& arguments) +{ + consoleCountImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), state, WTFMove(arguments)); +} + +inline void InspectorInstrumentation::takeHeapSnapshot(Frame& frame, const String& title) +{ FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) - updateApplicationCacheStatusImpl(instrumentingAgents, frame); -#else - UNUSED_PARAM(frame); -#endif + takeHeapSnapshotImpl(*instrumentingAgents, title); +} + +inline void InspectorInstrumentation::startConsoleTiming(Frame& frame, const String& title) +{ + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + startConsoleTimingImpl(*instrumentingAgents, frame, title); +} + +inline void InspectorInstrumentation::startConsoleTiming(WorkerGlobalScope& workerGlobalScope, const String& title) +{ + startConsoleTimingImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), title); +} + +inline void InspectorInstrumentation::stopConsoleTiming(Frame& frame, const String& title, Ref<Inspector::ScriptCallStack>&& stack) +{ + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + stopConsoleTimingImpl(*instrumentingAgents, frame, title, WTFMove(stack)); +} + +inline void InspectorInstrumentation::stopConsoleTiming(WorkerGlobalScope& workerGlobalScope, const String& title, Ref<Inspector::ScriptCallStack>&& stack) +{ + stopConsoleTimingImpl(instrumentingAgentsForWorkerGlobalScope(workerGlobalScope), title, WTFMove(stack)); +} + +inline void InspectorInstrumentation::consoleTimeStamp(Frame& frame, Ref<Inspector::ScriptArguments>&& arguments) +{ + FAST_RETURN_IF_NO_FRONTENDS(void()); + if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame)) + consoleTimeStampImpl(*instrumentingAgents, frame, WTFMove(arguments)); +} + +inline void InspectorInstrumentation::startProfiling(Page& page, JSC::ExecState* exec, const String &title) +{ + startProfilingImpl(instrumentingAgentsForPage(page), exec, title); +} + +inline void InspectorInstrumentation::stopProfiling(Page& page, JSC::ExecState* exec, const String &title) +{ + stopProfilingImpl(instrumentingAgentsForPage(page), exec, title); } inline void InspectorInstrumentation::didRequestAnimationFrame(Document* document, int callbackId) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didRequestAnimationFrameImpl(instrumentingAgents, callbackId, document->frame()); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(callbackId); -#endif + didRequestAnimationFrameImpl(*instrumentingAgents, callbackId, document->frame()); } inline void InspectorInstrumentation::didCancelAnimationFrame(Document* document, int callbackId) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - didCancelAnimationFrameImpl(instrumentingAgents, callbackId, document->frame()); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(callbackId); -#endif + didCancelAnimationFrameImpl(*instrumentingAgents, callbackId, document->frame()); } inline InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrame(Document* document, int callbackId) { -#if ENABLE(INSPECTOR) if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) - return willFireAnimationFrameImpl(instrumentingAgents, callbackId, document->frame()); -#else - UNUSED_PARAM(document); - UNUSED_PARAM(callbackId); -#endif + return willFireAnimationFrameImpl(*instrumentingAgents, callbackId, document->frame()); return InspectorInstrumentationCookie(); } inline void InspectorInstrumentation::didFireAnimationFrame(const InspectorInstrumentationCookie& cookie) { -#if ENABLE(INSPECTOR) FAST_RETURN_IF_NO_FRONTENDS(void()); if (cookie.isValid()) didFireAnimationFrameImpl(cookie); -#else - UNUSED_PARAM(cookie); -#endif } -#if USE(ACCELERATED_COMPOSITING) inline void InspectorInstrumentation::layerTreeDidChange(Page* page) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - layerTreeDidChangeImpl(instrumentingAgents); -#else - UNUSED_PARAM(page); -#endif + layerTreeDidChangeImpl(*instrumentingAgents); } -inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const RenderLayer* renderLayer) +inline void InspectorInstrumentation::renderLayerDestroyed(Page* page, const RenderLayer& renderLayer) { -#if ENABLE(INSPECTOR) + FAST_RETURN_IF_NO_FRONTENDS(void()); if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - renderLayerDestroyedImpl(instrumentingAgents, renderLayer); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(renderLayer); -#endif + renderLayerDestroyedImpl(*instrumentingAgents, renderLayer); } -inline void InspectorInstrumentation::pseudoElementDestroyed(Page* page, PseudoElement* pseudoElement) +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext* context) { -#if ENABLE(INSPECTOR) - if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page)) - pseudoElementDestroyedImpl(instrumentingAgents, pseudoElement); -#else - UNUSED_PARAM(page); - UNUSED_PARAM(pseudoElement); -#endif + return context ? instrumentingAgentsForContext(*context) : nullptr; } -#endif -#if ENABLE(INSPECTOR) -inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext* context) +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForContext(ScriptExecutionContext& context) { - if (!context) - return nullptr; - if (context->isDocument()) - return instrumentingAgentsForPage(toDocument(context)->page()); - return instrumentingAgentsForNonDocumentContext(context); + if (is<Document>(context)) + return instrumentingAgentsForPage(downcast<Document>(context).page()); + if (is<WorkerGlobalScope>(context)) + return &instrumentingAgentsForWorkerGlobalScope(downcast<WorkerGlobalScope>(context)); + return nullptr; } inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForFrame(Frame* frame) { - if (frame) - return instrumentingAgentsForPage(frame->page()); - return nullptr; + return frame ? instrumentingAgentsForFrame(*frame) : nullptr; +} + +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForFrame(Frame& frame) +{ + return instrumentingAgentsForPage(frame.page()); } inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForDocument(Document* document) { - if (document) { - Page* page = document->page(); -#if ENABLE(TEMPLATE_ELEMENT) - if (!page && document->templateDocumentHost()) - page = document->templateDocumentHost()->page(); -#endif - return instrumentingAgentsForPage(page); - } - return nullptr; + return document ? instrumentingAgentsForDocument(*document) : nullptr; } -#endif -} // namespace WebCore +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForDocument(Document& document) +{ + Page* page = document.page(); + if (!page && document.templateDocumentHost()) + page = document.templateDocumentHost()->page(); + return instrumentingAgentsForPage(page); +} -#endif // !defined(InspectorInstrumentation_h) +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForPage(Page* page) +{ + return page ? &instrumentingAgentsForPage(*page) : nullptr; +} + +inline InstrumentingAgents& InspectorInstrumentation::instrumentingAgentsForPage(Page& page) +{ + ASSERT(isMainThread()); + return page.inspectorController().m_instrumentingAgents.get(); +} + +inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope) +{ + return workerGlobalScope ? &instrumentingAgentsForWorkerGlobalScope(*workerGlobalScope) : nullptr; +} + +inline InstrumentingAgents& InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope& workerGlobalScope) +{ + return workerGlobalScope.inspectorController().m_instrumentingAgents; +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorInstrumentationCookie.cpp b/Source/WebCore/inspector/InspectorInstrumentationCookie.cpp index 7f00deb3f..b99a40f33 100644 --- a/Source/WebCore/inspector/InspectorInstrumentationCookie.cpp +++ b/Source/WebCore/inspector/InspectorInstrumentationCookie.cpp @@ -31,20 +31,17 @@ #include "config.h" #include "InspectorInstrumentationCookie.h" -#if ENABLE(INSPECTOR) - #include "InstrumentingAgents.h" namespace WebCore { InspectorInstrumentationCookie::InspectorInstrumentationCookie() - : m_instrumentingAgents(nullptr) - , m_timelineAgentId(0) + : m_timelineAgentId(0) { } -InspectorInstrumentationCookie::InspectorInstrumentationCookie(InstrumentingAgents* agents, int timelineAgentId) - : m_instrumentingAgents(agents) +InspectorInstrumentationCookie::InspectorInstrumentationCookie(InstrumentingAgents& agents, int timelineAgentId) + : m_instrumentingAgents(&agents) , m_timelineAgentId(timelineAgentId) { } @@ -70,5 +67,3 @@ InspectorInstrumentationCookie::~InspectorInstrumentationCookie() } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorInstrumentationCookie.h b/Source/WebCore/inspector/InspectorInstrumentationCookie.h index 6db514fc9..904cd94dc 100644 --- a/Source/WebCore/inspector/InspectorInstrumentationCookie.h +++ b/Source/WebCore/inspector/InspectorInstrumentationCookie.h @@ -28,21 +28,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorInstrumentationCookie_h -#define InspectorInstrumentationCookie_h +#pragma once #include <wtf/RefPtr.h> namespace WebCore { -class InspectorInstrumentation; class InstrumentingAgents; class InspectorInstrumentationCookie { -#if ENABLE(INSPECTOR) public: InspectorInstrumentationCookie(); - InspectorInstrumentationCookie(InstrumentingAgents*, int); + InspectorInstrumentationCookie(InstrumentingAgents&, int); InspectorInstrumentationCookie(const InspectorInstrumentationCookie&); InspectorInstrumentationCookie& operator=(const InspectorInstrumentationCookie&); ~InspectorInstrumentationCookie(); @@ -54,9 +51,6 @@ public: private: RefPtr<InstrumentingAgents> m_instrumentingAgents; int m_timelineAgentId; -#endif }; } // namespace WebCore - -#endif // InspectorInstrumentationCookie_h diff --git a/Source/WebCore/inspector/InspectorLayerTreeAgent.cpp b/Source/WebCore/inspector/InspectorLayerTreeAgent.cpp index 086e3c80c..d96e04ea3 100644 --- a/Source/WebCore/inspector/InspectorLayerTreeAgent.cpp +++ b/Source/WebCore/inspector/InspectorLayerTreeAgent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,29 +29,27 @@ */ #include "config.h" - -#if USE(ACCELERATED_COMPOSITING) -#if ENABLE(INSPECTOR) - #include "InspectorLayerTreeAgent.h" -#include "IdentifiersFactory.h" #include "InspectorDOMAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" #include "IntRect.h" #include "PseudoElement.h" +#include "RenderChildIterator.h" #include "RenderLayer.h" #include "RenderLayerBacking.h" #include "RenderLayerCompositor.h" #include "RenderView.h" +#include <inspector/IdentifiersFactory.h> using namespace Inspector; namespace WebCore { -InspectorLayerTreeAgent::InspectorLayerTreeAgent(InstrumentingAgents* instrumentingAgents) - : InspectorAgentBase(ASCIILiteral("LayerTree"), instrumentingAgents) +InspectorLayerTreeAgent::InspectorLayerTreeAgent(WebAgentContext& context) + : InspectorAgentBase(ASCIILiteral("LayerTree"), context) + , m_frontendDispatcher(std::make_unique<Inspector::LayerTreeFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::LayerTreeBackendDispatcher::create(context.backendDispatcher, this)) { } @@ -60,18 +58,14 @@ InspectorLayerTreeAgent::~InspectorLayerTreeAgent() reset(); } -void InspectorLayerTreeAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorLayerTreeAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorLayerTreeFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorLayerTreeBackendDispatcher::create(backendDispatcher, this); } -void InspectorLayerTreeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorLayerTreeAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - disable(nullptr); + ErrorString unused; + disable(unused); } void InspectorLayerTreeAgent::reset() @@ -82,14 +76,14 @@ void InspectorLayerTreeAgent::reset() m_idToPseudoElement.clear(); } -void InspectorLayerTreeAgent::enable(ErrorString*) +void InspectorLayerTreeAgent::enable(ErrorString&) { - m_instrumentingAgents->setInspectorLayerTreeAgent(this); + m_instrumentingAgents.setInspectorLayerTreeAgent(this); } -void InspectorLayerTreeAgent::disable(ErrorString*) +void InspectorLayerTreeAgent::disable(ErrorString&) { - m_instrumentingAgents->setInspectorLayerTreeAgent(nullptr); + m_instrumentingAgents.setInspectorLayerTreeAgent(nullptr); } void InspectorLayerTreeAgent::layerTreeDidChange() @@ -97,47 +91,48 @@ void InspectorLayerTreeAgent::layerTreeDidChange() m_frontendDispatcher->layerTreeDidChange(); } -void InspectorLayerTreeAgent::renderLayerDestroyed(const RenderLayer* renderLayer) +void InspectorLayerTreeAgent::renderLayerDestroyed(const RenderLayer& renderLayer) { - unbind(renderLayer); + unbind(&renderLayer); } -void InspectorLayerTreeAgent::pseudoElementDestroyed(PseudoElement* pseudoElement) +void InspectorLayerTreeAgent::pseudoElementDestroyed(PseudoElement& pseudoElement) { - unbindPseudoElement(pseudoElement); + unbindPseudoElement(&pseudoElement); } -void InspectorLayerTreeAgent::layersForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>& layers) +void InspectorLayerTreeAgent::layersForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>& layers) { - layers = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>::create(); + layers = Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>::create(); - Node* node = m_instrumentingAgents->inspectorDOMAgent()->nodeForId(nodeId); + auto* node = m_instrumentingAgents.inspectorDOMAgent()->nodeForId(nodeId); if (!node) { - *errorString = "Provided node id doesn't match any known node"; + errorString = ASCIILiteral("Provided node id doesn't match any known node"); return; } - RenderObject* renderer = node->renderer(); + auto* renderer = node->renderer(); if (!renderer) { - *errorString = "Node for provided node id doesn't have a renderer"; + errorString = ASCIILiteral("Node for provided node id doesn't have a renderer"); return; } - gatherLayersUsingRenderObjectHierarchy(errorString, renderer, layers); + if (is<RenderElement>(*renderer)) + gatherLayersUsingRenderObjectHierarchy(errorString, downcast<RenderElement>(*renderer), layers); } -void InspectorLayerTreeAgent::gatherLayersUsingRenderObjectHierarchy(ErrorString* errorString, RenderObject* renderer, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>& layers) +void InspectorLayerTreeAgent::gatherLayersUsingRenderObjectHierarchy(ErrorString& errorString, RenderElement& renderer, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>& layers) { - if (renderer->hasLayer()) { - gatherLayersUsingRenderLayerHierarchy(errorString, toRenderLayerModelObject(renderer)->layer(), layers); + if (renderer.hasLayer()) { + gatherLayersUsingRenderLayerHierarchy(errorString, downcast<RenderLayerModelObject>(renderer).layer(), layers); return; } - for (renderer = renderer->firstChildSlow(); renderer; renderer = renderer->nextSibling()) - gatherLayersUsingRenderObjectHierarchy(errorString, renderer, layers); + for (auto& child : childrenOfType<RenderElement>(renderer)) + gatherLayersUsingRenderObjectHierarchy(errorString, child, layers); } -void InspectorLayerTreeAgent::gatherLayersUsingRenderLayerHierarchy(ErrorString* errorString, RenderLayer* renderLayer, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>& layers) +void InspectorLayerTreeAgent::gatherLayersUsingRenderLayerHierarchy(ErrorString& errorString, RenderLayer* renderLayer, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>& layers) { if (renderLayer->isComposited()) layers->addItem(buildObjectForLayer(errorString, renderLayer)); @@ -146,7 +141,7 @@ void InspectorLayerTreeAgent::gatherLayersUsingRenderLayerHierarchy(ErrorString* gatherLayersUsingRenderLayerHierarchy(errorString, renderLayer, layers); } -PassRefPtr<Inspector::TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectForLayer(ErrorString* errorString, RenderLayer* renderLayer) +Ref<Inspector::Protocol::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectForLayer(ErrorString& errorString, RenderLayer* renderLayer) { RenderObject* renderer = &renderLayer->renderer(); RenderLayerBacking* backing = renderLayer->backing(); @@ -166,13 +161,14 @@ PassRefPtr<Inspector::TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::bu node = renderer->parent()->element(); // Basic set of properties. - RefPtr<Inspector::TypeBuilder::LayerTree::Layer> layerObject = Inspector::TypeBuilder::LayerTree::Layer::create() + auto layerObject = Inspector::Protocol::LayerTree::Layer::create() .setLayerId(bind(renderLayer)) .setNodeId(idForNode(errorString, node)) .setBounds(buildObjectForIntRect(renderer->absoluteBoundingBoxRect())) .setMemory(backing->backingStoreMemoryEstimate()) .setCompositedBounds(buildObjectForIntRect(enclosingIntRect(backing->compositedBounds()))) - .setPaintCount(backing->graphicsLayer()->repaintCount()); + .setPaintCount(backing->graphicsLayer()->repaintCount()) + .release(); if (node && node->shadowHost()) layerObject->setIsInShadowTree(true); @@ -184,7 +180,7 @@ PassRefPtr<Inspector::TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::bu if (isReflection) renderer = renderer->parent(); layerObject->setIsGeneratedContent(true); - layerObject->setPseudoElementId(bindPseudoElement(toPseudoElement(renderer->node()))); + layerObject->setPseudoElementId(bindPseudoElement(downcast<PseudoElement>(renderer->node()))); if (renderer->isBeforeContent()) layerObject->setPseudoElement("before"); else if (renderer->isAfterContent()) @@ -204,12 +200,12 @@ PassRefPtr<Inspector::TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::bu return layerObject; } -int InspectorLayerTreeAgent::idForNode(ErrorString* errorString, Node* node) +int InspectorLayerTreeAgent::idForNode(ErrorString& errorString, Node* node) { if (!node) return 0; - InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent(); + InspectorDOMAgent* domAgent = m_instrumentingAgents.inspectorDOMAgent(); int nodeId = domAgent->boundNodeId(node); if (!nodeId) @@ -218,26 +214,27 @@ int InspectorLayerTreeAgent::idForNode(ErrorString* errorString, Node* node) return nodeId; } -PassRefPtr<Inspector::TypeBuilder::LayerTree::IntRect> InspectorLayerTreeAgent::buildObjectForIntRect(const IntRect& rect) +Ref<Inspector::Protocol::LayerTree::IntRect> InspectorLayerTreeAgent::buildObjectForIntRect(const IntRect& rect) { - return Inspector::TypeBuilder::LayerTree::IntRect::create() + return Inspector::Protocol::LayerTree::IntRect::create() .setX(rect.x()) .setY(rect.y()) .setWidth(rect.width()) - .setHeight(rect.height()).release(); + .setHeight(rect.height()) + .release(); } -void InspectorLayerTreeAgent::reasonsForCompositingLayer(ErrorString* errorString, const String& layerId, RefPtr<Inspector::TypeBuilder::LayerTree::CompositingReasons>& compositingReasons) +void InspectorLayerTreeAgent::reasonsForCompositingLayer(ErrorString& errorString, const String& layerId, RefPtr<Inspector::Protocol::LayerTree::CompositingReasons>& compositingReasonsResult) { const RenderLayer* renderLayer = m_idToLayer.get(layerId); if (!renderLayer) { - *errorString = "Could not find a bound layer for the provided id"; + errorString = ASCIILiteral("Could not find a bound layer for the provided id"); return; } CompositingReasons reasonsBitmask = renderLayer->compositor().reasonsForCompositing(*renderLayer); - compositingReasons = Inspector::TypeBuilder::LayerTree::CompositingReasons::create(); + auto compositingReasons = Inspector::Protocol::LayerTree::CompositingReasons::create().release(); if (reasonsBitmask & CompositingReason3DTransform) compositingReasons->setTransform3D(true); @@ -295,21 +292,26 @@ void InspectorLayerTreeAgent::reasonsForCompositingLayer(ErrorString* errorStrin if (reasonsBitmask & CompositingReasonFilterWithCompositedDescendants) compositingReasons->setFilterWithCompositedDescendants(true); - + if (reasonsBitmask & CompositingReasonBlendingWithCompositedDescendants) compositingReasons->setBlendingWithCompositedDescendants(true); + if (reasonsBitmask & CompositingReasonIsolatesCompositedBlendingDescendants) + compositingReasons->setIsolatesCompositedBlendingDescendants(true); + if (reasonsBitmask & CompositingReasonPerspective) compositingReasons->setPerspective(true); if (reasonsBitmask & CompositingReasonPreserve3D) compositingReasons->setPreserve3D(true); + if (reasonsBitmask & CompositingReasonWillChange) + compositingReasons->setWillChange(true); + if (reasonsBitmask & CompositingReasonRoot) compositingReasons->setRoot(true); - - if (reasonsBitmask & CompositingReasonBlending) - compositingReasons->setBlending(true); + + compositingReasonsResult = WTFMove(compositingReasons); } String InspectorLayerTreeAgent::bind(const RenderLayer* layer) @@ -357,6 +359,3 @@ void InspectorLayerTreeAgent::unbindPseudoElement(PseudoElement* pseudoElement) } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/inspector/InspectorLayerTreeAgent.h b/Source/WebCore/inspector/InspectorLayerTreeAgent.h index 7561ac754..2de7a28e2 100644 --- a/Source/WebCore/inspector/InspectorLayerTreeAgent.h +++ b/Source/WebCore/inspector/InspectorLayerTreeAgent.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,64 +26,63 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorLayerTreeAgent_h -#define InspectorLayerTreeAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InspectorWebTypeBuilders.h" -#include "RenderLayer.h" -#include <wtf/PassOwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/Vector.h> +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <inspector/InspectorProtocolObjects.h> #include <wtf/text/WTFString.h> namespace WebCore { -class InstrumentingAgents; +class IntRect; +class Node; +class PseudoElement; +class RenderElement; +class RenderLayer; typedef String ErrorString; -class InspectorLayerTreeAgent : public InspectorAgentBase, public Inspector::InspectorLayerTreeBackendDispatcherHandler { +class InspectorLayerTreeAgent final : public InspectorAgentBase, public Inspector::LayerTreeBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; public: - explicit InspectorLayerTreeAgent(InstrumentingAgents*); - ~InspectorLayerTreeAgent(); + explicit InspectorLayerTreeAgent(WebAgentContext&); + virtual ~InspectorLayerTreeAgent(); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; void reset(); + // InspectorInstrumentation void layerTreeDidChange(); - void renderLayerDestroyed(const RenderLayer*); - void pseudoElementDestroyed(PseudoElement*); + void renderLayerDestroyed(const RenderLayer&); + void pseudoElementDestroyed(PseudoElement&); // Called from the front-end. - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void layersForNode(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>&) override; - virtual void reasonsForCompositingLayer(ErrorString*, const String& layerId, RefPtr<Inspector::TypeBuilder::LayerTree::CompositingReasons>&) override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void layersForNode(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>&) override; + void reasonsForCompositingLayer(ErrorString&, const String& layerId, RefPtr<Inspector::Protocol::LayerTree::CompositingReasons>&) override; private: // RenderLayer-related methods. String bind(const RenderLayer*); void unbind(const RenderLayer*); - void gatherLayersUsingRenderObjectHierarchy(ErrorString*, RenderObject*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>&); - void gatherLayersUsingRenderLayerHierarchy(ErrorString*, RenderLayer*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::LayerTree::Layer>>&); + void gatherLayersUsingRenderObjectHierarchy(ErrorString&, RenderElement&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>&); + void gatherLayersUsingRenderLayerHierarchy(ErrorString&, RenderLayer*, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::LayerTree::Layer>>&); - PassRefPtr<Inspector::TypeBuilder::LayerTree::Layer> buildObjectForLayer(ErrorString*, RenderLayer*); - PassRefPtr<Inspector::TypeBuilder::LayerTree::IntRect> buildObjectForIntRect(const IntRect&); + Ref<Inspector::Protocol::LayerTree::Layer> buildObjectForLayer(ErrorString&, RenderLayer*); + Ref<Inspector::Protocol::LayerTree::IntRect> buildObjectForIntRect(const IntRect&); - int idForNode(ErrorString*, Node*); + int idForNode(ErrorString&, Node*); String bindPseudoElement(PseudoElement*); void unbindPseudoElement(PseudoElement*); - std::unique_ptr<Inspector::InspectorLayerTreeFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorLayerTreeBackendDispatcher> m_backendDispatcher; + std::unique_ptr<Inspector::LayerTreeFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::LayerTreeBackendDispatcher> m_backendDispatcher; HashMap<const RenderLayer*, String> m_documentLayerToIdMap; HashMap<String, const RenderLayer*> m_idToLayer; @@ -93,7 +92,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorLayerTreeAgent_h) diff --git a/Source/WebCore/inspector/InspectorMemoryAgent.cpp b/Source/WebCore/inspector/InspectorMemoryAgent.cpp index 164d914d6..ebf9c364a 100644 --- a/Source/WebCore/inspector/InspectorMemoryAgent.cpp +++ b/Source/WebCore/inspector/InspectorMemoryAgent.cpp @@ -1,95 +1,156 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorMemoryAgent.h" -#include "CharacterData.h" -#include "Document.h" -#include "EventListenerMap.h" -#include "Frame.h" -#include "InspectorDOMStorageAgent.h" -#include "InspectorWebFrontendDispatchers.h" +#if ENABLE(RESOURCE_USAGE) + #include "InstrumentingAgents.h" -#include "MemoryCache.h" -#include "Node.h" -#include "NodeTraversal.h" -#include "ScriptProfiler.h" -#include "StyledElement.h" -#include <inspector/InspectorValues.h> -#include <runtime/ArrayBufferView.h> -#include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/Vector.h> -#include <wtf/text/StringBuilder.h> -#include <wtf/text/StringImpl.h> -#include <wtf/text/WTFString.h> - -// Use a type alias instead of 'using' here which would cause a conflict on Mac. -typedef Inspector::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock; -typedef Inspector::TypeBuilder::Array<InspectorMemoryBlock> InspectorMemoryBlocks; +#include "ResourceUsageThread.h" +#include <inspector/InspectorEnvironment.h> +#include <wtf/Stopwatch.h> using namespace Inspector; namespace WebCore { -InspectorMemoryAgent::~InspectorMemoryAgent() +InspectorMemoryAgent::InspectorMemoryAgent(PageAgentContext& context) + : InspectorAgentBase(ASCIILiteral("Memory"), context) + , m_frontendDispatcher(std::make_unique<Inspector::MemoryFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::MemoryBackendDispatcher::create(context.backendDispatcher, this)) +{ +} + +void InspectorMemoryAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) +{ + m_instrumentingAgents.setInspectorMemoryAgent(this); +} + +void InspectorMemoryAgent::willDestroyFrontendAndBackend(DisconnectReason) +{ + m_instrumentingAgents.setInspectorMemoryAgent(nullptr); + + ErrorString ignored; + stopTracking(ignored); + disable(ignored); +} + +void InspectorMemoryAgent::enable(ErrorString&) +{ + m_enabled = true; +} + +void InspectorMemoryAgent::disable(ErrorString&) { + m_enabled = false; } -void InspectorMemoryAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, InspectorBackendDispatcher* backendDispatcher) +void InspectorMemoryAgent::startTracking(ErrorString&) { - m_backendDispatcher = InspectorMemoryBackendDispatcher::create(backendDispatcher, this); + if (m_tracking) + return; + + ResourceUsageThread::addObserver(this, [this] (const ResourceUsageData& data) { + collectSample(data); + }); + + m_tracking = true; + + m_frontendDispatcher->trackingStart(m_environment.executionStopwatch()->elapsedTime()); } -void InspectorMemoryAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorMemoryAgent::stopTracking(ErrorString&) { - m_backendDispatcher.clear(); + if (!m_tracking) + return; + + ResourceUsageThread::removeObserver(this); + + m_tracking = false; + + m_frontendDispatcher->trackingComplete(); } -void InspectorMemoryAgent::getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners) +void InspectorMemoryAgent::didHandleMemoryPressure(Critical critical) { - *documents = InspectorCounters::counterValue(InspectorCounters::DocumentCounter); - *nodes = InspectorCounters::counterValue(InspectorCounters::NodeCounter); - *jsEventListeners = ThreadLocalInspectorCounters::current().counterValue(ThreadLocalInspectorCounters::JSEventListenerCounter); + if (!m_enabled) + return; + + MemoryFrontendDispatcher::Severity severity = critical == Critical::Yes ? MemoryFrontendDispatcher::Severity::Critical : MemoryFrontendDispatcher::Severity::NonCritical; + m_frontendDispatcher->memoryPressure(m_environment.executionStopwatch()->elapsedTime(), severity); } -InspectorMemoryAgent::InspectorMemoryAgent(InstrumentingAgents* instrumentingAgents) - : InspectorAgentBase(ASCIILiteral("Memory"), instrumentingAgents) +void InspectorMemoryAgent::collectSample(const ResourceUsageData& data) { + auto javascriptCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::Javascript) + .setSize(data.categories[MemoryCategory::GCHeap].totalSize() + data.categories[MemoryCategory::GCOwned].totalSize()) + .release(); + + auto jitCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::JIT) + .setSize(data.categories[MemoryCategory::JSJIT].totalSize()) + .release(); + + auto imagesCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::Images) + .setSize(data.categories[MemoryCategory::Images].totalSize()) + .release(); + + auto layersCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::Layers) + .setSize(data.categories[MemoryCategory::Layers].totalSize()) + .release(); + + auto pageCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::Page) + .setSize(data.categories[MemoryCategory::bmalloc].totalSize() + data.categories[MemoryCategory::LibcMalloc].totalSize()) + .release(); + + auto otherCategory = Protocol::Memory::CategoryData::create() + .setType(Protocol::Memory::CategoryData::Type::Other) + .setSize(data.categories[MemoryCategory::Other].totalSize()) + .release(); + + auto categories = Protocol::Array<Protocol::Memory::CategoryData>::create(); + categories->addItem(WTFMove(javascriptCategory)); + categories->addItem(WTFMove(jitCategory)); + categories->addItem(WTFMove(imagesCategory)); + categories->addItem(WTFMove(layersCategory)); + categories->addItem(WTFMove(pageCategory)); + categories->addItem(WTFMove(otherCategory)); + + auto event = Protocol::Memory::Event::create() + .setTimestamp(m_environment.executionStopwatch()->elapsedTime()) + .setCategories(WTFMove(categories)) + .release(); + + m_frontendDispatcher->trackingUpdate(WTFMove(event)); } -} // namespace WebCore +} // namespace Inspector -#endif // ENABLE(INSPECTOR) +#endif // ENABLE(RESOURCE_USAGE) diff --git a/Source/WebCore/inspector/InspectorMemoryAgent.h b/Source/WebCore/inspector/InspectorMemoryAgent.h index 12f3a9c5e..039222cd7 100644 --- a/Source/WebCore/inspector/InspectorMemoryAgent.h +++ b/Source/WebCore/inspector/InspectorMemoryAgent.h @@ -1,66 +1,70 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorMemoryAgent_h -#define InspectorMemoryAgent_h +#pragma once -#if ENABLE(INSPECTOR) +#if ENABLE(RESOURCE_USAGE) #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include <wtf/PassOwnPtr.h> -#include <wtf/RefPtr.h> +#include "MemoryPressureHandler.h" +#include "ResourceUsageData.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> namespace WebCore { -class InspectorDOMStorageAgent; -class InstrumentingAgents; - typedef String ErrorString; -class InspectorMemoryAgent : public InspectorAgentBase, public Inspector::InspectorMemoryBackendDispatcherHandler { +class InspectorMemoryAgent final : public InspectorAgentBase, public Inspector::MemoryBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorMemoryAgent); + WTF_MAKE_FAST_ALLOCATED; public: - explicit InspectorMemoryAgent(InstrumentingAgents*); - virtual ~InspectorMemoryAgent(); + InspectorMemoryAgent(PageAgentContext&); + virtual ~InspectorMemoryAgent() { } - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; - virtual void getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners) override; + // MemoryBackendDispatcherHandler + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void startTracking(ErrorString&) override; + void stopTracking(ErrorString&) override; + + // InspectorInstrumentation + void didHandleMemoryPressure(Critical); private: - RefPtr<Inspector::InspectorMemoryBackendDispatcher> m_backendDispatcher; + void collectSample(const ResourceUsageData&); + + std::unique_ptr<Inspector::MemoryFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::MemoryBackendDispatcher> m_backendDispatcher; + bool m_enabled { false }; + bool m_tracking { false }; }; } // namespace WebCore -#endif // !ENABLE(INSPECTOR) -#endif // !defined(InspectorMemoryAgent_h) +#endif // ENABLE(RESOURCE_USAGE) diff --git a/Source/WebCore/inspector/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/InspectorNetworkAgent.cpp new file mode 100644 index 000000000..569ce4a2c --- /dev/null +++ b/Source/WebCore/inspector/InspectorNetworkAgent.cpp @@ -0,0 +1,740 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InspectorNetworkAgent.h" + +#include "CachedRawResource.h" +#include "CachedResource.h" +#include "CachedResourceLoader.h" +#include "CachedResourceRequestInitiators.h" +#include "Document.h" +#include "DocumentLoader.h" +#include "DocumentThreadableLoader.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "HTTPHeaderMap.h" +#include "HTTPHeaderNames.h" +#include "IconController.h" +#include "InspectorPageAgent.h" +#include "InspectorTimelineAgent.h" +#include "InstrumentingAgents.h" +#include "JSMainThreadExecState.h" +#include "MemoryCache.h" +#include "NetworkResourcesData.h" +#include "Page.h" +#include "ProgressTracker.h" +#include "ResourceError.h" +#include "ResourceLoader.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "ScriptableDocumentParser.h" +#include "SubresourceLoader.h" +#include "ThreadableLoaderClient.h" +#include "URL.h" +#include "WebSocketFrame.h" +#include <inspector/ContentSearchUtilities.h> +#include <inspector/IdentifiersFactory.h> +#include <inspector/InspectorFrontendRouter.h> +#include <inspector/InspectorValues.h> +#include <inspector/ScriptCallStack.h> +#include <inspector/ScriptCallStackFactory.h> +#include <wtf/RefPtr.h> +#include <wtf/Stopwatch.h> +#include <wtf/text/StringBuilder.h> + +using namespace Inspector; + +typedef Inspector::NetworkBackendDispatcherHandler::LoadResourceCallback LoadResourceCallback; + +namespace WebCore { + +namespace { + +class InspectorThreadableLoaderClient final : public ThreadableLoaderClient { + WTF_MAKE_NONCOPYABLE(InspectorThreadableLoaderClient); +public: + InspectorThreadableLoaderClient(RefPtr<LoadResourceCallback>&& callback) + : m_callback(WTFMove(callback)) { } + + virtual ~InspectorThreadableLoaderClient() { } + + void didReceiveResponse(unsigned long, const ResourceResponse& response) override + { + m_mimeType = response.mimeType(); + m_statusCode = response.httpStatusCode(); + + // FIXME: This assumes text only responses. We should support non-text responses as well. + TextEncoding textEncoding(response.textEncodingName()); + bool useDetector = false; + if (!textEncoding.isValid()) { + textEncoding = UTF8Encoding(); + useDetector = true; + } + + m_decoder = TextResourceDecoder::create(ASCIILiteral("text/plain"), textEncoding, useDetector); + } + + void didReceiveData(const char* data, int dataLength) override + { + if (!dataLength) + return; + + if (dataLength == -1) + dataLength = strlen(data); + + m_responseText.append(m_decoder->decode(data, dataLength)); + } + + void didFinishLoading(unsigned long, double) override + { + if (m_decoder) + m_responseText.append(m_decoder->flush()); + + m_callback->sendSuccess(m_responseText.toString(), m_mimeType, m_statusCode); + dispose(); + } + + void didFail(const ResourceError& error) override + { + m_callback->sendFailure(error.isAccessControl() ? ASCIILiteral("Loading resource for inspector failed access control check") : ASCIILiteral("Loading resource for inspector failed")); + dispose(); + } + + void setLoader(RefPtr<ThreadableLoader>&& loader) + { + m_loader = WTFMove(loader); + } + +private: + void dispose() + { + m_loader = nullptr; + delete this; + } + + RefPtr<LoadResourceCallback> m_callback; + RefPtr<ThreadableLoader> m_loader; + RefPtr<TextResourceDecoder> m_decoder; + String m_mimeType; + StringBuilder m_responseText; + int m_statusCode; +}; + +} // namespace + +InspectorNetworkAgent::InspectorNetworkAgent(WebAgentContext& context, InspectorPageAgent* pageAgent) + : InspectorAgentBase(ASCIILiteral("Network"), context) + , m_frontendDispatcher(std::make_unique<Inspector::NetworkFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::NetworkBackendDispatcher::create(context.backendDispatcher, this)) + , m_pageAgent(pageAgent) + , m_resourcesData(std::make_unique<NetworkResourcesData>()) +{ +} + +void InspectorNetworkAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) +{ +} + +void InspectorNetworkAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) +{ + ErrorString unused; + disable(unused); +} + +static Ref<InspectorObject> buildObjectForHeaders(const HTTPHeaderMap& headers) +{ + Ref<InspectorObject> headersObject = InspectorObject::create(); + + for (const auto& header : headers) + headersObject->setString(header.key, header.value); + return headersObject; +} + +Ref<Inspector::Protocol::Network::ResourceTiming> InspectorNetworkAgent::buildObjectForTiming(const NetworkLoadTiming& timing, ResourceLoader& resourceLoader) +{ + MonotonicTime startTime = resourceLoader.loadTiming().startTime(); + double startTimeInInspector = m_environment.executionStopwatch()->elapsedTimeSince(startTime); + + return Inspector::Protocol::Network::ResourceTiming::create() + .setStartTime(startTimeInInspector) + .setDomainLookupStart(timing.domainLookupStart) + .setDomainLookupEnd(timing.domainLookupEnd) + .setConnectStart(timing.connectStart) + .setConnectEnd(timing.connectEnd) + .setSecureConnectionStart(timing.secureConnectionStart) + .setRequestStart(timing.requestStart) + .setResponseStart(timing.responseStart) + .release(); +} + +static Ref<Inspector::Protocol::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request) +{ + auto requestObject = Inspector::Protocol::Network::Request::create() + .setUrl(request.url().string()) + .setMethod(request.httpMethod()) + .setHeaders(buildObjectForHeaders(request.httpHeaderFields())) + .release(); + if (request.httpBody() && !request.httpBody()->isEmpty()) { + Vector<char> bytes; + request.httpBody()->flatten(bytes); + requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size())); + } + return requestObject; +} + +RefPtr<Inspector::Protocol::Network::Response> InspectorNetworkAgent::buildObjectForResourceResponse(const ResourceResponse& response, ResourceLoader* resourceLoader) +{ + if (response.isNull()) + return nullptr; + + double status = response.httpStatusCode(); + Ref<InspectorObject> headers = buildObjectForHeaders(response.httpHeaderFields()); + + auto responseObject = Inspector::Protocol::Network::Response::create() + .setUrl(response.url().string()) + .setStatus(status) + .setStatusText(response.httpStatusText()) + .setHeaders(WTFMove(headers)) + .setMimeType(response.mimeType()) + .release(); + + responseObject->setFromDiskCache(response.source() == ResourceResponse::Source::DiskCache || response.source() == ResourceResponse::Source::DiskCacheAfterValidation); + if (resourceLoader) + responseObject->setTiming(buildObjectForTiming(response.networkLoadTiming(), *resourceLoader)); + + return WTFMove(responseObject); +} + +Ref<Inspector::Protocol::Network::CachedResource> InspectorNetworkAgent::buildObjectForCachedResource(CachedResource* cachedResource) +{ + auto resourceObject = Inspector::Protocol::Network::CachedResource::create() + .setUrl(cachedResource->url()) + .setType(InspectorPageAgent::cachedResourceTypeJson(*cachedResource)) + .setBodySize(cachedResource->encodedSize()) + .release(); + + auto resourceResponse = buildObjectForResourceResponse(cachedResource->response(), cachedResource->loader()); + resourceObject->setResponse(WTFMove(resourceResponse)); + + String sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(cachedResource); + if (!sourceMappingURL.isEmpty()) + resourceObject->setSourceMapURL(sourceMappingURL); + + return resourceObject; +} + +InspectorNetworkAgent::~InspectorNetworkAgent() +{ + if (m_enabled) { + ErrorString unused; + disable(unused); + } + ASSERT(!m_instrumentingAgents.inspectorNetworkAgent()); +} + +double InspectorNetworkAgent::timestamp() +{ + return m_environment.executionStopwatch()->elapsedTime(); +} + +void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + if (request.hiddenFromInspector()) { + m_hiddenRequestIdentifiers.add(identifier); + return; + } + + String requestId = IdentifiersFactory::requestId(identifier); + m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(&loader)); + + CachedResource* cachedResource = InspectorPageAgent::cachedResource(loader.frame(), request.url()); + InspectorPageAgent::ResourceType type = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : m_resourcesData->resourceType(requestId); + if (type == InspectorPageAgent::OtherResource) { + if (m_loadingXHRSynchronously) + type = InspectorPageAgent::XHRResource; + else if (equalIgnoringFragmentIdentifier(request.url(), loader.frameLoader()->icon().url())) + type = InspectorPageAgent::ImageResource; + else if (equalIgnoringFragmentIdentifier(request.url(), loader.url()) && !loader.isCommitted()) + type = InspectorPageAgent::DocumentResource; + } + + m_resourcesData->setResourceType(requestId, type); + + for (auto& entry : m_extraRequestHeaders) + request.setHTTPHeaderField(entry.key, entry.value); + + request.setReportLoadTiming(true); + request.setReportRawHeaders(true); + + if (m_cacheDisabled) { + request.setHTTPHeaderField(HTTPHeaderName::Pragma, "no-cache"); + request.setCachePolicy(ReloadIgnoringCacheData); + request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache"); + } + + Inspector::Protocol::Page::ResourceType resourceType = InspectorPageAgent::resourceTypeJson(type); + + RefPtr<Inspector::Protocol::Network::Initiator> initiatorObject = buildInitiatorObject(loader.frame() ? loader.frame()->document() : nullptr); + String targetId = request.initiatorIdentifier(); + + m_frontendDispatcher->requestWillBeSent(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), loader.url().string(), buildObjectForResourceRequest(request), timestamp(), initiatorObject, buildObjectForResourceResponse(redirectResponse, nullptr), type != InspectorPageAgent::OtherResource ? &resourceType : nullptr, targetId.isEmpty() ? nullptr : &targetId); +} + +void InspectorNetworkAgent::markResourceAsCached(unsigned long identifier) +{ + if (m_hiddenRequestIdentifiers.contains(identifier)) + return; + + m_frontendDispatcher->requestServedFromCache(IdentifiersFactory::requestId(identifier)); +} + +void InspectorNetworkAgent::didReceiveResponse(unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response, ResourceLoader* resourceLoader) +{ + if (m_hiddenRequestIdentifiers.contains(identifier)) + return; + + String requestId = IdentifiersFactory::requestId(identifier); + RefPtr<Inspector::Protocol::Network::Response> resourceResponse = buildObjectForResourceResponse(response, resourceLoader); + + bool isNotModified = response.httpStatusCode() == 304; + + CachedResource* cachedResource = nullptr; + if (resourceLoader && resourceLoader->isSubresourceLoader() && !isNotModified) + cachedResource = static_cast<SubresourceLoader*>(resourceLoader)->cachedResource(); + if (!cachedResource) + cachedResource = InspectorPageAgent::cachedResource(loader.frame(), response.url()); + + if (cachedResource) { + // Use mime type from cached resource in case the one in response is empty. + if (resourceResponse && response.mimeType().isEmpty()) + resourceResponse->setString(Inspector::Protocol::Network::Response::MimeType, cachedResource->response().mimeType()); + m_resourcesData->addCachedResource(requestId, cachedResource); + } + + InspectorPageAgent::ResourceType type = m_resourcesData->resourceType(requestId); + InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : type; + + // FIXME: XHRResource is returned for CachedResource::RawResource, it should be OtherResource unless it truly is an XHR. + // RawResource is used for loading worker scripts, and those should stay as ScriptResource and not change to XHRResource. + if (type != newType && newType != InspectorPageAgent::XHRResource && newType != InspectorPageAgent::OtherResource) + type = newType; + + m_resourcesData->responseReceived(requestId, m_pageAgent->frameId(loader.frame()), response); + m_resourcesData->setResourceType(requestId, type); + + m_frontendDispatcher->responseReceived(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), timestamp(), InspectorPageAgent::resourceTypeJson(type), resourceResponse); + + // If we revalidated the resource and got Not modified, send content length following didReceiveResponse + // as there will be no calls to didReceiveData from the network stack. + if (isNotModified && cachedResource && cachedResource->encodedSize()) + didReceiveData(identifier, nullptr, cachedResource->encodedSize(), 0); +} + +static bool isErrorStatusCode(int statusCode) +{ + return statusCode >= 400; +} + +void InspectorNetworkAgent::didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength) +{ + if (m_hiddenRequestIdentifiers.contains(identifier)) + return; + + String requestId = IdentifiersFactory::requestId(identifier); + + if (data) { + NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); + if (resourceData && !m_loadingXHRSynchronously && (!resourceData->cachedResource() || resourceData->cachedResource()->dataBufferingPolicy() == DoNotBufferData || isErrorStatusCode(resourceData->httpStatusCode()))) + m_resourcesData->maybeAddResourceData(requestId, data, dataLength); + } + + m_frontendDispatcher->dataReceived(requestId, timestamp(), dataLength, encodedDataLength); +} + +void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader, double finishTime) +{ + if (m_hiddenRequestIdentifiers.remove(identifier)) + return; + + String requestId = IdentifiersFactory::requestId(identifier); + if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) + m_resourcesData->addResourceSharedBuffer(requestId, loader.frameLoader()->documentLoader()->mainResourceData(), loader.frame()->document()->encoding()); + + m_resourcesData->maybeDecodeDataToContent(requestId); + + double elapsedFinishTime = finishTime ? m_environment.executionStopwatch()->elapsedTimeSince(MonotonicTime::fromRawSeconds(finishTime)) : timestamp(); + + String sourceMappingURL; + NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); + if (resourceData && resourceData->cachedResource()) + sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource()); + + m_frontendDispatcher->loadingFinished(requestId, elapsedFinishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr); +} + +void InspectorNetworkAgent::didFailLoading(unsigned long identifier, DocumentLoader& loader, const ResourceError& error) +{ + if (m_hiddenRequestIdentifiers.remove(identifier)) + return; + + String requestId = IdentifiersFactory::requestId(identifier); + + if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) { + Frame* frame = loader.frame(); + if (frame && frame->loader().documentLoader() && frame->document()) { + m_resourcesData->addResourceSharedBuffer(requestId, + frame->loader().documentLoader()->mainResourceData(), + frame->document()->encoding()); + } + } + + bool canceled = error.isCancellation(); + m_frontendDispatcher->loadingFailed(requestId, timestamp(), error.localizedDescription(), canceled ? &canceled : nullptr); +} + +void InspectorNetworkAgent::didLoadResourceFromMemoryCache(DocumentLoader& loader, CachedResource& resource) +{ + String loaderId = m_pageAgent->loaderId(&loader); + String frameId = m_pageAgent->frameId(loader.frame()); + unsigned long identifier = loader.frame()->page()->progress().createUniqueIdentifier(); + String requestId = IdentifiersFactory::requestId(identifier); + m_resourcesData->resourceCreated(requestId, loaderId); + m_resourcesData->addCachedResource(requestId, &resource); + + RefPtr<Inspector::Protocol::Network::Initiator> initiatorObject = buildInitiatorObject(loader.frame() ? loader.frame()->document() : nullptr); + + m_frontendDispatcher->requestServedFromMemoryCache(requestId, frameId, loaderId, loader.url().string(), timestamp(), initiatorObject, buildObjectForCachedResource(&resource)); +} + +void InspectorNetworkAgent::setInitialScriptContent(unsigned long identifier, const String& sourceString) +{ + m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), sourceString); +} + +void InspectorNetworkAgent::didReceiveScriptResponse(unsigned long identifier) +{ + m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::ScriptResource); +} + +void InspectorNetworkAgent::didReceiveThreadableLoaderResponse(unsigned long identifier, DocumentThreadableLoader& documentThreadableLoader) +{ + String initiator = documentThreadableLoader.options().initiator; + if (initiator == cachedResourceRequestInitiators().fetch) + m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::FetchResource); + else if (initiator == cachedResourceRequestInitiators().xmlhttprequest) + m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::XHRResource); +} + +void InspectorNetworkAgent::didFinishXHRLoading(unsigned long identifier, const String& decodedText) +{ + m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), decodedText); +} + +void InspectorNetworkAgent::willLoadXHRSynchronously() +{ + m_loadingXHRSynchronously = true; +} + +void InspectorNetworkAgent::didLoadXHRSynchronously() +{ + m_loadingXHRSynchronously = false; +} + +void InspectorNetworkAgent::willDestroyCachedResource(CachedResource& cachedResource) +{ + Vector<String> requestIds = m_resourcesData->removeCachedResource(&cachedResource); + if (!requestIds.size()) + return; + + String content; + bool base64Encoded; + if (!InspectorPageAgent::cachedResourceContent(&cachedResource, &content, &base64Encoded)) + return; + for (auto& id : requestIds) + m_resourcesData->setResourceContent(id, content, base64Encoded); +} + +void InspectorNetworkAgent::willRecalculateStyle() +{ + m_isRecalculatingStyle = true; +} + +void InspectorNetworkAgent::didRecalculateStyle() +{ + m_isRecalculatingStyle = false; + m_styleRecalculationInitiator = nullptr; +} + +void InspectorNetworkAgent::didScheduleStyleRecalculation(Document& document) +{ + if (!m_styleRecalculationInitiator) + m_styleRecalculationInitiator = buildInitiatorObject(&document); +} + +RefPtr<Inspector::Protocol::Network::Initiator> InspectorNetworkAgent::buildInitiatorObject(Document* document) +{ + Ref<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture); + if (stackTrace->size() > 0) { + auto initiatorObject = Inspector::Protocol::Network::Initiator::create() + .setType(Inspector::Protocol::Network::Initiator::Type::Script) + .release(); + initiatorObject->setStackTrace(stackTrace->buildInspectorArray()); + return WTFMove(initiatorObject); + } + + if (document && document->scriptableDocumentParser()) { + auto initiatorObject = Inspector::Protocol::Network::Initiator::create() + .setType(Inspector::Protocol::Network::Initiator::Type::Parser) + .release(); + initiatorObject->setUrl(document->url().string()); + initiatorObject->setLineNumber(document->scriptableDocumentParser()->textPosition().m_line.oneBasedInt()); + return WTFMove(initiatorObject); + } + + if (m_isRecalculatingStyle && m_styleRecalculationInitiator) + return m_styleRecalculationInitiator; + + return Inspector::Protocol::Network::Initiator::create() + .setType(Inspector::Protocol::Network::Initiator::Type::Other) + .release(); +} + +#if ENABLE(WEB_SOCKETS) + +void InspectorNetworkAgent::didCreateWebSocket(unsigned long identifier, const URL& requestURL) +{ + m_frontendDispatcher->webSocketCreated(IdentifiersFactory::requestId(identifier), requestURL.string()); +} + +void InspectorNetworkAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, const ResourceRequest& request) +{ + auto requestObject = Inspector::Protocol::Network::WebSocketRequest::create() + .setHeaders(buildObjectForHeaders(request.httpHeaderFields())) + .release(); + m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(requestObject)); +} + +void InspectorNetworkAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response) +{ + auto responseObject = Inspector::Protocol::Network::WebSocketResponse::create() + .setStatus(response.httpStatusCode()) + .setStatusText(response.httpStatusText()) + .setHeaders(buildObjectForHeaders(response.httpHeaderFields())) + .release(); + m_frontendDispatcher->webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(responseObject)); +} + +void InspectorNetworkAgent::didCloseWebSocket(unsigned long identifier) +{ + m_frontendDispatcher->webSocketClosed(IdentifiersFactory::requestId(identifier), timestamp()); +} + +void InspectorNetworkAgent::didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame) +{ + auto frameObject = Inspector::Protocol::Network::WebSocketFrame::create() + .setOpcode(frame.opCode) + .setMask(frame.masked) + .setPayloadData(String(frame.payload, frame.payloadLength)) + .release(); + m_frontendDispatcher->webSocketFrameReceived(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(frameObject)); +} + +void InspectorNetworkAgent::didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame) +{ + auto frameObject = Inspector::Protocol::Network::WebSocketFrame::create() + .setOpcode(frame.opCode) + .setMask(frame.masked) + .setPayloadData(String(frame.payload, frame.payloadLength)) + .release(); + m_frontendDispatcher->webSocketFrameSent(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(frameObject)); +} + +void InspectorNetworkAgent::didReceiveWebSocketFrameError(unsigned long identifier, const String& errorMessage) +{ + m_frontendDispatcher->webSocketFrameError(IdentifiersFactory::requestId(identifier), timestamp(), errorMessage); +} + +#endif // ENABLE(WEB_SOCKETS) + +void InspectorNetworkAgent::enable(ErrorString&) +{ + enable(); +} + +void InspectorNetworkAgent::enable() +{ + m_enabled = true; + m_instrumentingAgents.setInspectorNetworkAgent(this); +} + +void InspectorNetworkAgent::disable(ErrorString&) +{ + m_enabled = false; + m_instrumentingAgents.setInspectorNetworkAgent(nullptr); + m_resourcesData->clear(); + m_extraRequestHeaders.clear(); +} + +void InspectorNetworkAgent::setExtraHTTPHeaders(ErrorString&, const InspectorObject& headers) +{ + for (auto& entry : headers) { + String stringValue; + if (entry.value->asString(stringValue)) + m_extraRequestHeaders.set(entry.key, stringValue); + } +} + +void InspectorNetworkAgent::getResponseBody(ErrorString& errorString, const String& requestId, String* content, bool* base64Encoded) +{ + NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); + if (!resourceData) { + errorString = ASCIILiteral("No resource with given identifier found"); + return; + } + + if (resourceData->hasContent()) { + *base64Encoded = resourceData->base64Encoded(); + *content = resourceData->content(); + return; + } + + if (resourceData->isContentEvicted()) { + errorString = ASCIILiteral("Request content was evicted from inspector cache"); + return; + } + + if (resourceData->buffer() && !resourceData->textEncodingName().isNull()) { + *base64Encoded = false; + if (InspectorPageAgent::sharedBufferContent(resourceData->buffer(), resourceData->textEncodingName(), *base64Encoded, content)) + return; + } + + if (resourceData->cachedResource()) { + if (InspectorPageAgent::cachedResourceContent(resourceData->cachedResource(), content, base64Encoded)) + return; + } + + errorString = ASCIILiteral("No data found for resource with given identifier"); +} + +void InspectorNetworkAgent::setCacheDisabled(ErrorString&, bool cacheDisabled) +{ + m_cacheDisabled = cacheDisabled; + if (cacheDisabled) + MemoryCache::singleton().evictResources(); +} + +void InspectorNetworkAgent::loadResource(ErrorString& errorString, const String& frameId, const String& urlString, Ref<LoadResourceCallback>&& callback) +{ + Frame* frame = m_pageAgent->assertFrame(errorString, frameId); + if (!frame) + return; + + Document* document = frame->document(); + if (!document) { + errorString = ASCIILiteral("No Document instance for the specified frame"); + return; + } + + URL url = document->completeURL(urlString); + ResourceRequest request(url); + request.setHTTPMethod(ASCIILiteral("GET")); + request.setHiddenFromInspector(true); + + ThreadableLoaderOptions options; + options.sendLoadCallbacks = SendCallbacks; // So we remove this from m_hiddenRequestIdentifiers on completion. + options.defersLoadingPolicy = DefersLoadingPolicy::DisallowDefersLoading; // So the request is never deferred. + options.mode = FetchOptions::Mode::NoCors; + options.credentials = FetchOptions::Credentials::SameOrigin; + options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce; + + // InspectorThreadableLoaderClient deletes itself when the load completes or fails. + InspectorThreadableLoaderClient* inspectorThreadableLoaderClient = new InspectorThreadableLoaderClient(callback.copyRef()); + auto loader = DocumentThreadableLoader::create(*document, *inspectorThreadableLoaderClient, WTFMove(request), options); + if (!loader) + return; + + // If the load already completed, inspectorThreadableLoaderClient will have been deleted and we will have already called the callback. + if (!callback->isActive()) + return; + + inspectorThreadableLoaderClient->setLoader(WTFMove(loader)); +} + +static Ref<Inspector::Protocol::Page::SearchResult> buildObjectForSearchResult(const String& requestId, const String& frameId, const String& url, int matchesCount) +{ + auto searchResult = Inspector::Protocol::Page::SearchResult::create() + .setUrl(url) + .setFrameId(frameId) + .setMatchesCount(matchesCount) + .release(); + searchResult->setRequestId(requestId); + return searchResult; +} + +void InspectorNetworkAgent::searchOtherRequests(const JSC::Yarr::RegularExpression& regex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>>& result) +{ + Vector<NetworkResourcesData::ResourceData*> resources = m_resourcesData->resources(); + for (auto* resourceData : resources) { + if (resourceData->hasContent()) { + int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, resourceData->content()); + if (matchesCount) + result->addItem(buildObjectForSearchResult(resourceData->requestId(), resourceData->frameId(), resourceData->url(), matchesCount)); + } + } +} + +void InspectorNetworkAgent::searchInRequest(ErrorString& errorString, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>& results) +{ + NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); + if (!resourceData) { + errorString = ASCIILiteral("No resource with given identifier found"); + return; + } + + if (!resourceData->hasContent()) { + errorString = ASCIILiteral("No resource content"); + return; + } + + results = ContentSearchUtilities::searchInTextByLines(resourceData->content(), query, caseSensitive, isRegex); +} + +void InspectorNetworkAgent::mainFrameNavigated(DocumentLoader& loader) +{ + if (m_cacheDisabled) + MemoryCache::singleton().evictResources(); + + m_resourcesData->clear(m_pageAgent->loaderId(&loader)); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorNetworkAgent.h b/Source/WebCore/inspector/InspectorNetworkAgent.h new file mode 100644 index 000000000..a07e0dc3f --- /dev/null +++ b/Source/WebCore/inspector/InspectorNetworkAgent.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "InspectorWebAgentBase.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <wtf/HashSet.h> +#include <wtf/text/WTFString.h> +#include <yarr/RegularExpression.h> + +namespace Inspector { +class InspectorObject; +} + +namespace WebCore { + +class CachedResource; +class Document; +class DocumentLoader; +class DocumentThreadableLoader; +class InspectorPageAgent; +class NetworkLoadTiming; +class NetworkResourcesData; +class ResourceError; +class ResourceLoader; +class ResourceRequest; +class ResourceResponse; +class URL; + +#if ENABLE(WEB_SOCKETS) +struct WebSocketFrame; +#endif + +typedef String ErrorString; + +class InspectorNetworkAgent final : public InspectorAgentBase, public Inspector::NetworkBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; +public: + InspectorNetworkAgent(WebAgentContext&, InspectorPageAgent*); + virtual ~InspectorNetworkAgent(); + + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; + + // InspectorInstrumentation + void willRecalculateStyle(); + void didRecalculateStyle(); + void willSendRequest(unsigned long identifier, DocumentLoader&, ResourceRequest&, const ResourceResponse& redirectResponse); + void markResourceAsCached(unsigned long identifier); + void didReceiveResponse(unsigned long identifier, DocumentLoader&, const ResourceResponse&, ResourceLoader*); + void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength); + void didFinishLoading(unsigned long identifier, DocumentLoader&, double finishTime); + void didFailLoading(unsigned long identifier, DocumentLoader&, const ResourceError&); + void didLoadResourceFromMemoryCache(DocumentLoader&, CachedResource&); + void didReceiveThreadableLoaderResponse(unsigned long identifier, DocumentThreadableLoader&); + void didFinishXHRLoading(unsigned long identifier, const String& decodedText); + void willLoadXHRSynchronously(); + void didLoadXHRSynchronously(); + void didReceiveScriptResponse(unsigned long identifier); + void willDestroyCachedResource(CachedResource&); +#if ENABLE(WEB_SOCKETS) + void didCreateWebSocket(unsigned long identifier, const URL& requestURL); + void willSendWebSocketHandshakeRequest(unsigned long identifier, const ResourceRequest&); + void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse&); + void didCloseWebSocket(unsigned long identifier); + void didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame&); + void didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame&); + void didReceiveWebSocketFrameError(unsigned long identifier, const String&); +#endif + void mainFrameNavigated(DocumentLoader&); + void setInitialScriptContent(unsigned long identifier, const String& sourceString); + void didScheduleStyleRecalculation(Document&); + + void searchOtherRequests(const JSC::Yarr::RegularExpression&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>>&); + void searchInRequest(ErrorString&, const String& requestId, const String& query, bool caseSensitive, bool isRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>&); + + RefPtr<Inspector::Protocol::Network::Initiator> buildInitiatorObject(Document*); + + // Called from frontend. + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void setExtraHTTPHeaders(ErrorString&, const Inspector::InspectorObject& headers) override; + void getResponseBody(ErrorString&, const String& requestId, String* content, bool* base64Encoded) override; + void setCacheDisabled(ErrorString&, bool cacheDisabled) override; + void loadResource(ErrorString&, const String& frameId, const String& url, Ref<LoadResourceCallback>&&) override; + +private: + void enable(); + + Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadTiming&, ResourceLoader&); + RefPtr<Inspector::Protocol::Network::Response> buildObjectForResourceResponse(const ResourceResponse&, ResourceLoader*); + Ref<Inspector::Protocol::Network::CachedResource> buildObjectForCachedResource(CachedResource*); + + double timestamp(); + + std::unique_ptr<Inspector::NetworkFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::NetworkBackendDispatcher> m_backendDispatcher; + InspectorPageAgent* m_pageAgent { nullptr }; + + // FIXME: InspectorNetworkAgent should not be aware of style recalculation. + RefPtr<Inspector::Protocol::Network::Initiator> m_styleRecalculationInitiator; + bool m_isRecalculatingStyle { false }; + + std::unique_ptr<NetworkResourcesData> m_resourcesData; + bool m_enabled { false }; + bool m_cacheDisabled { false }; + bool m_loadingXHRSynchronously { false }; + HashMap<String, String> m_extraRequestHeaders; + HashSet<unsigned long> m_hiddenRequestIdentifiers; +}; + +} // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorNodeFinder.cpp b/Source/WebCore/inspector/InspectorNodeFinder.cpp index 34bea3723..59583a902 100644 --- a/Source/WebCore/inspector/InspectorNodeFinder.cpp +++ b/Source/WebCore/inspector/InspectorNodeFinder.cpp @@ -13,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -33,17 +33,17 @@ #include "InspectorNodeFinder.h" #include "Attr.h" -#include "Attribute.h" #include "Document.h" #include "Element.h" #include "HTMLFrameOwnerElement.h" #include "NodeList.h" #include "NodeTraversal.h" +#include "XPathNSResolver.h" #include "XPathResult.h" namespace WebCore { -static String stripCharacters(String string, const char startCharacter, const char endCharacter, bool& startCharFound, bool& endCharFound) +static String stripCharacters(const String& string, const char startCharacter, const char endCharacter, bool& startCharFound, bool& endCharFound) { startCharFound = string.startsWith(startCharacter); endCharFound = string.endsWith(endCharacter); @@ -53,7 +53,7 @@ static String stripCharacters(String string, const char startCharacter, const ch return string.substring(start, end - start); } -InspectorNodeFinder::InspectorNodeFinder(String whitespaceTrimmedQuery) +InspectorNodeFinder::InspectorNodeFinder(const String& whitespaceTrimmedQuery) : m_whitespaceTrimmedQuery(whitespaceTrimmedQuery) { m_tagNameQuery = stripCharacters(whitespaceTrimmedQuery, '<', '>', m_startTagFound, m_endTagFound); @@ -65,38 +65,33 @@ InspectorNodeFinder::InspectorNodeFinder(String whitespaceTrimmedQuery) void InspectorNodeFinder::performSearch(Node* parentNode) { - searchUsingXPath(parentNode); - searchUsingCSSSelectors(parentNode); + if (!parentNode) + return; + + searchUsingXPath(*parentNode); + searchUsingCSSSelectors(*parentNode); // Keep the DOM tree traversal last. This way iframe content will come after their parents. - searchUsingDOMTreeTraversal(parentNode); + searchUsingDOMTreeTraversal(*parentNode); } -void InspectorNodeFinder::searchUsingDOMTreeTraversal(Node* parentNode) +void InspectorNodeFinder::searchUsingDOMTreeTraversal(Node& parentNode) { // Manual plain text search. - for (auto node = parentNode; node; node = NodeTraversal::next(node, parentNode)) { + for (auto* node = &parentNode; node; node = NodeTraversal::next(*node, &parentNode)) { switch (node->nodeType()) { case Node::TEXT_NODE: case Node::COMMENT_NODE: - case Node::CDATA_SECTION_NODE: { - if (node->nodeValue().findIgnoringCase(m_whitespaceTrimmedQuery) != notFound) + case Node::CDATA_SECTION_NODE: + if (node->nodeValue().containsIgnoringASCIICase(m_whitespaceTrimmedQuery)) m_results.add(node); break; - } - case Node::ELEMENT_NODE: { - if (matchesElement(*toElement(node))) + case Node::ELEMENT_NODE: + if (matchesElement(downcast<Element>(*node))) m_results.add(node); - - // Search inside frame elements. - if (node->isFrameOwnerElement()) { - HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node); - if (Document* document = frameOwner->contentDocument()) - performSearch(document); - } - + if (is<HTMLFrameOwnerElement>(downcast<Element>(*node))) + performSearch(downcast<HTMLFrameOwnerElement>(*node).contentDocument()); break; - } default: break; } @@ -105,16 +100,16 @@ void InspectorNodeFinder::searchUsingDOMTreeTraversal(Node* parentNode) bool InspectorNodeFinder::matchesAttribute(const Attribute& attribute) { - if (attribute.localName().find(m_whitespaceTrimmedQuery) != notFound) + if (attribute.localName().string().containsIgnoringASCIICase(m_whitespaceTrimmedQuery)) return true; - return m_exactAttributeMatch ? attribute.value() == m_attributeQuery : attribute.value().find(m_attributeQuery) != notFound; + return m_exactAttributeMatch ? attribute.value() == m_attributeQuery : attribute.value().string().containsIgnoringASCIICase(m_attributeQuery); } bool InspectorNodeFinder::matchesElement(const Element& element) { String nodeName = element.nodeName(); - if ((!m_startTagFound && !m_endTagFound && (nodeName.findIgnoringCase(m_tagNameQuery) != notFound)) - || (m_startTagFound && m_endTagFound && equalIgnoringCase(nodeName, m_tagNameQuery)) + if ((!m_startTagFound && !m_endTagFound && nodeName.containsIgnoringASCIICase(m_tagNameQuery)) + || (m_startTagFound && m_endTagFound && equalIgnoringASCIICase(nodeName, m_tagNameQuery)) || (m_startTagFound && !m_endTagFound && nodeName.startsWith(m_tagNameQuery, false)) || (!m_startTagFound && m_endTagFound && nodeName.endsWith(m_tagNameQuery, false))) return true; @@ -130,41 +125,43 @@ bool InspectorNodeFinder::matchesElement(const Element& element) return false; } -void InspectorNodeFinder::searchUsingXPath(Node* parentNode) +void InspectorNodeFinder::searchUsingXPath(Node& parentNode) { - ExceptionCode ec = 0; - RefPtr<XPathResult> result = parentNode->document().evaluate(m_whitespaceTrimmedQuery, parentNode, nullptr, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr, ec); - if (ec || !result) + auto evaluateResult = parentNode.document().evaluate(m_whitespaceTrimmedQuery, &parentNode, nullptr, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr); + if (evaluateResult.hasException()) return; + auto result = evaluateResult.releaseReturnValue(); - unsigned long size = result->snapshotLength(ec); - if (ec) + auto snapshotLengthResult = result->snapshotLength(); + if (snapshotLengthResult.hasException()) return; + unsigned size = snapshotLengthResult.releaseReturnValue(); - for (unsigned long i = 0; i < size; ++i) { - Node* node = result->snapshotItem(i, ec); - if (ec) + for (unsigned i = 0; i < size; ++i) { + auto snapshotItemResult = result->snapshotItem(i); + if (snapshotItemResult.hasException()) return; + Node* node = snapshotItemResult.releaseReturnValue(); - if (node->isAttributeNode()) - node = toAttr(node)->ownerElement(); + if (is<Attr>(*node)) + node = downcast<Attr>(*node).ownerElement(); // XPath can get out of the context node that we pass as the starting point to evaluate, so we need to filter for just the nodes we care about. - if (node == parentNode || node->isDescendantOf(parentNode)) + if (parentNode.contains(node)) m_results.add(node); } } -void InspectorNodeFinder::searchUsingCSSSelectors(Node* parentNode) +void InspectorNodeFinder::searchUsingCSSSelectors(Node& parentNode) { - if (!parentNode->isContainerNode()) + if (!is<ContainerNode>(parentNode)) return; - ExceptionCode ec = 0; - RefPtr<NodeList> nodeList = toContainerNode(parentNode)->querySelectorAll(m_whitespaceTrimmedQuery, ec); - if (ec || !nodeList) + auto queryResult = downcast<ContainerNode>(parentNode).querySelectorAll(m_whitespaceTrimmedQuery); + if (queryResult.hasException()) return; + auto nodeList = queryResult.releaseReturnValue(); unsigned size = nodeList->length(); for (unsigned i = 0; i < size; ++i) m_results.add(nodeList->item(i)); diff --git a/Source/WebCore/inspector/InspectorNodeFinder.h b/Source/WebCore/inspector/InspectorNodeFinder.h index 941253f71..5d55dd371 100644 --- a/Source/WebCore/inspector/InspectorNodeFinder.h +++ b/Source/WebCore/inspector/InspectorNodeFinder.h @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -28,8 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorNodeFinder_h -#define InspectorNodeFinder_h +#pragma once #include <wtf/ListHashSet.h> #include <wtf/text/WTFString.h> @@ -42,7 +41,7 @@ class Node; class InspectorNodeFinder { public: - InspectorNodeFinder(String whitespaceTrimmedQuery); + InspectorNodeFinder(const String& whitespaceTrimmedQuery); void performSearch(Node*); const ListHashSet<Node*>& results() const { return m_results; } @@ -50,9 +49,9 @@ private: bool matchesAttribute(const Attribute&); bool matchesElement(const Element&); - void searchUsingDOMTreeTraversal(Node*); - void searchUsingXPath(Node*); - void searchUsingCSSSelectors(Node*); + void searchUsingDOMTreeTraversal(Node&); + void searchUsingXPath(Node&); + void searchUsingCSSSelectors(Node&); bool m_startTagFound; bool m_endTagFound; @@ -66,5 +65,3 @@ private: }; } // namespace WebCore - -#endif // InspectorNodeFinder_h diff --git a/Source/WebCore/inspector/InspectorOverlay.cpp b/Source/WebCore/inspector/InspectorOverlay.cpp index f334f456d..a873c174d 100644 --- a/Source/WebCore/inspector/InspectorOverlay.cpp +++ b/Source/WebCore/inspector/InspectorOverlay.cpp @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,22 +27,23 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorOverlay.h" #include "DocumentLoader.h" +#include "EditorClient.h" #include "Element.h" #include "EmptyClients.h" #include "FrameView.h" #include "GraphicsContext.h" #include "InspectorClient.h" #include "InspectorOverlayPage.h" +#include "LibWebRTCProvider.h" #include "MainFrame.h" #include "Node.h" #include "Page.h" +#include "PageConfiguration.h" #include "PolygonShape.h" +#include "PseudoElement.h" #include "RectangleShape.h" #include "RenderBoxModelObject.h" #include "RenderElement.h" @@ -55,120 +56,86 @@ #include "ScriptController.h" #include "ScriptSourceCode.h" #include "Settings.h" +#include "SocketProvider.h" #include "StyledElement.h" -#include <bindings/ScriptValue.h> +#include <inspector/InspectorProtocolObjects.h> #include <inspector/InspectorValues.h> -#include <wtf/text/StringBuilder.h> using namespace Inspector; namespace WebCore { -namespace { - -Path quadToPath(const FloatQuad& quad) -{ - Path quadPath; - quadPath.moveTo(quad.p1()); - quadPath.addLineTo(quad.p2()); - quadPath.addLineTo(quad.p3()); - quadPath.addLineTo(quad.p4()); - quadPath.closeSubpath(); - return quadPath; -} - -void drawOutlinedQuad(GraphicsContext* context, const FloatQuad& quad, const Color& fillColor, const Color& outlineColor) +static void contentsQuadToCoordinateSystem(const FrameView* mainView, const FrameView* view, FloatQuad& quad, InspectorOverlay::CoordinateSystem coordinateSystem) { - static const int outlineThickness = 2; - - Path quadPath = quadToPath(quad); - - // Clip out the quad, then draw with a 2px stroke to get a pixel - // of outline (because inflating a quad is hard) - { - context->save(); - context->clipOut(quadPath); - - context->setStrokeThickness(outlineThickness); - context->setStrokeColor(outlineColor, ColorSpaceDeviceRGB); - context->strokePath(quadPath); - - context->restore(); - } + quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1()))); + quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2()))); + quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3()))); + quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4()))); - // Now do the fill - context->setFillColor(fillColor, ColorSpaceDeviceRGB); - context->fillPath(quadPath); + if (coordinateSystem == InspectorOverlay::CoordinateSystem::View) + quad += toIntSize(mainView->scrollPosition()); } static void contentsQuadToPage(const FrameView* mainView, const FrameView* view, FloatQuad& quad) { - quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1()))); - quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2()))); - quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3()))); - quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4()))); - quad += mainView->scrollOffset(); + contentsQuadToCoordinateSystem(mainView, view, quad, InspectorOverlay::CoordinateSystem::View); } -static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight* highlight) +static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem) { Frame* containingFrame = renderer->document().frame(); if (!containingFrame) return; - highlight->setDataFromConfig(highlightConfig); + highlight.setDataFromConfig(highlightConfig); FrameView* containingView = containingFrame->view(); FrameView* mainView = containingFrame->page()->mainFrame().view(); // RenderSVGRoot should be highlighted through the isBox() code path, all other SVG elements should just dump their absoluteQuads(). -#if ENABLE(SVG) bool isSVGRenderer = renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGRoot(); -#else - bool isSVGRenderer = false; -#endif if (isSVGRenderer) { - highlight->type = HighlightTypeRects; - renderer->absoluteQuads(highlight->quads); - for (size_t i = 0; i < highlight->quads.size(); ++i) - contentsQuadToPage(mainView, containingView, highlight->quads[i]); - } else if (renderer->isBox() || renderer->isRenderInline()) { + highlight.type = HighlightType::Rects; + renderer->absoluteQuads(highlight.quads); + for (auto& quad : highlight.quads) + contentsQuadToCoordinateSystem(mainView, containingView, quad, coordinateSystem); + } else if (is<RenderBox>(*renderer) || is<RenderInline>(*renderer)) { LayoutRect contentBox; LayoutRect paddingBox; LayoutRect borderBox; LayoutRect marginBox; - if (renderer->isBox()) { - RenderBox* renderBox = toRenderBox(renderer); + if (is<RenderBox>(*renderer)) { + auto& renderBox = downcast<RenderBox>(*renderer); - LayoutBoxExtent margins(renderBox->marginTop(), renderBox->marginRight(), renderBox->marginBottom(), renderBox->marginLeft()); + LayoutBoxExtent margins(renderBox.marginTop(), renderBox.marginRight(), renderBox.marginBottom(), renderBox.marginLeft()); - if (!renderBox->isOutOfFlowPositioned() && region) { + if (!renderBox.isOutOfFlowPositioned() && region) { RenderBox::LogicalExtentComputedValues computedValues; - renderBox->computeLogicalWidthInRegion(computedValues, region); - margins.mutableLogicalLeft(renderBox->style().writingMode()) = computedValues.m_margins.m_start; - margins.mutableLogicalRight(renderBox->style().writingMode()) = computedValues.m_margins.m_end; + renderBox.computeLogicalWidthInRegion(computedValues, region); + margins.start(renderBox.style().writingMode()) = computedValues.m_margins.m_start; + margins.end(renderBox.style().writingMode()) = computedValues.m_margins.m_end; } - paddingBox = renderBox->clientBoxRectInRegion(region); - contentBox = LayoutRect(paddingBox.x() + renderBox->paddingLeft(), paddingBox.y() + renderBox->paddingTop(), - paddingBox.width() - renderBox->paddingLeft() - renderBox->paddingRight(), paddingBox.height() - renderBox->paddingTop() - renderBox->paddingBottom()); - borderBox = LayoutRect(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(), - paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom()); + paddingBox = renderBox.clientBoxRectInRegion(region); + contentBox = LayoutRect(paddingBox.x() + renderBox.paddingLeft(), paddingBox.y() + renderBox.paddingTop(), + paddingBox.width() - renderBox.paddingLeft() - renderBox.paddingRight(), paddingBox.height() - renderBox.paddingTop() - renderBox.paddingBottom()); + borderBox = LayoutRect(paddingBox.x() - renderBox.borderLeft(), paddingBox.y() - renderBox.borderTop(), + paddingBox.width() + renderBox.borderLeft() + renderBox.borderRight(), paddingBox.height() + renderBox.borderTop() + renderBox.borderBottom()); marginBox = LayoutRect(borderBox.x() - margins.left(), borderBox.y() - margins.top(), borderBox.width() + margins.left() + margins.right(), borderBox.height() + margins.top() + margins.bottom()); } else { - RenderInline* renderInline = toRenderInline(renderer); + auto& renderInline = downcast<RenderInline>(*renderer); // RenderInline's bounding box includes paddings and borders, excludes margins. - borderBox = renderInline->linesBoundingBox(); - paddingBox = LayoutRect(borderBox.x() + renderInline->borderLeft(), borderBox.y() + renderInline->borderTop(), - borderBox.width() - renderInline->borderLeft() - renderInline->borderRight(), borderBox.height() - renderInline->borderTop() - renderInline->borderBottom()); - contentBox = LayoutRect(paddingBox.x() + renderInline->paddingLeft(), paddingBox.y() + renderInline->paddingTop(), - paddingBox.width() - renderInline->paddingLeft() - renderInline->paddingRight(), paddingBox.height() - renderInline->paddingTop() - renderInline->paddingBottom()); + borderBox = renderInline.linesBoundingBox(); + paddingBox = LayoutRect(borderBox.x() + renderInline.borderLeft(), borderBox.y() + renderInline.borderTop(), + borderBox.width() - renderInline.borderLeft() - renderInline.borderRight(), borderBox.height() - renderInline.borderTop() - renderInline.borderBottom()); + contentBox = LayoutRect(paddingBox.x() + renderInline.paddingLeft(), paddingBox.y() + renderInline.paddingTop(), + paddingBox.width() - renderInline.paddingLeft() - renderInline.paddingRight(), paddingBox.height() - renderInline.paddingTop() - renderInline.paddingBottom()); // Ignore marginTop and marginBottom for inlines. - marginBox = LayoutRect(borderBox.x() - renderInline->marginLeft(), borderBox.y(), - borderBox.width() + renderInline->marginWidth(), borderBox.height()); + marginBox = LayoutRect(borderBox.x() - renderInline.marginLeft(), borderBox.y(), + borderBox.width() + renderInline.horizontalMarginExtent(), borderBox.height()); } FloatQuad absContentQuad; @@ -207,39 +174,39 @@ static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox)); } - contentsQuadToPage(mainView, containingView, absContentQuad); - contentsQuadToPage(mainView, containingView, absPaddingQuad); - contentsQuadToPage(mainView, containingView, absBorderQuad); - contentsQuadToPage(mainView, containingView, absMarginQuad); + contentsQuadToCoordinateSystem(mainView, containingView, absContentQuad, coordinateSystem); + contentsQuadToCoordinateSystem(mainView, containingView, absPaddingQuad, coordinateSystem); + contentsQuadToCoordinateSystem(mainView, containingView, absBorderQuad, coordinateSystem); + contentsQuadToCoordinateSystem(mainView, containingView, absMarginQuad, coordinateSystem); - highlight->type = HighlightTypeNode; - highlight->quads.append(absMarginQuad); - highlight->quads.append(absBorderQuad); - highlight->quads.append(absPaddingQuad); - highlight->quads.append(absContentQuad); + highlight.type = HighlightType::Node; + highlight.quads.append(absMarginQuad); + highlight.quads.append(absBorderQuad); + highlight.quads.append(absPaddingQuad); + highlight.quads.append(absContentQuad); } } -static void buildNodeHighlight(Node* node, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight* highlight) +static void buildNodeHighlight(Node& node, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem) { - RenderObject* renderer = node->renderer(); + RenderObject* renderer = node.renderer(); if (!renderer) return; - buildRendererHighlight(renderer, region, highlightConfig, highlight); + + buildRendererHighlight(renderer, region, highlightConfig, highlight, coordinateSystem); } -static void buildQuadHighlight(const FloatQuad& quad, const HighlightConfig& highlightConfig, Highlight *highlight) +static void buildQuadHighlight(const FloatQuad& quad, const HighlightConfig& highlightConfig, Highlight& highlight) { - highlight->setDataFromConfig(highlightConfig); - highlight->type = HighlightTypeRects; - highlight->quads.append(quad); + highlight.setDataFromConfig(highlightConfig); + highlight.type = HighlightType::Rects; + highlight.quads.append(quad); } -} // anonymous namespace - InspectorOverlay::InspectorOverlay(Page& page, InspectorClient* client) : m_page(page) , m_client(client) + , m_paintRectUpdateTimer(*this, &InspectorOverlay::updatePaintRectsTimerFired) { } @@ -249,29 +216,33 @@ InspectorOverlay::~InspectorOverlay() void InspectorOverlay::paint(GraphicsContext& context) { - if (m_pausedInDebuggerMessage.isNull() && !m_highlightNode && !m_highlightQuad && m_size.isEmpty()) + if (!shouldShowOverlay()) return; + GraphicsContextStateSaver stateSaver(context); FrameView* view = overlayPage()->mainFrame().view(); view->updateLayoutAndStyleIfNeededRecursive(); - view->paint(&context, IntRect(0, 0, view->width(), view->height())); + view->paint(context, IntRect(0, 0, view->width(), view->height())); } -void InspectorOverlay::drawOutline(GraphicsContext* context, const LayoutRect& rect, const Color& color) +void InspectorOverlay::getHighlight(Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem) const { - FloatRect outlineRect = rect; - drawOutlinedQuad(context, outlineRect, Color(), color); -} - -void InspectorOverlay::getHighlight(Highlight* highlight) const -{ - if (!m_highlightNode && !m_highlightQuad) + if (!m_highlightNode && !m_highlightQuad && !m_highlightNodeList) return; - highlight->type = HighlightTypeRects; + highlight.type = HighlightType::Rects; if (m_highlightNode) - buildNodeHighlight(m_highlightNode.get(), nullptr, m_nodeHighlightConfig, highlight); - else + buildNodeHighlight(*m_highlightNode, nullptr, m_nodeHighlightConfig, highlight, coordinateSystem); + else if (m_highlightNodeList) { + highlight.setDataFromConfig(m_nodeHighlightConfig); + for (unsigned i = 0; i < m_highlightNodeList->length(); ++i) { + Highlight nodeHighlight; + buildNodeHighlight(*(m_highlightNodeList->item(i)), nullptr, m_nodeHighlightConfig, nodeHighlight, coordinateSystem); + if (nodeHighlight.type == HighlightType::Node) + highlight.quads.appendVector(nodeHighlight.quads); + } + highlight.type = HighlightType::NodeList; + } else buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, highlight); } @@ -283,8 +254,17 @@ void InspectorOverlay::setPausedInDebuggerMessage(const String* message) void InspectorOverlay::hideHighlight() { - m_highlightNode.clear(); - m_highlightQuad.clear(); + m_highlightNode = nullptr; + m_highlightNodeList = nullptr; + m_highlightQuad = nullptr; + update(); +} + +void InspectorOverlay::highlightNodeList(RefPtr<NodeList>&& nodes, const HighlightConfig& highlightConfig) +{ + m_nodeHighlightConfig = highlightConfig; + m_highlightNodeList = WTFMove(nodes); + m_highlightNode = nullptr; update(); } @@ -292,16 +272,17 @@ void InspectorOverlay::highlightNode(Node* node, const HighlightConfig& highligh { m_nodeHighlightConfig = highlightConfig; m_highlightNode = node; + m_highlightNodeList = nullptr; update(); } -void InspectorOverlay::highlightQuad(PassOwnPtr<FloatQuad> quad, const HighlightConfig& highlightConfig) +void InspectorOverlay::highlightQuad(std::unique_ptr<FloatQuad> quad, const HighlightConfig& highlightConfig) { - if (m_quadHighlightConfig.usePageCoordinates) - *quad -= m_page.mainFrame().view()->scrollOffset(); + if (highlightConfig.usePageCoordinates) + *quad -= toIntSize(m_page.mainFrame().view()->scrollPosition()); m_quadHighlightConfig = highlightConfig; - m_highlightQuad = quad; + m_highlightQuad = WTFMove(quad); update(); } @@ -315,9 +296,26 @@ void InspectorOverlay::didSetSearchingForNode(bool enabled) m_client->didSetSearchingForNode(enabled); } +void InspectorOverlay::setIndicating(bool indicating) +{ + m_indicating = indicating; + + if (m_indicating) + evaluateInOverlay(ASCIILiteral("showPageIndication")); + else + evaluateInOverlay(ASCIILiteral("hidePageIndication")); + + update(); +} + +bool InspectorOverlay::shouldShowOverlay() const +{ + return m_highlightNode || m_highlightNodeList || m_highlightQuad || m_indicating || m_showingPaintRects || !m_pausedInDebuggerMessage.isNull(); +} + void InspectorOverlay::update() { - if (!m_highlightNode && !m_highlightQuad && m_pausedInDebuggerMessage.isNull() && m_size.isEmpty()) { + if (!shouldShowOverlay()) { m_client->hideHighlight(); return; } @@ -327,80 +325,88 @@ void InspectorOverlay::update() return; FrameView* overlayView = overlayPage()->mainFrame().view(); - IntSize viewportSize = view->visibleContentRect().size(); - IntSize frameViewFullSize = view->visibleContentRectIncludingScrollbars().size(); - IntSize size = m_size.isEmpty() ? frameViewFullSize : m_size; - overlayPage()->setPageScaleFactor(m_page.pageScaleFactor(), IntPoint()); - size.scale(m_page.pageScaleFactor()); - overlayView->resize(size); + IntSize viewportSize = view->sizeForVisibleContent(); + IntSize frameViewFullSize = view->sizeForVisibleContent(ScrollableArea::IncludeScrollbars); + overlayView->resize(frameViewFullSize); // Clear canvas and paint things. - reset(viewportSize, m_size.isEmpty() ? IntSize() : frameViewFullSize); + // FIXME: Remove extra parameter? + reset(viewportSize, IntSize()); // Include scrollbars to avoid masking them by the gutter. drawGutter(); drawNodeHighlight(); drawQuadHighlight(); drawPausedInDebuggerMessage(); + drawPaintRects(); // Position DOM elements. overlayPage()->mainFrame().document()->recalcStyle(Style::Force); if (overlayView->needsLayout()) overlayView->layout(); - // Kick paint. - m_client->highlight(); + forcePaint(); } -static PassRefPtr<InspectorObject> buildObjectForPoint(const FloatPoint& point) +static Ref<Inspector::Protocol::OverlayTypes::Point> buildObjectForPoint(const FloatPoint& point) { - RefPtr<InspectorObject> object = InspectorObject::create(); - object->setNumber("x", point.x()); - object->setNumber("y", point.y()); - return object.release(); + return Inspector::Protocol::OverlayTypes::Point::create() + .setX(point.x()) + .setY(point.y()) + .release(); } -static PassRefPtr<InspectorArray> buildArrayForQuad(const FloatQuad& quad) +static Ref<Inspector::Protocol::OverlayTypes::Rect> buildObjectForRect(const FloatRect& rect) { - RefPtr<InspectorArray> array = InspectorArray::create(); - array->pushObject(buildObjectForPoint(quad.p1())); - array->pushObject(buildObjectForPoint(quad.p2())); - array->pushObject(buildObjectForPoint(quad.p3())); - array->pushObject(buildObjectForPoint(quad.p4())); - return array.release(); + return Inspector::Protocol::OverlayTypes::Rect::create() + .setX(rect.x()) + .setY(rect.y()) + .setWidth(rect.width()) + .setHeight(rect.height()) + .release(); } -static PassRefPtr<InspectorObject> buildObjectForHighlight(const Highlight& highlight) +static Ref<Inspector::Protocol::OverlayTypes::Quad> buildArrayForQuad(const FloatQuad& quad) { - RefPtr<InspectorObject> object = InspectorObject::create(); - RefPtr<InspectorArray> array = InspectorArray::create(); - for (size_t i = 0; i < highlight.quads.size(); ++i) - array->pushArray(buildArrayForQuad(highlight.quads[i])); - object->setArray("quads", array.release()); - object->setBoolean("showRulers", highlight.showRulers); - object->setString("contentColor", highlight.contentColor.serialized()); - object->setString("contentOutlineColor", highlight.contentOutlineColor.serialized()); - object->setString("paddingColor", highlight.paddingColor.serialized()); - object->setString("borderColor", highlight.borderColor.serialized()); - object->setString("marginColor", highlight.marginColor.serialized()); - return object.release(); + auto array = Inspector::Protocol::OverlayTypes::Quad::create(); + array->addItem(buildObjectForPoint(quad.p1())); + array->addItem(buildObjectForPoint(quad.p2())); + array->addItem(buildObjectForPoint(quad.p3())); + array->addItem(buildObjectForPoint(quad.p4())); + return array; } -static PassRefPtr<InspectorObject> buildObjectForRegionHighlight(FrameView* mainView, RenderRegion* region) +static Ref<Inspector::Protocol::OverlayTypes::FragmentHighlightData> buildObjectForHighlight(const Highlight& highlight) +{ + auto arrayOfQuads = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Quad>::create(); + for (auto& quad : highlight.quads) + arrayOfQuads->addItem(buildArrayForQuad(quad)); + + return Inspector::Protocol::OverlayTypes::FragmentHighlightData::create() + .setQuads(WTFMove(arrayOfQuads)) + .setContentColor(highlight.contentColor.serialized()) + .setContentOutlineColor(highlight.contentOutlineColor.serialized()) + .setPaddingColor(highlight.paddingColor.serialized()) + .setBorderColor(highlight.borderColor.serialized()) + .setMarginColor(highlight.marginColor.serialized()) + .release(); +} + +static RefPtr<Inspector::Protocol::OverlayTypes::Region> buildObjectForRegion(FrameView* mainView, RenderRegion* region) { FrameView* containingView = region->frame().view(); if (!containingView) return nullptr; - RenderBlockFlow* regionContainer = toRenderBlockFlow(region->parent()); - LayoutRect borderBox = regionContainer->borderBoxRect(); - borderBox.setWidth(borderBox.width() + regionContainer->verticalScrollbarWidth()); - borderBox.setHeight(borderBox.height() + regionContainer->horizontalScrollbarHeight()); + RenderBlockFlow& regionContainer = downcast<RenderBlockFlow>(*region->parent()); + LayoutRect borderBox = regionContainer.borderBoxRect(); + borderBox.setWidth(borderBox.width() + regionContainer.verticalScrollbarWidth()); + borderBox.setHeight(borderBox.height() + regionContainer.horizontalScrollbarHeight()); // Create incoming and outgoing boxes that we use to chain the regions toghether. const LayoutSize linkBoxSize(10, 10); const LayoutSize linkBoxMidpoint(linkBoxSize.width() / 2, linkBoxSize.height() / 2); - + LayoutRect incomingRectBox = LayoutRect(borderBox.location() - linkBoxMidpoint, linkBoxSize); LayoutRect outgoingRectBox = LayoutRect(borderBox.location() - linkBoxMidpoint + borderBox.size(), linkBoxSize); @@ -410,55 +416,53 @@ static PassRefPtr<InspectorObject> buildObjectForRegionHighlight(FrameView* main incomingRectBox.move(0, linkBoxVerticalOffset); outgoingRectBox.move(0, -linkBoxVerticalOffset); - FloatQuad borderRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(borderBox)); - FloatQuad incomingRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(incomingRectBox)); - FloatQuad outgoingRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(outgoingRectBox)); + FloatQuad borderRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(borderBox)); + FloatQuad incomingRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(incomingRectBox)); + FloatQuad outgoingRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(outgoingRectBox)); contentsQuadToPage(mainView, containingView, borderRectQuad); contentsQuadToPage(mainView, containingView, incomingRectQuad); contentsQuadToPage(mainView, containingView, outgoingRectQuad); - RefPtr<InspectorObject> regionObject = InspectorObject::create(); - - regionObject->setArray("borderQuad", buildArrayForQuad(borderRectQuad)); - regionObject->setArray("incomingQuad", buildArrayForQuad(incomingRectQuad)); - regionObject->setArray("outgoingQuad", buildArrayForQuad(outgoingRectQuad)); - - return regionObject.release(); + return Inspector::Protocol::OverlayTypes::Region::create() + .setBorderQuad(buildArrayForQuad(borderRectQuad)) + .setIncomingQuad(buildArrayForQuad(incomingRectQuad)) + .setOutgoingQuad(buildArrayForQuad(outgoingRectQuad)) + .release(); } -static PassRefPtr<InspectorArray> buildObjectForCSSRegionsHighlight(RenderRegion* region, RenderFlowThread* flowThread) +static Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Region>> buildObjectForFlowRegions(RenderRegion* region, RenderFlowThread* flowThread) { FrameView* mainFrameView = region->document().page()->mainFrame().view(); - RefPtr<InspectorArray> array = InspectorArray::create(); + auto arrayOfRegions = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Region>::create(); const RenderRegionList& regionList = flowThread->renderRegionList(); for (auto& iterRegion : regionList) { if (!iterRegion->isValid()) continue; - RefPtr<InspectorObject> regionHighlightObject = buildObjectForRegionHighlight(mainFrameView, iterRegion); - if (!regionHighlightObject) + RefPtr<Inspector::Protocol::OverlayTypes::Region> regionObject = buildObjectForRegion(mainFrameView, iterRegion); + if (!regionObject) continue; if (region == iterRegion) { // Let the script know that this is the currently highlighted node. - regionHighlightObject->setBoolean("isHighlighted", true); + regionObject->setIsHighlighted(true); } - array->pushObject(regionHighlightObject.release()); + arrayOfRegions->addItem(WTFMove(regionObject)); } - return array.release(); + return arrayOfRegions; } -static PassRefPtr<InspectorObject> buildObjectForSize(const IntSize& size) +static Ref<Inspector::Protocol::OverlayTypes::Size> buildObjectForSize(const IntSize& size) { - RefPtr<InspectorObject> result = InspectorObject::create(); - result->setNumber("width", size.width()); - result->setNumber("height", size.height()); - return result.release(); + return Inspector::Protocol::OverlayTypes::Size::create() + .setWidth(size.width()) + .setHeight(size.height()) + .release(); } -static PassRefPtr<InspectorObject> buildObjectForCSSRegionContentClip(RenderRegion* region) +static RefPtr<Inspector::Protocol::OverlayTypes::Quad> buildQuadObjectForCSSRegionContentClip(RenderRegion* region) { Frame* containingFrame = region->document().frame(); if (!containingFrame) @@ -478,104 +482,161 @@ static PassRefPtr<InspectorObject> buildObjectForCSSRegionContentClip(RenderRegi FloatQuad clipQuad = region->localToAbsoluteQuad(FloatRect(flippedRegionRect)); contentsQuadToPage(mainView, containingView, clipQuad); - RefPtr<InspectorObject> regionObject = InspectorObject::create(); - regionObject->setArray("quad", buildArrayForQuad(clipQuad)); - return regionObject.release(); + return buildArrayForQuad(clipQuad); +} + +void InspectorOverlay::setShowingPaintRects(bool showingPaintRects) +{ + if (m_showingPaintRects == showingPaintRects) + return; + + m_showingPaintRects = showingPaintRects; + if (!m_showingPaintRects) { + m_paintRects.clear(); + m_paintRectUpdateTimer.stop(); + drawPaintRects(); + forcePaint(); + } +} + +void InspectorOverlay::showPaintRect(const FloatRect& rect) +{ + if (!m_showingPaintRects) + return; + + IntRect rootRect = m_page.mainFrame().view()->contentsToRootView(enclosingIntRect(rect)); + + const auto removeDelay = 250ms; + + std::chrono::steady_clock::time_point removeTime = std::chrono::steady_clock::now() + removeDelay; + m_paintRects.append(TimeRectPair(removeTime, rootRect)); + + if (!m_paintRectUpdateTimer.isActive()) { + const double paintRectsUpdateIntervalSeconds = 0.032; + m_paintRectUpdateTimer.startRepeating(paintRectsUpdateIntervalSeconds); + } + + drawPaintRects(); + forcePaint(); +} + +void InspectorOverlay::updatePaintRectsTimerFired() +{ + std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); + bool rectsChanged = false; + while (!m_paintRects.isEmpty() && m_paintRects.first().first < now) { + m_paintRects.removeFirst(); + rectsChanged = true; + } + + if (m_paintRects.isEmpty()) + m_paintRectUpdateTimer.stop(); + + if (rectsChanged) { + drawPaintRects(); + forcePaint(); + } +} + +void InspectorOverlay::drawPaintRects() +{ + auto arrayOfRects = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Rect>::create(); + for (const auto& pair : m_paintRects) + arrayOfRects->addItem(buildObjectForRect(pair.second)); + + evaluateInOverlay(ASCIILiteral("updatePaintRects"), WTFMove(arrayOfRects)); } void InspectorOverlay::drawGutter() { - evaluateInOverlay("drawGutter", ""); + evaluateInOverlay(ASCIILiteral("drawGutter")); } -static PassRefPtr<InspectorArray> buildObjectForRendererFragments(RenderObject* renderer, const HighlightConfig& config) +static RefPtr<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>> buildArrayForRendererFragments(RenderObject* renderer, const HighlightConfig& config) { - RefPtr<InspectorArray> fragmentsArray = InspectorArray::create(); + auto arrayOfFragments = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>::create(); RenderFlowThread* containingFlowThread = renderer->flowThreadContainingBlock(); if (!containingFlowThread) { Highlight highlight; - buildRendererHighlight(renderer, nullptr, config, &highlight); - fragmentsArray->pushObject(buildObjectForHighlight(highlight)); + buildRendererHighlight(renderer, nullptr, config, highlight, InspectorOverlay::CoordinateSystem::View); + arrayOfFragments->addItem(buildObjectForHighlight(highlight)); } else { - RenderBox* enclosingBox = renderer->enclosingBox(); RenderRegion* startRegion = nullptr; RenderRegion* endRegion = nullptr; - containingFlowThread->getRegionRangeForBox(enclosingBox, startRegion, endRegion); - if (!startRegion) { + if (!containingFlowThread->getRegionRangeForBox(&renderer->enclosingBox(), startRegion, endRegion)) { // The flow has no visible regions. The renderer is not visible on screen. return nullptr; } + const RenderRegionList& regionList = containingFlowThread->renderRegionList(); for (RenderRegionList::const_iterator iter = regionList.find(startRegion); iter != regionList.end(); ++iter) { RenderRegion* region = *iter; if (region->isValid()) { // Compute the highlight of the fragment inside the current region. Highlight highlight; - buildRendererHighlight(renderer, region, config, &highlight); - RefPtr<InspectorObject> fragmentObject = buildObjectForHighlight(highlight); + buildRendererHighlight(renderer, region, config, highlight, InspectorOverlay::CoordinateSystem::View); + Ref<Inspector::Protocol::OverlayTypes::FragmentHighlightData> fragmentHighlight = buildObjectForHighlight(highlight); // Compute the clipping area of the region. - fragmentObject->setObject("region", buildObjectForCSSRegionContentClip(region)); - fragmentsArray->pushObject(fragmentObject.release()); + fragmentHighlight->setRegionClippingArea(buildQuadObjectForCSSRegionContentClip(region)); + arrayOfFragments->addItem(WTFMove(fragmentHighlight)); } if (region == endRegion) break; } } - return fragmentsArray.release(); + return WTFMove(arrayOfFragments); } -#if ENABLE(CSS_SHAPES) static FloatPoint localPointToRoot(RenderObject* renderer, const FrameView* mainView, const FrameView* view, const FloatPoint& point) { FloatPoint result = renderer->localToAbsolute(point); result = view->contentsToRootView(roundedIntPoint(result)); - result += mainView->scrollOffset(); + result += toIntSize(mainView->scrollPosition()); return result; } struct PathApplyInfo { FrameView* rootView; FrameView* view; - InspectorArray* array; + Inspector::Protocol::OverlayTypes::DisplayPath* pathArray; RenderObject* renderer; const ShapeOutsideInfo* shapeOutsideInfo; }; -static void appendPathCommandAndPoints(PathApplyInfo* info, const String& command, const FloatPoint points[], unsigned length) +static void appendPathCommandAndPoints(PathApplyInfo& info, const String& command, const FloatPoint points[], unsigned length) { FloatPoint point; - info->array->pushString(command); + info.pathArray->addItem(command); for (unsigned i = 0; i < length; i++) { - point = info->shapeOutsideInfo->shapeToRendererPoint(points[i]); - point = localPointToRoot(info->renderer, info->rootView, info->view, point); - info->array->pushNumber(point.x()); - info->array->pushNumber(point.y()); + point = info.shapeOutsideInfo->shapeToRendererPoint(points[i]); + point = localPointToRoot(info.renderer, info.rootView, info.view, point); + info.pathArray->addItem(point.x()); + info.pathArray->addItem(point.y()); } } -static void appendPathSegment(void* info, const PathElement* pathElement) +static void appendPathSegment(PathApplyInfo& pathApplyInfo, const PathElement& pathElement) { - PathApplyInfo* pathApplyInfo = static_cast<PathApplyInfo*>(info); FloatPoint point; - switch (pathElement->type) { + switch (pathElement.type) { // The points member will contain 1 value. case PathElementMoveToPoint: - appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("M"), pathElement->points, 1); + appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("M"), pathElement.points, 1); break; // The points member will contain 1 value. case PathElementAddLineToPoint: - appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("L"), pathElement->points, 1); + appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("L"), pathElement.points, 1); break; // The points member will contain 3 values. case PathElementAddCurveToPoint: - appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("C"), pathElement->points, 3); + appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("C"), pathElement.points, 3); break; // The points member will contain 2 values. case PathElementAddQuadCurveToPoint: - appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("Q"), pathElement->points, 2); + appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("Q"), pathElement.points, 2); break; // The points member will contain no values. case PathElementCloseSubpath: @@ -584,149 +645,198 @@ static void appendPathSegment(void* info, const PathElement* pathElement) } } -static PassRefPtr<InspectorObject> buildObjectForShapeOutside(Frame* containingFrame, RenderBox* renderer) +static RefPtr<Inspector::Protocol::OverlayTypes::ShapeOutsideData> buildObjectForShapeOutside(Frame* containingFrame, RenderBox* renderer) { const ShapeOutsideInfo* shapeOutsideInfo = renderer->shapeOutsideInfo(); if (!shapeOutsideInfo) return nullptr; - RefPtr<InspectorObject> shapeObject = InspectorObject::create(); LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox(); FloatQuad shapeQuad = renderer->localToAbsoluteQuad(FloatRect(shapeBounds)); contentsQuadToPage(containingFrame->page()->mainFrame().view(), containingFrame->view(), shapeQuad); - shapeObject->setArray(ASCIILiteral("bounds"), buildArrayForQuad(shapeQuad)); + + auto shapeObject = Inspector::Protocol::OverlayTypes::ShapeOutsideData::create() + .setBounds(buildArrayForQuad(shapeQuad)) + .release(); Shape::DisplayPaths paths; shapeOutsideInfo->computedShape().buildDisplayPaths(paths); if (paths.shape.length()) { - RefPtr<InspectorArray> shapePath = InspectorArray::create(); + auto shapePath = Inspector::Protocol::OverlayTypes::DisplayPath::create(); PathApplyInfo info; info.rootView = containingFrame->page()->mainFrame().view(); info.view = containingFrame->view(); - info.array = shapePath.get(); + info.pathArray = &shapePath.get(); info.renderer = renderer; info.shapeOutsideInfo = shapeOutsideInfo; - paths.shape.apply(&info, &appendPathSegment); + paths.shape.apply([&info](const PathElement& pathElement) { + appendPathSegment(info, pathElement); + }); - shapeObject->setArray(ASCIILiteral("shape"), shapePath.release()); + shapeObject->setShape(shapePath.copyRef()); if (paths.marginShape.length()) { - shapePath = InspectorArray::create(); - info.array = shapePath.get(); + auto marginShapePath = Inspector::Protocol::OverlayTypes::DisplayPath::create(); + info.pathArray = &marginShapePath.get(); - paths.marginShape.apply(&info, &appendPathSegment); + paths.marginShape.apply([&info](const PathElement& pathElement) { + appendPathSegment(info, pathElement); + }); - shapeObject->setArray(ASCIILiteral("marginShape"), shapePath.release()); + shapeObject->setMarginShape(marginShapePath.copyRef()); } } - return shapeObject.release(); + return WTFMove(shapeObject); } -#endif -static PassRefPtr<InspectorObject> buildObjectForElementInfo(Node* node) +static RefPtr<Inspector::Protocol::OverlayTypes::ElementData> buildObjectForElementData(Node* node, HighlightType type) { - if (!node->isElementNode() || !node->document().frame()) + if (!is<Element>(node) || !node->document().frame()) return nullptr; - RefPtr<InspectorObject> elementInfo = InspectorObject::create(); - - Element* element = toElement(node); - bool isXHTML = element->document().isXHTMLDocument(); - elementInfo->setString("tagName", isXHTML ? element->nodeName() : element->nodeName().lower()); - elementInfo->setString("idValue", element->getIdAttribute()); - HashSet<AtomicString> usedClassNames; - if (element->hasClass() && element->isStyledElement()) { - StringBuilder classNames; - const SpaceSplitString& classNamesString = toStyledElement(element)->classNames(); - size_t classNameCount = classNamesString.size(); - for (size_t i = 0; i < classNameCount; ++i) { + Element* effectiveElement = downcast<Element>(node); + if (node->isPseudoElement()) { + Element* hostElement = downcast<PseudoElement>(*node).hostElement(); + if (!hostElement) + return nullptr; + effectiveElement = hostElement; + } + + Element& element = *effectiveElement; + bool isXHTML = element.document().isXHTMLDocument(); + auto elementData = Inspector::Protocol::OverlayTypes::ElementData::create() + .setTagName(isXHTML ? element.nodeName() : element.nodeName().convertToASCIILowercase()) + .setIdValue(element.getIdAttribute()) + .release(); + + if (element.hasClass() && is<StyledElement>(element)) { + auto classes = Inspector::Protocol::Array<String>::create(); + HashSet<AtomicString> usedClassNames; + const SpaceSplitString& classNamesString = downcast<StyledElement>(element).classNames(); + for (size_t i = 0; i < classNamesString.size(); ++i) { const AtomicString& className = classNamesString[i]; if (usedClassNames.contains(className)) continue; + usedClassNames.add(className); - classNames.append('.'); - classNames.append(className); + classes->addItem(className); } - elementInfo->setString("className", classNames.toString()); + elementData->setClasses(WTFMove(classes)); + } + + if (node->isPseudoElement()) { + if (node->pseudoId() == BEFORE) + elementData->setPseudoElement("before"); + else if (node->pseudoId() == AFTER) + elementData->setPseudoElement("after"); } - RenderElement* renderer = element->renderer(); + RenderElement* renderer = element.renderer(); + if (!renderer) + return nullptr; + Frame* containingFrame = node->document().frame(); FrameView* containingView = containingFrame->view(); - IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect())); - RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : nullptr; - elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), *modelObject) : boundingBox.width())); - elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), *modelObject) : boundingBox.height())); - - if (renderer->isRenderNamedFlowFragmentContainer()) { - RenderNamedFlowFragment* region = toRenderBlockFlow(renderer)->renderNamedFlowFragment(); - RenderFlowThread* flowThread = region->flowThread(); - if (flowThread && flowThread->isRenderNamedFlowThread()) { - RefPtr<InspectorObject> regionFlowInfo = InspectorObject::create(); - regionFlowInfo->setString("name", toRenderNamedFlowThread(flowThread)->flowThreadName()); - regionFlowInfo->setArray("regions", buildObjectForCSSRegionsHighlight(region, flowThread)); - elementInfo->setObject("regionFlowInfo", regionFlowInfo.release()); + IntRect boundingBox = snappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect())); + RenderBoxModelObject* modelObject = is<RenderBoxModelObject>(*renderer) ? downcast<RenderBoxModelObject>(renderer) : nullptr; + auto sizeObject = Inspector::Protocol::OverlayTypes::Size::create() + .setWidth(modelObject ? adjustForAbsoluteZoom(roundToInt(modelObject->offsetWidth()), *modelObject) : boundingBox.width()) + .setHeight(modelObject ? adjustForAbsoluteZoom(roundToInt(modelObject->offsetHeight()), *modelObject) : boundingBox.height()) + .release(); + elementData->setSize(WTFMove(sizeObject)); + + if (type != HighlightType::NodeList && renderer->isRenderNamedFlowFragmentContainer()) { + RenderNamedFlowFragment& region = *downcast<RenderBlockFlow>(*renderer).renderNamedFlowFragment(); + if (region.isValid()) { + RenderFlowThread* flowThread = region.flowThread(); + auto regionFlowData = Inspector::Protocol::OverlayTypes::RegionFlowData::create() + .setName(downcast<RenderNamedFlowThread>(*flowThread).flowThreadName()) + .setRegions(buildObjectForFlowRegions(®ion, flowThread)) + .release(); + elementData->setRegionFlowData(WTFMove(regionFlowData)); } } RenderFlowThread* containingFlowThread = renderer->flowThreadContainingBlock(); - if (containingFlowThread && containingFlowThread->isRenderNamedFlowThread()) { - RefPtr<InspectorObject> contentFlowInfo = InspectorObject::create(); - contentFlowInfo->setString("name", toRenderNamedFlowThread(containingFlowThread)->flowThreadName()); - elementInfo->setObject("contentFlowInfo", contentFlowInfo.release()); + if (is<RenderNamedFlowThread>(containingFlowThread)) { + auto contentFlowData = Inspector::Protocol::OverlayTypes::ContentFlowData::create() + .setName(downcast<RenderNamedFlowThread>(*containingFlowThread).flowThreadName()) + .release(); + + elementData->setContentFlowData(WTFMove(contentFlowData)); } -#if ENABLE(CSS_SHAPES) - if (renderer->isBox()) { - RenderBox* renderBox = toRenderBox(renderer); - if (RefPtr<InspectorObject> shapeObject = buildObjectForShapeOutside(containingFrame, renderBox)) - elementInfo->setObject("shapeOutsideInfo", shapeObject.release()); + if (is<RenderBox>(*renderer)) { + auto& renderBox = downcast<RenderBox>(*renderer); + if (RefPtr<Inspector::Protocol::OverlayTypes::ShapeOutsideData> shapeObject = buildObjectForShapeOutside(containingFrame, &renderBox)) + elementData->setShapeOutsideData(WTFMove(shapeObject)); + } + + // Need to enable AX to get the computed role. + if (!WebCore::AXObjectCache::accessibilityEnabled()) + WebCore::AXObjectCache::enableAccessibility(); + + if (AXObjectCache* axObjectCache = node->document().axObjectCache()) { + if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node)) + elementData->setRole(axObject->computedRoleString()); } -#endif - return elementInfo.release(); + return WTFMove(elementData); } -PassRefPtr<InspectorObject> InspectorOverlay::buildObjectForHighlightedNode() const +RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> InspectorOverlay::buildHighlightObjectForNode(Node* node, HighlightType type) const { - if (!m_highlightNode) + if (!node) return nullptr; - Node* node = m_highlightNode.get(); RenderObject* renderer = node->renderer(); if (!renderer) return nullptr; - RefPtr<InspectorArray> highlightFragments = buildObjectForRendererFragments(renderer, m_nodeHighlightConfig); - if (!highlightFragments) + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>> arrayOfFragmentHighlights = buildArrayForRendererFragments(renderer, m_nodeHighlightConfig); + if (!arrayOfFragmentHighlights) return nullptr; - RefPtr<InspectorObject> highlightObject = InspectorObject::create(); - // The main view's scroll offset is shared across all quads. FrameView* mainView = m_page.mainFrame().view(); - highlightObject->setObject("scroll", buildObjectForPoint(!mainView->delegatesScrolling() ? mainView->visibleContentRect().location() : FloatPoint())); - highlightObject->setArray("fragments", highlightFragments.release()); + auto nodeHighlightObject = Inspector::Protocol::OverlayTypes::NodeHighlightData::create() + .setScrollOffset(buildObjectForPoint(!mainView->delegatesScrolling() ? mainView->visibleContentRect().location() : FloatPoint())) + .setFragments(WTFMove(arrayOfFragmentHighlights)) + .release(); if (m_nodeHighlightConfig.showInfo) { - RefPtr<InspectorObject> elementInfo = buildObjectForElementInfo(node); - if (elementInfo) - highlightObject->setObject("elementInfo", elementInfo.release()); + if (RefPtr<Inspector::Protocol::OverlayTypes::ElementData> elementData = buildObjectForElementData(node, type)) + nodeHighlightObject->setElementData(WTFMove(elementData)); } - - return highlightObject.release(); + + return WTFMove(nodeHighlightObject); +} + +Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> InspectorOverlay::buildObjectForHighlightedNodes() const +{ + auto highlights = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>::create(); + + if (m_highlightNode) { + if (RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> nodeHighlightData = buildHighlightObjectForNode(m_highlightNode.get(), HighlightType::Node)) + highlights->addItem(WTFMove(nodeHighlightData)); + } else if (m_highlightNodeList) { + for (unsigned i = 0; i < m_highlightNodeList->length(); ++i) { + if (RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> nodeHighlightData = buildHighlightObjectForNode(m_highlightNodeList->item(i), HighlightType::NodeList)) + highlights->addItem(WTFMove(nodeHighlightData)); + } + } + + return highlights; } void InspectorOverlay::drawNodeHighlight() { - RefPtr<InspectorObject> highlightObject = buildObjectForHighlightedNode(); - if (!highlightObject) - return; - evaluateInOverlay("drawNodeHighlight", highlightObject); + if (m_highlightNode || m_highlightNodeList) + evaluateInOverlay("drawNodeHighlight", buildObjectForHighlightedNodes()); } void InspectorOverlay::drawQuadHighlight() @@ -735,7 +845,7 @@ void InspectorOverlay::drawQuadHighlight() return; Highlight highlight; - buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, &highlight); + buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, highlight); evaluateInOverlay("drawQuadHighlight", buildObjectForHighlight(highlight)); } @@ -750,9 +860,14 @@ Page* InspectorOverlay::overlayPage() if (m_overlayPage) return m_overlayPage.get(); - Page::PageClients pageClients; - fillWithEmptyClients(pageClients); - m_overlayPage = adoptPtr(new Page(pageClients)); + PageConfiguration pageConfiguration( + createEmptyEditorClient(), + SocketProvider::create(), + makeUniqueRef<LibWebRTCProvider>() + ); + fillWithEmptyClients(pageConfiguration); + m_overlayPage = std::make_unique<Page>(WTFMove(pageConfiguration)); + m_overlayPage->setDeviceScaleFactor(m_page.deviceScaleFactor()); Settings& settings = m_page.settings(); Settings& overlaySettings = m_overlayPage->settings(); @@ -792,36 +907,56 @@ Page* InspectorOverlay::overlayPage() return m_overlayPage.get(); } +void InspectorOverlay::forcePaint() +{ + // This overlay page is very weird and doesn't automatically paint. We have to force paints manually. + m_client->highlight(); +} + void InspectorOverlay::reset(const IntSize& viewportSize, const IntSize& frameViewFullSize) { - RefPtr<InspectorObject> resetData = InspectorObject::create(); - resetData->setNumber("deviceScaleFactor", m_page.deviceScaleFactor()); - resetData->setObject("viewportSize", buildObjectForSize(viewportSize)); - resetData->setObject("frameViewFullSize", buildObjectForSize(frameViewFullSize)); - evaluateInOverlay("reset", resetData.release()); + auto configObject = Inspector::Protocol::OverlayTypes::OverlayConfiguration::create() + .setDeviceScaleFactor(m_page.deviceScaleFactor()) + .setViewportSize(buildObjectForSize(viewportSize)) + .setFrameViewFullSize(buildObjectForSize(frameViewFullSize)) + .release(); + evaluateInOverlay("reset", WTFMove(configObject)); +} + +static void evaluateCommandInOverlay(Page* page, Ref<InspectorArray>&& command) +{ + page->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ')'))); +} + +void InspectorOverlay::evaluateInOverlay(const String& method) +{ + Ref<InspectorArray> command = InspectorArray::create(); + command->pushString(method); + + evaluateCommandInOverlay(overlayPage(), WTFMove(command)); } void InspectorOverlay::evaluateInOverlay(const String& method, const String& argument) { - RefPtr<InspectorArray> command = InspectorArray::create(); + Ref<InspectorArray> command = InspectorArray::create(); command->pushString(method); command->pushString(argument); - overlayPage()->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ")"))); + + evaluateCommandInOverlay(overlayPage(), WTFMove(command)); } -void InspectorOverlay::evaluateInOverlay(const String& method, PassRefPtr<InspectorValue> argument) +void InspectorOverlay::evaluateInOverlay(const String& method, RefPtr<InspectorValue>&& argument) { - RefPtr<InspectorArray> command = InspectorArray::create(); + Ref<InspectorArray> command = InspectorArray::create(); command->pushString(method); - command->pushValue(argument); - overlayPage()->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ")"))); + command->pushValue(WTFMove(argument)); + + evaluateCommandInOverlay(overlayPage(), WTFMove(command)); } void InspectorOverlay::freePage() { - m_overlayPage.clear(); + m_overlayPage = nullptr; } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorOverlay.h b/Source/WebCore/inspector/InspectorOverlay.h index 7e3d017b2..a8af0d299 100644 --- a/Source/WebCore/inspector/InspectorOverlay.h +++ b/Source/WebCore/inspector/InspectorOverlay.h @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,14 +26,15 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorOverlay_h -#define InspectorOverlay_h +#pragma once #include "Color.h" #include "FloatQuad.h" #include "LayoutRect.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> +#include "NodeList.h" +#include "Timer.h" +#include <inspector/InspectorProtocolObjects.h> +#include <wtf/Deque.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> @@ -41,6 +42,12 @@ namespace Inspector { class InspectorObject; class InspectorValue; + +namespace Protocol { +namespace OverlayTypes { +class NodeHighlightData; +} +} } namespace WebCore { @@ -61,21 +68,17 @@ public: Color border; Color margin; bool showInfo; - bool showRulers; bool usePageCoordinates; }; -enum HighlightType { - HighlightTypeNode, - HighlightTypeRects, +enum class HighlightType { + Node, // Provides 4 quads: margin, border, padding, content. + NodeList, // Provides a list of nodes. + Rects, // Provides a list of quads. }; struct Highlight { - Highlight() - : type(HighlightTypeNode) - , showRulers(false) - { - } + Highlight() { } void setDataFromConfig(const HighlightConfig& highlightConfig) { @@ -84,7 +87,6 @@ struct Highlight { paddingColor = highlightConfig.padding; borderColor = highlightConfig.border; marginColor = highlightConfig.margin; - showRulers = highlightConfig.showRulers; usePageCoordinates = highlightConfig.usePageCoordinates; } @@ -94,12 +96,9 @@ struct Highlight { Color borderColor; Color marginColor; - // When the type is Node, there are 4 quads (margin, border, padding, content). - // When the type is Rects, this is just a list of quads. - HighlightType type; + HighlightType type {HighlightType::Node}; Vector<FloatQuad> quads; - bool showRulers; - bool usePageCoordinates; + bool usePageCoordinates {true}; }; class InspectorOverlay { @@ -108,46 +107,67 @@ public: InspectorOverlay(Page&, InspectorClient*); ~InspectorOverlay(); + enum class CoordinateSystem { + View, // Adjusts for the main frame's scroll offset. + Document, // Does not adjust for the main frame's scroll offset. + }; + void update(); void paint(GraphicsContext&); - void drawOutline(GraphicsContext*, const LayoutRect&, const Color&); - void getHighlight(Highlight*) const; + void getHighlight(Highlight&, CoordinateSystem) const; void setPausedInDebuggerMessage(const String*); void hideHighlight(); + void highlightNodeList(RefPtr<NodeList>&&, const HighlightConfig&); void highlightNode(Node*, const HighlightConfig&); - void highlightQuad(PassOwnPtr<FloatQuad>, const HighlightConfig&); - + void highlightQuad(std::unique_ptr<FloatQuad>, const HighlightConfig&); + + void setShowingPaintRects(bool); + void showPaintRect(const FloatRect&); + Node* highlightedNode() const; void didSetSearchingForNode(bool enabled); - PassRefPtr<Inspector::InspectorObject> buildObjectForHighlightedNode() const; + void setIndicating(bool indicating); + + RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> buildHighlightObjectForNode(Node*, HighlightType) const; + Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> buildObjectForHighlightedNodes() const; void freePage(); private: + bool shouldShowOverlay() const; void drawGutter(); void drawNodeHighlight(); void drawQuadHighlight(); void drawPausedInDebuggerMessage(); + void drawPaintRects(); + void updatePaintRectsTimerFired(); + Page* overlayPage(); + + void forcePaint(); void reset(const IntSize& viewportSize, const IntSize& frameViewFullSize); + void evaluateInOverlay(const String& method); void evaluateInOverlay(const String& method, const String& argument); - void evaluateInOverlay(const String& method, PassRefPtr<Inspector::InspectorValue> argument); + void evaluateInOverlay(const String& method, RefPtr<Inspector::InspectorValue>&& argument); Page& m_page; InspectorClient* m_client; String m_pausedInDebuggerMessage; RefPtr<Node> m_highlightNode; + RefPtr<NodeList> m_highlightNodeList; HighlightConfig m_nodeHighlightConfig; - OwnPtr<FloatQuad> m_highlightQuad; - OwnPtr<Page> m_overlayPage; + std::unique_ptr<FloatQuad> m_highlightQuad; + std::unique_ptr<Page> m_overlayPage; HighlightConfig m_quadHighlightConfig; - IntSize m_size; + + typedef std::pair<std::chrono::steady_clock::time_point, FloatRect> TimeRectPair; + Deque<TimeRectPair> m_paintRects; + Timer m_paintRectUpdateTimer; + bool m_indicating {false}; + bool m_showingPaintRects {false}; }; } // namespace WebCore - - -#endif // InspectorOverlay_h diff --git a/Source/WebCore/inspector/InspectorOverlayPage.css b/Source/WebCore/inspector/InspectorOverlayPage.css index 619e356f8..de6c53ff8 100644 --- a/Source/WebCore/inspector/InspectorOverlayPage.css +++ b/Source/WebCore/inspector/InspectorOverlayPage.css @@ -26,6 +26,10 @@ body.platform-linux { left: 0; } +.indicate { + background-color: rgba(111, 168, 220, 0.66) !important; +} + .dimmed { background-color: rgba(0, 0, 0, 0.31); } @@ -55,18 +59,19 @@ body.platform-linux { position: absolute; } -.tag-name { - /* Keep this in sync with view-source.css (.webkit-html-tag-name) */ +.tag-name, +.pseudo-type { + /* Keep this in sync with XMLViewer.css (.tag) */ color: rgb(136, 18, 128); } .node-id { - /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */ + /* Keep this in sync with XMLViewer.css (.attribute-value) */ color: rgb(26, 26, 166); } .class-name { - /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */ + /* Keep this in sync with XMLViewer.css (.attribute-name) */ color: rgb(153, 69, 0); } diff --git a/Source/WebCore/inspector/InspectorOverlayPage.html b/Source/WebCore/inspector/InspectorOverlayPage.html index af1711ce7..c56178117 100644 --- a/Source/WebCore/inspector/InspectorOverlayPage.html +++ b/Source/WebCore/inspector/InspectorOverlayPage.html @@ -10,7 +10,7 @@ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -34,6 +34,7 @@ <body class="fill"> <div class="message-line"><span class="message-box" id="paused-in-debugger"></span></div> <canvas id="canvas" class="fill"></canvas> +<canvas id="paintrects-canvas" class="fill"></canvas> <div id="element-title-container"></div> <div id="right-gutter"></div> <div id="bottom-gutter"></div> diff --git a/Source/WebCore/inspector/InspectorOverlayPage.js b/Source/WebCore/inspector/InspectorOverlayPage.js index ad01900d4..352996f70 100644 --- a/Source/WebCore/inspector/InspectorOverlayPage.js +++ b/Source/WebCore/inspector/InspectorOverlayPage.js @@ -22,6 +22,8 @@ const regionNumberStrokeColor = "rgb(61, 127, 204)"; const shapeHighlightColor = "rgba(96, 82, 127, 0.8)"; const shapeMarginHighlightColor = "rgba(96, 82, 127, 0.6)"; +const paintRectFillColor = "rgba(255, 0, 0, 0.5)"; + function drawPausedInDebuggerMessage(message) { var pausedInDebugger = document.getElementById("paused-in-debugger"); @@ -30,124 +32,6 @@ function drawPausedInDebuggerMessage(message) document.body.classList.add("dimmed"); } -function _drawGrid(highlight, rulerAtRight, rulerAtBottom) -{ - if (!highlight.showRulers) - return; - context.save(); - - var width = canvas.width; - var height = canvas.height; - - const gridSubStep = 5; - const gridStep = 50; - - { - // Draw X grid background - context.save(); - context.fillStyle = gridBackgroundColor; - if (rulerAtBottom) - context.fillRect(0, height - 15, width, height); - else - context.fillRect(0, 0, width, 15); - - // Clip out backgrounds intersection - context.globalCompositeOperation = "destination-out"; - context.fillStyle = "red"; - if (rulerAtRight) - context.fillRect(width - 15, 0, width, height); - else - context.fillRect(0, 0, 15, height); - context.restore(); - - // Draw Y grid background - context.fillStyle = gridBackgroundColor; - if (rulerAtRight) - context.fillRect(width - 15, 0, width, height); - else - context.fillRect(0, 0, 15, height); - } - - context.lineWidth = 1; - context.strokeStyle = darkGridColor; - context.fillStyle = darkGridColor; - { - // Draw labels. - context.save(); - context.translate(-highlight.scrollX, 0.5 - highlight.scrollY); - for (var y = 2 * gridStep; y < height + highlight.scrollY; y += 2 * gridStep) { - context.save(); - context.translate(highlight.scrollX, y); - context.rotate(-Math.PI / 2); - context.fillText(y, 2, rulerAtRight ? width - 7 : 13); - context.restore(); - } - context.translate(0.5, -0.5); - for (var x = 2 * gridStep; x < width + highlight.scrollX; x += 2 * gridStep) { - context.save(); - context.fillText(x, x + 2, rulerAtBottom ? highlight.scrollY + height - 7 : highlight.scrollY + 13); - context.restore(); - } - context.restore(); - } - - { - // Draw vertical grid - context.save(); - if (rulerAtRight) { - context.translate(width, 0); - context.scale(-1, 1); - } - context.translate(-highlight.scrollX, 0.5 - highlight.scrollY); - for (var y = gridStep; y < height + highlight.scrollY; y += gridStep) { - context.beginPath(); - context.moveTo(highlight.scrollX, y); - var markLength = (y % (gridStep * 2)) ? 5 : 8; - context.lineTo(highlight.scrollX + markLength, y); - context.stroke(); - } - context.strokeStyle = lightGridColor; - for (var y = gridSubStep; y < highlight.scrollY + height; y += gridSubStep) { - if (!(y % gridStep)) - continue; - context.beginPath(); - context.moveTo(highlight.scrollX, y); - context.lineTo(highlight.scrollX + gridSubStep, y); - context.stroke(); - } - context.restore(); - } - - { - // Draw horizontal grid - context.save(); - if (rulerAtBottom) { - context.translate(0, height); - context.scale(1, -1); - } - context.translate(0.5 - highlight.scrollX, -highlight.scrollY); - for (var x = gridStep; x < width + highlight.scrollX; x += gridStep) { - context.beginPath(); - context.moveTo(x, highlight.scrollY); - var markLength = (x % (gridStep * 2)) ? 5 : 8; - context.lineTo(x, highlight.scrollY + markLength); - context.stroke(); - } - context.strokeStyle = lightGridColor; - for (var x = gridSubStep; x < highlight.scrollX + width; x += gridSubStep) { - if (!(x % gridStep)) - continue; - context.beginPath(); - context.moveTo(x, highlight.scrollY); - context.lineTo(x, highlight.scrollY + gridSubStep); - context.stroke(); - } - context.restore(); - } - - context.restore(); -} - function _drawRegionNumber(quad, number) { context.save(); @@ -281,6 +165,24 @@ function drawGutter() } } +var updatePaintRectsIntervalID; + +function updatePaintRects(paintRectList) +{ + var context = paintRectsCanvas.getContext("2d"); + context.save(); + context.scale(window.devicePixelRatio, window.devicePixelRatio); + + context.clearRect(0, 0, paintRectsCanvas.width, paintRectsCanvas.height); + + context.fillStyle = paintRectFillColor; + + for (var rectObject of paintRectList) + context.fillRect(rectObject.x, rectObject.y, rectObject.width, rectObject.height); + + context.restore(); +} + function reset(resetData) { var deviceScaleFactor = resetData.deviceScaleFactor; @@ -288,6 +190,8 @@ function reset(resetData) window.frameViewFullSize = resetData.frameViewFullSize; window.canvas = document.getElementById("canvas"); + window.paintRectsCanvas = document.getElementById("paintrects-canvas"); + window.context = canvas.getContext("2d"); window.rightGutter = document.getElementById("right-gutter"); window.bottomGutter = document.getElementById("bottom-gutter"); @@ -298,6 +202,12 @@ function reset(resetData) canvas.style.height = viewportSize.height + "px"; context.scale(deviceScaleFactor, deviceScaleFactor); + // We avoid getting the the context for the paint rects canvas until we need to paint, to avoid backing store allocation. + paintRectsCanvas.width = deviceScaleFactor * viewportSize.width; + paintRectsCanvas.height = deviceScaleFactor * viewportSize.height; + paintRectsCanvas.style.width = viewportSize.width + "px"; + paintRectsCanvas.style.height = viewportSize.height + "px"; + document.getElementById("paused-in-debugger").style.visibility = "hidden"; document.getElementById("element-title-container").innerHTML = ""; document.body.classList.remove("dimmed"); @@ -311,8 +221,7 @@ function DOMBuilder(tagName, className) DOMBuilder.prototype.appendTextNode = function(content) { - var node = document.createTextNode(); - node.textContent = content; + let node = document.createTextNode(content); this.element.appendChild(node); return node; } @@ -351,35 +260,41 @@ function _truncateString(value, maxLength) return value && value.length > maxLength ? value.substring(0, 50) + "\u2026" : value; } -function _createElementTitle(elementInfo) +function _createElementTitle(elementData) { - var builder = new DOMBuilder("div", "element-title"); - - builder.appendSpanIfNotNull("tag-name", elementInfo.tagName); - builder.appendSpanIfNotNull("node-id", elementInfo.idValue, "#"); - builder.appendSpanIfNotNull("class-name", _truncateString(elementInfo.className, 50)); + let builder = new DOMBuilder("div", "element-title"); + + builder.appendSpanIfNotNull("tag-name", elementData.tagName); + builder.appendSpanIfNotNull("node-id", CSS.escape(elementData.idValue), "#"); + + let classes = elementData.classes; + if (classes && classes.length) + builder.appendSpan("class-name", _truncateString(classes.map((className) => "." + CSS.escape(className)).join(""), 50)); + + builder.appendSpanIfNotNull("pseudo-type", elementData.pseudoElement, "::"); builder.appendTextNode(" "); - builder.appendSpan("node-width", elementInfo.nodeWidth); + builder.appendSpan("node-width", elementData.size.width); // \xd7 is the code for the × HTML entity. builder.appendSpan("px", "px \xd7 "); - builder.appendSpan("node-height", elementInfo.nodeHeight); + builder.appendSpan("node-height", elementData.size.height); builder.appendSpan("px", "px"); - builder.appendPropertyIfNotNull("region-flow-name", "Region Flow", elementInfo.regionFlowInfo ? elementInfo.regionFlowInfo.name : null); - builder.appendPropertyIfNotNull("content-flow-name", "Content Flow", elementInfo.contentFlowInfo ? elementInfo.contentFlowInfo.name : null); + builder.appendPropertyIfNotNull("role-name", "Role", elementData.role); + builder.appendPropertyIfNotNull("region-flow-name", "Region Flow", elementData.regionFlowData ? elementData.regionFlowData.name : null); + builder.appendPropertyIfNotNull("content-flow-name", "Content Flow", elementData.contentFlowData ? elementData.contentFlowData.name : null); document.getElementById("element-title-container").appendChild(builder.element); return builder.element; } -function _drawElementTitle(elementInfo, fragmentHighlight, scroll) +function _drawElementTitle(elementData, fragmentHighlight, scroll) { - if (!elementInfo || !fragmentHighlight.quads.length) + if (!elementData || !fragmentHighlight.quads.length) return; - - var elementTitle = _createElementTitle(elementInfo); + + var elementTitle = _createElementTitle(elementData); var marginQuad = fragmentHighlight.quads[0]; @@ -394,11 +309,10 @@ function _drawElementTitle(elementInfo, fragmentHighlight, scroll) var renderArrowDown = false; var boxX = marginQuad[0].x; - - var containingRegion = fragmentHighlight.region; - if (containingRegion) { + + var clipQuad = fragmentHighlight.regionClippingArea; + if (clipQuad) { // Restrict the position of the title box to the area of the containing region. - var clipQuad = containingRegion.quad; anchorTop = Math.max(anchorTop, Math.min(clipQuad[0].y, clipQuad[1].y, clipQuad[2].y, clipQuad[3].y)); anchorBottom = Math.min(anchorBottom, Math.max(clipQuad[0].y, clipQuad[1].y, clipQuad[2].y, clipQuad[3].y)); boxX = Math.max(boxX, Math.min(clipQuad[0].x, clipQuad[1].x, clipQuad[2].x, clipQuad[3].x)); @@ -457,68 +371,6 @@ function _drawElementTitle(elementInfo, fragmentHighlight, scroll) elementTitle.style.left = (boxX + 3) + "px"; } -function _drawRulers(highlight, rulerAtRight, rulerAtBottom) -{ - if (!highlight.showRulers) - return; - context.save(); - var width = canvas.width; - var height = canvas.height; - context.strokeStyle = "rgba(128, 128, 128, 0.3)"; - context.lineWidth = 1; - context.translate(0.5, 0.5); - var leftmostXForY = {}; - var rightmostXForY = {}; - var topmostYForX = {}; - var bottommostYForX = {}; - - for (var i = 0; i < highlight.quads.length; ++i) { - var quad = highlight.quads[i]; - for (var j = 0; j < quad.length; ++j) { - var x = quad[j].x; - var y = quad[j].y; - leftmostXForY[Math.round(y)] = Math.min(leftmostXForY[y] || Number.MAX_VALUE, Math.round(quad[j].x)); - rightmostXForY[Math.round(y)] = Math.max(rightmostXForY[y] || Number.MIN_VALUE, Math.round(quad[j].x)); - topmostYForX[Math.round(x)] = Math.min(topmostYForX[x] || Number.MAX_VALUE, Math.round(quad[j].y)); - bottommostYForX[Math.round(x)] = Math.max(bottommostYForX[x] || Number.MIN_VALUE, Math.round(quad[j].y)); - } - } - - if (rulerAtRight) { - for (var y in rightmostXForY) { - context.beginPath(); - context.moveTo(width, y); - context.lineTo(rightmostXForY[y], y); - context.stroke(); - } - } else { - for (var y in leftmostXForY) { - context.beginPath(); - context.moveTo(0, y); - context.lineTo(leftmostXForY[y], y); - context.stroke(); - } - } - - if (rulerAtBottom) { - for (var x in bottommostYForX) { - context.beginPath(); - context.moveTo(x, height); - context.lineTo(x, topmostYForX[x]); - context.stroke(); - } - } else { - for (var x in topmostYForX) { - context.beginPath(); - context.moveTo(x, 0); - context.lineTo(x, topmostYForX[x]); - context.stroke(); - } - } - - context.restore(); -} - function _quadMidPoint(quad) { return { @@ -562,7 +414,8 @@ function _drawRegionsHighlight(regions) } } -function _drawShapeHighlight(shapeInfo) { +function _drawShapeHighlight(shapeInfo) +{ if (shapeInfo.marginShape) drawPath(context, shapeInfo.marginShape, shapeMarginHighlightColor); @@ -575,16 +428,14 @@ function _drawShapeHighlight(shapeInfo) { function _drawFragmentHighlight(highlight) { - if (!highlight.quads.length) { - _drawGrid(highlight, false, false); + if (!highlight.quads.length) return; - } context.save(); - if (highlight.region) { + if (highlight.regionClippingArea) { // Clip to the containing region to avoid showing fragments that are not rendered by this region. - quadToPath(highlight.region.quad).clip(); + quadToPath(highlight.regionClippingArea).clip(); } var quads = highlight.quads.slice(); @@ -628,34 +479,44 @@ function _drawFragmentHighlight(highlight) } context.restore(); +} - var rulerAtRight = minX < 20 && maxX + 20 < width; - var rulerAtBottom = minY < 20 && maxY + 20 < height; +function showPageIndication() +{ + document.body.classList.add("indicate"); +} - _drawGrid(highlight, rulerAtRight, rulerAtBottom); - _drawRulers(highlight, rulerAtRight, rulerAtBottom); +function hidePageIndication() +{ + document.body.classList.remove("indicate"); } -function drawNodeHighlight(highlight) +function drawNodeHighlight(allHighlights) { - context.save(); - context.translate(-highlight.scroll.x, -highlight.scroll.y); + var elementTitleContainer = document.getElementById("element-title-container"); + while (elementTitleContainer.hasChildNodes()) + elementTitleContainer.removeChild(elementTitleContainer.lastChild); - for (var i = 0; i < highlight.fragments.length; ++i) - _drawFragmentHighlight(highlight.fragments[i], highlight); + for (var highlight of allHighlights) { + context.save(); + context.translate(-highlight.scrollOffset.x, -highlight.scrollOffset.y); - if (highlight.elementInfo && highlight.elementInfo.regionFlowInfo) - _drawRegionsHighlight(highlight.elementInfo.regionFlowInfo.regions, highlight); + for (var fragment of highlight.fragments) + _drawFragmentHighlight(fragment); - if (highlight.elementInfo && highlight.elementInfo.shapeOutsideInfo) - _drawShapeHighlight(highlight.elementInfo.shapeOutsideInfo); + if (highlight.elementData && highlight.elementData.regionFlowData) + _drawRegionsHighlight(highlight.elementData.regionFlowData.regions); - context.restore(); + if (highlight.elementData && highlight.elementData.shapeOutsideData) + _drawShapeHighlight(highlight.elementData.shapeOutsideData); - var elementTitleContainer = document.getElementById("element-title-container"); - elementTitleContainer.innerHTML = ""; - for (var i = 0; i < highlight.fragments.length; ++i) - _drawElementTitle(highlight.elementInfo, highlight.fragments[i], highlight.scroll); + context.restore(); + + if (allHighlights.length === 1) { + for (var fragment of highlight.fragments) + _drawElementTitle(highlight.elementData, fragment, highlight.scrollOffset); + } + } } function drawQuadHighlight(highlight) diff --git a/Source/WebCore/inspector/InspectorPageAgent.cpp b/Source/WebCore/inspector/InspectorPageAgent.cpp index e3d0cc0be..de057b5ac 100644 --- a/Source/WebCore/inspector/InspectorPageAgent.cpp +++ b/Source/WebCore/inspector/InspectorPageAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,9 +30,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorPageAgent.h" #include "CachedCSSStyleSheet.h" @@ -42,41 +40,39 @@ #include "CachedScript.h" #include "Cookie.h" #include "CookieJar.h" -#include "DOMImplementation.h" -#include "DOMPatchSupport.h" #include "DOMWrapperWorld.h" #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" +#include "FrameLoadRequest.h" #include "FrameLoader.h" #include "FrameSnapshotting.h" #include "FrameView.h" #include "HTMLFrameOwnerElement.h" #include "HTMLNames.h" -#include "IdentifiersFactory.h" #include "ImageBuffer.h" #include "InspectorClient.h" #include "InspectorDOMAgent.h" -#include "InspectorInstrumentation.h" +#include "InspectorNetworkAgent.h" #include "InspectorOverlay.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" +#include "MIMETypeRegistry.h" #include "MainFrame.h" #include "MemoryCache.h" #include "Page.h" -#include "ResourceBuffer.h" +#include "RenderObject.h" #include "ScriptController.h" #include "SecurityOrigin.h" #include "Settings.h" +#include "StyleScope.h" #include "TextEncoding.h" #include "TextResourceDecoder.h" #include "UserGestureIndicator.h" -#include <bindings/ScriptValue.h> #include <inspector/ContentSearchUtilities.h> +#include <inspector/IdentifiersFactory.h> #include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> #include <wtf/ListHashSet.h> -#include <wtf/Vector.h> +#include <wtf/Stopwatch.h> #include <wtf/text/Base64.h> #include <wtf/text/StringBuilder.h> #include <yarr/RegularExpression.h> @@ -113,43 +109,25 @@ static bool prepareCachedResourceBuffer(CachedResource* cachedResource, bool* ha return true; } - if (cachedResource->isPurgeable()) { - // If the resource is purgeable then make it unpurgeable to get - // get its data. This might fail, in which case we return an - // empty String. - // FIXME: should we do something else in the case of a purged - // resource that informs the user why there is no data in the - // inspector? - if (!cachedResource->makePurgeable(false)) - return false; - } - return true; } static bool hasTextContent(CachedResource* cachedResource) { - InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource); - return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource; -} + // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text + // We should not assume XHR / Fetch have text content. -static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName) -{ - RefPtr<TextResourceDecoder> decoder; - if (!textEncodingName.isEmpty()) - decoder = TextResourceDecoder::create("text/plain", textEncodingName); - else if (DOMImplementation::isXMLMIMEType(mimeType.lower())) { - decoder = TextResourceDecoder::create("application/xml"); - decoder->useLenientXMLDecoding(); - } else if (equalIgnoringCase(mimeType, "text/html")) - decoder = TextResourceDecoder::create("text/html", "UTF-8"); - else - decoder = TextResourceDecoder::create("text/plain", "UTF-8"); - return decoder; + InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource); + return type == InspectorPageAgent::DocumentResource + || type == InspectorPageAgent::StylesheetResource + || type == InspectorPageAgent::ScriptResource + || type == InspectorPageAgent::XHRResource + || type == InspectorPageAgent::FetchResource; } bool InspectorPageAgent::cachedResourceContent(CachedResource* cachedResource, String* result, bool* base64Encoded) { + // FIXME: result should be a String& and base64Encoded should be a bool&. bool hasZeroSize; bool prepared = prepareCachedResourceBuffer(cachedResource, &hasZeroSize); if (!prepared) @@ -157,42 +135,45 @@ bool InspectorPageAgent::cachedResourceContent(CachedResource* cachedResource, S *base64Encoded = !hasTextContent(cachedResource); if (*base64Encoded) { - RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer()->sharedBuffer(); - - if (!buffer) - return false; - - *result = base64Encode(buffer->data(), buffer->size()); - return true; + if (hasZeroSize) { + *result = { }; + return true; + } + if (auto* buffer = cachedResource->resourceBuffer()) { + *result = base64Encode(buffer->data(), buffer->size()); + return true; + } + return false; } if (hasZeroSize) { - *result = ""; + *result = emptyString(); return true; } if (cachedResource) { switch (cachedResource->type()) { case CachedResource::CSSStyleSheet: - *result = static_cast<CachedCSSStyleSheet*>(cachedResource)->sheetText(false); - return true; + // This can return a null String if the MIME type is invalid. + *result = downcast<CachedCSSStyleSheet>(*cachedResource).sheetText(); + return !result->isNull(); case CachedResource::Script: - *result = static_cast<CachedScript*>(cachedResource)->script(); + *result = downcast<CachedScript>(*cachedResource).script().toString(); return true; + case CachedResource::MediaResource: case CachedResource::RawResource: { - ResourceBuffer* buffer = cachedResource->resourceBuffer(); + auto* buffer = cachedResource->resourceBuffer(); if (!buffer) return false; - RefPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName()); + RefPtr<TextResourceDecoder> decoder = InspectorPageAgent::createTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName()); // We show content for raw resources only for certain mime types (text, html and xml). Otherwise decoder will be null. if (!decoder) return false; - String content = decoder->decode(buffer->data(), buffer->size()); - *result = content + decoder->flush(); + *result = decoder->decodeAndFlush(buffer->data(), buffer->size()); return true; } default: - ResourceBuffer* buffer = cachedResource->resourceBuffer(); + auto* buffer = cachedResource->resourceBuffer(); return decodeBuffer(buffer ? buffer->data() : nullptr, buffer ? buffer->size() : 0, cachedResource->encoding(), result); } } @@ -201,16 +182,13 @@ bool InspectorPageAgent::cachedResourceContent(CachedResource* cachedResource, S bool InspectorPageAgent::mainResourceContent(Frame* frame, bool withBase64Encode, String* result) { - RefPtr<ResourceBuffer> buffer = frame->loader().documentLoader()->mainResourceData(); + RefPtr<SharedBuffer> buffer = frame->loader().documentLoader()->mainResourceData(); if (!buffer) return false; - String textEncodingName = frame->document()->inputEncoding(); - - return InspectorPageAgent::dataContent(buffer->data(), buffer->size(), textEncodingName, withBase64Encode, result); + return InspectorPageAgent::dataContent(buffer->data(), buffer->size(), frame->document()->encoding(), withBase64Encode, result); } -// static -bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result) +bool InspectorPageAgent::sharedBufferContent(RefPtr<SharedBuffer>&& buffer, const String& textEncodingName, bool withBase64Encode, String* result) { return dataContent(buffer ? buffer->data() : nullptr, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result); } @@ -225,8 +203,7 @@ bool InspectorPageAgent::dataContent(const char* data, unsigned size, const Stri return decodeBuffer(data, size, textEncodingName, result); } -// static -void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const URL& url, String* result, bool* base64Encoded) +void InspectorPageAgent::resourceContent(ErrorString& errorString, Frame* frame, const URL& url, String* result, bool* base64Encoded) { DocumentLoader* loader = assertDocumentLoader(errorString, frame); if (!loader) @@ -243,14 +220,14 @@ void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, success = cachedResourceContent(cachedResource(frame, url), result, base64Encoded); if (!success) - *errorString = "No resource with given URL found"; + errorString = ASCIILiteral("No resource with given URL found"); } //static String InspectorPageAgent::sourceMapURLForResource(CachedResource* cachedResource) { - DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeader, (ASCIILiteral("SourceMap"))); - DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeaderDeprecated, (ASCIILiteral("X-SourceMap"))); + static NeverDestroyed<String> sourceMapHTTPHeader(ASCIILiteral("SourceMap")); + static NeverDestroyed<String> sourceMapHTTPHeaderDeprecated(ASCIILiteral("X-SourceMap")); if (!cachedResource) return String(); @@ -277,39 +254,42 @@ String InspectorPageAgent::sourceMapURLForResource(CachedResource* cachedResourc CachedResource* InspectorPageAgent::cachedResource(Frame* frame, const URL& url) { - CachedResource* cachedResource = frame->document()->cachedResourceLoader()->cachedResource(url); + if (url.isNull()) + return nullptr; + + CachedResource* cachedResource = frame->document()->cachedResourceLoader().cachedResource(MemoryCache::removeFragmentIdentifierIfNeeded(url)); if (!cachedResource) { ResourceRequest request(url); -#if ENABLE(CACHE_PARTITIONING) - request.setCachePartition(frame->document()->topOrigin()->cachePartition()); -#endif - cachedResource = memoryCache()->resourceForRequest(request); + request.setDomainForCachePartition(frame->document()->topOrigin().domainForCachePartition()); + cachedResource = MemoryCache::singleton().resourceForRequest(request, frame->page()->sessionID()); } return cachedResource; } -Inspector::TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType) +Inspector::Protocol::Page::ResourceType InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType) { switch (resourceType) { case DocumentResource: - return Inspector::TypeBuilder::Page::ResourceType::Document; + return Inspector::Protocol::Page::ResourceType::Document; case ImageResource: - return Inspector::TypeBuilder::Page::ResourceType::Image; + return Inspector::Protocol::Page::ResourceType::Image; case FontResource: - return Inspector::TypeBuilder::Page::ResourceType::Font; + return Inspector::Protocol::Page::ResourceType::Font; case StylesheetResource: - return Inspector::TypeBuilder::Page::ResourceType::Stylesheet; + return Inspector::Protocol::Page::ResourceType::Stylesheet; case ScriptResource: - return Inspector::TypeBuilder::Page::ResourceType::Script; + return Inspector::Protocol::Page::ResourceType::Script; case XHRResource: - return Inspector::TypeBuilder::Page::ResourceType::XHR; + return Inspector::Protocol::Page::ResourceType::XHR; + case FetchResource: + return Inspector::Protocol::Page::ResourceType::Fetch; case WebSocketResource: - return Inspector::TypeBuilder::Page::ResourceType::WebSocket; + return Inspector::Protocol::Page::ResourceType::WebSocket; case OtherResource: - return Inspector::TypeBuilder::Page::ResourceType::Other; + return Inspector::Protocol::Page::ResourceType::Other; } - return Inspector::TypeBuilder::Page::ResourceType::Other; + return Inspector::Protocol::Page::ResourceType::Other; } InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const CachedResource& cachedResource) @@ -317,87 +297,106 @@ InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Ca switch (cachedResource.type()) { case CachedResource::ImageResource: return InspectorPageAgent::ImageResource; +#if ENABLE(SVG_FONTS) + case CachedResource::SVGFontResource: +#endif case CachedResource::FontResource: return InspectorPageAgent::FontResource; - case CachedResource::CSSStyleSheet: - // Fall through. #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: #endif + case CachedResource::CSSStyleSheet: return InspectorPageAgent::StylesheetResource; case CachedResource::Script: return InspectorPageAgent::ScriptResource; - case CachedResource::RawResource: - return InspectorPageAgent::XHRResource; case CachedResource::MainResource: return InspectorPageAgent::DocumentResource; + case CachedResource::MediaResource: + case CachedResource::RawResource: { + switch (cachedResource.resourceRequest().requester()) { + case ResourceRequest::Requester::Fetch: + return InspectorPageAgent::FetchResource; + case ResourceRequest::Requester::Main: + return InspectorPageAgent::DocumentResource; + default: + return InspectorPageAgent::XHRResource; + } + } default: break; } return InspectorPageAgent::OtherResource; } -Inspector::TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const CachedResource& cachedResource) +Inspector::Protocol::Page::ResourceType InspectorPageAgent::cachedResourceTypeJson(const CachedResource& cachedResource) { return resourceTypeJson(cachedResourceType(cachedResource)); } -InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents, Page* page, InspectorClient* client, InspectorOverlay* overlay) - : InspectorAgentBase(ASCIILiteral("Page"), instrumentingAgents) - , m_page(page) +RefPtr<TextResourceDecoder> InspectorPageAgent::createTextDecoder(const String& mimeType, const String& textEncodingName) +{ + if (!textEncodingName.isEmpty()) + return TextResourceDecoder::create(ASCIILiteral("text/plain"), textEncodingName); + + if (MIMETypeRegistry::isTextMIMEType(mimeType)) + return TextResourceDecoder::create(mimeType, "UTF-8"); + + if (MIMETypeRegistry::isXMLMIMEType(mimeType)) { + RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(ASCIILiteral("application/xml")); + decoder->useLenientXMLDecoding(); + return decoder; + } + + return TextResourceDecoder::create(ASCIILiteral("text/plain"), "UTF-8"); +} + +InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorClient* client, InspectorOverlay* overlay) + : InspectorAgentBase(ASCIILiteral("Page"), context) + , m_frontendDispatcher(std::make_unique<Inspector::PageFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::PageBackendDispatcher::create(context.backendDispatcher, this)) + , m_page(context.inspectedPage) , m_client(client) , m_overlay(overlay) - , m_lastScriptIdentifier(0) - , m_enabled(false) - , m_isFirstLayoutAfterOnLoad(false) - , m_originalScriptExecutionDisabled(false) - , m_ignoreScriptsEnabledNotification(false) - , m_showPaintRects(false) { } -void InspectorPageAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorPageAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorPageFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorPageBackendDispatcher::create(backendDispatcher, this); } -void InspectorPageAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorPageAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); + ErrorString unused; + disable(unused); +} - ErrorString error; - disable(&error); -#if ENABLE(TOUCH_EVENTS) - updateTouchEventEmulationInPage(false); -#endif +double InspectorPageAgent::timestamp() +{ + return m_environment.executionStopwatch()->elapsedTime(); } -void InspectorPageAgent::enable(ErrorString*) +void InspectorPageAgent::enable(ErrorString&) { m_enabled = true; - m_instrumentingAgents->setInspectorPageAgent(this); + m_instrumentingAgents.setInspectorPageAgent(this); - if (Frame* frame = mainFrame()) - m_originalScriptExecutionDisabled = !frame->settings().isScriptEnabled(); + auto stopwatch = m_environment.executionStopwatch(); + stopwatch->reset(); + stopwatch->start(); } -void InspectorPageAgent::disable(ErrorString*) +void InspectorPageAgent::disable(ErrorString&) { m_enabled = false; - m_scriptsToEvaluateOnLoad.clear(); - m_instrumentingAgents->setInspectorPageAgent(nullptr); + m_scriptsToEvaluateOnLoad = nullptr; + m_instrumentingAgents.setInspectorPageAgent(nullptr); - setScriptExecutionDisabled(nullptr, m_originalScriptExecutionDisabled); - setShowPaintRects(nullptr, false); - setShowDebugBorders(nullptr, false); - setShowFPSCounter(nullptr, false); - setEmulatedMedia(nullptr, ""); - setContinuousPaintingEnabled(nullptr, false); + ErrorString unused; + setShowPaintRects(unused, false); + setEmulatedMedia(unused, emptyString()); } -void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier) +void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString&, const String& source, String* identifier) { if (!m_scriptsToEvaluateOnLoad) m_scriptsToEvaluateOnLoad = InspectorObject::create(); @@ -411,32 +410,35 @@ void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& s m_scriptsToEvaluateOnLoad->setString(*identifier, source); } -void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier) +void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString& error, const String& identifier) { if (!m_scriptsToEvaluateOnLoad || m_scriptsToEvaluateOnLoad->find(identifier) == m_scriptsToEvaluateOnLoad->end()) { - *error = "Script not found"; + error = ASCIILiteral("Script not found"); return; } m_scriptsToEvaluateOnLoad->remove(identifier); } -void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad) +void InspectorPageAgent::reload(ErrorString&, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad) { - m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : ""; - m_page->mainFrame().loader().reload(optionalIgnoreCache ? *optionalIgnoreCache : false); + m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : emptyString(); + m_page.mainFrame().loader().reload(optionalIgnoreCache ? *optionalIgnoreCache : false); } -void InspectorPageAgent::navigate(ErrorString*, const String& url) +void InspectorPageAgent::navigate(ErrorString&, const String& url) { - UserGestureIndicator indicator(DefinitelyProcessingUserGesture); - Frame& frame = m_page->mainFrame(); - frame.loader().changeLocation(frame.document()->securityOrigin(), frame.document()->completeURL(url), "", false, false); + UserGestureIndicator indicator(ProcessingUserGesture); + Frame& frame = m_page.mainFrame(); + + ResourceRequest resourceRequest(frame.document()->completeURL(url)); + FrameLoadRequest frameRequest(frame.document()->securityOrigin(), resourceRequest, "_self", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldReplaceDocumentIfJavaScriptURL::ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow); + frame.loader().changeLocation(frameRequest); } -static PassRefPtr<Inspector::TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie) +static Ref<Inspector::Protocol::Page::Cookie> buildObjectForCookie(const Cookie& cookie) { - return Inspector::TypeBuilder::Page::Cookie::create() + return Inspector::Protocol::Page::Cookie::create() .setName(cookie.name) .setValue(cookie.value) .setDomain(cookie.domain) @@ -449,14 +451,12 @@ static PassRefPtr<Inspector::TypeBuilder::Page::Cookie> buildObjectForCookie(con .release(); } -static PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::Cookie>> buildArrayForCookies(ListHashSet<Cookie>& cookiesList) +static Ref<Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>> buildArrayForCookies(ListHashSet<Cookie>& cookiesList) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::Cookie>> cookies = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::Cookie>::create(); + auto cookies = Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>::create(); - ListHashSet<Cookie>::iterator end = cookiesList.end(); - ListHashSet<Cookie>::iterator it = cookiesList.begin(); - for (int i = 0; it != end; ++it, i++) - cookies->addItem(buildObjectForCookie(*it)); + for (const auto& cookie : cookiesList) + cookies->addItem(buildObjectForCookie(cookie)); return cookies; } @@ -465,14 +465,17 @@ static Vector<CachedResource*> cachedResourcesForFrame(Frame* frame) { Vector<CachedResource*> result; - const CachedResourceLoader::DocumentResourceMap& allResources = frame->document()->cachedResourceLoader()->allCachedResources(); - CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); - for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) { - CachedResource* cachedResource = it->value.get(); + for (auto& cachedResourceHandle : frame->document()->cachedResourceLoader().allCachedResources().values()) { + auto* cachedResource = cachedResourceHandle.get(); + if (cachedResource->resourceRequest().hiddenFromInspector()) + continue; switch (cachedResource->type()) { case CachedResource::ImageResource: // Skip images that were not auto loaded (images disabled in the user agent). +#if ENABLE(SVG_FONTS) + case CachedResource::SVGFontResource: +#endif case CachedResource::FontResource: // Skip fonts that were referenced in CSS but never used/downloaded. if (cachedResource->stillNeedsLoad()) @@ -495,14 +498,13 @@ static Vector<URL> allResourcesURLsForFrame(Frame* frame) result.append(frame->loader().documentLoader()->url()); - Vector<CachedResource*> allResources = cachedResourcesForFrame(frame); - for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) - result.append((*it)->url()); + for (auto* cachedResource : cachedResourcesForFrame(frame)) + result.append(cachedResource->url()); return result; } -void InspectorPageAgent::getCookies(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::Cookie>>& cookies) +void InspectorPageAgent::getCookies(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>>& cookies) { // If we can get raw cookies. ListHashSet<Cookie> rawCookiesList; @@ -515,23 +517,24 @@ void InspectorPageAgent::getCookies(ErrorString*, RefPtr<Inspector::TypeBuilder: // always return the same true/false value. bool rawCookiesImplemented = false; - for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) { + for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) { Document* document = frame->document(); - Vector<URL> allURLs = allResourcesURLsForFrame(frame); - for (Vector<URL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) { + if (!document) + continue; + + for (auto& url : allResourcesURLsForFrame(frame)) { Vector<Cookie> docCookiesList; - rawCookiesImplemented = getRawCookies(document, URL(ParsedURLString, *it), docCookiesList); + rawCookiesImplemented = getRawCookies(*document, URL(ParsedURLString, url), docCookiesList); + if (!rawCookiesImplemented) { // FIXME: We need duplication checking for the String representation of cookies. - // // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here // because "document" is the document of the main frame of the page. - stringCookiesList.append(document->cookie(ASSERT_NO_EXCEPTION)); + stringCookiesList.append(document->cookie().releaseReturnValue()); } else { - int cookiesSize = docCookiesList.size(); - for (int i = 0; i < cookiesSize; i++) { - if (!rawCookiesList.contains(docCookiesList[i])) - rawCookiesList.add(docCookiesList[i]); + for (auto& cookie : docCookiesList) { + if (!rawCookiesList.contains(cookie)) + rawCookiesList.add(cookie); } } } @@ -541,22 +544,24 @@ void InspectorPageAgent::getCookies(ErrorString*, RefPtr<Inspector::TypeBuilder: if (rawCookiesImplemented) cookies = buildArrayForCookies(rawCookiesList); else - cookies = Inspector::TypeBuilder::Array<TypeBuilder::Page::Cookie>::create(); + cookies = Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>::create(); } -void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url) +void InspectorPageAgent::deleteCookie(ErrorString&, const String& cookieName, const String& url) { URL parsedURL(ParsedURLString, url); - for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext(&m_page->mainFrame())) - WebCore::deleteCookie(frame->document(), parsedURL, cookieName); + for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) { + if (auto* document = frame->document()) + WebCore::deleteCookie(*document, parsedURL, cookieName); + } } -void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<Inspector::TypeBuilder::Page::FrameResourceTree>& object) +void InspectorPageAgent::getResourceTree(ErrorString&, RefPtr<Inspector::Protocol::Page::FrameResourceTree>& object) { - object = buildObjectForFrameTree(&m_page->mainFrame()); + object = buildObjectForFrameTree(&m_page.mainFrame()); } -void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded) +void InspectorPageAgent::getResourceContent(ErrorString& errorString, const String& frameId, const String& url, String* content, bool* base64Encoded) { Frame* frame = assertFrame(errorString, frameId); if (!frame) @@ -568,7 +573,6 @@ void InspectorPageAgent::getResourceContent(ErrorString* errorString, const Stri static bool textContentForCachedResource(CachedResource* cachedResource, String* result) { if (hasTextContent(cachedResource)) { - String content; bool base64Encoded; if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) { ASSERT(!base64Encoded); @@ -578,18 +582,25 @@ static bool textContentForCachedResource(CachedResource* cachedResource, String* return false; } -void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>>& results) +void InspectorPageAgent::searchInResource(ErrorString& errorString, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, const String* optionalRequestId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>& results) { - results = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>::create(); + results = Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>::create(); bool isRegex = optionalIsRegex ? *optionalIsRegex : false; bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false; - Frame* frame = frameForId(frameId); + if (optionalRequestId) { + if (InspectorNetworkAgent* networkAgent = m_instrumentingAgents.inspectorNetworkAgent()) { + networkAgent->searchInRequest(errorString, *optionalRequestId, query, caseSensitive, isRegex, results); + return; + } + } + + Frame* frame = assertFrame(errorString, frameId); if (!frame) return; - DocumentLoader* loader = frame->loader().documentLoader(); + DocumentLoader* loader = assertDocumentLoader(errorString, frame); if (!loader) return; @@ -612,134 +623,54 @@ void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, c results = ContentSearchUtilities::searchInTextByLines(content, query, caseSensitive, isRegex); } -static PassRefPtr<Inspector::TypeBuilder::Page::SearchResult> buildObjectForSearchResult(const String& frameId, const String& url, int matchesCount) +static Ref<Inspector::Protocol::Page::SearchResult> buildObjectForSearchResult(const String& frameId, const String& url, int matchesCount) { - return Inspector::TypeBuilder::Page::SearchResult::create() + return Inspector::Protocol::Page::SearchResult::create() .setUrl(url) .setFrameId(frameId) .setMatchesCount(matchesCount) .release(); } -void InspectorPageAgent::searchInResources(ErrorString*, const String& text, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::SearchResult>>& results) +void InspectorPageAgent::searchInResources(ErrorString&, const String& text, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>>& result) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::SearchResult>> searchResults = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::SearchResult>::create(); + result = Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>::create(); bool isRegex = optionalIsRegex ? *optionalIsRegex : false; bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false; JSC::Yarr::RegularExpression regex = ContentSearchUtilities::createSearchRegex(text, caseSensitive, isRegex); - for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext(&m_page->mainFrame())) { + for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) { String content; - Vector<CachedResource*> allResources = cachedResourcesForFrame(frame); - for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) { - CachedResource* cachedResource = *it; + + for (auto* cachedResource : cachedResourcesForFrame(frame)) { if (textContentForCachedResource(cachedResource, &content)) { int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, content); if (matchesCount) - searchResults->addItem(buildObjectForSearchResult(frameId(frame), cachedResource->url(), matchesCount)); + result->addItem(buildObjectForSearchResult(frameId(frame), cachedResource->url(), matchesCount)); } } + if (mainResourceContent(frame, false, &content)) { int matchesCount = ContentSearchUtilities::countRegularExpressionMatches(regex, content); if (matchesCount) - searchResults->addItem(buildObjectForSearchResult(frameId(frame), frame->document()->url(), matchesCount)); + result->addItem(buildObjectForSearchResult(frameId(frame), frame->document()->url(), matchesCount)); } } - results = searchResults; -} - -void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html) -{ - Frame* frame = assertFrame(errorString, frameId); - if (!frame) - return; - - Document* document = frame->document(); - if (!document) { - *errorString = "No Document instance to set HTML for"; - return; - } - DOMPatchSupport::patchDocument(document, html); + if (InspectorNetworkAgent* networkAgent = m_instrumentingAgents.inspectorNetworkAgent()) + networkAgent->searchOtherRequests(regex, result); } -void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show) +void InspectorPageAgent::setShowPaintRects(ErrorString&, bool show) { m_showPaintRects = show; m_client->setShowPaintRects(show); - if (!show && mainFrame() && mainFrame()->view()) - mainFrame()->view()->invalidate(); -} - -void InspectorPageAgent::canShowDebugBorders(ErrorString*, bool* outParam) -{ - *outParam = m_client->canShowDebugBorders(); -} - -void InspectorPageAgent::setShowDebugBorders(ErrorString*, bool show) -{ - m_client->setShowDebugBorders(show); - if (mainFrame() && mainFrame()->view()) - mainFrame()->view()->invalidate(); -} - -void InspectorPageAgent::canShowFPSCounter(ErrorString*, bool* outParam) -{ - *outParam = m_client->canShowFPSCounter(); -} - -void InspectorPageAgent::setShowFPSCounter(ErrorString*, bool show) -{ - m_client->setShowFPSCounter(show); - - if (mainFrame() && mainFrame()->view()) - mainFrame()->view()->invalidate(); -} - -void InspectorPageAgent::canContinuouslyPaint(ErrorString*, bool* outParam) -{ - *outParam = m_client->canContinuouslyPaint(); -} - -void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString*, bool enabled) -{ - m_client->setContinuousPaintingEnabled(enabled); - - if (!enabled && mainFrame() && mainFrame()->view()) - mainFrame()->view()->invalidate(); -} - -void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, InspectorPageBackendDispatcherHandler::Result::Enum* status) -{ - bool disabledByScriptController = false; - bool disabledInSettings = false; - Frame* frame = mainFrame(); - if (frame) { - disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript); - disabledInSettings = !frame->settings().isScriptEnabled(); - } - - if (!disabledByScriptController) { - *status = InspectorPageBackendDispatcherHandler::Result::Allowed; + if (m_client->overridesShowPaintRects()) return; - } - - if (disabledInSettings) - *status = InspectorPageBackendDispatcherHandler::Result::Disabled; - else - *status = InspectorPageBackendDispatcherHandler::Result::Forbidden; -} -void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value) -{ - if (!mainFrame()) - return; - - m_ignoreScriptsEnabledNotification = true; - mainFrame()->settings().setScriptEnabled(!value); - m_ignoreScriptsEnabledNotification = false; + m_overlay->setShowingPaintRects(show); } void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld& world) @@ -747,14 +678,10 @@ void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWor if (&world != &mainThreadNormalWorld()) return; - if (!m_frontendDispatcher) - return; - if (m_scriptsToEvaluateOnLoad) { - InspectorObject::const_iterator end = m_scriptsToEvaluateOnLoad->end(); - for (InspectorObject::const_iterator it = m_scriptsToEvaluateOnLoad->begin(); it != end; ++it) { + for (auto& keyValuePair : *m_scriptsToEvaluateOnLoad) { String scriptText; - if (it->value->asString(&scriptText)) + if (keyValuePair.value->asString(scriptText)) frame->script().executeScript(scriptText); } } @@ -766,26 +693,26 @@ void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWor void InspectorPageAgent::domContentEventFired() { m_isFirstLayoutAfterOnLoad = true; - m_frontendDispatcher->domContentEventFired(currentTime()); + m_frontendDispatcher->domContentEventFired(timestamp()); } void InspectorPageAgent::loadEventFired() { - m_frontendDispatcher->loadEventFired(currentTime()); + m_frontendDispatcher->loadEventFired(timestamp()); } -void InspectorPageAgent::frameNavigated(DocumentLoader* loader) +void InspectorPageAgent::frameNavigated(Frame& frame) { - if (loader->frame()->isMainFrame()) { + if (frame.isMainFrame()) { m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce; m_pendingScriptToEvaluateOnLoadOnce = String(); } - m_frontendDispatcher->frameNavigated(buildObjectForFrame(loader->frame())); + m_frontendDispatcher->frameNavigated(buildObjectForFrame(&frame)); } -void InspectorPageAgent::frameDetached(Frame* frame) +void InspectorPageAgent::frameDetached(Frame& frame) { - HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(frame); + HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(&frame); if (iterator != m_frameToIdentifier.end()) { m_frontendDispatcher->frameDetached(iterator->value); m_identifierToFrame.remove(iterator->value); @@ -793,10 +720,9 @@ void InspectorPageAgent::frameDetached(Frame* frame) } } -Frame* InspectorPageAgent::mainFrame() +MainFrame& InspectorPageAgent::mainFrame() { - // FIXME: This should return a Frame& - return &m_page->mainFrame(); + return m_page.mainFrame(); } Frame* InspectorPageAgent::frameForId(const String& frameId) @@ -807,7 +733,7 @@ Frame* InspectorPageAgent::frameForId(const String& frameId) String InspectorPageAgent::frameId(Frame* frame) { if (!frame) - return ""; + return emptyString(); String identifier = m_frameToIdentifier.get(frame); if (identifier.isNull()) { identifier = IdentifiersFactory::createIdentifier(); @@ -825,7 +751,7 @@ bool InspectorPageAgent::hasIdForFrame(Frame* frame) const String InspectorPageAgent::loaderId(DocumentLoader* loader) { if (!loader) - return ""; + return emptyString(); String identifier = m_loaderToIdentifier.get(loader); if (identifier.isNull()) { identifier = IdentifiersFactory::createIdentifier(); @@ -836,37 +762,34 @@ String InspectorPageAgent::loaderId(DocumentLoader* loader) Frame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString) { - for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { - RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin(); + for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) { + Ref<SecurityOrigin> documentOrigin = frame->document()->securityOrigin(); if (documentOrigin->toRawString() == originRawString) return frame; } return nullptr; } -Frame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId) +Frame* InspectorPageAgent::assertFrame(ErrorString& errorString, const String& frameId) { Frame* frame = frameForId(frameId); if (!frame) - *errorString = "No frame for given id found"; + errorString = ASCIILiteral("No frame for given id found"); return frame; } -// static -DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, Frame* frame) +DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString& errorString, Frame* frame) { FrameLoader& frameLoader = frame->loader(); DocumentLoader* documentLoader = frameLoader.documentLoader(); if (!documentLoader) - *errorString = "No documentLoader for given frame found"; + errorString = ASCIILiteral("No documentLoader for given frame found"); return documentLoader; } -void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader) +void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader& loader) { - HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader); - if (iterator != m_loaderToIdentifier.end()) - m_loaderToIdentifier.remove(iterator); + m_loaderToIdentifier.remove(&loader); } void InspectorPageAgent::frameStartedLoading(Frame& frame) @@ -889,31 +812,26 @@ void InspectorPageAgent::frameClearedScheduledNavigation(Frame& frame) m_frontendDispatcher->frameClearedScheduledNavigation(frameId(&frame)); } -void InspectorPageAgent::willRunJavaScriptDialog(const String& message) +void InspectorPageAgent::didPaint(RenderObject& renderer, const LayoutRect& rect) { - m_frontendDispatcher->javascriptDialogOpening(message); -} + if (!m_enabled || !m_showPaintRects) + return; -void InspectorPageAgent::didRunJavaScriptDialog() -{ - m_frontendDispatcher->javascriptDialogClosed(); -} + LayoutRect absoluteRect = LayoutRect(renderer.localToAbsoluteQuad(FloatRect(rect)).boundingBox()); + FrameView* view = renderer.document().view(); -void InspectorPageAgent::didPaint(GraphicsContext* context, const LayoutRect& rect) -{ - if (!m_enabled || m_client->overridesShowPaintRects() || !m_showPaintRects) - return; + LayoutRect rootRect = absoluteRect; + if (!view->frame().isMainFrame()) { + IntRect rootViewRect = view->contentsToRootView(snappedIntRect(absoluteRect)); + rootRect = view->frame().mainFrame().view()->rootViewToContents(rootViewRect); + } - static int colorSelector = 0; - const Color colors[] = { - Color(0xFF, 0, 0, 0x3F), - Color(0xFF, 0, 0xFF, 0x3F), - Color(0, 0, 0xFF, 0x3F), - }; + if (m_client->overridesShowPaintRects()) { + m_client->showPaintRect(rootRect); + return; + } - LayoutRect inflatedRect(rect); - inflatedRect.inflate(-1); - m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]); + m_overlay->showPaintRect(rootRect); } void InspectorPageAgent::didLayout() @@ -940,50 +858,46 @@ void InspectorPageAgent::didRecalculateStyle() m_overlay->update(); } -void InspectorPageAgent::scriptsEnabled(bool isEnabled) +Ref<Inspector::Protocol::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame) { - if (m_ignoreScriptsEnabledNotification) - return; - - m_frontendDispatcher->scriptsEnabled(isEnabled); -} + ASSERT_ARG(frame, frame); -PassRefPtr<Inspector::TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame) -{ - RefPtr<Inspector::TypeBuilder::Page::Frame> frameObject = Inspector::TypeBuilder::Page::Frame::create() + auto frameObject = Inspector::Protocol::Page::Frame::create() .setId(frameId(frame)) .setLoaderId(loaderId(frame->loader().documentLoader())) .setUrl(frame->document()->url().string()) .setMimeType(frame->loader().documentLoader()->responseMIMEType()) - .setSecurityOrigin(frame->document()->securityOrigin()->toRawString()); + .setSecurityOrigin(frame->document()->securityOrigin().toRawString()) + .release(); if (frame->tree().parent()) frameObject->setParentId(frameId(frame->tree().parent())); if (frame->ownerElement()) { String name = frame->ownerElement()->getNameAttribute(); if (name.isEmpty()) - name = frame->ownerElement()->getAttribute(HTMLNames::idAttr); + name = frame->ownerElement()->attributeWithoutSynchronization(HTMLNames::idAttr); frameObject->setName(name); } return frameObject; } -PassRefPtr<Inspector::TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame) +Ref<Inspector::Protocol::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame) { - RefPtr<Inspector::TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame); - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::FrameResourceTree::Resources>> subresources = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::FrameResourceTree::Resources>::create(); - RefPtr<Inspector::TypeBuilder::Page::FrameResourceTree> result = Inspector::TypeBuilder::Page::FrameResourceTree::create() - .setFrame(frameObject) - .setResources(subresources); + ASSERT_ARG(frame, frame); - Vector<CachedResource*> allResources = cachedResourcesForFrame(frame); - for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) { - CachedResource* cachedResource = *it; + Ref<Inspector::Protocol::Page::Frame> frameObject = buildObjectForFrame(frame); + auto subresources = Inspector::Protocol::Array<Inspector::Protocol::Page::FrameResource>::create(); + auto result = Inspector::Protocol::Page::FrameResourceTree::create() + .setFrame(WTFMove(frameObject)) + .setResources(subresources.copyRef()) + .release(); - RefPtr<Inspector::TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = Inspector::TypeBuilder::Page::FrameResourceTree::Resources::create() + for (auto* cachedResource : cachedResourcesForFrame(frame)) { + auto resourceObject = Inspector::Protocol::Page::FrameResource::create() .setUrl(cachedResource->url()) .setType(cachedResourceTypeJson(*cachedResource)) - .setMimeType(cachedResource->response().mimeType()); + .setMimeType(cachedResource->response().mimeType()) + .release(); if (cachedResource->wasCanceled()) resourceObject->setCanceled(true); else if (cachedResource->status() == CachedResource::LoadError) @@ -991,13 +905,16 @@ PassRefPtr<Inspector::TypeBuilder::Page::FrameResourceTree> InspectorPageAgent:: String sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(cachedResource); if (!sourceMappingURL.isEmpty()) resourceObject->setSourceMapURL(sourceMappingURL); - subresources->addItem(resourceObject); + String targetId = cachedResource->resourceRequest().initiatorIdentifier(); + if (!targetId.isEmpty()) + resourceObject->setTargetId(targetId); + subresources->addItem(WTFMove(resourceObject)); } - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::FrameResourceTree>> childrenArray; + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::FrameResourceTree>> childrenArray; for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) { if (!childrenArray) { - childrenArray = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::FrameResourceTree>::create(); + childrenArray = Inspector::Protocol::Array<Inspector::Protocol::Page::FrameResourceTree>::create(); result->setChildFrames(childrenArray); } childrenArray->addItem(buildObjectForFrameTree(child)); @@ -1005,113 +922,81 @@ PassRefPtr<Inspector::TypeBuilder::Page::FrameResourceTree> InspectorPageAgent:: return result; } -#if ENABLE(TOUCH_EVENTS) -void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled) -{ - if (mainFrame()) - mainFrame()->settings().setTouchEventEmulationEnabled(enabled); -} -#endif - -void InspectorPageAgent::setTouchEmulationEnabled(ErrorString* error, bool enabled) -{ -#if ENABLE(TOUCH_EVENTS) - UNUSED_PARAM(error); - updateTouchEventEmulationInPage(enabled); -#else - *error = "Touch events emulation not supported"; - UNUSED_PARAM(enabled); -#endif -} - -void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media) +void InspectorPageAgent::setEmulatedMedia(ErrorString&, const String& media) { if (media == m_emulatedMedia) return; m_emulatedMedia = media; - Document* document = m_page->mainFrame().document(); + Document* document = m_page.mainFrame().document(); if (document) { - document->styleResolverChanged(RecalcStyleImmediately); + document->styleScope().didChangeStyleSheetEnvironment(); document->updateLayout(); } } -void InspectorPageAgent::applyEmulatedMedia(String* media) +void InspectorPageAgent::applyEmulatedMedia(String& media) { if (!m_emulatedMedia.isEmpty()) - *media = m_emulatedMedia; + media = m_emulatedMedia; } -void InspectorPageAgent::getCompositingBordersVisible(ErrorString*, bool* outParam) +void InspectorPageAgent::getCompositingBordersVisible(ErrorString&, bool* outParam) { - *outParam = m_page->settings().showDebugBorders() || m_page->settings().showRepaintCounter(); + *outParam = m_page.settings().showDebugBorders() || m_page.settings().showRepaintCounter(); } -void InspectorPageAgent::setCompositingBordersVisible(ErrorString*, bool visible) +void InspectorPageAgent::setCompositingBordersVisible(ErrorString&, bool visible) { - m_page->settings().setShowDebugBorders(visible); - m_page->settings().setShowRepaintCounter(visible); + m_page.settings().setShowDebugBorders(visible); + m_page.settings().setShowRepaintCounter(visible); } -void InspectorPageAgent::snapshotNode(ErrorString* errorString, int nodeId, String* outDataURL) +void InspectorPageAgent::snapshotNode(ErrorString& errorString, int nodeId, String* outDataURL) { - Frame* frame = mainFrame(); - ASSERT(frame); + Frame& frame = mainFrame(); - InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent(); + InspectorDOMAgent* domAgent = m_instrumentingAgents.inspectorDOMAgent(); ASSERT(domAgent); Node* node = domAgent->assertNode(errorString, nodeId); if (!node) return; - std::unique_ptr<ImageBuffer> snapshot = WebCore::snapshotNode(*frame, *node); + std::unique_ptr<ImageBuffer> snapshot = WebCore::snapshotNode(frame, *node); if (!snapshot) { - *errorString = ASCIILiteral("Could not capture snapshot"); + errorString = ASCIILiteral("Could not capture snapshot"); return; } *outDataURL = snapshot->toDataURL(ASCIILiteral("image/png")); } -void InspectorPageAgent::snapshotRect(ErrorString* errorString, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL) +void InspectorPageAgent::snapshotRect(ErrorString& errorString, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL) { - Frame* frame = mainFrame(); - ASSERT(frame); + Frame& frame = mainFrame(); SnapshotOptions options = SnapshotOptionsNone; if (coordinateSystem == "Viewport") options |= SnapshotOptionsInViewCoordinates; IntRect rectangle(x, y, width, height); - std::unique_ptr<ImageBuffer> snapshot = snapshotFrameRect(*frame, rectangle, options); + std::unique_ptr<ImageBuffer> snapshot = snapshotFrameRect(frame, rectangle, options); if (!snapshot) { - *errorString = ASCIILiteral("Could not capture snapshot"); + errorString = ASCIILiteral("Could not capture snapshot"); return; } *outDataURL = snapshot->toDataURL(ASCIILiteral("image/png")); } -void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText) -{ - if (!m_client->handleJavaScriptDialog(accept, promptText)) - *errorString = "Could not handle JavaScript dialog"; -} - -void InspectorPageAgent::archive(ErrorString* errorString, String* data) +void InspectorPageAgent::archive(ErrorString& errorString, String* data) { - Frame* frame = mainFrame(); - if (!frame) { - *errorString = "No main frame"; - return; - } - #if ENABLE(WEB_ARCHIVE) && USE(CF) + Frame& frame = mainFrame(); RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame); if (!archive) { - *errorString = "Could not create web archive for main frame"; + errorString = ASCIILiteral("Could not create web archive for main frame"); return; } @@ -1119,10 +1004,8 @@ void InspectorPageAgent::archive(ErrorString* errorString, String* data) *data = base64Encode(CFDataGetBytePtr(buffer.get()), CFDataGetLength(buffer.get())); #else UNUSED_PARAM(data); - *errorString = "No support for creating archives"; + errorString = ASCIILiteral("No support for creating archives"); #endif } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorPageAgent.h b/Source/WebCore/inspector/InspectorPageAgent.h index 570657629..7e928ae0c 100644 --- a/Source/WebCore/inspector/InspectorPageAgent.h +++ b/Source/WebCore/inspector/InspectorPageAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,23 +29,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorPageAgent_h -#define InspectorPageAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include "IntSize.h" #include "LayoutRect.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <wtf/HashMap.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace Inspector { -class InspectorArray; class InspectorObject; } @@ -54,22 +48,22 @@ class CachedResource; class DOMWrapperWorld; class DocumentLoader; class Frame; -class Frontend; -class GraphicsContext; class InspectorClient; class InspectorOverlay; -class InstrumentingAgents; -class URL; +class MainFrame; class Page; +class RenderObject; class SharedBuffer; class TextResourceDecoder; +class URL; typedef String ErrorString; -class InspectorPageAgent : public InspectorAgentBase, public Inspector::InspectorPageBackendDispatcherHandler { +class InspectorPageAgent final : public InspectorAgentBase, public Inspector::PageBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorPageAgent); + WTF_MAKE_FAST_ALLOCATED; public: - InspectorPageAgent(InstrumentingAgents*, Page*, InspectorClient*, InspectorOverlay*); + InspectorPageAgent(PageAgentContext&, InspectorClient*, InspectorOverlay*); enum ResourceType { DocumentResource, @@ -78,122 +72,102 @@ public: FontResource, ScriptResource, XHRResource, + FetchResource, WebSocketResource, OtherResource }; static bool cachedResourceContent(CachedResource*, String* result, bool* base64Encoded); - static bool sharedBufferContent(PassRefPtr<SharedBuffer>, const String& textEncodingName, bool withBase64Encode, String* result); - static void resourceContent(ErrorString*, Frame*, const URL&, String* result, bool* base64Encoded); + static bool sharedBufferContent(RefPtr<SharedBuffer>&&, const String& textEncodingName, bool withBase64Encode, String* result); + static void resourceContent(ErrorString&, Frame*, const URL&, String* result, bool* base64Encoded); static String sourceMapURLForResource(CachedResource*); - static PassRefPtr<SharedBuffer> resourceData(Frame*, const URL&, String* textEncodingName); static CachedResource* cachedResource(Frame*, const URL&); - static Inspector::TypeBuilder::Page::ResourceType::Enum resourceTypeJson(ResourceType); + static Inspector::Protocol::Page::ResourceType resourceTypeJson(ResourceType); static ResourceType cachedResourceType(const CachedResource&); - static Inspector::TypeBuilder::Page::ResourceType::Enum cachedResourceTypeJson(const CachedResource&); + static Inspector::Protocol::Page::ResourceType cachedResourceTypeJson(const CachedResource&); + static RefPtr<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName); // Page API for InspectorFrontend - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* result) override; - virtual void removeScriptToEvaluateOnLoad(ErrorString*, const String& identifier) override; - virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad) override; - virtual void navigate(ErrorString*, const String& url) override; - virtual void getCookies(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::Cookie>>& cookies) override; - virtual void deleteCookie(ErrorString*, const String& cookieName, const String& url) override; - virtual void getResourceTree(ErrorString*, RefPtr<Inspector::TypeBuilder::Page::FrameResourceTree>&) override; - virtual void getResourceContent(ErrorString*, const String& frameId, const String& url, String* content, bool* base64Encoded) override; - virtual void searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch>>&) override; - virtual void searchInResources(ErrorString*, const String&, const bool* caseSensitive, const bool* isRegex, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Page::SearchResult>>&) override; - virtual void setDocumentContent(ErrorString*, const String& frameId, const String& html) override; - virtual void setShowPaintRects(ErrorString*, bool show) override; - virtual void canShowDebugBorders(ErrorString*, bool*) override; - virtual void setShowDebugBorders(ErrorString*, bool show) override; - virtual void canShowFPSCounter(ErrorString*, bool*) override; - virtual void setShowFPSCounter(ErrorString*, bool show) override; - virtual void canContinuouslyPaint(ErrorString*, bool*) override; - virtual void setContinuousPaintingEnabled(ErrorString*, bool enabled) override; - virtual void getScriptExecutionStatus(ErrorString*, Inspector::InspectorPageBackendDispatcherHandler::Result::Enum*) override; - virtual void setScriptExecutionDisabled(ErrorString*, bool) override; - virtual void setTouchEmulationEnabled(ErrorString*, bool) override; - virtual void setEmulatedMedia(ErrorString*, const String&) override; - virtual void getCompositingBordersVisible(ErrorString*, bool* out_param) override; - virtual void setCompositingBordersVisible(ErrorString*, bool) override; - virtual void snapshotNode(ErrorString*, int nodeId, String* outDataURL) override; - virtual void snapshotRect(ErrorString*, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL) override; - virtual void handleJavaScriptDialog(ErrorString*, bool accept, const String* promptText) override; - virtual void archive(ErrorString*, String* data) override; - - // InspectorInstrumentation API + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void addScriptToEvaluateOnLoad(ErrorString&, const String& source, String* result) override; + void removeScriptToEvaluateOnLoad(ErrorString&, const String& identifier) override; + void reload(ErrorString&, const bool* const optionalIgnoreCache, const String* const optionalScriptToEvaluateOnLoad) override; + void navigate(ErrorString&, const String& url) override; + void getCookies(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::Cookie>>& cookies) override; + void deleteCookie(ErrorString&, const String& cookieName, const String& url) override; + void getResourceTree(ErrorString&, RefPtr<Inspector::Protocol::Page::FrameResourceTree>&) override; + void getResourceContent(ErrorString&, const String& frameId, const String& url, String* content, bool* base64Encoded) override; + void searchInResource(ErrorString&, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, const String* const optionalRequestId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::GenericTypes::SearchMatch>>&) override; + void searchInResources(ErrorString&, const String&, const bool* const caseSensitive, const bool* const isRegex, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Page::SearchResult>>&) override; + void setShowPaintRects(ErrorString&, bool show) override; + void setEmulatedMedia(ErrorString&, const String&) override; + void getCompositingBordersVisible(ErrorString&, bool* out_param) override; + void setCompositingBordersVisible(ErrorString&, bool) override; + void snapshotNode(ErrorString&, int nodeId, String* outDataURL) override; + void snapshotRect(ErrorString&, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL) override; + void archive(ErrorString&, String* data) override; + + // InspectorInstrumentation void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld&); void domContentEventFired(); void loadEventFired(); - void frameNavigated(DocumentLoader*); - void frameDetached(Frame*); - void loaderDetachedFromFrame(DocumentLoader*); + void frameNavigated(Frame&); + void frameDetached(Frame&); + void loaderDetachedFromFrame(DocumentLoader&); void frameStartedLoading(Frame&); void frameStoppedLoading(Frame&); void frameScheduledNavigation(Frame&, double delay); void frameClearedScheduledNavigation(Frame&); - void willRunJavaScriptDialog(const String& message); - void didRunJavaScriptDialog(); - void applyEmulatedMedia(String*); - void didPaint(GraphicsContext*, const LayoutRect&); + void applyEmulatedMedia(String&); + void didPaint(RenderObject&, const LayoutRect&); void didLayout(); void didScroll(); void didRecalculateStyle(); - void scriptsEnabled(bool isEnabled); // Inspector Controller API - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; // Cross-agents API - Page* page() { return m_page; } - Frame* mainFrame(); - String createIdentifier(); + Page& page() { return m_page; } + MainFrame& mainFrame(); Frame* frameForId(const String& frameId); - String frameId(Frame*); + WEBCORE_EXPORT String frameId(Frame*); bool hasIdForFrame(Frame*) const; String loaderId(DocumentLoader*); Frame* findFrameWithSecurityOrigin(const String& originRawString); - Frame* assertFrame(ErrorString*, const String& frameId); - static DocumentLoader* assertDocumentLoader(ErrorString*, Frame*); + Frame* assertFrame(ErrorString&, const String& frameId); + static DocumentLoader* assertDocumentLoader(ErrorString&, Frame*); private: -#if ENABLE(TOUCH_EVENTS) - void updateTouchEventEmulationInPage(bool); -#endif + double timestamp(); static bool mainResourceContent(Frame*, bool withBase64Encode, String* result); static bool dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result); - PassRefPtr<Inspector::TypeBuilder::Page::Frame> buildObjectForFrame(Frame*); - PassRefPtr<Inspector::TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(Frame*); - Page* m_page; - InspectorClient* m_client; - std::unique_ptr<Inspector::InspectorPageFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorPageBackendDispatcher> m_backendDispatcher; - InspectorOverlay* m_overlay; - long m_lastScriptIdentifier; + Ref<Inspector::Protocol::Page::Frame> buildObjectForFrame(Frame*); + Ref<Inspector::Protocol::Page::FrameResourceTree> buildObjectForFrameTree(Frame*); + + std::unique_ptr<Inspector::PageFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::PageBackendDispatcher> m_backendDispatcher; + + Page& m_page; + InspectorClient* m_client { nullptr }; + InspectorOverlay* m_overlay { nullptr }; + + long m_lastScriptIdentifier { 0 }; String m_pendingScriptToEvaluateOnLoadOnce; String m_scriptToEvaluateOnLoadOnce; HashMap<Frame*, String> m_frameToIdentifier; HashMap<String, Frame*> m_identifierToFrame; HashMap<DocumentLoader*, String> m_loaderToIdentifier; - bool m_enabled; - bool m_isFirstLayoutAfterOnLoad; - bool m_originalScriptExecutionDisabled; - bool m_ignoreScriptsEnabledNotification; - bool m_showPaintRects; + bool m_enabled { false }; + bool m_isFirstLayoutAfterOnLoad { false }; + bool m_showPaintRects { false }; String m_emulatedMedia; RefPtr<Inspector::InspectorObject> m_scriptsToEvaluateOnLoad; }; - } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorPagerAgent_h) diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.cpp b/Source/WebCore/inspector/InspectorProfilerAgent.cpp deleted file mode 100644 index 5acc3a161..000000000 --- a/Source/WebCore/inspector/InspectorProfilerAgent.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorProfilerAgent.h" - -#include "CommandLineAPIHost.h" -#include "Console.h" -#include "ConsoleAPITypes.h" -#include "ConsoleTypes.h" -#include "InspectorConsoleAgent.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InstrumentingAgents.h" -#include "URL.h" -#include "Page.h" -#include "PageInjectedScriptManager.h" -#include "PageScriptDebugServer.h" -#include "ScriptHeapSnapshot.h" -#include "ScriptProfile.h" -#include "ScriptProfiler.h" -#include "WorkerScriptDebugServer.h" -#include <bindings/ScriptObject.h> -#include <inspector/InjectedScript.h> -#include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> -#include <wtf/OwnPtr.h> -#include <wtf/text/StringConcatenate.h> - -using namespace Inspector; - -namespace WebCore { - -static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated"; -static const char* const CPUProfileType = "CPU"; -static const char* const HeapProfileType = "HEAP"; - - -class PageProfilerAgent : public InspectorProfilerAgent { -public: - PageProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, PageInjectedScriptManager* injectedScriptManager) - : InspectorProfilerAgent(instrumentingAgents, consoleAgent, injectedScriptManager), m_inspectedPage(inspectedPage) { } - virtual ~PageProfilerAgent() { } - -private: - virtual void recompileScript() override - { - PageScriptDebugServer::shared().recompileAllJSFunctions(); - } - - virtual void startProfiling(const String& title) override - { - ScriptProfiler::startForPage(m_inspectedPage, title); - } - - virtual PassRefPtr<ScriptProfile> stopProfiling(const String& title) override - { - return ScriptProfiler::stopForPage(m_inspectedPage, title); - } - - Page* m_inspectedPage; -}; - -std::unique_ptr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, PageInjectedScriptManager* injectedScriptManager) -{ - return std::make_unique<PageProfilerAgent>(instrumentingAgents, consoleAgent, inspectedPage, injectedScriptManager); -} - -class WorkerProfilerAgent : public InspectorProfilerAgent { -public: - WorkerProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, WorkerGlobalScope* workerGlobalScope, PageInjectedScriptManager* injectedScriptManager) - : InspectorProfilerAgent(instrumentingAgents, consoleAgent, injectedScriptManager), m_workerGlobalScope(workerGlobalScope) { } - virtual ~WorkerProfilerAgent() { } - -private: - virtual void recompileScript() override { } - - virtual void startProfiling(const String& title) override - { - ScriptProfiler::startForWorkerGlobalScope(m_workerGlobalScope, title); - } - - virtual PassRefPtr<ScriptProfile> stopProfiling(const String& title) override - { - return ScriptProfiler::stopForWorkerGlobalScope(m_workerGlobalScope, title); - } - - WorkerGlobalScope* m_workerGlobalScope; -}; - -std::unique_ptr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, WorkerGlobalScope* workerGlobalScope, PageInjectedScriptManager* injectedScriptManager) -{ - return std::make_unique<WorkerProfilerAgent>(instrumentingAgents, consoleAgent, workerGlobalScope, injectedScriptManager); -} - -InspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, PageInjectedScriptManager* injectedScriptManager) - : InspectorAgentBase(ASCIILiteral("Profiler"), instrumentingAgents) - , m_consoleAgent(consoleAgent) - , m_injectedScriptManager(injectedScriptManager) - , m_enabled(false) - , m_profileHeadersRequested(false) - , m_recordingCPUProfile(false) - , m_currentUserInitiatedProfileNumber(-1) - , m_nextUserInitiatedProfileNumber(1) - , m_nextUserInitiatedHeapSnapshotNumber(1) - , m_profileNameIdleTimeMap(ScriptProfiler::currentProfileNameIdleTimeMap()) -{ - m_instrumentingAgents->setInspectorProfilerAgent(this); -} - -InspectorProfilerAgent::~InspectorProfilerAgent() -{ - m_instrumentingAgents->setInspectorProfilerAgent(nullptr); -} - -void InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, unsigned columnNumber, const String& sourceURL) -{ - RefPtr<ScriptProfile> profile = prpProfile; - m_profiles.add(profile->uid(), profile); - if (m_frontendDispatcher && m_profileHeadersRequested) - m_frontendDispatcher->addProfileHeader(createProfileHeader(*profile)); - addProfileFinishedMessageToConsole(profile, lineNumber, columnNumber, sourceURL); -} - -void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, unsigned columnNumber, const String& sourceURL) -{ - if (!m_frontendDispatcher) - return; - RefPtr<ScriptProfile> profile = prpProfile; - String message = makeString(profile->title(), '#', String::number(profile->uid())); - m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileEndMessageType, DebugMessageLevel, message, sourceURL, lineNumber, columnNumber); -} - -void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL) -{ - if (!m_frontendDispatcher) - return; - m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileMessageType, DebugMessageLevel, title, sourceURL, lineNumber, columnNumber); -} - -void InspectorProfilerAgent::collectGarbage(WebCore::ErrorString*) -{ - ScriptProfiler::collectGarbage(); -} - -PassRefPtr<Inspector::TypeBuilder::Profiler::ProfileHeader> InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile) -{ - return Inspector::TypeBuilder::Profiler::ProfileHeader::create() - .setTypeId(Inspector::TypeBuilder::Profiler::ProfileHeader::TypeId::CPU) - .setUid(profile.uid()) - .setTitle(profile.title()) - .release(); -} - -PassRefPtr<Inspector::TypeBuilder::Profiler::ProfileHeader> InspectorProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot) -{ - RefPtr<Inspector::TypeBuilder::Profiler::ProfileHeader> header = Inspector::TypeBuilder::Profiler::ProfileHeader::create() - .setTypeId(Inspector::TypeBuilder::Profiler::ProfileHeader::TypeId::HEAP) - .setUid(snapshot.uid()) - .setTitle(snapshot.title()); - header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId()); - return header.release(); -} - -void InspectorProfilerAgent::isSampling(ErrorString*, bool* result) -{ - *result = ScriptProfiler::isSampling(); -} - -void InspectorProfilerAgent::hasHeapProfiler(ErrorString*, bool* result) -{ - *result = ScriptProfiler::hasHeapProfiler(); -} - -void InspectorProfilerAgent::enable(ErrorString*) -{ - enable(false); -} - -void InspectorProfilerAgent::disable(ErrorString*) -{ - disable(false); -} - -void InspectorProfilerAgent::disable(bool skipRecompile) -{ - if (!m_enabled) - return; - m_enabled = false; - m_profileHeadersRequested = false; - if (!skipRecompile) - recompileScript(); -} - -void InspectorProfilerAgent::enable(bool skipRecompile) -{ - if (m_enabled) - return; - m_enabled = true; - if (!skipRecompile) - recompileScript(); -} - -String InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber) -{ - if (incrementProfileNumber) - m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++; - - return makeString(UserInitiatedProfileName, '.', String::number(m_currentUserInitiatedProfileNumber)); -} - -void InspectorProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Profiler::ProfileHeader>>& headers) -{ - m_profileHeadersRequested = true; - headers = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Profiler::ProfileHeader>::create(); - - ProfilesMap::iterator profilesEnd = m_profiles.end(); - for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it) - headers->addItem(createProfileHeader(*it->value)); - HeapSnapshotsMap::iterator snapshotsEnd = m_snapshots.end(); - for (HeapSnapshotsMap::iterator it = m_snapshots.begin(); it != snapshotsEnd; ++it) - headers->addItem(createSnapshotHeader(*it->value)); -} - -namespace { - -class OutputStream : public ScriptHeapSnapshot::OutputStream { -public: - OutputStream(InspectorProfilerFrontendDispatcher* frontend, unsigned uid) - : m_frontendDispatcher(frontend), m_uid(uid) { } - void Write(const String& chunk) override { m_frontendDispatcher->addHeapSnapshotChunk(m_uid, chunk); } - void Close() override { m_frontendDispatcher->finishHeapSnapshot(m_uid); } -private: - InspectorProfilerFrontendDispatcher* m_frontendDispatcher; - int m_uid; -}; - -} // namespace - -void InspectorProfilerAgent::getCPUProfile(ErrorString* errorString, int rawUid, RefPtr<Inspector::TypeBuilder::Profiler::CPUProfile>& profileObject) -{ - unsigned uid = static_cast<unsigned>(rawUid); - ProfilesMap::iterator it = m_profiles.find(uid); - if (it == m_profiles.end()) { - *errorString = "Profile wasn't found"; - return; - } - profileObject = Inspector::TypeBuilder::Profiler::CPUProfile::create(); - profileObject->setHead(it->value->buildInspectorObjectForHead()); - profileObject->setIdleTime(it->value->idleTime()); -} - -void InspectorProfilerAgent::getHeapSnapshot(ErrorString* errorString, int rawUid) -{ - unsigned uid = static_cast<unsigned>(rawUid); - HeapSnapshotsMap::iterator it = m_snapshots.find(uid); - if (it == m_snapshots.end()) { - *errorString = "Profile wasn't found"; - return; - } - RefPtr<ScriptHeapSnapshot> snapshot = it->value; - if (m_frontendDispatcher) { - OutputStream stream(m_frontendDispatcher.get(), uid); - snapshot->writeJSON(&stream); - } -} - -void InspectorProfilerAgent::removeProfile(ErrorString*, const String& type, int rawUid) -{ - unsigned uid = static_cast<unsigned>(rawUid); - if (type == CPUProfileType) - m_profiles.remove(uid); - else if (type == HeapProfileType) - m_snapshots.remove(uid); -} - -void InspectorProfilerAgent::resetState() -{ - stop(); - m_profiles.clear(); - m_snapshots.clear(); - m_currentUserInitiatedProfileNumber = 1; - m_nextUserInitiatedProfileNumber = 1; - m_nextUserInitiatedHeapSnapshotNumber = 1; - resetFrontendProfiles(); - - if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) - commandLineAPIHost->clearInspectedObjects(); -} - -void InspectorProfilerAgent::resetFrontendProfiles() -{ - if (!m_frontendDispatcher) - return; - if (!m_profileHeadersRequested) - return; - if (m_profiles.isEmpty() && m_snapshots.isEmpty()) - m_frontendDispatcher->resetProfiles(); -} - -void InspectorProfilerAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) -{ - m_frontendDispatcher = std::make_unique<InspectorProfilerFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorProfilerBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorProfilerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason) -{ - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - stop(); - - bool skipRecompile = reason == InspectorDisconnectReason::InspectedTargetDestroyed; - disable(skipRecompile); -} - -void InspectorProfilerAgent::start(ErrorString*) -{ - if (m_recordingCPUProfile) - return; - if (!enabled()) { - enable(true); - PageScriptDebugServer::shared().recompileAllJSFunctions(); - } - m_recordingCPUProfile = true; - String title = getCurrentUserInitiatedProfileName(true); - startProfiling(title); - addStartProfilingMessageToConsole(title, 0, 0, String()); - toggleRecordButton(true); -} - -void InspectorProfilerAgent::stop(ErrorString*) -{ - if (!m_recordingCPUProfile) - return; - m_recordingCPUProfile = false; - String title = getCurrentUserInitiatedProfileName(); - RefPtr<ScriptProfile> profile = stopProfiling(title); - if (profile) - addProfile(profile, 0, 0, String()); - toggleRecordButton(false); -} - -namespace { - -class HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress { -public: - explicit HeapSnapshotProgress(InspectorProfilerFrontendDispatcher* frontend) - : m_frontendDispatcher(frontend) { } - void Start(int totalWork) override - { - m_totalWork = totalWork; - } - void Worked(int workDone) override - { - if (m_frontendDispatcher) - m_frontendDispatcher->reportHeapSnapshotProgress(workDone, m_totalWork); - } - void Done() override { } - bool isCanceled() { return false; } -private: - InspectorProfilerFrontendDispatcher* m_frontendDispatcher; - int m_totalWork; -}; - -}; - -void InspectorProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* reportProgress) -{ - String title = makeString(UserInitiatedProfileName, '.', String::number(m_nextUserInitiatedHeapSnapshotNumber)); - ++m_nextUserInitiatedHeapSnapshotNumber; - - HeapSnapshotProgress progress(reportProgress && *reportProgress ? m_frontendDispatcher.get() : nullptr); - RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, &progress); - if (snapshot) { - m_snapshots.add(snapshot->uid(), snapshot); - if (m_frontendDispatcher) - m_frontendDispatcher->addProfileHeader(createSnapshotHeader(*snapshot)); - } -} - -void InspectorProfilerAgent::toggleRecordButton(bool isProfiling) -{ - if (m_frontendDispatcher) - m_frontendDispatcher->setRecordingProfile(isProfiling); -} - -void InspectorProfilerAgent::getObjectByHeapObjectId(ErrorString* error, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) -{ - bool ok; - unsigned id = heapSnapshotObjectId.toUInt(&ok); - if (!ok) { - *error = "Invalid heap snapshot object id"; - return; - } - Deprecated::ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id); - if (heapObject.hasNoValue()) { - *error = "Object is not available"; - return; - } - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState()); - if (injectedScript.hasNoValue()) { - *error = "Object is not available. Inspected context is gone"; - return; - } - result = injectedScript.wrapObject(heapObject, objectGroup ? *objectGroup : ""); - if (!result) - *error = "Failed to wrap object"; -} - -void InspectorProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId) -{ - InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); - if (injectedScript.hasNoValue()) { - *errorString = "Inspected context has gone"; - return; - } - Deprecated::ScriptValue value = injectedScript.findObjectById(objectId); - if (value.hasNoValue() || value.isUndefined()) { - *errorString = "Object with given id not found"; - return; - } - unsigned id = ScriptProfiler::getHeapObjectId(value); - *heapSnapshotObjectId = String::number(id); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.h b/Source/WebCore/inspector/InspectorProfilerAgent.h deleted file mode 100644 index b9b60316d..000000000 --- a/Source/WebCore/inspector/InspectorProfilerAgent.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorProfilerAgent_h -#define InspectorProfilerAgent_h - -#if ENABLE(INSPECTOR) - -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/text/WTFString.h> - -namespace Inspector { -class InspectorArray; -class InspectorObject; -} - -namespace WebCore { - -class InspectorConsoleAgent; -class InstrumentingAgents; -class Page; -class PageInjectedScriptManager; -class ScriptHeapSnapshot; -class ScriptProfile; -class WorkerGlobalScope; - -typedef String ErrorString; - -class InspectorProfilerAgent : public InspectorAgentBase, public Inspector::InspectorProfilerBackendDispatcherHandler { - WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent); WTF_MAKE_FAST_ALLOCATED; -public: - static std::unique_ptr<InspectorProfilerAgent> create(InstrumentingAgents*, InspectorConsoleAgent*, Page*, PageInjectedScriptManager*); - static std::unique_ptr<InspectorProfilerAgent> create(InstrumentingAgents*, InspectorConsoleAgent*, WorkerGlobalScope*, PageInjectedScriptManager*); - - virtual ~InspectorProfilerAgent(); - - void addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL); - virtual void collectGarbage(ErrorString*) override; - virtual void clearProfiles(ErrorString*) override { resetState(); } - void resetState(); - - virtual void recompileScript() = 0; - virtual void isSampling(ErrorString*, bool*) override; - virtual void hasHeapProfiler(ErrorString*, bool*) override; - - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void start(ErrorString* = nullptr) override; - virtual void stop(ErrorString* = nullptr) override; - - void disable(bool skipRecompile); - void enable(bool skipRecompile); - bool enabled() const { return m_enabled; } - String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false); - virtual void getProfileHeaders(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Profiler::ProfileHeader>>&) override; - virtual void getCPUProfile(ErrorString*, int uid, RefPtr<Inspector::TypeBuilder::Profiler::CPUProfile>&) override; - virtual void getHeapSnapshot(ErrorString*, int uid) override; - virtual void removeProfile(ErrorString*, const String& type, int uid) override; - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - virtual void takeHeapSnapshot(ErrorString*, const bool* reportProgress) override; - void toggleRecordButton(bool isProfiling); - - virtual void getObjectByHeapObjectId(ErrorString*, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result) override; - virtual void getHeapObjectId(ErrorString*, const String& objectId, String* heapSnapshotObjectId) override; - -protected: - InspectorProfilerAgent(InstrumentingAgents*, InspectorConsoleAgent*, PageInjectedScriptManager*); - virtual void startProfiling(const String& title) = 0; - virtual PassRefPtr<ScriptProfile> stopProfiling(const String& title) = 0; - -private: - typedef HashMap<unsigned int, RefPtr<ScriptProfile>> ProfilesMap; - typedef HashMap<unsigned int, RefPtr<ScriptHeapSnapshot>> HeapSnapshotsMap; - - void resetFrontendProfiles(); - void restoreEnablement(); - - PassRefPtr<Inspector::TypeBuilder::Profiler::ProfileHeader> createProfileHeader(const ScriptProfile&); - PassRefPtr<Inspector::TypeBuilder::Profiler::ProfileHeader> createSnapshotHeader(const ScriptHeapSnapshot&); - - InspectorConsoleAgent* m_consoleAgent; - PageInjectedScriptManager* m_injectedScriptManager; - std::unique_ptr<Inspector::InspectorProfilerFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorProfilerBackendDispatcher> m_backendDispatcher; - bool m_enabled; - bool m_profileHeadersRequested; - bool m_recordingCPUProfile; - int m_currentUserInitiatedProfileNumber; - unsigned m_nextUserInitiatedProfileNumber; - unsigned m_nextUserInitiatedHeapSnapshotNumber; - ProfilesMap m_profiles; - HeapSnapshotsMap m_snapshots; - - typedef HashMap<String, double> ProfileNameIdleTimeMap; - ProfileNameIdleTimeMap* m_profileNameIdleTimeMap; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorProfilerAgent_h) diff --git a/Source/WebCore/inspector/InspectorReplayAgent.cpp b/Source/WebCore/inspector/InspectorReplayAgent.cpp new file mode 100644 index 000000000..3aaa52a6b --- /dev/null +++ b/Source/WebCore/inspector/InspectorReplayAgent.cpp @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2011-2013 University of Washington. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InspectorReplayAgent.h" + +#if ENABLE(WEB_REPLAY) + +#include "DocumentLoader.h" +#include "Event.h" +#include "EventLoopInput.h" +#include "Frame.h" +#include "FunctorInputCursor.h" +#include "InspectorController.h" +#include "InspectorPageAgent.h" +#include <inspector/InspectorProtocolObjects.h> +#include "InstrumentingAgents.h" +#include "Logging.h" +#include "Page.h" +#include "ReplayController.h" +#include "ReplaySession.h" +#include "ReplaySessionSegment.h" +#include "SerializationMethods.h" +#include "WebReplayInputs.h" +#include <inspector/InspectorValues.h> +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +using namespace Inspector; + +namespace WebCore { + +static Ref<Inspector::Protocol::Replay::ReplayPosition> buildInspectorObjectForPosition(const ReplayPosition& position) +{ + return Inspector::Protocol::Replay::ReplayPosition::create() + .setSegmentOffset(position.segmentOffset) + .setInputOffset(position.inputOffset) + .release(); +} + +static Ref<Inspector::Protocol::Replay::ReplayInput> buildInspectorObjectForInput(const NondeterministicInputBase& input, size_t offset) +{ + EncodedValue encodedInput = EncodingTraits<NondeterministicInputBase>::encodeValue(input); + return Inspector::Protocol::Replay::ReplayInput::create() + .setType(input.type()) + .setOffset(offset) + .setData(encodedInput.asObject()) + .release(); +} + +static Ref<Inspector::Protocol::Replay::ReplaySession> buildInspectorObjectForSession(RefPtr<ReplaySession>&& session) +{ + auto segments = Inspector::Protocol::Array<SegmentIdentifier>::create(); + + for (auto& segment : *session) + segments->addItem(static_cast<int>(segment->identifier())); + + return Inspector::Protocol::Replay::ReplaySession::create() + .setId(session->identifier()) + .setTimestamp(session->timestamp()) + .setSegments(WTFMove(segments)) + .release(); +} + +static Inspector::Protocol::Replay::SessionState buildInspectorObjectForSessionState(WebCore::SessionState sessionState) +{ + switch (sessionState) { + case WebCore::SessionState::Capturing: return Inspector::Protocol::Replay::SessionState::Capturing; + case WebCore::SessionState::Inactive: return Inspector::Protocol::Replay::SessionState::Inactive; + case WebCore::SessionState::Replaying: return Inspector::Protocol::Replay::SessionState::Replaying; + } + + RELEASE_ASSERT_NOT_REACHED(); + return Inspector::Protocol::Replay::SessionState::Inactive; +} + +static Inspector::Protocol::Replay::SegmentState buildInspectorObjectForSegmentState(WebCore::SegmentState segmentState) +{ + switch (segmentState) { + case WebCore::SegmentState::Appending: return Inspector::Protocol::Replay::SegmentState::Appending; + case WebCore::SegmentState::Unloaded: return Inspector::Protocol::Replay::SegmentState::Unloaded; + case WebCore::SegmentState::Loaded: return Inspector::Protocol::Replay::SegmentState::Loaded; + case WebCore::SegmentState::Dispatching: return Inspector::Protocol::Replay::SegmentState::Dispatching; + } + + RELEASE_ASSERT_NOT_REACHED(); + return Inspector::Protocol::Replay::SegmentState::Unloaded; +} + +class SerializeInputToJSONFunctor { +public: + typedef RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Replay::ReplayInput>> ReturnType; + + SerializeInputToJSONFunctor() + : m_inputs(Inspector::Protocol::Array<Inspector::Protocol::Replay::ReplayInput>::create()) { } + ~SerializeInputToJSONFunctor() { } + + void operator()(size_t index, const NondeterministicInputBase* input) + { + LOG(WebReplay, "%-25s Writing %5zu: %s\n", "[SerializeInput]", index, input->type().ascii().data()); + + if (RefPtr<Inspector::Protocol::Replay::ReplayInput> serializedInput = buildInspectorObjectForInput(*input, index)) + m_inputs->addItem(WTFMove(serializedInput)); + } + + ReturnType returnValue() { return WTFMove(m_inputs); } +private: + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Replay::ReplayInput>> m_inputs; +}; + +static Ref<Inspector::Protocol::Replay::SessionSegment> buildInspectorObjectForSegment(RefPtr<ReplaySessionSegment>&& segment) +{ + auto queuesObject = Inspector::Protocol::Array<Inspector::Protocol::Replay::ReplayInputQueue>::create(); + + for (size_t i = 0; i < static_cast<size_t>(InputQueue::Count); i++) { + SerializeInputToJSONFunctor collector; + InputQueue queue = static_cast<InputQueue>(i); + RefPtr<FunctorInputCursor> functorCursor = FunctorInputCursor::create(segment.copyRef()); + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Replay::ReplayInput>> queueInputs = functorCursor->forEachInputInQueue(queue, collector); + + auto queueObject = Inspector::Protocol::Replay::ReplayInputQueue::create() + .setType(EncodingTraits<InputQueue>::encodeValue(queue).convertTo<String>()) + .setInputs(queueInputs) + .release(); + queuesObject->addItem(WTFMove(queueObject)); + } + + return Inspector::Protocol::Replay::SessionSegment::create() + .setId(segment->identifier()) + .setTimestamp(segment->timestamp()) + .setQueues(WTFMove(queuesObject)) + .release(); +} + +InspectorReplayAgent::InspectorReplayAgent(PageAgentContext& context) + : InspectorAgentBase(ASCIILiteral("Replay"), context) + , m_frontendDispatcher(std::make_unique<Inspector::ReplayFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::ReplayBackendDispatcher::create(context.backendDispatcher, this)) + , m_page(context.inspectedPage) +{ +} + +InspectorReplayAgent::~InspectorReplayAgent() +{ + ASSERT(!m_sessionsMap.size()); + ASSERT(!m_segmentsMap.size()); +} + +WebCore::SessionState InspectorReplayAgent::sessionState() const +{ + return m_page.replayController().sessionState(); +} + +void InspectorReplayAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) +{ + m_instrumentingAgents.setInspectorReplayAgent(this); + ASSERT(sessionState() == WebCore::SessionState::Inactive); + + // Keep track of the (default) session currently loaded by ReplayController, + // and any segments within the session. + RefPtr<ReplaySession> session = m_page.replayController().loadedSession(); + m_sessionsMap.add(session->identifier(), session); + + for (auto& segment : *session) + m_segmentsMap.add(segment->identifier(), segment); +} + +void InspectorReplayAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) +{ + m_instrumentingAgents.setInspectorReplayAgent(nullptr); + + // Drop references to all sessions and segments. + m_sessionsMap.clear(); + m_segmentsMap.clear(); +} + +void InspectorReplayAgent::frameNavigated(Frame& frame) +{ + if (sessionState() != WebCore::SessionState::Inactive) + m_page.replayController().frameNavigated(frame); +} + +void InspectorReplayAgent::frameDetached(Frame& frame) +{ + if (sessionState() != WebCore::SessionState::Inactive) + m_page.replayController().frameDetached(frame); +} + +void InspectorReplayAgent::willDispatchEvent(const Event& event, Frame* frame) +{ + if (sessionState() != WebCore::SessionState::Inactive) + m_page.replayController().willDispatchEvent(event, frame); +} + +void InspectorReplayAgent::sessionCreated(RefPtr<ReplaySession>&& session) +{ + auto result = m_sessionsMap.add(session->identifier(), session); + // Can't have two sessions with same identifier. + ASSERT_UNUSED(result, result.isNewEntry); + + m_frontendDispatcher->sessionCreated(session->identifier()); +} + +void InspectorReplayAgent::sessionModified(RefPtr<ReplaySession>&& session) +{ + m_frontendDispatcher->sessionModified(session->identifier()); +} + +void InspectorReplayAgent::sessionLoaded(RefPtr<ReplaySession>&& session) +{ + // In case we didn't know about the loaded session, add here. + m_sessionsMap.add(session->identifier(), session); + + m_frontendDispatcher->sessionLoaded(session->identifier()); +} + +void InspectorReplayAgent::segmentCreated(RefPtr<ReplaySessionSegment>&& segment) +{ + auto result = m_segmentsMap.add(segment->identifier(), segment); + // Can't have two segments with the same identifier. + ASSERT_UNUSED(result, result.isNewEntry); + + m_frontendDispatcher->segmentCreated(segment->identifier()); +} + +void InspectorReplayAgent::segmentCompleted(RefPtr<ReplaySessionSegment>&& segment) +{ + m_frontendDispatcher->segmentCompleted(segment->identifier()); +} + +void InspectorReplayAgent::segmentLoaded(RefPtr<ReplaySessionSegment>&& segment) +{ + // In case we didn't know about the loaded segment, add here. + m_segmentsMap.add(segment->identifier(), segment.copyRef()); + + m_frontendDispatcher->segmentLoaded(segment->identifier()); +} + +void InspectorReplayAgent::segmentUnloaded() +{ + m_frontendDispatcher->segmentUnloaded(); +} + +void InspectorReplayAgent::captureStarted() +{ + LOG(WebReplay, "-----CAPTURE START-----"); + + m_frontendDispatcher->captureStarted(); +} + +void InspectorReplayAgent::captureStopped() +{ + LOG(WebReplay, "-----CAPTURE STOP-----"); + + m_frontendDispatcher->captureStopped(); +} + +void InspectorReplayAgent::playbackStarted() +{ + LOG(WebReplay, "-----REPLAY START-----"); + + m_frontendDispatcher->playbackStarted(); +} + +void InspectorReplayAgent::playbackPaused(const ReplayPosition& position) +{ + LOG(WebReplay, "-----REPLAY PAUSED-----"); + + m_frontendDispatcher->playbackPaused(buildInspectorObjectForPosition(position)); +} + +void InspectorReplayAgent::playbackHitPosition(const ReplayPosition& position) +{ + m_frontendDispatcher->playbackHitPosition(buildInspectorObjectForPosition(position), monotonicallyIncreasingTime()); +} + +void InspectorReplayAgent::playbackFinished() +{ + LOG(WebReplay, "-----REPLAY FINISHED-----"); + + m_frontendDispatcher->playbackFinished(); +} + +void InspectorReplayAgent::startCapturing(ErrorString& errorString) +{ + if (sessionState() != WebCore::SessionState::Inactive) { + errorString = ASCIILiteral("Can't start capturing if the session is already capturing or replaying."); + return; + } + + m_page.replayController().startCapturing(); +} + +void InspectorReplayAgent::stopCapturing(ErrorString& errorString) +{ + if (sessionState() != WebCore::SessionState::Capturing) { + errorString = ASCIILiteral("Can't stop capturing if capture is not in progress."); + return; + } + + m_page.replayController().stopCapturing(); +} + +void InspectorReplayAgent::replayToPosition(ErrorString& errorString, const InspectorObject& positionObject, bool fastReplay) +{ + ReplayPosition position; + if (!positionObject.getInteger(ASCIILiteral("segmentOffset"), position.segmentOffset)) { + errorString = ASCIILiteral("Couldn't decode ReplayPosition segment offset provided to ReplayAgent.replayToPosition."); + return; + } + + if (!positionObject.getInteger(ASCIILiteral("inputOffset"), position.inputOffset)) { + errorString = ASCIILiteral("Couldn't decode ReplayPosition input offset provided to ReplayAgent.replayToPosition."); + return; + } + + if (sessionState() == WebCore::SessionState::Capturing) { + errorString = ASCIILiteral("Can't start replay while capture is in progress."); + return; + } + + m_page.replayController().replayToPosition(position, (fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime); +} + +void InspectorReplayAgent::replayToCompletion(ErrorString& errorString, bool fastReplay) +{ + if (sessionState() == WebCore::SessionState::Capturing) { + errorString = ASCIILiteral("Can't start replay while capture is in progress."); + return; + } + + m_page.replayController().replayToCompletion((fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime); +} + +void InspectorReplayAgent::pausePlayback(ErrorString& errorString) +{ + if (sessionState() != WebCore::SessionState::Replaying) { + errorString = ASCIILiteral("Can't pause playback if playback is not in progress."); + return; + } + + m_page.replayController().pausePlayback(); +} + +void InspectorReplayAgent::cancelPlayback(ErrorString& errorString) +{ + if (sessionState() == WebCore::SessionState::Capturing) { + errorString = ASCIILiteral("Can't cancel playback if capture is in progress."); + return; + } + + m_page.replayController().cancelPlayback(); +} + +void InspectorReplayAgent::switchSession(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier identifier) +{ + ASSERT_ARG(identifier, identifier > 0); + + if (sessionState() != WebCore::SessionState::Inactive) { + errorString = ASCIILiteral("Can't switch sessions unless the session is neither capturing or replaying."); + return; + } + + RefPtr<ReplaySession> session = findSession(errorString, identifier); + if (!session) + return; + + m_page.replayController().switchSession(WTFMove(session)); +} + +void InspectorReplayAgent::insertSessionSegment(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier sessionIdentifier, SegmentIdentifier segmentIdentifier, int segmentIndex) +{ + ASSERT_ARG(sessionIdentifier, sessionIdentifier > 0); + ASSERT_ARG(segmentIdentifier, segmentIdentifier > 0); + ASSERT_ARG(segmentIndex, segmentIndex >= 0); + + RefPtr<ReplaySession> session = findSession(errorString, sessionIdentifier); + RefPtr<ReplaySessionSegment> segment = findSegment(errorString, segmentIdentifier); + + if (!session || !segment) + return; + + if (static_cast<size_t>(segmentIndex) > session->size()) { + errorString = ASCIILiteral("Invalid segment index."); + return; + } + + if (session == m_page.replayController().loadedSession() && sessionState() != WebCore::SessionState::Inactive) { + errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive."); + return; + } + + session->insertSegment(segmentIndex, WTFMove(segment)); + sessionModified(WTFMove(session)); +} + +void InspectorReplayAgent::removeSessionSegment(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier identifier, int segmentIndex) +{ + ASSERT_ARG(identifier, identifier > 0); + ASSERT_ARG(segmentIndex, segmentIndex >= 0); + + RefPtr<ReplaySession> session = findSession(errorString, identifier); + + if (!session) + return; + + if (static_cast<size_t>(segmentIndex) >= session->size()) { + errorString = ASCIILiteral("Invalid segment index."); + return; + } + + if (session == m_page.replayController().loadedSession() && sessionState() != WebCore::SessionState::Inactive) { + errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive."); + return; + } + + session->removeSegment(segmentIndex); + sessionModified(WTFMove(session)); +} + +RefPtr<ReplaySession> InspectorReplayAgent::findSession(ErrorString& errorString, SessionIdentifier identifier) +{ + ASSERT_ARG(identifier, identifier > 0); + + auto it = m_sessionsMap.find(identifier); + if (it == m_sessionsMap.end()) { + errorString = ASCIILiteral("Couldn't find session with specified identifier"); + return nullptr; + } + + return it->value; +} + +RefPtr<ReplaySessionSegment> InspectorReplayAgent::findSegment(ErrorString& errorString, SegmentIdentifier identifier) +{ + ASSERT_ARG(identifier, identifier > 0); + + auto it = m_segmentsMap.find(identifier); + if (it == m_segmentsMap.end()) { + errorString = ASCIILiteral("Couldn't find segment with specified identifier"); + return nullptr; + } + + return it->value; +} + +void InspectorReplayAgent::currentReplayState(ErrorString&, Inspector::Protocol::Replay::SessionIdentifier* sessionIdentifier, Inspector::Protocol::OptOutput<Inspector::Protocol::Replay::SegmentIdentifier>* segmentIdentifier, Inspector::Protocol::Replay::SessionState* sessionState, Inspector::Protocol::Replay::SegmentState* segmentState, RefPtr<Inspector::Protocol::Replay::ReplayPosition>& replayPosition) +{ + *sessionState = buildInspectorObjectForSessionState(m_page.replayController().sessionState()); + *segmentState = buildInspectorObjectForSegmentState(m_page.replayController().segmentState()); + + *sessionIdentifier = m_page.replayController().loadedSession()->identifier(); + if (m_page.replayController().loadedSegment()) + *segmentIdentifier = m_page.replayController().loadedSegment()->identifier(); + + replayPosition = buildInspectorObjectForPosition(m_page.replayController().currentPosition()); +} + +void InspectorReplayAgent::getAvailableSessions(ErrorString&, RefPtr<Inspector::Protocol::Array<SessionIdentifier>>& sessionsList) +{ + sessionsList = Inspector::Protocol::Array<Inspector::Protocol::Replay::SessionIdentifier>::create(); + for (auto& pair : m_sessionsMap) + sessionsList->addItem(pair.key); +} + +void InspectorReplayAgent::getSessionData(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier identifier, RefPtr<Inspector::Protocol::Replay::ReplaySession>& serializedObject) +{ + RefPtr<ReplaySession> session = findSession(errorString, identifier); + if (!session) { + errorString = ASCIILiteral("Couldn't find the specified session."); + return; + } + + serializedObject = buildInspectorObjectForSession(WTFMove(session)); +} + +void InspectorReplayAgent::getSegmentData(ErrorString& errorString, Inspector::Protocol::Replay::SegmentIdentifier identifier, RefPtr<Inspector::Protocol::Replay::SessionSegment>& serializedObject) +{ + RefPtr<ReplaySessionSegment> segment = findSegment(errorString, identifier); + if (!segment) { + errorString = ASCIILiteral("Couldn't find the specified segment."); + return; + } + + serializedObject = buildInspectorObjectForSegment(WTFMove(segment)); +} + +} // namespace WebCore +#endif // ENABLE(WEB_REPLAY) diff --git a/Source/WebCore/inspector/InspectorReplayAgent.h b/Source/WebCore/inspector/InspectorReplayAgent.h new file mode 100644 index 000000000..ff6e5876b --- /dev/null +++ b/Source/WebCore/inspector/InspectorReplayAgent.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011-2013 University of Washington. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(WEB_REPLAY) + +#include "InspectorWebAgentBase.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class DocumentLoader; +class Event; +class Frame; +class Page; +class ReplaySession; +class ReplaySessionSegment; + +enum class SessionState; + +struct ReplayPosition; + +typedef String ErrorString; +typedef int SessionIdentifier; +typedef int SegmentIdentifier; + +class InspectorReplayAgent final + : public InspectorAgentBase + , public Inspector::ReplayBackendDispatcherHandler { + WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_NONCOPYABLE(InspectorReplayAgent); +public: + InspectorReplayAgent(PageAgentContext&); + virtual ~InspectorReplayAgent(); + + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; + + // InspectorInstrumentation + void frameNavigated(Frame&); + void frameDetached(Frame&); + void willDispatchEvent(const Event&, Frame*); + + // Notifications from ReplayController. + void sessionCreated(RefPtr<ReplaySession>&&); + // This is called internally (when adding/removing) and by ReplayController during capture. + void sessionModified(RefPtr<ReplaySession>&&); + void sessionLoaded(RefPtr<ReplaySession>&&); + + void segmentCreated(RefPtr<ReplaySessionSegment>&&); + void segmentCompleted(RefPtr<ReplaySessionSegment>&&); + void segmentLoaded(RefPtr<ReplaySessionSegment>&&); + void segmentUnloaded(); + + void captureStarted(); + void captureStopped(); + + void playbackStarted(); + void playbackPaused(const ReplayPosition&); + void playbackHitPosition(const ReplayPosition&); + void playbackFinished(); + + // Calls from the Inspector frontend. + void startCapturing(ErrorString&) override; + void stopCapturing(ErrorString&) override; + + void replayToPosition(ErrorString&, const Inspector::InspectorObject& position, bool shouldFastForward) override; + void replayToCompletion(ErrorString&, bool shouldFastForward) override; + void pausePlayback(ErrorString&) override; + void cancelPlayback(ErrorString&) override; + + void switchSession(ErrorString&, SessionIdentifier) override; + void insertSessionSegment(ErrorString&, Inspector::Protocol::Replay::SessionIdentifier, Inspector::Protocol::Replay::SegmentIdentifier, int segmentIndex) override; + void removeSessionSegment(ErrorString&, Inspector::Protocol::Replay::SessionIdentifier, int segmentIndex) override; + + void currentReplayState(ErrorString&, Inspector::Protocol::Replay::SessionIdentifier*, Inspector::Protocol::OptOutput<Inspector::Protocol::Replay::SegmentIdentifier>*, Inspector::Protocol::Replay::SessionState*, Inspector::Protocol::Replay::SegmentState* segmentState, RefPtr<Inspector::Protocol::Replay::ReplayPosition>&) override; + void getAvailableSessions(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Replay::SessionIdentifier>>&) override; + void getSessionData(ErrorString&, Inspector::Protocol::Replay::SessionIdentifier, RefPtr<Inspector::Protocol::Replay::ReplaySession>&) override; + void getSegmentData(ErrorString&, Inspector::Protocol::Replay::SegmentIdentifier, RefPtr<Inspector::Protocol::Replay::SessionSegment>&) override; + +private: + RefPtr<ReplaySession> findSession(ErrorString&, SessionIdentifier); + RefPtr<ReplaySessionSegment> findSegment(ErrorString&, SegmentIdentifier); + WebCore::SessionState sessionState() const; + + std::unique_ptr<Inspector::ReplayFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::ReplayBackendDispatcher> m_backendDispatcher; + Page& m_page; + + HashMap<int, RefPtr<ReplaySession>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> m_sessionsMap; + HashMap<int, RefPtr<ReplaySessionSegment>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> m_segmentsMap; +}; + +} // namespace WebCore + +#endif // ENABLE(WEB_REPLAY) diff --git a/Source/WebCore/inspector/InspectorResourceAgent.cpp b/Source/WebCore/inspector/InspectorResourceAgent.cpp deleted file mode 100644 index 783d0176d..000000000 --- a/Source/WebCore/inspector/InspectorResourceAgent.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorResourceAgent.h" - -#include "CachedRawResource.h" -#include "CachedResource.h" -#include "CachedResourceLoader.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "ExceptionCodePlaceholder.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "HTTPHeaderMap.h" -#include "IconController.h" -#include "IdentifiersFactory.h" -#include "InspectorClient.h" -#include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" -#include "InstrumentingAgents.h" -#include "MemoryCache.h" -#include "NetworkResourcesData.h" -#include "Page.h" -#include "ProgressTracker.h" -#include "ResourceBuffer.h" -#include "ResourceError.h" -#include "ResourceLoader.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" -#include "ScriptableDocumentParser.h" -#include "Settings.h" -#include "SubresourceLoader.h" -#include "URL.h" -#include "WebSocketFrame.h" -#include "XMLHttpRequest.h" -#include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> -#include <wtf/HexNumber.h> -#include <wtf/ListHashSet.h> -#include <wtf/RefPtr.h> -#include <wtf/text/StringBuilder.h> - -using namespace Inspector; - -namespace WebCore { - -void InspectorResourceAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) -{ - m_frontendDispatcher = std::make_unique<InspectorNetworkFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorNetworkBackendDispatcher::create(backendDispatcher, this); -} - -void InspectorResourceAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) -{ - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - - ErrorString error; - disable(&error); -} - -static PassRefPtr<InspectorObject> buildObjectForHeaders(const HTTPHeaderMap& headers) -{ - RefPtr<InspectorObject> headersObject = InspectorObject::create(); - HTTPHeaderMap::const_iterator end = headers.end(); - for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) - headersObject->setString(it->key.string(), it->value); - return headersObject; -} - -static PassRefPtr<Inspector::TypeBuilder::Network::ResourceTiming> buildObjectForTiming(const ResourceLoadTiming& timing, DocumentLoader* loader) -{ - return Inspector::TypeBuilder::Network::ResourceTiming::create() - .setRequestTime(loader->timing()->monotonicTimeToPseudoWallTime(timing.convertResourceLoadTimeToMonotonicTime(0))) - .setProxyStart(timing.proxyStart) - .setProxyEnd(timing.proxyEnd) - .setDnsStart(timing.dnsStart) - .setDnsEnd(timing.dnsEnd) - .setConnectStart(timing.connectStart) - .setConnectEnd(timing.connectEnd) - .setSslStart(timing.sslStart) - .setSslEnd(timing.sslEnd) - .setSendStart(timing.sendStart) - .setSendEnd(timing.sendEnd) - .setReceiveHeadersEnd(timing.receiveHeadersEnd) - .release(); -} - -static PassRefPtr<Inspector::TypeBuilder::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request) -{ - RefPtr<Inspector::TypeBuilder::Network::Request> requestObject = Inspector::TypeBuilder::Network::Request::create() - .setUrl(request.url().string()) - .setMethod(request.httpMethod()) - .setHeaders(buildObjectForHeaders(request.httpHeaderFields())); - if (request.httpBody() && !request.httpBody()->isEmpty()) - requestObject->setPostData(request.httpBody()->flattenToString()); - return requestObject; -} - -static PassRefPtr<Inspector::TypeBuilder::Network::Response> buildObjectForResourceResponse(const ResourceResponse& response, DocumentLoader* loader) -{ - if (response.isNull()) - return nullptr; - - double status = response.httpStatusCode(); - RefPtr<InspectorObject> headers = buildObjectForHeaders(response.httpHeaderFields()); - - RefPtr<Inspector::TypeBuilder::Network::Response> responseObject = Inspector::TypeBuilder::Network::Response::create() - .setUrl(response.url().string()) - .setStatus(status) - .setStatusText(response.httpStatusText()) - .setHeaders(headers) - .setMimeType(response.mimeType()) - .setConnectionReused(response.connectionReused()) - .setConnectionId(response.connectionID()); - - responseObject->setFromDiskCache(response.wasCached()); - if (response.resourceLoadTiming()) - responseObject->setTiming(buildObjectForTiming(*response.resourceLoadTiming(), loader)); - - return responseObject; -} - -static PassRefPtr<Inspector::TypeBuilder::Network::CachedResource> buildObjectForCachedResource(CachedResource* cachedResource, DocumentLoader* loader) -{ - RefPtr<Inspector::TypeBuilder::Network::CachedResource> resourceObject = Inspector::TypeBuilder::Network::CachedResource::create() - .setUrl(cachedResource->url()) - .setType(InspectorPageAgent::cachedResourceTypeJson(*cachedResource)) - .setBodySize(cachedResource->encodedSize()); - - RefPtr<Inspector::TypeBuilder::Network::Response> resourceResponse = buildObjectForResourceResponse(cachedResource->response(), loader); - if (resourceResponse) - resourceObject->setResponse(resourceResponse); - - String sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(cachedResource); - if (!sourceMappingURL.isEmpty()) - resourceObject->setSourceMapURL(sourceMappingURL); - - return resourceObject; -} - -InspectorResourceAgent::~InspectorResourceAgent() -{ - if (m_enabled) { - ErrorString error; - disable(&error); - } - ASSERT(!m_instrumentingAgents->inspectorResourceAgent()); -} - -void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse) -{ - String requestId = IdentifiersFactory::requestId(identifier); - m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(loader)); - - CachedResource* cachedResource = loader ? InspectorPageAgent::cachedResource(loader->frame(), request.url()) : nullptr; - InspectorPageAgent::ResourceType type = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : m_resourcesData->resourceType(requestId); - if (type == InspectorPageAgent::OtherResource) { - if (m_loadingXHRSynchronously) - type = InspectorPageAgent::XHRResource; - else if (equalIgnoringFragmentIdentifier(request.url(), loader->frameLoader()->icon().url())) - type = InspectorPageAgent::ImageResource; - else if (equalIgnoringFragmentIdentifier(request.url(), loader->url()) && !loader->isCommitted()) - type = InspectorPageAgent::DocumentResource; - } - - m_resourcesData->setResourceType(requestId, type); - - if (m_extraRequestHeaders) { - InspectorObject::const_iterator end = m_extraRequestHeaders->end(); - for (InspectorObject::const_iterator it = m_extraRequestHeaders->begin(); it != end; ++it) { - String value; - if (it->value->asString(&value)) - request.setHTTPHeaderField(it->key, value); - } - } - - request.setReportLoadTiming(true); - request.setReportRawHeaders(true); - - if (m_cacheDisabled) { - request.setHTTPHeaderField("Pragma", "no-cache"); - request.setCachePolicy(ReloadIgnoringCacheData); - request.setHTTPHeaderField("Cache-Control", "no-cache"); - } - - Inspector::TypeBuilder::Page::ResourceType::Enum resourceType = InspectorPageAgent::resourceTypeJson(type); - - RefPtr<Inspector::TypeBuilder::Network::Initiator> initiatorObject = buildInitiatorObject(loader->frame() ? loader->frame()->document() : nullptr); - m_frontendDispatcher->requestWillBeSent(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), loader->url().string(), buildObjectForResourceRequest(request), currentTime(), initiatorObject, buildObjectForResourceResponse(redirectResponse, loader), type != InspectorPageAgent::OtherResource ? &resourceType : nullptr); -} - -void InspectorResourceAgent::markResourceAsCached(unsigned long identifier) -{ - m_frontendDispatcher->requestServedFromCache(IdentifiersFactory::requestId(identifier)); -} - -void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader) -{ - String requestId = IdentifiersFactory::requestId(identifier); - RefPtr<Inspector::TypeBuilder::Network::Response> resourceResponse = buildObjectForResourceResponse(response, loader); - - bool isNotModified = response.httpStatusCode() == 304; - - CachedResource* cachedResource = nullptr; - if (resourceLoader && resourceLoader->isSubresourceLoader() && !isNotModified) - cachedResource = static_cast<SubresourceLoader*>(resourceLoader)->cachedResource(); - if (!cachedResource) - cachedResource = InspectorPageAgent::cachedResource(loader->frame(), response.url()); - - if (cachedResource) { - // Use mime type from cached resource in case the one in response is empty. - if (resourceResponse && response.mimeType().isEmpty()) - resourceResponse->setString(Inspector::TypeBuilder::Network::Response::MimeType, cachedResource->response().mimeType()); - m_resourcesData->addCachedResource(requestId, cachedResource); - } - - InspectorPageAgent::ResourceType type = m_resourcesData->resourceType(requestId); - InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : type; - - // FIXME: XHRResource is returned for CachedResource::RawResource, it should be OtherResource unless it truly is an XHR. - // RawResource is used for loading worker scripts, and those should stay as ScriptResource and not change to XHRResource. - if (type != newType && newType != InspectorPageAgent::XHRResource && newType != InspectorPageAgent::OtherResource) - type = newType; - - m_resourcesData->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), response); - m_resourcesData->setResourceType(requestId, type); - - m_frontendDispatcher->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), currentTime(), InspectorPageAgent::resourceTypeJson(type), resourceResponse); - - // If we revalidated the resource and got Not modified, send content length following didReceiveResponse - // as there will be no calls to didReceiveData from the network stack. - if (isNotModified && cachedResource && cachedResource->encodedSize()) - didReceiveData(identifier, nullptr, cachedResource->encodedSize(), 0); -} - -static bool isErrorStatusCode(int statusCode) -{ - return statusCode >= 400; -} - -void InspectorResourceAgent::didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength) -{ - String requestId = IdentifiersFactory::requestId(identifier); - - if (data) { - NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); - if (resourceData && !m_loadingXHRSynchronously && (!resourceData->cachedResource() || resourceData->cachedResource()->dataBufferingPolicy() == DoNotBufferData || isErrorStatusCode(resourceData->httpStatusCode()))) - m_resourcesData->maybeAddResourceData(requestId, data, dataLength); - } - - m_frontendDispatcher->dataReceived(requestId, currentTime(), dataLength, encodedDataLength); -} - -void InspectorResourceAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double finishTime) -{ - String requestId = IdentifiersFactory::requestId(identifier); - if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) { - RefPtr<ResourceBuffer> buffer = loader->frameLoader()->documentLoader()->mainResourceData(); - m_resourcesData->addResourceSharedBuffer(requestId, buffer ? buffer->sharedBuffer() : nullptr, loader->frame()->document()->inputEncoding()); - } - - m_resourcesData->maybeDecodeDataToContent(requestId); - - // FIXME: The finishTime that is passed in is from the NetworkProcess and is more accurate. - // However, all other times passed to the Inspector are generated from the web process. Mixing - // times from different processes can cause the finish time to be earlier than the response - // received time due to inter-process communication lag. - finishTime = currentTime(); - - String sourceMappingURL; - NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); - if (resourceData && resourceData->cachedResource()) - sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource()); - - m_frontendDispatcher->loadingFinished(requestId, finishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr); -} - -void InspectorResourceAgent::didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error) -{ - String requestId = IdentifiersFactory::requestId(identifier); - - if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) { - Frame* frame = loader ? loader->frame() : nullptr; - if (frame && frame->loader().documentLoader() && frame->document()) { - RefPtr<ResourceBuffer> buffer = frame->loader().documentLoader()->mainResourceData(); - m_resourcesData->addResourceSharedBuffer(requestId, buffer ? buffer->sharedBuffer() : nullptr, frame->document()->inputEncoding()); - } - } - - bool canceled = error.isCancellation(); - m_frontendDispatcher->loadingFailed(requestId, currentTime(), error.localizedDescription(), canceled ? &canceled : nullptr); -} - -void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, CachedResource* resource) -{ - String loaderId = m_pageAgent->loaderId(loader); - String frameId = m_pageAgent->frameId(loader->frame()); - unsigned long identifier = loader->frame()->page()->progress().createUniqueIdentifier(); - String requestId = IdentifiersFactory::requestId(identifier); - m_resourcesData->resourceCreated(requestId, loaderId); - m_resourcesData->addCachedResource(requestId, resource); - if (resource->type() == CachedResource::RawResource) { - CachedRawResource* rawResource = static_cast<CachedRawResource*>(resource); - String rawRequestId = IdentifiersFactory::requestId(rawResource->identifier()); - m_resourcesData->reuseXHRReplayData(requestId, rawRequestId); - } - - RefPtr<Inspector::TypeBuilder::Network::Initiator> initiatorObject = buildInitiatorObject(loader->frame() ? loader->frame()->document() : nullptr); - - m_frontendDispatcher->requestServedFromMemoryCache(requestId, frameId, loaderId, loader->url().string(), currentTime(), initiatorObject, buildObjectForCachedResource(resource, loader)); -} - -void InspectorResourceAgent::setInitialScriptContent(unsigned long identifier, const String& sourceString) -{ - m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), sourceString); -} - -void InspectorResourceAgent::didReceiveScriptResponse(unsigned long identifier) -{ - m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::ScriptResource); -} - -void InspectorResourceAgent::documentThreadableLoaderStartedLoadingForClient(unsigned long identifier, ThreadableLoaderClient* client) -{ - if (!client) - return; - - PendingXHRReplayDataMap::iterator it = m_pendingXHRReplayData.find(client); - if (it == m_pendingXHRReplayData.end()) - return; - - XHRReplayData* xhrReplayData = it->value.get(); - String requestId = IdentifiersFactory::requestId(identifier); - m_resourcesData->setXHRReplayData(requestId, xhrReplayData); -} - -void InspectorResourceAgent::willLoadXHR(ThreadableLoaderClient* client, const String& method, const URL& url, bool async, PassRefPtr<FormData> formData, const HTTPHeaderMap& headers, bool includeCredentials) -{ - RefPtr<XHRReplayData> xhrReplayData = XHRReplayData::create(method, url, async, formData, includeCredentials); - HTTPHeaderMap::const_iterator end = headers.end(); - for (HTTPHeaderMap::const_iterator it = headers.begin(); it!= end; ++it) - xhrReplayData->addHeader(it->key, it->value); - m_pendingXHRReplayData.set(client, xhrReplayData); -} - -void InspectorResourceAgent::didFailXHRLoading(ThreadableLoaderClient* client) -{ - m_pendingXHRReplayData.remove(client); -} - -void InspectorResourceAgent::didFinishXHRLoading(ThreadableLoaderClient* client, unsigned long identifier, const String& sourceString) -{ - // For Asynchronous XHRs, the inspector can grab the data directly off of the CachedResource. For sync XHRs, we need to - // provide the data here, since no CachedResource was involved. - if (m_loadingXHRSynchronously) - m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), sourceString); - m_pendingXHRReplayData.remove(client); -} - -void InspectorResourceAgent::didReceiveXHRResponse(unsigned long identifier) -{ - m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::XHRResource); -} - -void InspectorResourceAgent::willLoadXHRSynchronously() -{ - m_loadingXHRSynchronously = true; -} - -void InspectorResourceAgent::didLoadXHRSynchronously() -{ - m_loadingXHRSynchronously = false; -} - -void InspectorResourceAgent::willDestroyCachedResource(CachedResource* cachedResource) -{ - Vector<String> requestIds = m_resourcesData->removeCachedResource(cachedResource); - if (!requestIds.size()) - return; - - String content; - bool base64Encoded; - if (!InspectorPageAgent::cachedResourceContent(cachedResource, &content, &base64Encoded)) - return; - Vector<String>::iterator end = requestIds.end(); - for (Vector<String>::iterator it = requestIds.begin(); it != end; ++it) - m_resourcesData->setResourceContent(*it, content, base64Encoded); -} - -void InspectorResourceAgent::willRecalculateStyle() -{ - m_isRecalculatingStyle = true; -} - -void InspectorResourceAgent::didRecalculateStyle() -{ - m_isRecalculatingStyle = false; - m_styleRecalculationInitiator = nullptr; -} - -void InspectorResourceAgent::didScheduleStyleRecalculation(Document* document) -{ - if (!m_styleRecalculationInitiator) - m_styleRecalculationInitiator = buildInitiatorObject(document); -} - -PassRefPtr<Inspector::TypeBuilder::Network::Initiator> InspectorResourceAgent::buildInitiatorObject(Document* document) -{ - RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); - if (stackTrace && stackTrace->size() > 0) { - RefPtr<Inspector::TypeBuilder::Network::Initiator> initiatorObject = Inspector::TypeBuilder::Network::Initiator::create() - .setType(Inspector::TypeBuilder::Network::Initiator::Type::Script); - initiatorObject->setStackTrace(stackTrace->buildInspectorArray()); - return initiatorObject; - } - - if (document && document->scriptableDocumentParser()) { - RefPtr<Inspector::TypeBuilder::Network::Initiator> initiatorObject = Inspector::TypeBuilder::Network::Initiator::create() - .setType(Inspector::TypeBuilder::Network::Initiator::Type::Parser); - initiatorObject->setUrl(document->url().string()); - initiatorObject->setLineNumber(document->scriptableDocumentParser()->textPosition().m_line.oneBasedInt()); - return initiatorObject; - } - - if (m_isRecalculatingStyle && m_styleRecalculationInitiator) - return m_styleRecalculationInitiator; - - return Inspector::TypeBuilder::Network::Initiator::create() - .setType(Inspector::TypeBuilder::Network::Initiator::Type::Other) - .release(); -} - -#if ENABLE(WEB_SOCKETS) - -void InspectorResourceAgent::didCreateWebSocket(unsigned long identifier, const URL& requestURL) -{ - m_frontendDispatcher->webSocketCreated(IdentifiersFactory::requestId(identifier), requestURL.string()); -} - -void InspectorResourceAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, const ResourceRequest& request) -{ - RefPtr<Inspector::TypeBuilder::Network::WebSocketRequest> requestObject = Inspector::TypeBuilder::Network::WebSocketRequest::create() - .setHeaders(buildObjectForHeaders(request.httpHeaderFields())); - m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), currentTime(), requestObject); -} - -void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response) -{ - RefPtr<Inspector::TypeBuilder::Network::WebSocketResponse> responseObject = Inspector::TypeBuilder::Network::WebSocketResponse::create() - .setStatus(response.httpStatusCode()) - .setStatusText(response.httpStatusText()) - .setHeaders(buildObjectForHeaders(response.httpHeaderFields())); - m_frontendDispatcher->webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), currentTime(), responseObject); -} - -void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier) -{ - m_frontendDispatcher->webSocketClosed(IdentifiersFactory::requestId(identifier), currentTime()); -} - -void InspectorResourceAgent::didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame) -{ - RefPtr<Inspector::TypeBuilder::Network::WebSocketFrame> frameObject = Inspector::TypeBuilder::Network::WebSocketFrame::create() - .setOpcode(frame.opCode) - .setMask(frame.masked) - .setPayloadData(String(frame.payload, frame.payloadLength)); - m_frontendDispatcher->webSocketFrameReceived(IdentifiersFactory::requestId(identifier), currentTime(), frameObject); -} - -void InspectorResourceAgent::didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame) -{ - RefPtr<Inspector::TypeBuilder::Network::WebSocketFrame> frameObject = Inspector::TypeBuilder::Network::WebSocketFrame::create() - .setOpcode(frame.opCode) - .setMask(frame.masked) - .setPayloadData(String(frame.payload, frame.payloadLength)); - m_frontendDispatcher->webSocketFrameSent(IdentifiersFactory::requestId(identifier), currentTime(), frameObject); -} - -void InspectorResourceAgent::didReceiveWebSocketFrameError(unsigned long identifier, const String& errorMessage) -{ - m_frontendDispatcher->webSocketFrameError(IdentifiersFactory::requestId(identifier), currentTime(), errorMessage); -} - -#endif // ENABLE(WEB_SOCKETS) - -// called from Internals for layout test purposes. -void InspectorResourceAgent::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize) -{ - m_resourcesData->setResourcesDataSizeLimits(maximumResourcesContentSize, maximumSingleResourceContentSize); -} - -void InspectorResourceAgent::enable(ErrorString*) -{ - enable(); -} - -void InspectorResourceAgent::enable() -{ - if (!m_frontendDispatcher) - return; - m_enabled = true; - m_instrumentingAgents->setInspectorResourceAgent(this); -} - -void InspectorResourceAgent::disable(ErrorString*) -{ - m_enabled = false; - m_instrumentingAgents->setInspectorResourceAgent(nullptr); - m_resourcesData->clear(); - m_extraRequestHeaders.clear(); -} - -void InspectorResourceAgent::setExtraHTTPHeaders(ErrorString*, const RefPtr<InspectorObject>& headers) -{ - m_extraRequestHeaders = headers; -} - -void InspectorResourceAgent::getResponseBody(ErrorString* errorString, const String& requestId, String* content, bool* base64Encoded) -{ - NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId); - if (!resourceData) { - *errorString = "No resource with given identifier found"; - return; - } - - if (resourceData->hasContent()) { - *base64Encoded = resourceData->base64Encoded(); - *content = resourceData->content(); - return; - } - - if (resourceData->isContentEvicted()) { - *errorString = "Request content was evicted from inspector cache"; - return; - } - - if (resourceData->buffer() && !resourceData->textEncodingName().isNull()) { - *base64Encoded = false; - if (InspectorPageAgent::sharedBufferContent(resourceData->buffer(), resourceData->textEncodingName(), *base64Encoded, content)) - return; - } - - if (resourceData->cachedResource()) { - if (InspectorPageAgent::cachedResourceContent(resourceData->cachedResource(), content, base64Encoded)) - return; - } - - *errorString = "No data found for resource with given identifier"; -} - -void InspectorResourceAgent::replayXHR(ErrorString*, const String& requestId) -{ - RefPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(*m_pageAgent->mainFrame()->document()); - String actualRequestId = requestId; - - XHRReplayData* xhrReplayData = m_resourcesData->xhrReplayData(requestId); - if (!xhrReplayData) - return; - - ResourceRequest request(xhrReplayData->url()); -#if ENABLE(CACHE_PARTITIONING) - request.setCachePartition(m_pageAgent->mainFrame()->document()->topOrigin()->cachePartition()); -#endif - CachedResource* cachedResource = memoryCache()->resourceForRequest(request); - if (cachedResource) - memoryCache()->remove(cachedResource); - - xhr->open(xhrReplayData->method(), xhrReplayData->url(), xhrReplayData->async(), IGNORE_EXCEPTION); - HTTPHeaderMap::const_iterator end = xhrReplayData->headers().end(); - for (HTTPHeaderMap::const_iterator it = xhrReplayData->headers().begin(); it!= end; ++it) - xhr->setRequestHeader(it->key, it->value, IGNORE_EXCEPTION); - xhr->sendFromInspector(xhrReplayData->formData(), IGNORE_EXCEPTION); -} - -void InspectorResourceAgent::canClearBrowserCache(ErrorString*, bool* result) -{ - *result = m_client->canClearBrowserCache(); -} - -void InspectorResourceAgent::clearBrowserCache(ErrorString*) -{ - m_client->clearBrowserCache(); -} - -void InspectorResourceAgent::canClearBrowserCookies(ErrorString*, bool* result) -{ - *result = m_client->canClearBrowserCookies(); -} - -void InspectorResourceAgent::clearBrowserCookies(ErrorString*) -{ - m_client->clearBrowserCookies(); -} - -void InspectorResourceAgent::setCacheDisabled(ErrorString*, bool cacheDisabled) -{ - m_cacheDisabled = cacheDisabled; - if (cacheDisabled) - memoryCache()->evictResources(); -} - -void InspectorResourceAgent::mainFrameNavigated(DocumentLoader* loader) -{ - if (m_cacheDisabled) - memoryCache()->evictResources(); - - m_resourcesData->clear(m_pageAgent->loaderId(loader)); -} - -InspectorResourceAgent::InspectorResourceAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorClient* client) - : InspectorAgentBase(ASCIILiteral("Network"), instrumentingAgents) - , m_pageAgent(pageAgent) - , m_client(client) - , m_resourcesData(adoptPtr(new NetworkResourcesData())) - , m_enabled(false) - , m_cacheDisabled(false) - , m_loadingXHRSynchronously(false) - , m_isRecalculatingStyle(false) -{ -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorResourceAgent.h b/Source/WebCore/inspector/InspectorResourceAgent.h deleted file mode 100644 index d2ca2a294..000000000 --- a/Source/WebCore/inspector/InspectorResourceAgent.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorResourceAgent_h -#define InspectorResourceAgent_h - -#include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" -#include <wtf/PassOwnPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> -#include <wtf/text/WTFString.h> - -#if ENABLE(INSPECTOR) - -namespace Inspector { -class InspectorArray; -class InspectorObject; -} - -namespace WebCore { - -class CachedResource; -class Document; -class DocumentLoader; -class FormData; -class Frame; -class HTTPHeaderMap; -class InspectorClient; -class InspectorPageAgent; -class InstrumentingAgents; -class URL; -class NetworkResourcesData; -class Page; -class ResourceError; -class ResourceLoader; -class ResourceRequest; -class ResourceResponse; -class SharedBuffer; -class ThreadableLoaderClient; -class XHRReplayData; -class XMLHttpRequest; - -#if ENABLE(WEB_SOCKETS) -struct WebSocketFrame; -#endif - -typedef String ErrorString; - -class InspectorResourceAgent : public InspectorAgentBase, public Inspector::InspectorNetworkBackendDispatcherHandler { -public: - InspectorResourceAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorClient*); - ~InspectorResourceAgent(); - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - - void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse); - void markResourceAsCached(unsigned long identifier); - void didReceiveResponse(unsigned long identifier, DocumentLoader* laoder, const ResourceResponse&, ResourceLoader*); - void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength); - void didFinishLoading(unsigned long identifier, DocumentLoader*, double finishTime); - void didFailLoading(unsigned long identifier, DocumentLoader*, const ResourceError&); - void didLoadResourceFromMemoryCache(DocumentLoader*, CachedResource*); - void mainFrameNavigated(DocumentLoader*); - void setInitialScriptContent(unsigned long identifier, const String& sourceString); - void didReceiveScriptResponse(unsigned long identifier); - - void documentThreadableLoaderStartedLoadingForClient(unsigned long identifier, ThreadableLoaderClient*); - void willLoadXHR(ThreadableLoaderClient*, const String& method, const URL&, bool async, PassRefPtr<FormData> body, const HTTPHeaderMap& headers, bool includeCrendentials); - void didFailXHRLoading(ThreadableLoaderClient*); - void didFinishXHRLoading(ThreadableLoaderClient*, unsigned long identifier, const String& sourceString); - void didReceiveXHRResponse(unsigned long identifier); - void willLoadXHRSynchronously(); - void didLoadXHRSynchronously(); - - void willDestroyCachedResource(CachedResource*); - - // FIXME: InspectorResourceAgent should now be aware of style recalculation. - void willRecalculateStyle(); - void didRecalculateStyle(); - void didScheduleStyleRecalculation(Document*); - - PassRefPtr<Inspector::TypeBuilder::Network::Initiator> buildInitiatorObject(Document*); - -#if ENABLE(WEB_SOCKETS) - void didCreateWebSocket(unsigned long identifier, const URL& requestURL); - void willSendWebSocketHandshakeRequest(unsigned long identifier, const ResourceRequest&); - void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse&); - void didCloseWebSocket(unsigned long identifier); - void didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame&); - void didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame&); - void didReceiveWebSocketFrameError(unsigned long identifier, const String&); -#endif - - // called from Internals for layout test purposes. - void setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize); - - // Called from frontend - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void setExtraHTTPHeaders(ErrorString*, const RefPtr<Inspector::InspectorObject>&) override; - virtual void getResponseBody(ErrorString*, const String& requestId, String* content, bool* base64Encoded) override; - - virtual void replayXHR(ErrorString*, const String& requestId) override; - - virtual void canClearBrowserCache(ErrorString*, bool*) override; - virtual void clearBrowserCache(ErrorString*) override; - virtual void canClearBrowserCookies(ErrorString*, bool*) override; - virtual void clearBrowserCookies(ErrorString*) override; - virtual void setCacheDisabled(ErrorString*, bool cacheDisabled) override; - -private: - void enable(); - - InspectorPageAgent* m_pageAgent; - InspectorClient* m_client; - std::unique_ptr<Inspector::InspectorNetworkFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorNetworkBackendDispatcher> m_backendDispatcher; - OwnPtr<NetworkResourcesData> m_resourcesData; - bool m_enabled; - bool m_cacheDisabled; - bool m_loadingXHRSynchronously; - RefPtr<Inspector::InspectorObject> m_extraRequestHeaders; - - typedef HashMap<ThreadableLoaderClient*, RefPtr<XHRReplayData>> PendingXHRReplayDataMap; - PendingXHRReplayDataMap m_pendingXHRReplayData; - // FIXME: InspectorResourceAgent should now be aware of style recalculation. - RefPtr<Inspector::TypeBuilder::Network::Initiator> m_styleRecalculationInitiator; - bool m_isRecalculatingStyle; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorResourceAgent_h) diff --git a/Source/WebCore/inspector/InspectorStyleSheet.cpp b/Source/WebCore/inspector/InspectorStyleSheet.cpp index 85cb2c461..b0c725ae2 100644 --- a/Source/WebCore/inspector/InspectorStyleSheet.cpp +++ b/Source/WebCore/inspector/InspectorStyleSheet.cpp @@ -23,16 +23,15 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorStyleSheet.h" -#include "CSSHostRule.h" #include "CSSImportRule.h" +#include "CSSKeyframesRule.h" #include "CSSMediaRule.h" #include "CSSParser.h" +#include "CSSParserObserver.h" #include "CSSPropertyNames.h" +#include "CSSPropertyParser.h" #include "CSSPropertySourceData.h" #include "CSSRule.h" #include "CSSRuleList.h" @@ -42,30 +41,28 @@ #include "ContentSecurityPolicy.h" #include "Document.h" #include "Element.h" +#include "ExceptionCode.h" #include "HTMLHeadElement.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" #include "HTMLStyleElement.h" #include "InspectorCSSAgent.h" #include "InspectorPageAgent.h" +#include "MediaList.h" #include "Node.h" -#include "SVGNames.h" +#include "SVGElement.h" +#include "SVGStyleElement.h" #include "StyleProperties.h" #include "StyleResolver.h" #include "StyleRule.h" #include "StyleRuleImport.h" #include "StyleSheetContents.h" #include "StyleSheetList.h" -#include "WebKitCSSKeyframesRule.h" #include <inspector/ContentSearchUtilities.h> -#include <inspector/InspectorValues.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/Vector.h> #include <wtf/text/StringBuilder.h> #include <yarr/RegularExpression.h> -using Inspector::TypeBuilder::Array; +using Inspector::Protocol::Array; using WebCore::RuleSourceDataList; using WebCore::CSSRuleSourceData; @@ -78,15 +75,15 @@ public: void setText(const String& text); bool hasText() const { return m_hasText; } RuleSourceDataList* sourceData() const { return m_sourceData.get(); } - void setSourceData(PassOwnPtr<RuleSourceDataList>); - bool hasSourceData() const { return m_sourceData; } - PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const; + void setSourceData(std::unique_ptr<RuleSourceDataList>); + bool hasSourceData() const { return m_sourceData != nullptr; } + WebCore::CSSRuleSourceData* ruleSourceDataAt(unsigned) const; private: String m_text; bool m_hasText; - OwnPtr<RuleSourceDataList> m_sourceData; + std::unique_ptr<RuleSourceDataList> m_sourceData; }; ParsedStyleSheet::ParsedStyleSheet() @@ -101,52 +98,286 @@ void ParsedStyleSheet::setText(const String& text) setSourceData(nullptr); } -static void flattenSourceData(RuleSourceDataList* dataList, RuleSourceDataList* target) +static void flattenSourceData(RuleSourceDataList& dataList, RuleSourceDataList& target) { - for (size_t i = 0; i < dataList->size(); ++i) { - RefPtr<CSSRuleSourceData>& data = dataList->at(i); - if (data->type == CSSRuleSourceData::STYLE_RULE) - target->append(data); - else if (data->type == CSSRuleSourceData::MEDIA_RULE) - flattenSourceData(&data->childRules, target); -#if ENABLE(SHADOW_DOM) - else if (data->type == CSSRuleSourceData::HOST_RULE) - flattenSourceData(&data->childRules, target); -#endif -#if ENABLE(CSS3_CONDITIONAL_RULES) - else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) - flattenSourceData(&data->childRules, target); -#endif + for (auto& data : dataList) { + if (data->type == WebCore::StyleRule::Style) + target.append(data.copyRef()); + else if (data->type == WebCore::StyleRule::Media) + flattenSourceData(data->childRules, target); + else if (data->type == WebCore::StyleRule::Supports) + flattenSourceData(data->childRules, target); } } -void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData) +void ParsedStyleSheet::setSourceData(std::unique_ptr<RuleSourceDataList> sourceData) { if (!sourceData) { - m_sourceData.clear(); + m_sourceData.reset(); return; } - m_sourceData = adoptPtr(new RuleSourceDataList()); + m_sourceData = std::make_unique<RuleSourceDataList>(); // FIXME: This is a temporary solution to retain the original flat sourceData structure // containing only style rules, even though CSSParser now provides the full rule source data tree. // Normally, we should just assign m_sourceData = sourceData; - flattenSourceData(sourceData.get(), m_sourceData.get()); + flattenSourceData(*sourceData, *m_sourceData); } -PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const +WebCore::CSSRuleSourceData* ParsedStyleSheet::ruleSourceDataAt(unsigned index) const { if (!hasSourceData() || index >= m_sourceData->size()) return nullptr; - return m_sourceData->at(index); + return m_sourceData->at(index).ptr(); } using namespace Inspector; namespace WebCore { +static CSSParserContext parserContextForDocument(Document* document) +{ + return document ? CSSParserContext(*document) : strictCSSParserContext(); +} + +class StyleSheetHandler : public CSSParserObserver { +public: + StyleSheetHandler(const String& parsedText, Document* document, RuleSourceDataList* result) + : m_parsedText(parsedText) + , m_document(document) + , m_ruleSourceDataResult(result) + { + ASSERT(m_ruleSourceDataResult); + } + +private: + void startRuleHeader(StyleRule::Type, unsigned) override; + void endRuleHeader(unsigned) override; + void observeSelector(unsigned startOffset, unsigned endOffset) override; + void startRuleBody(unsigned) override; + void endRuleBody(unsigned) override; + void observeProperty(unsigned startOffset, unsigned endOffset, bool isImportant, bool isParsed) override; + void observeComment(unsigned startOffset, unsigned endOffset) override; + + Ref<CSSRuleSourceData> popRuleData(); + template <typename CharacterType> inline void setRuleHeaderEnd(const CharacterType*, unsigned); + void fixUnparsedPropertyRanges(CSSRuleSourceData*); + + const String& m_parsedText; + Document* m_document; + + RuleSourceDataList m_currentRuleDataStack; + RefPtr<CSSRuleSourceData> m_currentRuleData; + RuleSourceDataList* m_ruleSourceDataResult { nullptr }; +}; + +void StyleSheetHandler::startRuleHeader(StyleRule::Type type, unsigned offset) +{ + // Pop off data for a previous invalid rule. + if (m_currentRuleData) + m_currentRuleDataStack.removeLast(); + + auto data = CSSRuleSourceData::create(type); + data->ruleHeaderRange.start = offset; + m_currentRuleData = data.copyRef(); + m_currentRuleDataStack.append(WTFMove(data)); +} + +template <typename CharacterType> inline void StyleSheetHandler::setRuleHeaderEnd(const CharacterType* dataStart, unsigned listEndOffset) +{ + while (listEndOffset > 1) { + if (isHTMLSpace<CharacterType>(*(dataStart + listEndOffset - 1))) + --listEndOffset; + else + break; + } + + m_currentRuleDataStack.last()->ruleHeaderRange.end = listEndOffset; + if (!m_currentRuleDataStack.last()->selectorRanges.isEmpty()) + m_currentRuleDataStack.last()->selectorRanges.last().end = listEndOffset; +} + +void StyleSheetHandler::endRuleHeader(unsigned offset) +{ + ASSERT(!m_currentRuleDataStack.isEmpty()); + + if (m_parsedText.is8Bit()) + setRuleHeaderEnd<LChar>(m_parsedText.characters8(), offset); + else + setRuleHeaderEnd<UChar>(m_parsedText.characters16(), offset); +} + +void StyleSheetHandler::observeSelector(unsigned startOffset, unsigned endOffset) +{ + ASSERT(m_currentRuleDataStack.size()); + m_currentRuleDataStack.last()->selectorRanges.append(SourceRange(startOffset, endOffset)); +} + +void StyleSheetHandler::startRuleBody(unsigned offset) +{ + m_currentRuleData = nullptr; + ASSERT(!m_currentRuleDataStack.isEmpty()); + + // Skip the rule body opening brace. + if (m_parsedText[offset] == '{') + ++offset; + + m_currentRuleDataStack.last()->ruleBodyRange.start = offset; +} + +void StyleSheetHandler::endRuleBody(unsigned offset) +{ + ASSERT(!m_currentRuleDataStack.isEmpty()); + m_currentRuleDataStack.last()->ruleBodyRange.end = offset; + auto rule = popRuleData(); + fixUnparsedPropertyRanges(rule.ptr()); + if (m_currentRuleDataStack.isEmpty()) + m_ruleSourceDataResult->append(WTFMove(rule)); + else + m_currentRuleDataStack.last()->childRules.append(WTFMove(rule)); +} + +Ref<CSSRuleSourceData> StyleSheetHandler::popRuleData() +{ + ASSERT(!m_currentRuleDataStack.isEmpty()); + m_currentRuleData = nullptr; + auto data = WTFMove(m_currentRuleDataStack.last()); + m_currentRuleDataStack.removeLast(); + return data; +} + +template <typename CharacterType> +static inline void fixUnparsedProperties(const CharacterType* characters, CSSRuleSourceData* ruleData) +{ + Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData; + unsigned size = propertyData.size(); + if (!size) + return; + + unsigned styleStart = ruleData->ruleBodyRange.start; + + CSSPropertySourceData* nextData = &(propertyData.at(0)); + for (unsigned i = 0; i < size; ++i) { + CSSPropertySourceData* currentData = nextData; + nextData = i < size - 1 ? &(propertyData.at(i + 1)) : nullptr; + + if (currentData->parsedOk) + continue; + if (currentData->range.end > 0 && characters[styleStart + currentData->range.end - 1] == ';') + continue; + + unsigned propertyEnd; + if (!nextData) + propertyEnd = ruleData->ruleBodyRange.end - 1; + else + propertyEnd = styleStart + nextData->range.start - 1; + + while (isHTMLSpace<CharacterType>(characters[propertyEnd])) + --propertyEnd; + + // propertyEnd points at the last property text character. + unsigned newPropertyEnd = propertyEnd + styleStart + 1; + if (currentData->range.end != newPropertyEnd) { + currentData->range.end = newPropertyEnd; + unsigned valueStart = styleStart + currentData->range.start + currentData->name.length(); + while (valueStart < propertyEnd && characters[valueStart] != ':') + ++valueStart; + + // Shift past the ':'. + if (valueStart < propertyEnd) + ++valueStart; + + while (valueStart < propertyEnd && isHTMLSpace<CharacterType>(characters[valueStart])) + ++valueStart; + + // Need to exclude the trailing ';' from the property value. + currentData->value = String(characters + valueStart, propertyEnd - valueStart + (characters[propertyEnd] == ';' ? 0 : 1)); + } + } +} + +void StyleSheetHandler::fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData) +{ + if (!ruleData->styleSourceData) + return; + + if (m_parsedText.is8Bit()) { + fixUnparsedProperties<LChar>(m_parsedText.characters8(), ruleData); + return; + } + + fixUnparsedProperties<UChar>(m_parsedText.characters16(), ruleData); +} + +void StyleSheetHandler::observeProperty(unsigned startOffset, unsigned endOffset, bool isImportant, bool isParsed) +{ + if (m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->styleSourceData) + return; + + ASSERT(endOffset <= m_parsedText.length()); + + // Include semicolon in the property text. + if (endOffset < m_parsedText.length() && m_parsedText[endOffset] == ';') + ++endOffset; + + ASSERT(startOffset < endOffset); + String propertyString = m_parsedText.substring(startOffset, endOffset - startOffset).stripWhiteSpace(); + if (propertyString.endsWith(';')) + propertyString = propertyString.left(propertyString.length() - 1); + size_t colonIndex = propertyString.find(':'); + ASSERT(colonIndex != notFound); + + String name = propertyString.left(colonIndex).stripWhiteSpace(); + String value = propertyString.substring(colonIndex + 1, propertyString.length()).stripWhiteSpace(); + + // FIXME-NEWPARSER: The property range is relative to the declaration start offset, but no + // good reason for it, and it complicates fixUnparsedProperties. + SourceRange& topRuleBodyRange = m_currentRuleDataStack.last()->ruleBodyRange; + m_currentRuleDataStack.last()->styleSourceData->propertyData.append(CSSPropertySourceData(name, value, isImportant, false, isParsed, SourceRange(startOffset - topRuleBodyRange.start, endOffset - topRuleBodyRange.start))); +} + +void StyleSheetHandler::observeComment(unsigned startOffset, unsigned endOffset) +{ + ASSERT(endOffset <= m_parsedText.length()); + + if (m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->ruleHeaderRange.end || !m_currentRuleDataStack.last()->styleSourceData) + return; + + // The lexer is not inside a property AND it is scanning a declaration-aware + // rule body. + String commentText = m_parsedText.substring(startOffset, endOffset - startOffset); + + ASSERT(commentText.startsWith("/*")); + commentText = commentText.substring(2); + + // Require well-formed comments. + if (!commentText.endsWith("*/")) + return; + commentText = commentText.substring(0, commentText.length() - 2).stripWhiteSpace(); + if (commentText.isEmpty()) + return; + + // FIXME: Use the actual rule type rather than STYLE_RULE? + RuleSourceDataList sourceData; + + StyleSheetHandler handler(commentText, m_document, &sourceData); + CSSParser::parseDeclarationForInspector(parserContextForDocument(m_document), commentText, handler); + Vector<CSSPropertySourceData>& commentPropertyData = sourceData.first()->styleSourceData->propertyData; + if (commentPropertyData.size() != 1) + return; + CSSPropertySourceData& propertyData = commentPropertyData.at(0); + bool parsedOk = propertyData.parsedOk || propertyData.name.startsWith("-moz-") || propertyData.name.startsWith("-o-") || propertyData.name.startsWith("-webkit-") || propertyData.name.startsWith("-ms-"); + if (!parsedOk || propertyData.range.length() != commentText.length()) + return; + + // FIXME-NEWPARSER: The property range is relative to the declaration start offset, but no + // good reason for it, and it complicates fixUnparsedProperties. + SourceRange& topRuleBodyRange = m_currentRuleDataStack.last()->ruleBodyRange; + m_currentRuleDataStack.last()->styleSourceData->propertyData.append(CSSPropertySourceData(propertyData.name, propertyData.value, false, true, true, SourceRange(startOffset - topRuleBodyRange.start, endOffset - topRuleBodyRange.start))); +} + enum MediaListSource { MediaListSourceLinkedSheet, MediaListSourceInlineSheet, @@ -154,92 +385,85 @@ enum MediaListSource { MediaListSourceImportRule }; -static PassRefPtr<Inspector::TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, Vector<size_t>* lineEndings) +static RefPtr<Inspector::Protocol::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, Vector<size_t>* lineEndings, int* endingLine = nullptr) { if (!lineEndings) return nullptr; TextPosition start = ContentSearchUtilities::textPositionFromOffset(range.start, *lineEndings); TextPosition end = ContentSearchUtilities::textPositionFromOffset(range.end, *lineEndings); - RefPtr<Inspector::TypeBuilder::CSS::SourceRange> result = Inspector::TypeBuilder::CSS::SourceRange::create() + if (endingLine) + *endingLine = end.m_line.zeroBasedInt(); + + return Inspector::Protocol::CSS::SourceRange::create() .setStartLine(start.m_line.zeroBasedInt()) .setStartColumn(start.m_column.zeroBasedInt()) .setEndLine(end.m_line.zeroBasedInt()) - .setEndColumn(end.m_column.zeroBasedInt()); - return result.release(); + .setEndColumn(end.m_column.zeroBasedInt()) + .release(); } -static PassRefPtr<Inspector::TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL) +static Ref<Inspector::Protocol::CSS::CSSMedia> buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL) { // Make certain compilers happy by initializing |source| up-front. - Inspector::TypeBuilder::CSS::CSSMedia::Source::Enum source = Inspector::TypeBuilder::CSS::CSSMedia::Source::InlineSheet; + Inspector::Protocol::CSS::CSSMedia::Source source = Inspector::Protocol::CSS::CSSMedia::Source::InlineSheet; switch (mediaListSource) { case MediaListSourceMediaRule: - source = Inspector::TypeBuilder::CSS::CSSMedia::Source::MediaRule; + source = Inspector::Protocol::CSS::CSSMedia::Source::MediaRule; break; case MediaListSourceImportRule: - source = Inspector::TypeBuilder::CSS::CSSMedia::Source::ImportRule; + source = Inspector::Protocol::CSS::CSSMedia::Source::ImportRule; break; case MediaListSourceLinkedSheet: - source = Inspector::TypeBuilder::CSS::CSSMedia::Source::LinkedSheet; + source = Inspector::Protocol::CSS::CSSMedia::Source::LinkedSheet; break; case MediaListSourceInlineSheet: - source = Inspector::TypeBuilder::CSS::CSSMedia::Source::InlineSheet; + source = Inspector::Protocol::CSS::CSSMedia::Source::InlineSheet; break; } - RefPtr<Inspector::TypeBuilder::CSS::CSSMedia> mediaObject = Inspector::TypeBuilder::CSS::CSSMedia::create() + auto mediaObject = Inspector::Protocol::CSS::CSSMedia::create() .setText(media->mediaText()) - .setSource(source); + .setSource(source) + .release(); if (!sourceURL.isEmpty()) { mediaObject->setSourceURL(sourceURL); mediaObject->setSourceLine(media->queries()->lastLine()); } - return mediaObject.release(); + return mediaObject; } -static PassRefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet) +static RefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet) { if (!styleSheet) return nullptr; RefPtr<StaticCSSRuleList> list = StaticCSSRuleList::create(); Vector<RefPtr<CSSRule>>& listRules = list->rules(); - for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { - CSSRule* item = styleSheet->item(i); - if (item->type() == CSSRule::CHARSET_RULE) - continue; - listRules.append(item); - } - return list.release(); + for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) + listRules.append(styleSheet->item(i)); + return WTFMove(list); } -static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule) +static RefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule) { if (!rule) return nullptr; - if (rule->type() == CSSRule::MEDIA_RULE) - return static_cast<CSSMediaRule*>(rule)->cssRules(); + if (is<CSSMediaRule>(*rule)) + return &downcast<CSSMediaRule>(*rule).cssRules(); - if (rule->type() == CSSRule::WEBKIT_KEYFRAMES_RULE) - return static_cast<WebKitCSSKeyframesRule*>(rule)->cssRules(); + if (is<CSSKeyframesRule>(*rule)) + return &downcast<CSSKeyframesRule>(*rule).cssRules(); -#if ENABLE(SHADOW_DOM) - if (rule->type() == CSSRule::HOST_RULE) - return static_cast<CSSHostRule*>(rule)->cssRules(); -#endif - -#if ENABLE(CSS3_CONDITIONAL_RULES) - if (rule->type() == CSSRule::SUPPORTS_RULE) - return static_cast<CSSSupportsRule*>(rule)->cssRules(); -#endif + if (is<CSSSupportsRule>(*rule)) + return &downcast<CSSSupportsRule>(*rule).cssRules(); return nullptr; } -static void fillMediaListChain(CSSRule* rule, Array<Inspector::TypeBuilder::CSS::CSSMedia>* mediaArray) +static void fillMediaListChain(CSSRule* rule, Array<Inspector::Protocol::CSS::CSSMedia>& mediaArray) { MediaList* mediaList; CSSRule* parentRule = rule; @@ -247,14 +471,14 @@ static void fillMediaListChain(CSSRule* rule, Array<Inspector::TypeBuilder::CSS: while (parentRule) { CSSStyleSheet* parentStyleSheet = nullptr; bool isMediaRule = true; - if (parentRule->type() == CSSRule::MEDIA_RULE) { - CSSMediaRule* mediaRule = static_cast<CSSMediaRule*>(parentRule); - mediaList = mediaRule->media(); - parentStyleSheet = mediaRule->parentStyleSheet(); - } else if (parentRule->type() == CSSRule::IMPORT_RULE) { - CSSImportRule* importRule = static_cast<CSSImportRule*>(parentRule); - mediaList = importRule->media(); - parentStyleSheet = importRule->parentStyleSheet(); + if (is<CSSMediaRule>(*parentRule)) { + CSSMediaRule& mediaRule = downcast<CSSMediaRule>(*parentRule); + mediaList = mediaRule.media(); + parentStyleSheet = mediaRule.parentStyleSheet(); + } else if (is<CSSImportRule>(*parentRule)) { + CSSImportRule& importRule = downcast<CSSImportRule>(*parentRule); + mediaList = &importRule.media(); + parentStyleSheet = importRule.parentStyleSheet(); isMediaRule = false; } else mediaList = nullptr; @@ -264,10 +488,10 @@ static void fillMediaListChain(CSSRule* rule, Array<Inspector::TypeBuilder::CSS: if (sourceURL.isEmpty()) sourceURL = InspectorDOMAgent::documentURLString(parentStyleSheet->ownerDocument()); } else - sourceURL = ""; + sourceURL = emptyString(); if (mediaList && mediaList->length()) - mediaArray->addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL)); + mediaArray.addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL)); if (parentRule->parentRule()) parentRule = parentRule->parentRule(); @@ -282,8 +506,8 @@ static void fillMediaListChain(CSSRule* rule, Array<Inspector::TypeBuilder::CSS: else if (!styleSheet->contents().baseURL().isEmpty()) sourceURL = styleSheet->contents().baseURL(); else - sourceURL = ""; - mediaArray->addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL)); + sourceURL = emptyString(); + mediaArray.addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL)); } parentRule = styleSheet->ownerRule(); if (parentRule) @@ -294,21 +518,15 @@ static void fillMediaListChain(CSSRule* rule, Array<Inspector::TypeBuilder::CSS: } } -static PassOwnPtr<CSSParser> createCSSParser(Document* document) +Ref<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, RefPtr<CSSStyleDeclaration>&& style, InspectorStyleSheet* parentStyleSheet) { - return adoptPtr(new CSSParser(document ? CSSParserContext(*document) : strictCSSParserContext())); + return adoptRef(*new InspectorStyle(styleId, WTFMove(style), parentStyleSheet)); } -PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet) -{ - return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet)); -} - -InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet) +InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, RefPtr<CSSStyleDeclaration>&& style, InspectorStyleSheet* parentStyleSheet) : m_styleId(styleId) , m_style(style) , m_parentStyleSheet(parentStyleSheet) - , m_formatAcquired(false) { ASSERT(m_style); } @@ -317,11 +535,11 @@ InspectorStyle::~InspectorStyle() { } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::buildObjectForStyle() const +RefPtr<Inspector::Protocol::CSS::CSSStyle> InspectorStyle::buildObjectForStyle() const { - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> result = styleWithProperties(); + Ref<Inspector::Protocol::CSS::CSSStyle> result = styleWithProperties(); if (!m_styleId.isEmpty()) - result->setStyleId(m_styleId.asProtocolValue<Inspector::TypeBuilder::CSS::CSSStyleId>()); + result->setStyleId(m_styleId.asProtocolValue<Inspector::Protocol::CSS::CSSStyleId>()); result->setWidth(m_style->getPropertyValue("width")); result->setHeight(m_style->getPropertyValue("height")); @@ -330,225 +548,116 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::buildObjectFor if (sourceData) result->setRange(buildSourceRangeObject(sourceData->ruleBodyRange, m_parentStyleSheet->lineEndings().get())); - return result.release(); + return WTFMove(result); } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>> InspectorStyle::buildArrayForComputedStyle() const +Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>> InspectorStyle::buildArrayForComputedStyle() const { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>::create(); + auto result = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>::create(); Vector<InspectorStyleProperty> properties; populateAllProperties(&properties); - for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) { - const CSSPropertySourceData& propertyEntry = it->sourceData; - RefPtr<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty> entry = Inspector::TypeBuilder::CSS::CSSComputedStyleProperty::create() + for (auto& property : properties) { + const CSSPropertySourceData& propertyEntry = property.sourceData; + auto entry = Inspector::Protocol::CSS::CSSComputedStyleProperty::create() .setName(propertyEntry.name) - .setValue(propertyEntry.value); - result->addItem(entry); - } - - return result.release(); -} - -// This method does the following preprocessing of |propertyText| with |overwrite| == false and |index| past the last active property: -// - If the last property (if present) has no closing ";", the ";" is prepended to the current |propertyText| value. -// - A heuristic formatting is attempted to retain the style structure. -// -// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not, -// the method returns false (denoting an error). -bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite, String* oldText, ExceptionCode& ec) -{ - ASSERT(m_parentStyleSheet); - DEFINE_STATIC_LOCAL(String, bogusPropertyName, (ASCIILiteral("-webkit-boguz-propertee"))); - - if (!m_parentStyleSheet->ensureParsedDataReady()) { - ec = NOT_FOUND_ERR; - return false; - } - - if (propertyText.stripWhiteSpace().length()) { - RefPtr<MutableStyleProperties> tempMutableStyle = MutableStyleProperties::create(); - RefPtr<CSSRuleSourceData> sourceData = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE); - Document* ownerDocument = m_parentStyleSheet->pageStyleSheet() ? m_parentStyleSheet->pageStyleSheet()->ownerDocument() : nullptr; - createCSSParser(ownerDocument)->parseDeclaration(tempMutableStyle.get(), propertyText + " " + bogusPropertyName + ": none", sourceData, &m_style->parentStyleSheet()->contents()); - Vector<CSSPropertySourceData>& propertyData = sourceData->styleSourceData->propertyData; - unsigned propertyCount = propertyData.size(); - - // At least one property + the bogus property added just above should be present. - if (propertyCount < 2) { - ec = SYNTAX_ERR; - return false; - } - - // Check for a proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state). - if (propertyData.at(propertyCount - 1).name != bogusPropertyName) { - ec = SYNTAX_ERR; - return false; - } - } - - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); - if (!sourceData) { - ec = NOT_FOUND_ERR; - return false; - } - - String text; - bool success = styleText(&text); - if (!success) { - ec = NOT_FOUND_ERR; - return false; + .setValue(propertyEntry.value) + .release(); + result->addItem(WTFMove(entry)); } - Vector<InspectorStyleProperty> allProperties; - populateAllProperties(&allProperties); - - InspectorStyleTextEditor editor(&allProperties, &m_disabledProperties, text, newLineAndWhitespaceDelimiters()); - if (overwrite) { - if (index >= allProperties.size()) { - ec = INDEX_SIZE_ERR; - return false; - } - *oldText = allProperties.at(index).rawText; - editor.replaceProperty(index, propertyText); - } else - editor.insertProperty(index, propertyText, sourceData->ruleBodyRange.length()); - - return applyStyleText(editor.styleText()); + return result; } -bool InspectorStyle::toggleProperty(unsigned index, bool disable, ExceptionCode& ec) +ExceptionOr<String> InspectorStyle::text() const { - ASSERT(m_parentStyleSheet); - if (!m_parentStyleSheet->ensureParsedDataReady()) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return false; - } - - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); - if (!sourceData) { - ec = NOT_FOUND_ERR; - return false; - } - - String text; - bool success = styleText(&text); - if (!success) { - ec = NOT_FOUND_ERR; - return false; - } - - Vector<InspectorStyleProperty> allProperties; - populateAllProperties(&allProperties); - if (index >= allProperties.size()) { - ec = INDEX_SIZE_ERR; - return false; - } + // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully. + auto sourceData = extractSourceData(); + if (!sourceData) + return Exception { NOT_FOUND_ERR }; - InspectorStyleProperty& property = allProperties.at(index); - if (property.disabled == disable) - return true; // Idempotent operation. + auto result = m_parentStyleSheet->text(); + if (result.hasException()) + return result.releaseException(); - InspectorStyleTextEditor editor(&allProperties, &m_disabledProperties, text, newLineAndWhitespaceDelimiters()); - if (disable) - editor.disableProperty(index); - else - editor.enableProperty(index); - - return applyStyleText(editor.styleText()); + auto& bodyRange = sourceData->ruleBodyRange; + return result.releaseReturnValue().substring(bodyRange.start, bodyRange.end - bodyRange.start); } -bool InspectorStyle::getText(String* result) const +static String lowercasePropertyName(const String& name) { - // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully. - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); - if (!sourceData) - return false; - - String styleSheetText; - bool success = m_parentStyleSheet->getText(&styleSheetText); - if (!success) - return false; - - SourceRange& bodyRange = sourceData->ruleBodyRange; - *result = styleSheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start); - return true; + // Custom properties are case-sensitive. + if (name.startsWith("--")) + return name; + return name.convertToASCIILowercase(); } -bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* result) const +void InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* result) const { HashSet<String> sourcePropertyNames; - unsigned disabledIndex = 0; - unsigned disabledLength = m_disabledProperties.size(); - InspectorStyleProperty disabledProperty; - if (disabledIndex < disabledLength) - disabledProperty = m_disabledProperties.at(disabledIndex); - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); - Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : nullptr; + auto sourceData = extractSourceData(); + auto* sourcePropertyData = sourceData ? &sourceData->styleSourceData->propertyData : nullptr; if (sourcePropertyData) { - String styleDeclaration; - bool isStyleTextKnown = styleText(&styleDeclaration); - ASSERT_UNUSED(isStyleTextKnown, isStyleTextKnown); - for (Vector<CSSPropertySourceData>::const_iterator it = sourcePropertyData->begin(); it != sourcePropertyData->end(); ++it) { - while (disabledIndex < disabledLength && disabledProperty.sourceData.range.start <= it->range.start) { - result->append(disabledProperty); - if (++disabledIndex < disabledLength) - disabledProperty = m_disabledProperties.at(disabledIndex); - } - InspectorStyleProperty p(*it, true, false); + auto styleDeclarationOrException = text(); + ASSERT(!styleDeclarationOrException.hasException()); + String styleDeclaration = styleDeclarationOrException.hasException() ? emptyString() : styleDeclarationOrException.releaseReturnValue(); + for (auto& sourceData : *sourcePropertyData) { + // FIXME: <https://webkit.org/b/166787> Web Inspector: Frontend should be made to expect and handle disabled properties + if (sourceData.disabled) + continue; + InspectorStyleProperty p(sourceData, true, sourceData.disabled); p.setRawTextFromStyleDeclaration(styleDeclaration); result->append(p); - sourcePropertyNames.add(it->name.lower()); + sourcePropertyNames.add(lowercasePropertyName(sourceData.name)); } } - while (disabledIndex < disabledLength) { - disabledProperty = m_disabledProperties.at(disabledIndex++); - result->append(disabledProperty); - } - for (int i = 0, size = m_style->length(); i < size; ++i) { String name = m_style->item(i); - if (sourcePropertyNames.contains(name.lower())) - continue; - - sourcePropertyNames.add(name.lower()); - result->append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), true, SourceRange()), false, false)); + if (sourcePropertyNames.add(lowercasePropertyName(name))) + result->append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), false, true, SourceRange()), false, false)); } - - return true; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() const +Ref<Inspector::Protocol::CSS::CSSStyle> InspectorStyle::styleWithProperties() const { Vector<InspectorStyleProperty> properties; populateAllProperties(&properties); - RefPtr<Array<Inspector::TypeBuilder::CSS::CSSProperty>> propertiesObject = Array<Inspector::TypeBuilder::CSS::CSSProperty>::create(); - RefPtr<Array<Inspector::TypeBuilder::CSS::ShorthandEntry>> shorthandEntries = Array<Inspector::TypeBuilder::CSS::ShorthandEntry>::create(); - HashMap<String, RefPtr<Inspector::TypeBuilder::CSS::CSSProperty>> propertyNameToPreviousActiveProperty; + auto propertiesObject = Array<Inspector::Protocol::CSS::CSSProperty>::create(); + auto shorthandEntries = Array<Inspector::Protocol::CSS::ShorthandEntry>::create(); + HashMap<String, RefPtr<Inspector::Protocol::CSS::CSSProperty>> propertyNameToPreviousActiveProperty; HashSet<String> foundShorthands; String previousPriority; String previousStatus; - OwnPtr<Vector<size_t>> lineEndings(m_parentStyleSheet ? m_parentStyleSheet->lineEndings() : PassOwnPtr<Vector<size_t>>()); - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); + std::unique_ptr<Vector<size_t>> lineEndings(m_parentStyleSheet ? m_parentStyleSheet->lineEndings() : nullptr); + auto sourceData = extractSourceData(); unsigned ruleBodyRangeStart = sourceData ? sourceData->ruleBodyRange.start : 0; for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) { const CSSPropertySourceData& propertyEntry = it->sourceData; const String& name = propertyEntry.name; - Inspector::TypeBuilder::CSS::CSSProperty::Status::Enum status = it->disabled ? Inspector::TypeBuilder::CSS::CSSProperty::Status::Disabled : Inspector::TypeBuilder::CSS::CSSProperty::Status::Active; + // Visual Studio disagrees with other compilers as to whether 'class' is needed here. +#if COMPILER(MSVC) + enum class Protocol::CSS::CSSPropertyStatus status; +#else + enum Inspector::Protocol::CSS::CSSPropertyStatus status; +#endif + status = it->disabled ? Inspector::Protocol::CSS::CSSPropertyStatus::Disabled : Inspector::Protocol::CSS::CSSPropertyStatus::Active; + + RefPtr<Inspector::Protocol::CSS::CSSProperty> property = Inspector::Protocol::CSS::CSSProperty::create() + .setName(name.convertToASCIILowercase()) + .setValue(propertyEntry.value) + .release(); - RefPtr<Inspector::TypeBuilder::CSS::CSSProperty> property = Inspector::TypeBuilder::CSS::CSSProperty::create() - .setName(name) - .setValue(propertyEntry.value); + propertiesObject->addItem(property.copyRef()); - propertiesObject->addItem(property); + CSSPropertyID propertyId = cssPropertyID(name); // Default "parsedOk" == true. - if (!propertyEntry.parsedOk) + if (!propertyEntry.parsedOk || isInternalCSSProperty(propertyId)) property->setParsedOk(false); if (it->hasRawText()) property->setText(it->rawText); @@ -571,25 +680,25 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithPrope // Parsed property overrides any property with the same name. Non-parsed property overrides // previous non-parsed property with the same name (if any). bool shouldInactivate = false; - CSSPropertyID propertyId = cssPropertyID(name); + // Canonicalize property names to treat non-prefixed and vendor-prefixed property names the same (opacity vs. -webkit-opacity). String canonicalPropertyName = propertyId ? getPropertyNameString(propertyId) : name; - HashMap<String, RefPtr<Inspector::TypeBuilder::CSS::CSSProperty>>::iterator activeIt = propertyNameToPreviousActiveProperty.find(canonicalPropertyName); + HashMap<String, RefPtr<Inspector::Protocol::CSS::CSSProperty>>::iterator activeIt = propertyNameToPreviousActiveProperty.find(canonicalPropertyName); if (activeIt != propertyNameToPreviousActiveProperty.end()) { if (propertyEntry.parsedOk) { - bool successPriority = activeIt->value->getString(Inspector::TypeBuilder::CSS::CSSProperty::Priority, &previousPriority); - bool successStatus = activeIt->value->getString(Inspector::TypeBuilder::CSS::CSSProperty::Status, &previousStatus); + bool successPriority = activeIt->value->getString(Inspector::Protocol::CSS::CSSProperty::Priority, previousPriority); + bool successStatus = activeIt->value->getString(Inspector::Protocol::CSS::CSSProperty::Status, previousStatus); if (successStatus && previousStatus != "inactive") { if (propertyEntry.important || !successPriority) // Priority not set == "not important". shouldInactivate = true; - else if (status == Inspector::TypeBuilder::CSS::CSSProperty::Status::Active) { + else if (status == Inspector::Protocol::CSS::CSSPropertyStatus::Active) { // Inactivate a non-important property following the same-named important property. - status = Inspector::TypeBuilder::CSS::CSSProperty::Status::Inactive; + status = Inspector::Protocol::CSS::CSSPropertyStatus::Inactive; } } } else { bool previousParsedOk; - bool success = activeIt->value->getBoolean(Inspector::TypeBuilder::CSS::CSSProperty::ParsedOk, &previousParsedOk); + bool success = activeIt->value->getBoolean(Inspector::Protocol::CSS::CSSProperty::ParsedOk, previousParsedOk); if (success && !previousParsedOk) shouldInactivate = true; } @@ -597,7 +706,7 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithPrope propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property); if (shouldInactivate) { - activeIt->value->setStatus(Inspector::TypeBuilder::CSS::CSSProperty::Status::Inactive); + activeIt->value->setStatus(Inspector::Protocol::CSS::CSSPropertyStatus::Inactive); propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property); } } else { @@ -605,63 +714,65 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithPrope // Default "implicit" == false. if (implicit) property->setImplicit(true); - status = Inspector::TypeBuilder::CSS::CSSProperty::Status::Style; + status = Inspector::Protocol::CSS::CSSPropertyStatus::Style; String shorthand = m_style->getPropertyShorthand(name); if (!shorthand.isEmpty()) { if (!foundShorthands.contains(shorthand)) { foundShorthands.add(shorthand); - RefPtr<Inspector::TypeBuilder::CSS::ShorthandEntry> entry = Inspector::TypeBuilder::CSS::ShorthandEntry::create() + auto entry = Inspector::Protocol::CSS::ShorthandEntry::create() .setName(shorthand) - .setValue(shorthandValue(shorthand)); - shorthandEntries->addItem(entry); + .setValue(shorthandValue(shorthand)) + .release(); + shorthandEntries->addItem(WTFMove(entry)); } } } } // Default "status" == "style". - if (status != Inspector::TypeBuilder::CSS::CSSProperty::Status::Style) + if (status != Inspector::Protocol::CSS::CSSPropertyStatus::Style) property->setStatus(status); } - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> result = Inspector::TypeBuilder::CSS::CSSStyle::create() - .setCssProperties(propertiesObject) - .setShorthandEntries(shorthandEntries); - return result.release(); + return Inspector::Protocol::CSS::CSSStyle::create() + .setCssProperties(WTFMove(propertiesObject)) + .setShorthandEntries(WTFMove(shorthandEntries)) + .release(); } -PassRefPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const +RefPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const { if (!m_parentStyleSheet || !m_parentStyleSheet->ensureParsedDataReady()) return nullptr; return m_parentStyleSheet->ruleSourceDataFor(m_style.get()); } -bool InspectorStyle::setText(const String& text, ExceptionCode& ec) +ExceptionOr<void> InspectorStyle::setText(const String& text) { - return m_parentStyleSheet->setStyleText(m_style.get(), text, ec); + return m_parentStyleSheet->setStyleText(m_style.get(), text); } String InspectorStyle::shorthandValue(const String& shorthandProperty) const { String value = m_style->getPropertyValue(shorthandProperty); - if (value.isEmpty()) { - for (unsigned i = 0; i < m_style->length(); ++i) { - String individualProperty = m_style->item(i); - if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - if (m_style->isPropertyImplicit(individualProperty)) - continue; - String individualValue = m_style->getPropertyValue(individualProperty); - if (individualValue == "initial") - continue; - if (value.length()) - value.append(" "); - value.append(individualValue); - } + if (!value.isEmpty()) + return value; + StringBuilder builder; + for (unsigned i = 0; i < m_style->length(); ++i) { + String individualProperty = m_style->item(i); + if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty) + continue; + if (m_style->isPropertyImplicit(individualProperty)) + continue; + String individualValue = m_style->getPropertyValue(individualProperty); + if (individualValue == "initial") + continue; + if (!builder.isEmpty()) + builder.append(' '); + builder.append(individualValue); } - return value; + return builder.toString(); } String InspectorStyle::shorthandPriority(const String& shorthandProperty) const @@ -694,78 +805,11 @@ Vector<String> InspectorStyle::longhandProperties(const String& shorthandPropert return properties; } -NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const +Ref<InspectorStyleSheet> InspectorStyleSheet::create(InspectorPageAgent* pageAgent, const String& id, RefPtr<CSSStyleSheet>&& pageStyleSheet, Inspector::Protocol::CSS::StyleSheetOrigin origin, const String& documentURL, Listener* listener) { - DEFINE_STATIC_LOCAL(String, defaultPrefix, (ASCIILiteral(" "))); - - if (m_formatAcquired) - return m_format; - - RefPtr<CSSRuleSourceData> sourceData = extractSourceData(); - Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : nullptr; - int propertyCount; - if (!sourcePropertyData || !(propertyCount = sourcePropertyData->size())) { - m_format.first = "\n"; - m_format.second = defaultPrefix; - return m_format; // Do not remember the default formatting and attempt to acquire it later. - } - - String text; - bool success = styleText(&text); - ASSERT_UNUSED(success, success); - - m_formatAcquired = true; - - String candidatePrefix = defaultPrefix; - StringBuilder formatLineFeed; - StringBuilder prefix; - int scanStart = 0; - int propertyIndex = 0; - bool isFullPrefixScanned = false; - bool lineFeedTerminated = false; - const UChar* characters = text.deprecatedCharacters(); - while (propertyIndex < propertyCount) { - const WebCore::CSSPropertySourceData& currentProperty = sourcePropertyData->at(propertyIndex++); - - bool processNextProperty = false; - int scanEnd = currentProperty.range.start; - for (int i = scanStart; i < scanEnd; ++i) { - UChar ch = characters[i]; - bool isLineFeed = isHTMLLineBreak(ch); - if (isLineFeed) { - if (!lineFeedTerminated) - formatLineFeed.append(ch); - prefix.clear(); - } else if (isHTMLSpace(ch)) - prefix.append(ch); - else { - candidatePrefix = prefix.toString(); - prefix.clear(); - scanStart = currentProperty.range.end; - ++propertyIndex; - processNextProperty = true; - break; - } - if (!isLineFeed && formatLineFeed.length()) - lineFeedTerminated = true; - } - if (!processNextProperty) { - isFullPrefixScanned = true; - break; - } - } - - m_format.first = formatLineFeed.toString(); - m_format.second = isFullPrefixScanned ? prefix.toString() : candidatePrefix; - return m_format; -} - -PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener) -{ - return adoptRef(new InspectorStyleSheet(pageAgent, id, pageStyleSheet, origin, documentURL, listener)); + return adoptRef(*new InspectorStyleSheet(pageAgent, id, WTFMove(pageStyleSheet), origin, documentURL, listener)); } -// static String InspectorStyleSheet::styleSheetURL(CSSStyleSheet* pageStyleSheet) { if (pageStyleSheet && !pageStyleSheet->contents().baseURL().isEmpty()) @@ -773,13 +817,12 @@ String InspectorStyleSheet::styleSheetURL(CSSStyleSheet* pageStyleSheet) return emptyString(); } -InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener) +InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, const String& id, RefPtr<CSSStyleSheet>&& pageStyleSheet, Inspector::Protocol::CSS::StyleSheetOrigin origin, const String& documentURL, Listener* listener) : m_pageAgent(pageAgent) , m_id(id) - , m_pageStyleSheet(pageStyleSheet) + , m_pageStyleSheet(WTFMove(pageStyleSheet)) , m_origin(origin) , m_documentURL(documentURL) - , m_isRevalidating(false) , m_listener(listener) { m_parsedStyleSheet = new ParsedStyleSheet(); @@ -807,103 +850,103 @@ void InspectorStyleSheet::reparseStyleSheet(const String& text) CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get()); m_pageStyleSheet->contents().parseString(text); m_pageStyleSheet->clearChildRuleCSSOMWrappers(); - m_inspectorStyles.clear(); fireStyleSheetChanged(); } + + // We just wiped the entire contents of the stylesheet. Clear the mutation flag. + m_pageStyleSheet->clearHadRulesMutation(); } -bool InspectorStyleSheet::setText(const String& text, ExceptionCode& ec) +ExceptionOr<void> InspectorStyleSheet::setText(const String& text) { - if (!checkPageStyleSheet(ec)) - return false; - if (!m_parsedStyleSheet) - return false; + if (!m_pageStyleSheet) + return Exception { NOT_SUPPORTED_ERR }; m_parsedStyleSheet->setText(text); m_flatRules.clear(); - return true; + return { }; } -String InspectorStyleSheet::ruleSelector(const InspectorCSSId& id, ExceptionCode& ec) +ExceptionOr<String> InspectorStyleSheet::ruleSelector(const InspectorCSSId& id) { CSSStyleRule* rule = ruleForId(id); - if (!rule) { - ec = NOT_FOUND_ERR; - return ""; - } + if (!rule) + return Exception { NOT_FOUND_ERR }; return rule->selectorText(); } -bool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector, ExceptionCode& ec) +static bool isValidSelectorListString(const String& selector, Document* document) { - if (!checkPageStyleSheet(ec)) - return false; + CSSSelectorList selectorList; + CSSParser parser(parserContextForDocument(document)); + parser.parseSelector(selector, selectorList); + return selectorList.isValid(); +} + +ExceptionOr<void> InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector) +{ + if (!m_pageStyleSheet) + return Exception { NOT_SUPPORTED_ERR }; + + // If the selector is invalid, do not proceed any further. + if (!isValidSelectorListString(selector, m_pageStyleSheet->ownerDocument())) + return Exception { SYNTAX_ERR }; + CSSStyleRule* rule = ruleForId(id); - if (!rule) { - ec = NOT_FOUND_ERR; - return false; - } + if (!rule) + return Exception { NOT_FOUND_ERR }; + CSSStyleSheet* styleSheet = rule->parentStyleSheet(); - if (!styleSheet || !ensureParsedDataReady()) { - ec = NOT_FOUND_ERR; - return false; - } + if (!styleSheet || !ensureParsedDataReady()) + return Exception { NOT_FOUND_ERR }; + + // If the stylesheet is already mutated at this point, that must mean that our data has been modified + // elsewhere. This should never happen as ensureParsedDataReady would return false in that case. + ASSERT(!styleSheetMutated()); rule->setSelectorText(selector); - RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style()); - if (!sourceData) { - ec = NOT_FOUND_ERR; - return false; - } + auto sourceData = ruleSourceDataFor(&rule->style()); + if (!sourceData) + return Exception { NOT_FOUND_ERR }; String sheetText = m_parsedStyleSheet->text(); sheetText.replace(sourceData->ruleHeaderRange.start, sourceData->ruleHeaderRange.length(), selector); m_parsedStyleSheet->setText(sheetText); + m_pageStyleSheet->clearHadRulesMutation(); fireStyleSheetChanged(); - return true; + return { }; } -static bool checkStyleRuleSelector(Document* document, const String& selector) +ExceptionOr<CSSStyleRule*> InspectorStyleSheet::addRule(const String& selector) { - CSSSelectorList selectorList; - createCSSParser(document)->parseSelector(selector, selectorList); - return selectorList.isValid(); -} + if (!m_pageStyleSheet) + return Exception { NOT_SUPPORTED_ERR }; -CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionCode& ec) -{ - if (!checkPageStyleSheet(ec)) - return nullptr; - if (!checkStyleRuleSelector(m_pageStyleSheet->ownerDocument(), selector)) { - ec = SYNTAX_ERR; - return nullptr; - } + if (!isValidSelectorListString(selector, m_pageStyleSheet->ownerDocument())) + return Exception { SYNTAX_ERR }; + + auto text = this->text(); + if (text.hasException()) + return text.releaseException(); - String text; - bool success = getText(&text); - if (!success) { - ec = NOT_FOUND_ERR; - return nullptr; - } StringBuilder styleSheetText; - styleSheetText.append(text); + styleSheetText.append(text.releaseReturnValue()); - m_pageStyleSheet->addRule(selector, "", ec); - if (ec) - return nullptr; + auto addRuleResult = m_pageStyleSheet->addRule(selector, emptyString(), std::nullopt); + if (addRuleResult.hasException()) + return addRuleResult.releaseException(); ASSERT(m_pageStyleSheet->length()); unsigned lastRuleIndex = m_pageStyleSheet->length() - 1; CSSRule* rule = m_pageStyleSheet->item(lastRuleIndex); ASSERT(rule); - CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(rule); + CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(*rule); if (!styleRule) { // What we just added has to be a CSSStyleRule - we cannot handle other types of rules yet. // If it is not a style rule, pretend we never touched the stylesheet. - m_pageStyleSheet->deleteRule(lastRuleIndex, ASSERT_NO_EXCEPTION); - ec = SYNTAX_ERR; - return nullptr; + m_pageStyleSheet->deleteRule(lastRuleIndex); + return Exception { SYNTAX_ERR }; } if (!styleSheetText.isEmpty()) @@ -911,46 +954,41 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionCode styleSheetText.append(selector); styleSheetText.appendLiteral(" {}"); - // Using setText() as this operation changes the style sheet rule set. - setText(styleSheetText.toString(), ASSERT_NO_EXCEPTION); + // Using setText() as this operation changes the stylesheet rule set. + setText(styleSheetText.toString()); fireStyleSheetChanged(); return styleRule; } -bool InspectorStyleSheet::deleteRule(const InspectorCSSId& id, ExceptionCode& ec) +ExceptionOr<void> InspectorStyleSheet::deleteRule(const InspectorCSSId& id) { - if (!checkPageStyleSheet(ec)) - return false; + if (!m_pageStyleSheet) + return Exception { NOT_SUPPORTED_ERR }; + RefPtr<CSSStyleRule> rule = ruleForId(id); - if (!rule) { - ec = NOT_FOUND_ERR; - return false; - } + if (!rule) + return Exception { NOT_FOUND_ERR }; CSSStyleSheet* styleSheet = rule->parentStyleSheet(); - if (!styleSheet || !ensureParsedDataReady()) { - ec = NOT_FOUND_ERR; - return false; - } + if (!styleSheet || !ensureParsedDataReady()) + return Exception { NOT_FOUND_ERR }; - RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style()); - if (!sourceData) { - ec = NOT_FOUND_ERR; - return false; - } + auto sourceData = ruleSourceDataFor(&rule->style()); + if (!sourceData) + return Exception { NOT_FOUND_ERR }; - styleSheet->deleteRule(id.ordinal(), ec); - // |rule| MAY NOT be addressed after this line! + auto deleteRuleResult = styleSheet->deleteRule(id.ordinal()); + if (deleteRuleResult.hasException()) + return deleteRuleResult.releaseException(); - if (ec) - return false; + // |rule| MAY NOT be addressed after this! String sheetText = m_parsedStyleSheet->text(); sheetText.remove(sourceData->ruleHeaderRange.start, sourceData->ruleBodyRange.end - sourceData->ruleHeaderRange.start + 1); - setText(sheetText, ASSERT_NO_EXCEPTION); + setText(sheetText); fireStyleSheetChanged(); - return true; + return { }; } CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const @@ -961,10 +999,9 @@ CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const ASSERT(!id.isEmpty()); ensureFlatRules(); return id.ordinal() >= m_flatRules.size() ? nullptr : m_flatRules.at(id.ordinal()).get(); - } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody> InspectorStyleSheet::buildObjectForStyleSheet() +RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody> InspectorStyleSheet::buildObjectForStyleSheet() { CSSStyleSheet* styleSheet = pageStyleSheet(); if (!styleSheet) @@ -972,19 +1009,19 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody> InspectorStyleSheet:: RefPtr<CSSRuleList> cssRuleList = asCSSRuleList(styleSheet); - RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody> result = Inspector::TypeBuilder::CSS::CSSStyleSheetBody::create() + auto result = Inspector::Protocol::CSS::CSSStyleSheetBody::create() .setStyleSheetId(id()) - .setRules(buildArrayForRuleList(cssRuleList.get())); + .setRules(buildArrayForRuleList(cssRuleList.get())) + .release(); - String styleSheetText; - bool success = getText(&styleSheetText); - if (success) - result->setText(styleSheetText); + auto styleSheetText = text(); + if (!styleSheetText.hasException()) + result->setText(styleSheetText.releaseReturnValue()); - return result.release(); + return WTFMove(result); } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObjectForStyleSheetInfo() +RefPtr<Inspector::Protocol::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObjectForStyleSheetInfo() { CSSStyleSheet* styleSheet = pageStyleSheet(); if (!styleSheet) @@ -992,92 +1029,160 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet Document* document = styleSheet->ownerDocument(); Frame* frame = document ? document->frame() : nullptr; - RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader> result = Inspector::TypeBuilder::CSS::CSSStyleSheetHeader::create() + return Inspector::Protocol::CSS::CSSStyleSheetHeader::create() .setStyleSheetId(id()) .setOrigin(m_origin) .setDisabled(styleSheet->disabled()) .setSourceURL(finalURL()) .setTitle(styleSheet->title()) - .setFrameId(m_pageAgent->frameId(frame)); + .setFrameId(m_pageAgent->frameId(frame)) + .setIsInline(styleSheet->isInline() && styleSheet->startPosition() != TextPosition()) + .setStartLine(styleSheet->startPosition().m_line.zeroBasedInt()) + .setStartColumn(styleSheet->startPosition().m_column.zeroBasedInt()) + .release(); +} - return result.release(); +static bool hasDynamicSpecificity(const CSSSelector& simpleSelector) +{ + // It is possible that these can have a static specificity if each selector in the list has + // equal specificity, but lets always report that they can be dynamic. + for (const CSSSelector* selector = &simpleSelector; selector; selector = selector->tagHistory()) { + if (selector->match() == CSSSelector::PseudoClass) { + CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType(); + if (pseudoClassType == CSSSelector::PseudoClassMatches) + return true; + if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild) { + if (selector->selectorList()) + return true; + return false; + } + } + } + + return false; } -static PassRefPtr<Inspector::TypeBuilder::Array<String>> selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText) +static Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelectorHelper(const String& selectorText, const CSSSelector& selector, Element* element) { - DEFINE_STATIC_LOCAL(JSC::Yarr::RegularExpression, comment, ("/\\*[^]*?\\*/", TextCaseSensitive, JSC::Yarr::MultilineEnabled)); - RefPtr<Inspector::TypeBuilder::Array<String>> result = Inspector::TypeBuilder::Array<String>::create(); - const SelectorRangeList& ranges = sourceData->selectorRanges; - for (size_t i = 0, size = ranges.size(); i < size; ++i) { - const SourceRange& range = ranges.at(i); - String selector = sheetText.substring(range.start, range.length()); + auto inspectorSelector = Inspector::Protocol::CSS::CSSSelector::create() + .setText(selectorText) + .release(); + + if (element) { + bool dynamic = hasDynamicSpecificity(selector); + if (dynamic) + inspectorSelector->setDynamic(true); + + SelectorChecker::CheckingContext context(SelectorChecker::Mode::CollectingRules); + SelectorChecker selectorChecker(element->document()); + + unsigned specificity; + bool okay = selectorChecker.match(selector, *element, context, specificity); + if (!okay) + specificity = selector.staticSpecificity(okay); + + if (okay) { + auto tuple = Inspector::Protocol::Array<int>::create(); + tuple->addItem(static_cast<int>((specificity & CSSSelector::idMask) >> 16)); + tuple->addItem(static_cast<int>((specificity & CSSSelector::classMask) >> 8)); + tuple->addItem(static_cast<int>(specificity & CSSSelector::elementMask)); + inspectorSelector->setSpecificity(WTFMove(tuple)); + } + } + + return inspectorSelector; +} + +static Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>> selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText, const CSSSelectorList& selectorList, Element* element) +{ + static NeverDestroyed<JSC::Yarr::RegularExpression> comment("/\\*[^]*?\\*/", TextCaseSensitive, JSC::Yarr::MultilineEnabled); + + auto result = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>::create(); + const CSSSelector* selector = selectorList.first(); + for (auto& range : sourceData->selectorRanges) { + // If we don't have a selector, that means the SourceData for this CSSStyleSheet + // no longer matches up with the actual rules in the CSSStyleSheet. + ASSERT(selector); + if (!selector) + break; + + String selectorText = sheetText.substring(range.start, range.length()); // We don't want to see any comments in the selector components, only the meaningful parts. - replace(selector, comment, ""); - result->addItem(selector.stripWhiteSpace()); + replace(selectorText, comment, String()); + result->addItem(buildObjectForSelectorHelper(selectorText.stripWhiteSpace(), *selector, element)); + + selector = CSSSelectorList::next(selector); } - return result.release(); + return result; } -PassRefPtr<Inspector::TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule) +Ref<Inspector::Protocol::CSS::CSSSelector> InspectorStyleSheet::buildObjectForSelector(const CSSSelector* selector, Element* element) +{ + return buildObjectForSelectorHelper(selector->selectorText(), *selector, element); +} + +Ref<Inspector::Protocol::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule, Element* element, int& endingLine) { RefPtr<CSSRuleSourceData> sourceData; if (ensureParsedDataReady()) - sourceData = ruleSourceDataFor(rule->style()); - RefPtr<Inspector::TypeBuilder::Array<String>> selectors; + sourceData = ruleSourceDataFor(&rule->style()); + RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>> selectors; // This intentionally does not rely on the source data to avoid catching the trailing comments (before the declaration starting '{'). String selectorText = rule->selectorText(); if (sourceData) - selectors = selectorsFromSource(sourceData.get(), m_parsedStyleSheet->text()); + selectors = selectorsFromSource(sourceData.get(), m_parsedStyleSheet->text(), rule->styleRule().selectorList(), element); else { - selectors = Inspector::TypeBuilder::Array<String>::create(); - const CSSSelectorList& selectorList = rule->styleRule()->selectorList(); + selectors = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSSelector>::create(); + const CSSSelectorList& selectorList = rule->styleRule().selectorList(); for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) - selectors->addItem(selector->selectorText()); + selectors->addItem(buildObjectForSelector(selector, element)); } - RefPtr<Inspector::TypeBuilder::CSS::SelectorList> result = Inspector::TypeBuilder::CSS::SelectorList::create() - .setSelectors(selectors) + auto result = Inspector::Protocol::CSS::SelectorList::create() + .setSelectors(WTFMove(selectors)) .setText(selectorText) .release(); if (sourceData) - result->setRange(buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get())); - return result.release(); + result->setRange(buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get(), &endingLine)); + return result; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule) +RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule, Element* element) { CSSStyleSheet* styleSheet = pageStyleSheet(); if (!styleSheet) return nullptr; - RefPtr<Inspector::TypeBuilder::CSS::CSSRule> result = Inspector::TypeBuilder::CSS::CSSRule::create() - .setSelectorList(buildObjectForSelectorList(rule)) - .setSourceLine(rule->styleRule()->sourceLine()) + int endingLine = 0; + auto result = Inspector::Protocol::CSS::CSSRule::create() + .setSelectorList(buildObjectForSelectorList(rule, element, endingLine)) + .setSourceLine(endingLine) .setOrigin(m_origin) - .setStyle(buildObjectForStyle(rule->style())); + .setStyle(buildObjectForStyle(&rule->style())) + .release(); // "sourceURL" is present only for regular rules, otherwise "origin" should be used in the frontend. - if (m_origin == Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular) + if (m_origin == Inspector::Protocol::CSS::StyleSheetOrigin::Regular) result->setSourceURL(finalURL()); if (canBind()) { InspectorCSSId id(ruleId(rule)); if (!id.isEmpty()) - result->setRuleId(id.asProtocolValue<Inspector::TypeBuilder::CSS::CSSRuleId>()); + result->setRuleId(id.asProtocolValue<Inspector::Protocol::CSS::CSSRuleId>()); } - RefPtr<Array<Inspector::TypeBuilder::CSS::CSSMedia>> mediaArray = Array<Inspector::TypeBuilder::CSS::CSSMedia>::create(); + auto mediaArray = Array<Inspector::Protocol::CSS::CSSMedia>::create(); fillMediaListChain(rule, mediaArray.get()); if (mediaArray->length()) - result->setMedia(mediaArray.release()); + result->setMedia(WTFMove(mediaArray)); - return result.release(); + return WTFMove(result); } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyleSheet::buildObjectForStyle(CSSStyleDeclaration* style) +RefPtr<Inspector::Protocol::CSS::CSSStyle> InspectorStyleSheet::buildObjectForStyle(CSSStyleDeclaration* style) { RefPtr<CSSRuleSourceData> sourceData; if (ensureParsedDataReady()) @@ -1085,83 +1190,50 @@ PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorStyleSheet::buildObje InspectorCSSId id = ruleOrStyleId(style); if (id.isEmpty()) { - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> bogusStyle = Inspector::TypeBuilder::CSS::CSSStyle::create() - .setCssProperties(Array<Inspector::TypeBuilder::CSS::CSSProperty>::create()) - .setShorthandEntries(Array<Inspector::TypeBuilder::CSS::ShorthandEntry>::create()); - return bogusStyle.release(); + return Inspector::Protocol::CSS::CSSStyle::create() + .setCssProperties(Array<Inspector::Protocol::CSS::CSSProperty>::create()) + .setShorthandEntries(Array<Inspector::Protocol::CSS::ShorthandEntry>::create()) + .release(); } RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> result = inspectorStyle->buildObjectForStyle(); + RefPtr<Inspector::Protocol::CSS::CSSStyle> result = inspectorStyle->buildObjectForStyle(); // Style text cannot be retrieved without stylesheet, so set cssText here. if (sourceData) { - String sheetText; - bool success = getText(&sheetText); - if (success) { - const SourceRange& bodyRange = sourceData->ruleBodyRange; - result->setCssText(sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start)); + auto sheetText = text(); + if (!sheetText.hasException()) { + auto& bodyRange = sourceData->ruleBodyRange; + result->setCssText(sheetText.releaseReturnValue().substring(bodyRange.start, bodyRange.end - bodyRange.start)); } } - return result.release(); + return result; } -bool InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text, String* oldText, ExceptionCode& ec) +ExceptionOr<void> InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text, String* oldText) { - RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); - if (!inspectorStyle) { - ec = NOT_FOUND_ERR; - return false; - } - - if (oldText && !inspectorStyle->getText(oldText)) - return false; + auto inspectorStyle = inspectorStyleForId(id); + if (!inspectorStyle) + return Exception { NOT_FOUND_ERR }; - bool success = inspectorStyle->setText(text, ec); - if (success) - fireStyleSheetChanged(); - return success; -} - -bool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, String* oldText, ExceptionCode& ec) -{ - RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); - if (!inspectorStyle) { - ec = NOT_FOUND_ERR; - return false; + if (oldText) { + auto result = inspectorStyle->text(); + if (result.hasException()) + return result.releaseException(); + *oldText = result.releaseReturnValue(); } - bool success = inspectorStyle->setPropertyText(propertyIndex, text, overwrite, oldText, ec); - if (success) + auto result = inspectorStyle->setText(text); + if (!result.hasException()) fireStyleSheetChanged(); - return success; -} - -bool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned propertyIndex, bool disable, ExceptionCode& ec) -{ - RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id); - if (!inspectorStyle) { - ec = NOT_FOUND_ERR; - return false; - } - - bool success = inspectorStyle->toggleProperty(propertyIndex, disable, ec); - if (success) { - if (disable) - rememberInspectorStyle(inspectorStyle); - else if (!inspectorStyle->hasDisabledProperties()) - forgetInspectorStyle(inspectorStyle->cssStyle()); - fireStyleSheetChanged(); - } - return success; + return result; } -bool InspectorStyleSheet::getText(String* result) const +ExceptionOr<String> InspectorStyleSheet::text() const { if (!ensureText()) - return false; - *result = m_parsedStyleSheet->text(); - return true; + return Exception { NOT_FOUND_ERR }; + return String { m_parsedStyleSheet->text() }; } CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) const @@ -1170,7 +1242,7 @@ CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) c if (!rule) return nullptr; - return rule->style(); + return &rule->style(); } void InspectorStyleSheet::fireStyleSheetChanged() @@ -1179,28 +1251,13 @@ void InspectorStyleSheet::fireStyleSheetChanged() m_listener->styleSheetChanged(this); } -PassRefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const InspectorCSSId& id) +RefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const InspectorCSSId& id) { CSSStyleDeclaration* style = styleForId(id); if (!style) return nullptr; - InspectorStyleMap::iterator it = m_inspectorStyles.find(style); - if (it == m_inspectorStyles.end()) { - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(id, style, this); - return inspectorStyle.release(); - } - return it->value; -} - -void InspectorStyleSheet::rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle) -{ - m_inspectorStyles.set(inspectorStyle->cssStyle(), inspectorStyle); -} - -void InspectorStyleSheet::forgetInspectorStyle(CSSStyleDeclaration* style) -{ - m_inspectorStyles.remove(style); + return InspectorStyle::create(id, style, this); } InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const @@ -1221,10 +1278,10 @@ RefPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataFor(CSSStyleDeclara return m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByStyle(style)); } -PassOwnPtr<Vector<size_t>> InspectorStyleSheet::lineEndings() const +std::unique_ptr<Vector<size_t>> InspectorStyleSheet::lineEndings() const { if (!m_parsedStyleSheet->hasText()) - return PassOwnPtr<Vector<size_t>>(); + return nullptr; return ContentSearchUtilities::lineEndings(m_parsedStyleSheet->text()); } @@ -1232,8 +1289,8 @@ unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) c { ensureFlatRules(); unsigned index = 0; - for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) { - if (m_flatRules.at(i)->style() == pageStyle) + for (auto& rule : m_flatRules) { + if (&rule->style() == pageStyle) return index; ++index; @@ -1241,18 +1298,15 @@ unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) c return UINT_MAX; } -bool InspectorStyleSheet::checkPageStyleSheet(ExceptionCode& ec) const +bool InspectorStyleSheet::styleSheetMutated() const { - if (!m_pageStyleSheet) { - ec = NOT_SUPPORTED_ERR; - return false; - } - return true; + return m_pageStyleSheet && m_pageStyleSheet->hadRulesMutation(); } bool InspectorStyleSheet::ensureParsedDataReady() { - return ensureText() && ensureSourceData(); + bool allowParsedData = m_origin == Inspector::Protocol::CSS::StyleSheetOrigin::Inspector || !styleSheetMutated(); + return allowParsedData && ensureText() && ensureSourceData(); } bool InspectorStyleSheet::ensureText() const @@ -1280,9 +1334,12 @@ bool InspectorStyleSheet::ensureSourceData() return false; RefPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create(); - OwnPtr<RuleSourceDataList> ruleSourceDataResult = adoptPtr(new RuleSourceDataList()); - createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), 0, ruleSourceDataResult.get()); - m_parsedStyleSheet->setSourceData(ruleSourceDataResult.release()); + auto ruleSourceDataResult = std::make_unique<RuleSourceDataList>(); + + CSSParserContext context(parserContextForDocument(m_pageStyleSheet->ownerDocument())); + StyleSheetHandler handler(m_parsedStyleSheet->text(), m_pageStyleSheet->ownerDocument(), ruleSourceDataResult.get()); + CSSParser::parseSheetForInspector(context, newStyleSheet.get(), m_parsedStyleSheet->text(), handler); + m_parsedStyleSheet->setSourceData(WTFMove(ruleSourceDataResult)); return m_parsedStyleSheet->hasSourceData(); } @@ -1293,27 +1350,28 @@ void InspectorStyleSheet::ensureFlatRules() const collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules); } -bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text, ExceptionCode& ec) +ExceptionOr<void> InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text) { if (!m_pageStyleSheet) - return false; + return Exception { NOT_FOUND_ERR }; if (!ensureParsedDataReady()) - return false; + return Exception { NOT_FOUND_ERR }; String patchedStyleSheetText; bool success = styleSheetTextWithChangedStyle(style, text, &patchedStyleSheetText); if (!success) - return false; + return Exception { NOT_FOUND_ERR }; InspectorCSSId id = ruleOrStyleId(style); if (id.isEmpty()) - return false; + return Exception { NOT_FOUND_ERR }; - style->setCssText(text, ec); - if (!ec) - m_parsedStyleSheet->setText(patchedStyleSheetText); + auto setCssTextResult = style->setCssText(text); + if (setCssTextResult.hasException()) + return setCssTextResult.releaseException(); - return !ec; + m_parsedStyleSheet->setText(patchedStyleSheetText); + return { }; } bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* style, const String& newStyleText, String* result) @@ -1339,30 +1397,7 @@ bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* st InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const { - return ruleOrStyleId(rule->style()); -} - -void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle) -{ - if (m_isRevalidating) - return; - - m_isRevalidating = true; - ensureFlatRules(); - for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) { - CSSStyleRule* parsedRule = m_flatRules.at(i).get(); - if (parsedRule->style() == pageStyle) { - if (parsedRule->styleRule()->properties().asText() != pageStyle->cssText()) { - // Clear the disabled properties for the invalid style here. - m_inspectorStyles.remove(pageStyle); - - ExceptionCode ec = 0; - setStyleText(pageStyle, pageStyle->cssText(), ec); - } - break; - } - } - m_isRevalidating = false; + return ruleOrStyleId(&rule->style()); } bool InspectorStyleSheet::originalStyleSheetText(String* result) const @@ -1375,7 +1410,7 @@ bool InspectorStyleSheet::originalStyleSheetText(String* result) const bool InspectorStyleSheet::resourceStyleSheetText(String* result) const { - if (m_origin == Inspector::TypeBuilder::CSS::StyleSheetOrigin::User || m_origin == Inspector::TypeBuilder::CSS::StyleSheetOrigin::UserAgent) + if (m_origin == Inspector::Protocol::CSS::StyleSheetOrigin::User || m_origin == Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent) return false; if (!m_pageStyleSheet || !ownerDocument() || !ownerDocument()->frame()) @@ -1383,7 +1418,7 @@ bool InspectorStyleSheet::resourceStyleSheetText(String* result) const String error; bool base64Encoded; - InspectorPageAgent::resourceContent(&error, ownerDocument()->frame(), URL(ParsedURLString, m_pageStyleSheet->href()), result, &base64Encoded); + InspectorPageAgent::resourceContent(error, ownerDocument()->frame(), URL(ParsedURLString, m_pageStyleSheet->href()), result, &base64Encoded); return error.isEmpty() && !base64Encoded; } @@ -1393,62 +1428,58 @@ bool InspectorStyleSheet::inlineStyleSheetText(String* result) const return false; Node* ownerNode = m_pageStyleSheet->ownerNode(); - if (!ownerNode || !ownerNode->isElementNode()) + if (!is<Element>(ownerNode)) return false; - Element* ownerElement = toElement(ownerNode); + Element& ownerElement = downcast<Element>(*ownerNode); - if (!isHTMLStyleElement(ownerElement) -#if ENABLE(SVG) - && !ownerElement->hasTagName(SVGNames::styleTag) -#endif - ) + if (!is<HTMLStyleElement>(ownerElement) && !is<SVGStyleElement>(ownerElement)) return false; - *result = ownerElement->textContent(); + *result = ownerElement.textContent(); return true; } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> InspectorStyleSheet::buildArrayForRuleList(CSSRuleList* ruleList) +Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSRule>> InspectorStyleSheet::buildArrayForRuleList(CSSRuleList* ruleList) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>::create(); + auto result = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSRule>::create(); if (!ruleList) - return result.release(); + return result; RefPtr<CSSRuleList> refRuleList = ruleList; CSSStyleRuleVector rules; - collectFlatRules(refRuleList, &rules); + collectFlatRules(WTFMove(refRuleList), &rules); - for (unsigned i = 0, size = rules.size(); i < size; ++i) - result->addItem(buildObjectForRule(rules.at(i).get())); + for (auto& rule : rules) + result->addItem(buildObjectForRule(rule.get(), nullptr)); - return result.release(); + return result; } -void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, CSSStyleRuleVector* result) +void InspectorStyleSheet::collectFlatRules(RefPtr<CSSRuleList>&& ruleList, CSSStyleRuleVector* result) { if (!ruleList) return; for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { CSSRule* rule = ruleList->item(i); - CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(rule); + CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(*rule); if (styleRule) result->append(styleRule); else { RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule); if (childRuleList) - collectFlatRules(childRuleList, result); + collectFlatRules(WTFMove(childRuleList), result); } } } -PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<Element> element, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener) +Ref<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, const String& id, RefPtr<Element>&& element, Inspector::Protocol::CSS::StyleSheetOrigin origin, Listener* listener) { - return adoptRef(new InspectorStyleSheetForInlineStyle(pageAgent, id, element, origin, listener)); + return adoptRef(*new InspectorStyleSheetForInlineStyle(pageAgent, id, WTFMove(element), origin, listener)); } -InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<Element> element, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener) - : InspectorStyleSheet(pageAgent, id, nullptr, origin, "", listener) - , m_element(element) +InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, const String& id, RefPtr<Element>&& element, Inspector::Protocol::CSS::StyleSheetOrigin origin, Listener* listener) + : InspectorStyleSheet(pageAgent, id, nullptr, origin, String(), listener) + , m_element(WTFMove(element)) , m_ruleSourceData(nullptr) , m_isStyleTextValid(false) { @@ -1460,37 +1491,37 @@ InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPa void InspectorStyleSheetForInlineStyle::didModifyElementAttribute() { m_isStyleTextValid = false; - if (m_element->isStyledElement() && m_element->style() != m_inspectorStyle->cssStyle()) + if (m_element->isStyledElement() && m_element->cssomStyle() != m_inspectorStyle->cssStyle()) m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id(), 0), inlineStyle(), this); - m_ruleSourceData.clear(); + m_ruleSourceData = nullptr; } -bool InspectorStyleSheetForInlineStyle::getText(String* result) const +ExceptionOr<String> InspectorStyleSheetForInlineStyle::text() const { if (!m_isStyleTextValid) { m_styleText = elementStyleText(); m_isStyleTextValid = true; } - *result = m_styleText; - return true; + return String { m_styleText }; } -bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text, ExceptionCode& ec) +ExceptionOr<void> InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text) { ASSERT_UNUSED(style, style == inlineStyle()); { - InspectorCSSAgent::InlineStyleOverrideScope overrideScope(&m_element->document()); - m_element->setAttribute("style", text, ec); + InspectorCSSAgent::InlineStyleOverrideScope overrideScope(m_element->document()); + m_element->setAttribute(HTMLNames::styleAttr, text); } m_styleText = text; m_isStyleTextValid = true; - m_ruleSourceData.clear(); - return !ec; + m_ruleSourceData = nullptr; + + return { }; } -PassOwnPtr<Vector<size_t>> InspectorStyleSheetForInlineStyle::lineEndings() const +std::unique_ptr<Vector<size_t>> InspectorStyleSheetForInlineStyle::lineEndings() const { return ContentSearchUtilities::lineEndings(elementStyleText()); } @@ -1505,7 +1536,7 @@ bool InspectorStyleSheetForInlineStyle::ensureParsedDataReady() // The "style" property value can get changed indirectly, e.g. via element.style.borderWidth = "2px". const String& currentStyleText = elementStyleText(); if (m_styleText != currentStyleText) { - m_ruleSourceData.clear(); + m_ruleSourceData = nullptr; m_styleText = currentStyleText; m_isStyleTextValid = true; } @@ -1513,23 +1544,22 @@ bool InspectorStyleSheetForInlineStyle::ensureParsedDataReady() if (m_ruleSourceData) return true; - m_ruleSourceData = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE); - bool success = getStyleAttributeRanges(m_ruleSourceData.get()); - if (!success) + if (!m_element->isStyledElement()) return false; + m_ruleSourceData = ruleSourceData(); return true; } -PassRefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id) +RefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id) { ASSERT_UNUSED(id, !id.ordinal()); - return m_inspectorStyle; + return m_inspectorStyle.copyRef(); } CSSStyleDeclaration* InspectorStyleSheetForInlineStyle::inlineStyle() const { - return m_element->style(); + return m_element->cssomStyle(); } const String& InspectorStyleSheetForInlineStyle::elementStyleText() const @@ -1537,22 +1567,20 @@ const String& InspectorStyleSheetForInlineStyle::elementStyleText() const return m_element->getAttribute("style").string(); } -bool InspectorStyleSheetForInlineStyle::getStyleAttributeRanges(CSSRuleSourceData* result) const +Ref<CSSRuleSourceData> InspectorStyleSheetForInlineStyle::ruleSourceData() const { - if (!m_element->isStyledElement()) - return false; - if (m_styleText.isEmpty()) { + auto result = CSSRuleSourceData::create(StyleRule::Style); result->ruleBodyRange.start = 0; result->ruleBodyRange.end = 0; - return true; + return result; } - RefPtr<MutableStyleProperties> tempDeclaration = MutableStyleProperties::create(); - createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.get(), m_styleText, result, &m_element->document().elementSheet().contents()); - return true; + CSSParserContext context(parserContextForDocument(&m_element->document())); + RuleSourceDataList ruleSourceDataResult; + StyleSheetHandler handler(m_styleText, &m_element->document(), &ruleSourceDataResult); + CSSParser::parseDeclarationForInspector(context, m_styleText, handler); + return WTFMove(ruleSourceDataResult.first()); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorStyleSheet.h b/Source/WebCore/inspector/InspectorStyleSheet.h index bc1f1ac79..df95d1ce5 100644 --- a/Source/WebCore/inspector/InspectorStyleSheet.h +++ b/Source/WebCore/inspector/InspectorStyleSheet.h @@ -22,27 +22,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorStyleSheet_h -#define InspectorStyleSheet_h +#pragma once #include "CSSPropertySourceData.h" #include "CSSStyleDeclaration.h" -#include "ExceptionCode.h" -#include "InspectorStyleTextEditor.h" -#include "InspectorWebTypeBuilders.h" +#include <inspector/InspectorProtocolObjects.h> #include <inspector/InspectorValues.h> #include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> #include <wtf/Vector.h> -#include <wtf/text/WTFString.h> class ParsedStyleSheet; namespace WebCore { class CSSRuleList; +class CSSSelector; class CSSStyleDeclaration; class CSSStyleRule; class CSSStyleSheet; @@ -50,27 +44,20 @@ class Document; class Element; class InspectorPageAgent; class InspectorStyleSheet; -class Node; - -#if ENABLE(INSPECTOR) typedef String ErrorString; class InspectorCSSId { public: - InspectorCSSId() - : m_ordinal(0) - { - } + InspectorCSSId() { } - explicit InspectorCSSId(RefPtr<Inspector::InspectorObject> value) + explicit InspectorCSSId(const Inspector::InspectorObject& value) { - if (!value->getString("styleSheetId", &m_styleSheetId)) + if (!value.getString(ASCIILiteral("styleSheetId"), m_styleSheetId)) return; - - RefPtr<Inspector::InspectorValue> ordinalValue = value->get("ordinal"); - if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal)) - m_styleSheetId = ""; + + if (!value.getInteger(ASCIILiteral("ordinal"), m_ordinal)) + m_styleSheetId = String(); } InspectorCSSId(const String& styleSheetId, unsigned ordinal) @@ -84,22 +71,22 @@ public: const String& styleSheetId() const { return m_styleSheetId; } unsigned ordinal() const { return m_ordinal; } - // ID type is either Inspector::TypeBuilder::CSS::CSSStyleId or Inspector::TypeBuilder::CSS::CSSRuleId. + // ID type is either Inspector::Protocol::CSS::CSSStyleId or Inspector::Protocol::CSS::CSSRuleId. template<typename ID> - PassRefPtr<ID> asProtocolValue() const + RefPtr<ID> asProtocolValue() const { if (isEmpty()) return nullptr; - RefPtr<ID> result = ID::create() + return ID::create() .setStyleSheetId(m_styleSheetId) - .setOrdinal(m_ordinal); - return result.release(); + .setOrdinal(m_ordinal) + .release(); } private: String m_styleSheetId; - unsigned m_ordinal; + unsigned m_ordinal = {0}; }; struct InspectorStyleProperty { @@ -133,42 +120,31 @@ struct InspectorStyleProperty { String rawText; }; -class InspectorStyle : public RefCounted<InspectorStyle> { +class InspectorStyle final : public RefCounted<InspectorStyle> { public: - static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); - virtual ~InspectorStyle(); + static Ref<InspectorStyle> create(const InspectorCSSId& styleId, RefPtr<CSSStyleDeclaration>&&, InspectorStyleSheet* parentStyleSheet); + ~InspectorStyle(); CSSStyleDeclaration* cssStyle() const { return m_style.get(); } - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> buildObjectForStyle() const; - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>> buildArrayForComputedStyle() const; - bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); } - bool setPropertyText(unsigned index, const String& text, bool overwrite, String* oldText, ExceptionCode&); - bool toggleProperty(unsigned index, bool disable, ExceptionCode&); + RefPtr<Inspector::Protocol::CSS::CSSStyle> buildObjectForStyle() const; + Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>> buildArrayForComputedStyle() const; - bool getText(String* result) const; - bool setText(const String&, ExceptionCode&); + ExceptionOr<String> text() const; + ExceptionOr<void> setText(const String&); private: - InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); + InspectorStyle(const InspectorCSSId& styleId, RefPtr<CSSStyleDeclaration>&&, InspectorStyleSheet* parentStyleSheet); - // FIXME: Remove these aliases and update all the current call sites to use the new public methods. - bool styleText(String* result) const { return getText(result); } - bool applyStyleText(const String& text) { ExceptionCode ec = 0; return setText(text, ec); } - - bool populateAllProperties(Vector<InspectorStyleProperty>* result) const; - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> styleWithProperties() const; - PassRefPtr<CSSRuleSourceData> extractSourceData() const; + void populateAllProperties(Vector<InspectorStyleProperty>* result) const; + Ref<Inspector::Protocol::CSS::CSSStyle> styleWithProperties() const; + RefPtr<CSSRuleSourceData> extractSourceData() const; String shorthandValue(const String& shorthandProperty) const; String shorthandPriority(const String& shorthandProperty) const; Vector<String> longhandProperties(const String& shorthandProperty) const; - NewLineAndWhitespace& newLineAndWhitespaceDelimiters() const; InspectorCSSId m_styleId; RefPtr<CSSStyleDeclaration> m_style; InspectorStyleSheet* m_parentStyleSheet; - Vector<InspectorStyleProperty> m_disabledProperties; - mutable std::pair<String, String> m_format; - mutable bool m_formatAcquired; }; class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> { @@ -181,7 +157,7 @@ public: }; typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle>> InspectorStyleMap; - static PassRefPtr<InspectorStyleSheet> create(InspectorPageAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*); + static Ref<InspectorStyleSheet> create(InspectorPageAgent*, const String& id, RefPtr<CSSStyleSheet>&& pageStyleSheet, Inspector::Protocol::CSS::StyleSheetOrigin, const String& documentURL, Listener*); static String styleSheetURL(CSSStyleSheet* pageStyleSheet); virtual ~InspectorStyleSheet(); @@ -190,21 +166,19 @@ public: String finalURL() const; CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); } void reparseStyleSheet(const String&); - bool setText(const String&, ExceptionCode&); - String ruleSelector(const InspectorCSSId&, ExceptionCode&); - bool setRuleSelector(const InspectorCSSId&, const String& selector, ExceptionCode&); - CSSStyleRule* addRule(const String& selector, ExceptionCode&); - bool deleteRule(const InspectorCSSId&, ExceptionCode&); + ExceptionOr<void> setText(const String&); + ExceptionOr<String> ruleSelector(const InspectorCSSId&); + ExceptionOr<void> setRuleSelector(const InspectorCSSId&, const String& selector); + ExceptionOr<CSSStyleRule*> addRule(const String& selector); + ExceptionOr<void> deleteRule(const InspectorCSSId&); CSSStyleRule* ruleForId(const InspectorCSSId&) const; - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody> buildObjectForStyleSheet(); - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo(); - PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*); - PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*); - bool setStyleText(const InspectorCSSId&, const String& text, String* oldText, ExceptionCode&); - bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText, ExceptionCode&); - bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable, ExceptionCode&); - - virtual bool getText(String* result) const; + RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody> buildObjectForStyleSheet(); + RefPtr<Inspector::Protocol::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo(); + RefPtr<Inspector::Protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, Element*); + RefPtr<Inspector::Protocol::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*); + ExceptionOr<void> setStyleText(const InspectorCSSId&, const String& text, String* oldText); + + virtual ExceptionOr<String> text() const; virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const; void fireStyleSheetChanged(); @@ -212,78 +186,72 @@ public: InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); } protected: - InspectorStyleSheet(InspectorPageAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*); + InspectorStyleSheet(InspectorPageAgent*, const String& id, RefPtr<CSSStyleSheet>&& pageStyleSheet, Inspector::Protocol::CSS::StyleSheetOrigin, const String& documentURL, Listener*); - bool canBind() const { return m_origin != Inspector::TypeBuilder::CSS::StyleSheetOrigin::UserAgent && m_origin != Inspector::TypeBuilder::CSS::StyleSheetOrigin::User; } - InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const; + bool canBind() const { return m_origin != Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent && m_origin != Inspector::Protocol::CSS::StyleSheetOrigin::User; } + InspectorCSSId ruleOrStyleId(CSSStyleDeclaration*) const; virtual Document* ownerDocument() const; - virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const; + virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration*) const; virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const; virtual bool ensureParsedDataReady(); - virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); - virtual void rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle); - virtual void forgetInspectorStyle(CSSStyleDeclaration* style); + virtual RefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); // Also accessed by friend class InspectorStyle. - virtual bool setStyleText(CSSStyleDeclaration*, const String&, ExceptionCode&); - virtual PassOwnPtr<Vector<size_t>> lineEndings() const; + virtual ExceptionOr<void> setStyleText(CSSStyleDeclaration*, const String&); + virtual std::unique_ptr<Vector<size_t>> lineEndings() const; private: typedef Vector<RefPtr<CSSStyleRule>> CSSStyleRuleVector; friend class InspectorStyle; - static void collectFlatRules(PassRefPtr<CSSRuleList>, CSSStyleRuleVector* result); - bool checkPageStyleSheet(ExceptionCode&) const; + static void collectFlatRules(RefPtr<CSSRuleList>&&, CSSStyleRuleVector* result); + bool styleSheetMutated() const; bool ensureText() const; bool ensureSourceData(); void ensureFlatRules() const; bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result); - void revalidateStyle(CSSStyleDeclaration*); bool originalStyleSheetText(String* result) const; bool resourceStyleSheetText(String* result) const; bool inlineStyleSheetText(String* result) const; - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> buildArrayForRuleList(CSSRuleList*); - PassRefPtr<Inspector::TypeBuilder::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*); + Ref<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSRule>> buildArrayForRuleList(CSSRuleList*); + Ref<Inspector::Protocol::CSS::CSSSelector> buildObjectForSelector(const CSSSelector*, Element*); + Ref<Inspector::Protocol::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*, Element*, int& endingLine); InspectorPageAgent* m_pageAgent; String m_id; RefPtr<CSSStyleSheet> m_pageStyleSheet; - Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin; + Inspector::Protocol::CSS::StyleSheetOrigin m_origin; String m_documentURL; - bool m_isRevalidating; ParsedStyleSheet* m_parsedStyleSheet; - InspectorStyleMap m_inspectorStyles; mutable CSSStyleRuleVector m_flatRules; Listener* m_listener; }; -class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet { +class InspectorStyleSheetForInlineStyle final : public InspectorStyleSheet { public: - static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, const String& id, PassRefPtr<Element>, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*); + static Ref<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, const String& id, RefPtr<Element>&&, Inspector::Protocol::CSS::StyleSheetOrigin, Listener*); void didModifyElementAttribute(); - virtual bool getText(String* result) const override; - virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const override { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); } + ExceptionOr<String> text() const final; + CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const final { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); } protected: - InspectorStyleSheetForInlineStyle(InspectorPageAgent*, const String& id, PassRefPtr<Element>, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*); + InspectorStyleSheetForInlineStyle(InspectorPageAgent*, const String& id, RefPtr<Element>&&, Inspector::Protocol::CSS::StyleSheetOrigin, Listener*); - virtual Document* ownerDocument() const override; - virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const override { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; } - virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const override { return 0; } - virtual bool ensureParsedDataReady() override; - virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) override; - virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) override { } - virtual void forgetInspectorStyle(CSSStyleDeclaration*) override { } + Document* ownerDocument() const final; + RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const final { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; } + unsigned ruleIndexByStyle(CSSStyleDeclaration*) const final { return 0; } + bool ensureParsedDataReady() final; + RefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) final; // Also accessed by friend class InspectorStyle. - virtual bool setStyleText(CSSStyleDeclaration*, const String&, ExceptionCode&) override; - virtual PassOwnPtr<Vector<size_t>> lineEndings() const override; + ExceptionOr<void> setStyleText(CSSStyleDeclaration*, const String&) final; + std::unique_ptr<Vector<size_t>> lineEndings() const final; private: CSSStyleDeclaration* inlineStyle() const; const String& elementStyleText() const; - bool getStyleAttributeRanges(CSSRuleSourceData* result) const; + Ref<CSSRuleSourceData> ruleSourceData() const; RefPtr<Element> m_element; RefPtr<CSSRuleSourceData> m_ruleSourceData; @@ -294,8 +262,4 @@ private: mutable bool m_isStyleTextValid; }; -#endif - } // namespace WebCore - -#endif // !defined(InspectorStyleSheet_h) diff --git a/Source/WebCore/inspector/InspectorStyleTextEditor.cpp b/Source/WebCore/inspector/InspectorStyleTextEditor.cpp deleted file mode 100644 index c17c3de41..000000000 --- a/Source/WebCore/inspector/InspectorStyleTextEditor.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2011, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorStyleTextEditor.h" - -#include "CSSPropertySourceData.h" -#include "HTMLParserIdioms.h" -#include "InspectorStyleSheet.h" - -using namespace Inspector; - -namespace WebCore { - -InspectorStyleTextEditor::InspectorStyleTextEditor(Vector<InspectorStyleProperty>* allProperties, Vector<InspectorStyleProperty>* disabledProperties, const String& styleText, const NewLineAndWhitespace& format) - : m_allProperties(allProperties) - , m_disabledProperties(disabledProperties) - , m_styleText(styleText) - , m_format(format) -{ -} - -void InspectorStyleTextEditor::insertProperty(unsigned index, const String& propertyText, unsigned styleBodyLength) -{ - long propertyStart = 0; - - bool insertLast = true; - if (index < m_allProperties->size()) { - const InspectorStyleProperty& property = m_allProperties->at(index); - if (property.hasSource) { - propertyStart = property.sourceData.range.start; - // If inserting before a disabled property, it should be shifted, too. - insertLast = false; - } - } - - bool insertFirstInSource = true; - for (unsigned i = 0, size = m_allProperties->size(); i < index && i < size; ++i) { - const InspectorStyleProperty& property = m_allProperties->at(i); - if (property.hasSource && !property.disabled) { - insertFirstInSource = false; - break; - } - } - - bool insertLastInSource = true; - for (unsigned i = index, size = m_allProperties->size(); i < size; ++i) { - const InspectorStyleProperty& property = m_allProperties->at(i); - if (property.hasSource && !property.disabled) { - insertLastInSource = false; - break; - } - } - - String textToSet = propertyText; - - int formattingPrependOffset = 0; - if (insertLast && !insertFirstInSource) { - propertyStart = styleBodyLength; - if (propertyStart && textToSet.length()) { - const UChar* characters = m_styleText.deprecatedCharacters(); - - long curPos = propertyStart - 1; // The last position of style declaration, since propertyStart points past one. - while (curPos && isHTMLSpace(characters[curPos])) - --curPos; - if (curPos && characters[curPos] != ';') { - // Prepend a ";" to the property text if appending to a style declaration where - // the last property has no trailing ";". - textToSet.insert(";", 0); - formattingPrependOffset = 1; - } - } - } - - const String& formatLineFeed = m_format.first; - const String& formatPropertyPrefix = m_format.second; - if (insertLastInSource) { - long formatPropertyPrefixLength = formatPropertyPrefix.length(); - if (!formattingPrependOffset && (propertyStart < formatPropertyPrefixLength || m_styleText.substring(propertyStart - formatPropertyPrefixLength, formatPropertyPrefixLength) != formatPropertyPrefix)) { - textToSet.insert(formatPropertyPrefix, formattingPrependOffset); - if (!propertyStart || !isHTMLLineBreak(m_styleText[propertyStart - 1])) - textToSet.insert(formatLineFeed, formattingPrependOffset); - } - if (!isHTMLLineBreak(m_styleText[propertyStart])) - textToSet.append(formatLineFeed); - } else { - String fullPrefix = formatLineFeed + formatPropertyPrefix; - long fullPrefixLength = fullPrefix.length(); - textToSet.append(fullPrefix); - if (insertFirstInSource && (propertyStart < fullPrefixLength || m_styleText.substring(propertyStart - fullPrefixLength, fullPrefixLength) != fullPrefix)) - textToSet.insert(fullPrefix, formattingPrependOffset); - } - m_styleText.insert(textToSet, propertyStart); - - // Recompute disabled property ranges after an inserted property. - long propertyLengthDelta = textToSet.length(); - shiftDisabledProperties(disabledIndexByOrdinal(index, true), propertyLengthDelta); -} - -void InspectorStyleTextEditor::replaceProperty(unsigned index, const String& newText) -{ - ASSERT_WITH_SECURITY_IMPLICATION(index < m_allProperties->size()); - - const InspectorStyleProperty& property = m_allProperties->at(index); - long propertyStart = property.sourceData.range.start; - long propertyEnd = property.sourceData.range.end; - long oldLength = propertyEnd - propertyStart; - long newLength = newText.length(); - long propertyLengthDelta = newLength - oldLength; - - if (!property.disabled) { - SourceRange overwrittenRange; - unsigned insertedLength; - internalReplaceProperty(property, newText, &overwrittenRange, &insertedLength); - propertyLengthDelta = static_cast<long>(insertedLength) - static_cast<long>(overwrittenRange.length()); - - // Recompute subsequent disabled property ranges if acting on a non-disabled property. - shiftDisabledProperties(disabledIndexByOrdinal(index, true), propertyLengthDelta); - } else { - long textLength = newText.length(); - unsigned disabledIndex = disabledIndexByOrdinal(index, false); - if (!textLength) { - // Delete disabled property. - m_disabledProperties->remove(disabledIndex); - } else { - // Patch disabled property text. - m_disabledProperties->at(disabledIndex).rawText = newText; - } - } -} - -void InspectorStyleTextEditor::removeProperty(unsigned index) -{ - replaceProperty(index, ""); -} - -void InspectorStyleTextEditor::enableProperty(unsigned index) -{ - ASSERT(m_allProperties->at(index).disabled); - - unsigned disabledIndex = disabledIndexByOrdinal(index, false); - ASSERT(disabledIndex != UINT_MAX); - - InspectorStyleProperty disabledProperty = m_disabledProperties->at(disabledIndex); - m_disabledProperties->remove(disabledIndex); - SourceRange removedRange; - unsigned insertedLength; - internalReplaceProperty(disabledProperty, disabledProperty.rawText, &removedRange, &insertedLength); - shiftDisabledProperties(disabledIndex, static_cast<long>(insertedLength) - static_cast<long>(removedRange.length())); -} - -void InspectorStyleTextEditor::disableProperty(unsigned index) -{ - ASSERT(!m_allProperties->at(index).disabled); - - const InspectorStyleProperty& property = m_allProperties->at(index); - InspectorStyleProperty disabledProperty(property); - disabledProperty.setRawTextFromStyleDeclaration(m_styleText); - disabledProperty.disabled = true; - - SourceRange removedRange; - unsigned insertedLength; - internalReplaceProperty(property, "", &removedRange, &insertedLength); - - // If some preceding formatting has been removed, move the property to the start of the removed range. - if (property.sourceData.range.start > removedRange.start) - disabledProperty.sourceData.range.start = removedRange.start; - disabledProperty.sourceData.range.end = disabledProperty.sourceData.range.start; - - // Add disabled property at correct position. - unsigned insertionIndex = disabledIndexByOrdinal(index, true); - if (insertionIndex == UINT_MAX) - m_disabledProperties->append(disabledProperty); - else { - m_disabledProperties->insert(insertionIndex, disabledProperty); - long styleLengthDelta = -(static_cast<long>(removedRange.length())); - shiftDisabledProperties(insertionIndex + 1, styleLengthDelta); // Property removed from text - shift these back. - } -} - -unsigned InspectorStyleTextEditor::disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent) -{ - unsigned disabledIndex = 0; - for (unsigned i = 0, size = m_allProperties->size(); i < size; ++i) { - if (m_allProperties->at(i).disabled) { - if (i == ordinal || (canUseSubsequent && i > ordinal)) - return disabledIndex; - ++disabledIndex; - } - } - - return UINT_MAX; -} - -void InspectorStyleTextEditor::shiftDisabledProperties(unsigned fromIndex, long delta) -{ - for (unsigned i = fromIndex, size = m_disabledProperties->size(); i < size; ++i) { - SourceRange& range = m_disabledProperties->at(i).sourceData.range; - range.start += delta; - range.end += delta; - } -} - -void InspectorStyleTextEditor::internalReplaceProperty(const InspectorStyleProperty& property, const String& newText, SourceRange* removedRange, unsigned* insertedLength) -{ - const SourceRange& range = property.sourceData.range; - long replaceRangeStart = range.start; - long replaceRangeEnd = range.end; - const UChar* characters = m_styleText.deprecatedCharacters(); - long newTextLength = newText.length(); - String finalNewText = newText; - - // Removing a property - remove preceding prefix. - String fullPrefix = m_format.first + m_format.second; - long fullPrefixLength = fullPrefix.length(); - if (!newTextLength && fullPrefixLength) { - if (replaceRangeStart >= fullPrefixLength && m_styleText.substring(replaceRangeStart - fullPrefixLength, fullPrefixLength) == fullPrefix) - replaceRangeStart -= fullPrefixLength; - } else if (newTextLength) { - if (isHTMLLineBreak(newText.deprecatedCharacters()[newTextLength - 1])) { - // Coalesce newlines of the original and new property values (to avoid a lot of blank lines while incrementally applying property values). - bool foundNewline = false; - bool isLastNewline = false; - int i; - int textLength = m_styleText.length(); - for (i = replaceRangeEnd; i < textLength && isSpaceOrNewline(characters[i]); ++i) { - isLastNewline = isHTMLLineBreak(characters[i]); - if (isLastNewline) - foundNewline = true; - else if (foundNewline && !isLastNewline) { - replaceRangeEnd = i; - break; - } - } - if (foundNewline && isLastNewline) - replaceRangeEnd = i; - } - - if (fullPrefixLength > replaceRangeStart || m_styleText.substring(replaceRangeStart - fullPrefixLength, fullPrefixLength) != fullPrefix) - finalNewText.insert(fullPrefix, 0); - } - - int replacedLength = replaceRangeEnd - replaceRangeStart; - m_styleText.replace(replaceRangeStart, replacedLength, finalNewText); - *removedRange = SourceRange(replaceRangeStart, replaceRangeEnd); - *insertedLength = finalNewText.length(); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorStyleTextEditor.h b/Source/WebCore/inspector/InspectorStyleTextEditor.h deleted file mode 100644 index d7502561b..000000000 --- a/Source/WebCore/inspector/InspectorStyleTextEditor.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorStyleTextEditor_h -#define InspectorStyleTextEditor_h - -#include "CSSPropertySourceData.h" - -#include <wtf/Vector.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { - -#if ENABLE(INSPECTOR) - -struct InspectorStyleProperty; -struct SourceRange; - -typedef std::pair<String, String> NewLineAndWhitespace; - -class InspectorStyleTextEditor { -public: - InspectorStyleTextEditor(Vector<InspectorStyleProperty>* allProperties, Vector<InspectorStyleProperty>* disabledProperties, const String& styleText, const NewLineAndWhitespace& format); - void insertProperty(unsigned index, const String& propertyText, unsigned styleBodyLength); - void replaceProperty(unsigned index, const String& newText); - void removeProperty(unsigned index); - void enableProperty(unsigned index); - void disableProperty(unsigned index); - const String& styleText() const { return m_styleText; } - -private: - unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent); - void shiftDisabledProperties(unsigned fromIndex, long delta); - void internalReplaceProperty(const InspectorStyleProperty&, const String& newText, SourceRange* removedRange, unsigned* insertedLength); - - Vector<InspectorStyleProperty>* m_allProperties; - Vector<InspectorStyleProperty>* m_disabledProperties; - String m_styleText; - const std::pair<String, String> m_format; -}; - -#endif - -} // namespace WebCore - -#endif // !defined(InspectorStyleTextEditor_h) diff --git a/Source/WebCore/inspector/InspectorTimelineAgent.cpp b/Source/WebCore/inspector/InspectorTimelineAgent.cpp index f8a6c38a3..1f0d0576d 100644 --- a/Source/WebCore/inspector/InspectorTimelineAgent.cpp +++ b/Source/WebCore/inspector/InspectorTimelineAgent.cpp @@ -1,5 +1,7 @@ /* * Copyright (C) 2013 Google Inc. All rights reserved. +* Copyright (C) 2014 University of Washington. +* Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,62 +31,133 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorTimelineAgent.h" #include "Event.h" #include "Frame.h" -#include "FrameView.h" -#include "IdentifiersFactory.h" -#include "InspectorClient.h" -#include "InspectorCounters.h" -#include "InspectorInstrumentation.h" #include "InspectorMemoryAgent.h" #include "InspectorPageAgent.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" -#include "IntRect.h" #include "JSDOMWindow.h" -#include "RenderElement.h" +#include "PageScriptDebugServer.h" #include "RenderView.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" +#include "ScriptState.h" #include "TimelineRecordFactory.h" -#include <wtf/CurrentTime.h> +#include "WebConsoleAgent.h" +#include <inspector/ConsoleMessage.h> +#include <inspector/ScriptBreakpoint.h> +#include <inspector/agents/InspectorDebuggerAgent.h> +#include <inspector/agents/InspectorHeapAgent.h> +#include <inspector/agents/InspectorScriptProfilerAgent.h> +#include <wtf/Stopwatch.h> + +#if PLATFORM(IOS) +#include "RuntimeApplicationChecks.h" +#include "WebCoreThreadInternal.h" +#endif + +#if PLATFORM(COCOA) +#include "RunLoopObserver.h" +#endif using namespace Inspector; namespace WebCore { -void TimelineTimeConverter::reset() +#if PLATFORM(COCOA) +static const CFIndex frameStopRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit + 1; + +static CFRunLoopRef currentRunLoop() +{ +#if PLATFORM(IOS) + // A race condition during WebView deallocation can lead to a crash if the layer sync run loop + // observer is added to the main run loop <rdar://problem/9798550>. However, for responsiveness, + // we still allow this, see <rdar://problem/7403328>. Since the race condition and subsequent + // crash are especially troublesome for iBooks, we never allow the observer to be added to the + // main run loop in iBooks. + if (IOSApplication::isIBooks()) + return WebThreadRunLoop(); +#endif + return CFRunLoopGetCurrent(); +} +#endif + +InspectorTimelineAgent::InspectorTimelineAgent(WebAgentContext& context, InspectorScriptProfilerAgent* scriptProfileAgent, InspectorHeapAgent* heapAgent, InspectorPageAgent* pageAgent) + : InspectorAgentBase(ASCIILiteral("Timeline"), context) + , m_frontendDispatcher(std::make_unique<Inspector::TimelineFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::TimelineBackendDispatcher::create(context.backendDispatcher, this)) + , m_scriptProfilerAgent(scriptProfileAgent) + , m_heapAgent(heapAgent) + , m_pageAgent(pageAgent) { - m_startOffset = monotonicallyIncreasingTime() - currentTime(); } InspectorTimelineAgent::~InspectorTimelineAgent() { } -void InspectorTimelineAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorTimelineAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) +{ + m_instrumentingAgents.setPersistentInspectorTimelineAgent(this); +} + +void InspectorTimelineAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) +{ + m_instrumentingAgents.setPersistentInspectorTimelineAgent(nullptr); + + ErrorString unused; + stop(unused); + + m_autoCaptureEnabled = false; + m_instruments.clear(); +} + +void InspectorTimelineAgent::start(ErrorString&, const int* maxCallStackDepth) +{ + m_enabledFromFrontend = true; + + internalStart(maxCallStackDepth); +} + +void InspectorTimelineAgent::stop(ErrorString&) +{ + internalStop(); + + m_enabledFromFrontend = false; +} + +void InspectorTimelineAgent::setAutoCaptureEnabled(ErrorString&, bool enabled) { - m_frontendDispatcher = std::make_unique<InspectorTimelineFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorTimelineBackendDispatcher::create(backendDispatcher, this); + m_autoCaptureEnabled = enabled; } -void InspectorTimelineAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorTimelineAgent::setInstruments(ErrorString& errorString, const InspectorArray& instruments) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); + Vector<Protocol::Timeline::Instrument> newInstruments; + newInstruments.reserveCapacity(instruments.length()); + + for (auto instrumentValue : instruments) { + String enumValueString; + if (!instrumentValue->asString(enumValueString)) { + errorString = ASCIILiteral("Unexpected type in instruments list, should be string"); + return; + } + + std::optional<Protocol::Timeline::Instrument> instrumentType = Protocol::InspectorHelpers::parseEnumValueFromString<Protocol::Timeline::Instrument>(enumValueString); + if (!instrumentType) { + errorString = makeString("Unexpected enum value: ", enumValueString); + return; + } + + newInstruments.uncheckedAppend(*instrumentType); + } - ErrorString error; - stop(&error); + m_instruments.swap(newInstruments); } -void InspectorTimelineAgent::start(ErrorString*, const int* maxCallStackDepth, const bool* includeDomCounters) +void InspectorTimelineAgent::internalStart(const int* maxCallStackDepth) { - if (!m_frontendDispatcher) + if (m_enabled) return; if (maxCallStackDepth && *maxCallStackDepth > 0) @@ -92,46 +165,134 @@ void InspectorTimelineAgent::start(ErrorString*, const int* maxCallStackDepth, c else m_maxCallStackDepth = 5; - if (includeDomCounters) - m_includeDOMCounters = *includeDomCounters; + m_instrumentingAgents.setInspectorTimelineAgent(this); - m_timeConverter.reset(); + m_environment.scriptDebugServer().addListener(this); - m_instrumentingAgents->setInspectorTimelineAgent(this); m_enabled = true; + + // FIXME: Abstract away platform-specific code once https://bugs.webkit.org/show_bug.cgi?id=142748 is fixed. + +#if PLATFORM(COCOA) + m_frameStartObserver = std::make_unique<RunLoopObserver>(0, [this]() { + if (!m_enabled || m_environment.scriptDebugServer().isPaused()) + return; + + if (!m_runLoopNestingLevel) + pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RenderingFrame, false, nullptr); + m_runLoopNestingLevel++; + }); + + m_frameStopObserver = std::make_unique<RunLoopObserver>(frameStopRunLoopOrder, [this]() { + if (!m_enabled || m_environment.scriptDebugServer().isPaused()) + return; + + ASSERT(m_runLoopNestingLevel > 0); + m_runLoopNestingLevel--; + if (m_runLoopNestingLevel) + return; + + if (m_startedComposite) + didComposite(); + + didCompleteCurrentRecord(TimelineRecordType::RenderingFrame); + }); + + m_frameStartObserver->schedule(currentRunLoop(), kCFRunLoopEntry | kCFRunLoopAfterWaiting); + m_frameStopObserver->schedule(currentRunLoop(), kCFRunLoopExit | kCFRunLoopBeforeWaiting); + + // Create a runloop record and increment the runloop nesting level, to capture the current turn of the main runloop + // (which is the outer runloop if recording started while paused in the debugger). + pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RenderingFrame, false, nullptr); + + m_runLoopNestingLevel = 1; +#endif + + m_frontendDispatcher->recordingStarted(timestamp()); } -void InspectorTimelineAgent::stop(ErrorString*) +void InspectorTimelineAgent::internalStop() { if (!m_enabled) return; - m_weakFactory.revokeAll(); - m_instrumentingAgents->setInspectorTimelineAgent(nullptr); + m_instrumentingAgents.setInspectorTimelineAgent(nullptr); + + m_environment.scriptDebugServer().removeListener(this, true); + +#if PLATFORM(COCOA) + m_frameStartObserver = nullptr; + m_frameStopObserver = nullptr; + m_runLoopNestingLevel = 0; + + // Complete all pending records to prevent discarding events that are currently in progress. + while (!m_recordStack.isEmpty()) + didCompleteCurrentRecord(m_recordStack.last().type); +#endif clearRecordStack(); m_enabled = false; -} + m_startedComposite = false; + m_autoCapturePhase = AutoCapturePhase::None; -void InspectorTimelineAgent::canMonitorMainThread(ErrorString*, bool* result) -{ - *result = m_client && m_client->canMonitorMainThread(); + m_frontendDispatcher->recordingStopped(timestamp()); } -void InspectorTimelineAgent::supportsFrameInstrumentation(ErrorString*, bool* result) +double InspectorTimelineAgent::timestamp() { - *result = m_client && m_client->supportsFrameInstrumentation(); + return m_environment.executionStopwatch()->elapsedTime(); } -void InspectorTimelineAgent::didBeginFrame() +void InspectorTimelineAgent::startFromConsole(JSC::ExecState* exec, const String& title) { - m_pendingFrameRecord = TimelineRecordFactory::createGenericRecord(timestamp(), 0); + // Allow duplicate unnamed profiles. Disallow duplicate named profiles. + if (!title.isEmpty()) { + for (const TimelineRecordEntry& record : m_pendingConsoleProfileRecords) { + String recordTitle; + record.data->getString(ASCIILiteral("title"), recordTitle); + if (recordTitle == title) { + if (WebConsoleAgent* consoleAgent = m_instrumentingAgents.webConsoleAgent()) { + // FIXME: Send an enum to the frontend for localization? + String warning = title.isEmpty() ? ASCIILiteral("Unnamed Profile already exists") : makeString("Profile \"", title, "\" already exists"); + consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Warning, warning)); + } + return; + } + } + } + + if (!m_enabled && m_pendingConsoleProfileRecords.isEmpty()) + startProgrammaticCapture(); + + m_pendingConsoleProfileRecords.append(createRecordEntry(TimelineRecordFactory::createConsoleProfileData(title), TimelineRecordType::ConsoleProfile, true, frameFromExecState(exec))); } -void InspectorTimelineAgent::didCancelFrame() +void InspectorTimelineAgent::stopFromConsole(JSC::ExecState*, const String& title) { - m_pendingFrameRecord.clear(); + // Stop profiles in reverse order. If the title is empty, then stop the last profile. + // Otherwise, match the title of the profile to stop. + for (int i = m_pendingConsoleProfileRecords.size() - 1; i >= 0; --i) { + const TimelineRecordEntry& record = m_pendingConsoleProfileRecords[i]; + + String recordTitle; + record.data->getString(ASCIILiteral("title"), recordTitle); + if (title.isEmpty() || recordTitle == title) { + didCompleteRecordEntry(record); + m_pendingConsoleProfileRecords.remove(i); + + if (!m_enabledFromFrontend && m_pendingConsoleProfileRecords.isEmpty()) + stopProgrammaticCapture(); + + return; + } + } + + if (WebConsoleAgent* consoleAgent = m_instrumentingAgents.webConsoleAgent()) { + // FIXME: Send an enum to the frontend for localization? + String warning = title.isEmpty() ? ASCIILiteral("No profiles exist") : makeString("Profile \"", title, "\" does not exist"); + consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::ProfileEnd, MessageLevel::Warning, warning)); + } } void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine, Frame* frame) @@ -139,7 +300,7 @@ void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scri pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame); } -void InspectorTimelineAgent::didCallFunction() +void InspectorTimelineAgent::didCallFunction(Frame*) { didCompleteCurrentRecord(TimelineRecordType::FunctionCall); } @@ -154,37 +315,24 @@ void InspectorTimelineAgent::didDispatchEvent() didCompleteCurrentRecord(TimelineRecordType::EventDispatch); } -void InspectorTimelineAgent::didInvalidateLayout(Frame* frame) +void InspectorTimelineAgent::didInvalidateLayout(Frame& frame) { - appendRecord(InspectorObject::create(), TimelineRecordType::InvalidateLayout, true, frame); + appendRecord(InspectorObject::create(), TimelineRecordType::InvalidateLayout, true, &frame); } -void InspectorTimelineAgent::willLayout(Frame* frame) +void InspectorTimelineAgent::willLayout(Frame& frame) { - RenderObject* root = frame->view()->layoutRoot(); - bool partialLayout = !!root; - - if (!partialLayout) - root = frame->contentRenderer(); - - unsigned dirtyObjects = 0; - unsigned totalObjects = 0; - for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) { - ++totalObjects; - if (o->needsLayout()) - ++dirtyObjects; - } - pushCurrentRecord(TimelineRecordFactory::createLayoutData(dirtyObjects, totalObjects, partialLayout), TimelineRecordType::Layout, true, frame); + pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Layout, true, &frame); } -void InspectorTimelineAgent::didLayout(RenderObject* root) +void InspectorTimelineAgent::didLayout(RenderObject& root) { if (m_recordStack.isEmpty()) return; TimelineRecordEntry& entry = m_recordStack.last(); ASSERT(entry.type == TimelineRecordType::Layout); Vector<FloatQuad> quads; - root->absoluteQuads(quads); + root.absoluteQuads(quads); if (quads.size() >= 1) TimelineRecordFactory::appendLayoutRoot(entry.data.get(), quads[0]); else @@ -207,56 +355,36 @@ void InspectorTimelineAgent::didRecalculateStyle() didCompleteCurrentRecord(TimelineRecordType::RecalculateStyles); } -void InspectorTimelineAgent::willPaint(Frame* frame) +void InspectorTimelineAgent::willComposite(Frame& frame) { - pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Paint, true, frame); -} - -void InspectorTimelineAgent::didPaint(RenderObject* renderer, const LayoutRect& clipRect) -{ - TimelineRecordEntry& entry = m_recordStack.last(); - ASSERT(entry.type == TimelineRecordType::Paint); - FloatQuad quad; - localToPageQuad(*renderer, clipRect, &quad); - entry.data = TimelineRecordFactory::createPaintData(quad); - didCompleteCurrentRecord(TimelineRecordType::Paint); -} - -void InspectorTimelineAgent::willScroll(Frame* frame) -{ - pushCurrentRecord(InspectorObject::create(), TimelineRecordType::ScrollLayer, false, frame); -} - -void InspectorTimelineAgent::didScroll() -{ - didCompleteCurrentRecord(TimelineRecordType::ScrollLayer); -} - -void InspectorTimelineAgent::willComposite() -{ - pushCurrentRecord(InspectorObject::create(), TimelineRecordType::CompositeLayers, false, nullptr); + ASSERT(!m_startedComposite); + pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Composite, true, &frame); + m_startedComposite = true; } void InspectorTimelineAgent::didComposite() { - didCompleteCurrentRecord(TimelineRecordType::CompositeLayers); + ASSERT(m_startedComposite); + didCompleteCurrentRecord(TimelineRecordType::Composite); + m_startedComposite = false; } -void InspectorTimelineAgent::willWriteHTML(unsigned startLine, Frame* frame) +void InspectorTimelineAgent::willPaint(Frame& frame) { - pushCurrentRecord(TimelineRecordFactory::createParseHTMLData(startLine), TimelineRecordType::ParseHTML, true, frame); + pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Paint, true, &frame); } -void InspectorTimelineAgent::didWriteHTML(unsigned endLine) +void InspectorTimelineAgent::didPaint(RenderObject& renderer, const LayoutRect& clipRect) { - if (!m_recordStack.isEmpty()) { - TimelineRecordEntry entry = m_recordStack.last(); - entry.data->setNumber("endLine", endLine); - didCompleteCurrentRecord(TimelineRecordType::ParseHTML); - } + TimelineRecordEntry& entry = m_recordStack.last(); + ASSERT(entry.type == TimelineRecordType::Paint); + FloatQuad quad; + localToPageQuad(renderer, clipRect, &quad); + entry.data = TimelineRecordFactory::createPaintData(quad); + didCompleteCurrentRecord(TimelineRecordType::Paint); } -void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot, Frame* frame) +void InspectorTimelineAgent::didInstallTimer(int timerId, std::chrono::milliseconds timeout, bool singleShot, Frame* frame) { appendRecord(TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot), TimelineRecordType::TimerInstall, true, frame); } @@ -276,99 +404,174 @@ void InspectorTimelineAgent::didFireTimer() didCompleteCurrentRecord(TimelineRecordType::TimerFire); } -void InspectorTimelineAgent::willDispatchXHRReadyStateChangeEvent(const String& url, int readyState, Frame* frame) +void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber, Frame& frame) { - pushCurrentRecord(TimelineRecordFactory::createXHRReadyStateChangeData(url, readyState), TimelineRecordType::XHRReadyStateChange, false, frame); + pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, &frame); } -void InspectorTimelineAgent::didDispatchXHRReadyStateChangeEvent() +void InspectorTimelineAgent::didEvaluateScript(Frame&) { - didCompleteCurrentRecord(TimelineRecordType::XHRReadyStateChange); + didCompleteCurrentRecord(TimelineRecordType::EvaluateScript); } -void InspectorTimelineAgent::willDispatchXHRLoadEvent(const String& url, Frame* frame) +void InspectorTimelineAgent::didTimeStamp(Frame& frame, const String& message) { - pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(url), TimelineRecordType::XHRLoad, true, frame); + appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeStamp, true, &frame); } -void InspectorTimelineAgent::didDispatchXHRLoadEvent() +void InspectorTimelineAgent::time(Frame& frame, const String& message) { - didCompleteCurrentRecord(TimelineRecordType::XHRLoad); + appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::Time, true, &frame); } -void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber, Frame* frame) +void InspectorTimelineAgent::timeEnd(Frame& frame, const String& message) { - pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame); + appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, &frame); } -void InspectorTimelineAgent::didEvaluateScript() +void InspectorTimelineAgent::mainFrameStartedLoading() { - didCompleteCurrentRecord(TimelineRecordType::EvaluateScript); -} + if (m_enabled) + return; -void InspectorTimelineAgent::didScheduleResourceRequest(const String& url, Frame* frame) -{ - appendRecord(TimelineRecordFactory::createScheduleResourceRequestData(url), TimelineRecordType::ScheduleResourceRequest, true, frame); -} + if (!m_autoCaptureEnabled) + return; -void InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, const ResourceRequest& request, Frame* frame) -{ - String requestId = IdentifiersFactory::requestId(identifier); - appendRecord(TimelineRecordFactory::createResourceSendRequestData(requestId, request), TimelineRecordType::ResourceSendRequest, true, frame); -} + if (m_instruments.isEmpty()) + return; -void InspectorTimelineAgent::willReceiveResourceData(unsigned long identifier, Frame* frame, int length) -{ - String requestId = IdentifiersFactory::requestId(identifier); - pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(requestId, length), TimelineRecordType::ResourceReceivedData, false, frame); -} + m_autoCapturePhase = AutoCapturePhase::BeforeLoad; -void InspectorTimelineAgent::didReceiveResourceData() -{ - didCompleteCurrentRecord(TimelineRecordType::ResourceReceivedData); + // Pre-emptively disable breakpoints. The frontend must re-enable them. + if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) { + ErrorString unused; + debuggerAgent->setBreakpointsActive(unused, false); + } + + // Inform the frontend we started an auto capture. The frontend must stop capture. + m_frontendDispatcher->autoCaptureStarted(); + + toggleInstruments(InstrumentState::Start); } -void InspectorTimelineAgent::willReceiveResourceResponse(unsigned long identifier, const ResourceResponse& response, Frame* frame) +void InspectorTimelineAgent::mainFrameNavigated() { - String requestId = IdentifiersFactory::requestId(identifier); - pushCurrentRecord(TimelineRecordFactory::createResourceReceiveResponseData(requestId, response), TimelineRecordType::ResourceReceiveResponse, false, frame); + if (m_autoCapturePhase == AutoCapturePhase::BeforeLoad) { + m_autoCapturePhase = AutoCapturePhase::FirstNavigation; + toggleInstruments(InstrumentState::Start); + m_autoCapturePhase = AutoCapturePhase::AfterFirstNavigation; + } } -void InspectorTimelineAgent::didReceiveResourceResponse() +void InspectorTimelineAgent::startProgrammaticCapture() { - didCompleteCurrentRecord(TimelineRecordType::ResourceReceiveResponse); + ASSERT(!m_enabled); + + // Disable breakpoints during programmatic capture. + if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) { + m_programmaticCaptureRestoreBreakpointActiveValue = debuggerAgent->breakpointsActive(); + if (m_programmaticCaptureRestoreBreakpointActiveValue) { + ErrorString unused; + debuggerAgent->setBreakpointsActive(unused, false); + } + } else + m_programmaticCaptureRestoreBreakpointActiveValue = false; + + m_frontendDispatcher->programmaticCaptureStarted(); + + toggleScriptProfilerInstrument(InstrumentState::Start); // Ensure JavaScript samping data. + toggleTimelineInstrument(InstrumentState::Start); // Ensure Console Profile event records. + toggleInstruments(InstrumentState::Start); // Any other instruments the frontend wants us to record. } -void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail, double finishTime, Frame* frame) +void InspectorTimelineAgent::stopProgrammaticCapture() { - appendRecord(TimelineRecordFactory::createResourceFinishData(IdentifiersFactory::requestId(identifier), didFail, finishTime * 1000), TimelineRecordType::ResourceFinish, false, frame); + ASSERT(m_enabled); + ASSERT(!m_enabledFromFrontend); + + toggleInstruments(InstrumentState::Stop); + toggleTimelineInstrument(InstrumentState::Stop); + toggleScriptProfilerInstrument(InstrumentState::Stop); + + // Re-enable breakpoints if they were enabled. + if (m_programmaticCaptureRestoreBreakpointActiveValue) { + if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) { + ErrorString unused; + debuggerAgent->setBreakpointsActive(unused, true); + } + } + + m_frontendDispatcher->programmaticCaptureStopped(); } -void InspectorTimelineAgent::didTimeStamp(Frame* frame, const String& message) +void InspectorTimelineAgent::toggleInstruments(InstrumentState state) { - appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeStamp, true, frame); + for (auto instrumentType : m_instruments) { + switch (instrumentType) { + case Inspector::Protocol::Timeline::Instrument::ScriptProfiler: { + toggleScriptProfilerInstrument(state); + break; + } + case Inspector::Protocol::Timeline::Instrument::Heap: { + toggleHeapInstrument(state); + break; + } + case Inspector::Protocol::Timeline::Instrument::Memory: { + toggleMemoryInstrument(state); + break; + } + case Inspector::Protocol::Timeline::Instrument::Timeline: + toggleTimelineInstrument(state); + break; + } + } } -void InspectorTimelineAgent::time(Frame* frame, const String& message) +void InspectorTimelineAgent::toggleScriptProfilerInstrument(InstrumentState state) { - appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::Time, true, frame); + if (m_scriptProfilerAgent) { + ErrorString unused; + if (state == InstrumentState::Start) { + const bool includeSamples = true; + m_scriptProfilerAgent->startTracking(unused, &includeSamples); + } else + m_scriptProfilerAgent->stopTracking(unused); + } } -void InspectorTimelineAgent::timeEnd(Frame* frame, const String& message) +void InspectorTimelineAgent::toggleHeapInstrument(InstrumentState state) { - appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, frame); + if (m_heapAgent) { + ErrorString unused; + if (state == InstrumentState::Start) { + if (m_autoCapturePhase == AutoCapturePhase::None || m_autoCapturePhase == AutoCapturePhase::FirstNavigation) + m_heapAgent->startTracking(unused); + } else + m_heapAgent->stopTracking(unused); + } } -void InspectorTimelineAgent::didMarkDOMContentEvent(Frame* frame) +void InspectorTimelineAgent::toggleMemoryInstrument(InstrumentState state) { - bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame()); - appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkDOMContent, false, frame); +#if ENABLE(RESOURCE_USAGE) + if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) { + ErrorString unused; + if (state == InstrumentState::Start) + memoryAgent->startTracking(unused); + else + memoryAgent->stopTracking(unused); + } +#else + UNUSED_PARAM(state); +#endif } -void InspectorTimelineAgent::didMarkLoadEvent(Frame* frame) +void InspectorTimelineAgent::toggleTimelineInstrument(InstrumentState state) { - bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame()); - appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkLoad, false, frame); + if (state == InstrumentState::Start) + internalStart(); + else + internalStop(); } void InspectorTimelineAgent::didCommitLoad() @@ -396,160 +599,83 @@ void InspectorTimelineAgent::didFireAnimationFrame() didCompleteCurrentRecord(TimelineRecordType::FireAnimationFrame); } -#if ENABLE(WEB_SOCKETS) -void InspectorTimelineAgent::didCreateWebSocket(unsigned long identifier, const URL& url, const String& protocol, Frame* frame) -{ - appendRecord(TimelineRecordFactory::createWebSocketCreateData(identifier, url, protocol), TimelineRecordType::WebSocketCreate, true, frame); -} +// ScriptDebugListener -void InspectorTimelineAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, Frame* frame) +void InspectorTimelineAgent::breakpointActionProbe(JSC::ExecState& state, const Inspector::ScriptBreakpointAction& action, unsigned /*batchId*/, unsigned sampleId, JSC::JSValue) { - appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketSendHandshakeRequest, true, frame); + appendRecord(TimelineRecordFactory::createProbeSampleData(action, sampleId), TimelineRecordType::ProbeSample, false, frameFromExecState(&state)); } -void InspectorTimelineAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, Frame* frame) -{ - appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketReceiveHandshakeResponse, false, frame); -} - -void InspectorTimelineAgent::didDestroyWebSocket(unsigned long identifier, Frame* frame) -{ - appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketDestroy, true, frame); -} -#endif // ENABLE(WEB_SOCKETS) - -void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<InspectorObject> record, TimelineRecordType type) -{ - commitFrameRecord(); - innerAddRecordToTimeline(record, type); -} - -static Inspector::TypeBuilder::Timeline::EventType::Enum toProtocol(TimelineRecordType type) +static Inspector::Protocol::Timeline::EventType toProtocol(TimelineRecordType type) { switch (type) { case TimelineRecordType::EventDispatch: - return Inspector::TypeBuilder::Timeline::EventType::EventDispatch; - case TimelineRecordType::BeginFrame: - return Inspector::TypeBuilder::Timeline::EventType::BeginFrame; + return Inspector::Protocol::Timeline::EventType::EventDispatch; case TimelineRecordType::ScheduleStyleRecalculation: - return Inspector::TypeBuilder::Timeline::EventType::ScheduleStyleRecalculation; + return Inspector::Protocol::Timeline::EventType::ScheduleStyleRecalculation; case TimelineRecordType::RecalculateStyles: - return Inspector::TypeBuilder::Timeline::EventType::RecalculateStyles; + return Inspector::Protocol::Timeline::EventType::RecalculateStyles; case TimelineRecordType::InvalidateLayout: - return Inspector::TypeBuilder::Timeline::EventType::InvalidateLayout; + return Inspector::Protocol::Timeline::EventType::InvalidateLayout; case TimelineRecordType::Layout: - return Inspector::TypeBuilder::Timeline::EventType::Layout; + return Inspector::Protocol::Timeline::EventType::Layout; case TimelineRecordType::Paint: - return Inspector::TypeBuilder::Timeline::EventType::Paint; - case TimelineRecordType::ScrollLayer: - return Inspector::TypeBuilder::Timeline::EventType::ScrollLayer; - case TimelineRecordType::ResizeImage: - return Inspector::TypeBuilder::Timeline::EventType::ResizeImage; - case TimelineRecordType::CompositeLayers: - return Inspector::TypeBuilder::Timeline::EventType::CompositeLayers; - - case TimelineRecordType::ParseHTML: - return Inspector::TypeBuilder::Timeline::EventType::ParseHTML; + return Inspector::Protocol::Timeline::EventType::Paint; + case TimelineRecordType::Composite: + return Inspector::Protocol::Timeline::EventType::Composite; + case TimelineRecordType::RenderingFrame: + return Inspector::Protocol::Timeline::EventType::RenderingFrame; case TimelineRecordType::TimerInstall: - return Inspector::TypeBuilder::Timeline::EventType::TimerInstall; + return Inspector::Protocol::Timeline::EventType::TimerInstall; case TimelineRecordType::TimerRemove: - return Inspector::TypeBuilder::Timeline::EventType::TimerRemove; + return Inspector::Protocol::Timeline::EventType::TimerRemove; case TimelineRecordType::TimerFire: - return Inspector::TypeBuilder::Timeline::EventType::TimerFire; + return Inspector::Protocol::Timeline::EventType::TimerFire; case TimelineRecordType::EvaluateScript: - return Inspector::TypeBuilder::Timeline::EventType::EvaluateScript; - - case TimelineRecordType::MarkLoad: - return Inspector::TypeBuilder::Timeline::EventType::MarkLoad; - case TimelineRecordType::MarkDOMContent: - return Inspector::TypeBuilder::Timeline::EventType::MarkDOMContent; + return Inspector::Protocol::Timeline::EventType::EvaluateScript; case TimelineRecordType::TimeStamp: - return Inspector::TypeBuilder::Timeline::EventType::TimeStamp; + return Inspector::Protocol::Timeline::EventType::TimeStamp; case TimelineRecordType::Time: - return Inspector::TypeBuilder::Timeline::EventType::Time; + return Inspector::Protocol::Timeline::EventType::Time; case TimelineRecordType::TimeEnd: - return Inspector::TypeBuilder::Timeline::EventType::TimeEnd; - - case TimelineRecordType::ScheduleResourceRequest: - return Inspector::TypeBuilder::Timeline::EventType::ScheduleResourceRequest; - case TimelineRecordType::ResourceSendRequest: - return Inspector::TypeBuilder::Timeline::EventType::ResourceSendRequest; - case TimelineRecordType::ResourceReceiveResponse: - return Inspector::TypeBuilder::Timeline::EventType::ResourceReceiveResponse; - case TimelineRecordType::ResourceReceivedData: - return Inspector::TypeBuilder::Timeline::EventType::ResourceReceivedData; - case TimelineRecordType::ResourceFinish: - return Inspector::TypeBuilder::Timeline::EventType::ResourceFinish; - - case TimelineRecordType::XHRReadyStateChange: - return Inspector::TypeBuilder::Timeline::EventType::XHRReadyStateChange; - case TimelineRecordType::XHRLoad: - return Inspector::TypeBuilder::Timeline::EventType::XHRLoad; + return Inspector::Protocol::Timeline::EventType::TimeEnd; case TimelineRecordType::FunctionCall: - return Inspector::TypeBuilder::Timeline::EventType::FunctionCall; + return Inspector::Protocol::Timeline::EventType::FunctionCall; + case TimelineRecordType::ProbeSample: + return Inspector::Protocol::Timeline::EventType::ProbeSample; + case TimelineRecordType::ConsoleProfile: + return Inspector::Protocol::Timeline::EventType::ConsoleProfile; case TimelineRecordType::RequestAnimationFrame: - return Inspector::TypeBuilder::Timeline::EventType::RequestAnimationFrame; + return Inspector::Protocol::Timeline::EventType::RequestAnimationFrame; case TimelineRecordType::CancelAnimationFrame: - return Inspector::TypeBuilder::Timeline::EventType::CancelAnimationFrame; + return Inspector::Protocol::Timeline::EventType::CancelAnimationFrame; case TimelineRecordType::FireAnimationFrame: - return Inspector::TypeBuilder::Timeline::EventType::FireAnimationFrame; - - case TimelineRecordType::WebSocketCreate: - return Inspector::TypeBuilder::Timeline::EventType::WebSocketCreate; - case TimelineRecordType::WebSocketSendHandshakeRequest: - return Inspector::TypeBuilder::Timeline::EventType::WebSocketSendHandshakeRequest; - case TimelineRecordType::WebSocketReceiveHandshakeResponse: - return Inspector::TypeBuilder::Timeline::EventType::WebSocketReceiveHandshakeResponse; - case TimelineRecordType::WebSocketDestroy: - return Inspector::TypeBuilder::Timeline::EventType::WebSocketDestroy; + return Inspector::Protocol::Timeline::EventType::FireAnimationFrame; } - return Inspector::TypeBuilder::Timeline::EventType::TimeStamp; + return Inspector::Protocol::Timeline::EventType::TimeStamp; } -void InspectorTimelineAgent::innerAddRecordToTimeline(PassRefPtr<InspectorObject> prpRecord, TimelineRecordType type) +void InspectorTimelineAgent::addRecordToTimeline(RefPtr<InspectorObject>&& record, TimelineRecordType type) { - prpRecord->setString("type", Inspector::TypeBuilder::getWebEnumConstantValue(toProtocol(type))); + ASSERT_ARG(record, record); + record->setString("type", Inspector::Protocol::InspectorHelpers::getEnumConstantValue(toProtocol(type))); - RefPtr<Inspector::TypeBuilder::Timeline::TimelineEvent> record = Inspector::TypeBuilder::Timeline::TimelineEvent::runtimeCast(prpRecord); + if (m_recordStack.isEmpty()) { + auto recordObject = BindingTraits<Inspector::Protocol::Timeline::TimelineEvent>::runtimeCast(WTFMove(record)); + sendEvent(WTFMove(recordObject)); + } else { + const TimelineRecordEntry& parent = m_recordStack.last(); + // Nested paint records are an implementation detail and add no information not already contained in the parent. + if (type == TimelineRecordType::Paint && parent.type == type) + return; - setDOMCounters(record.get()); - - if (m_recordStack.isEmpty()) - sendEvent(record.release()); - else { - TimelineRecordEntry parent = m_recordStack.last(); - parent.children->pushObject(record.release()); - } -} - -static size_t usedHeapSize() -{ - return JSDOMWindow::commonVM()->heap.size(); -} - -void InspectorTimelineAgent::setDOMCounters(Inspector::TypeBuilder::Timeline::TimelineEvent* record) -{ - record->setUsedHeapSize(usedHeapSize()); - - if (m_includeDOMCounters) { - int documentCount = 0; - int nodeCount = 0; - if (m_inspectorType == PageInspector) { - documentCount = InspectorCounters::counterValue(InspectorCounters::DocumentCounter); - nodeCount = InspectorCounters::counterValue(InspectorCounters::NodeCounter); - } - int listenerCount = ThreadLocalInspectorCounters::current().counterValue(ThreadLocalInspectorCounters::JSEventListenerCounter); - RefPtr<Inspector::TypeBuilder::Timeline::DOMCounters> counters = Inspector::TypeBuilder::Timeline::DOMCounters::create() - .setDocuments(documentCount) - .setNodes(nodeCount) - .setJsEventListeners(listenerCount); - record->setCounters(counters.release()); + parent.children->pushObject(WTFMove(record)); } } @@ -563,6 +689,14 @@ void InspectorTimelineAgent::setFrameIdentifier(InspectorObject* record, Frame* record->setString("frameId", frameId); } +void InspectorTimelineAgent::didCompleteRecordEntry(const TimelineRecordEntry& entry) +{ + entry.record->setObject(ASCIILiteral("data"), entry.data); + entry.record->setArray(ASCIILiteral("children"), entry.children); + entry.record->setDouble(ASCIILiteral("endTime"), timestamp()); + addRecordToTimeline(entry.record.copyRef(), entry.type); +} + void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type) { // An empty stack could merely mean that the timeline agent was turned on in the middle of @@ -570,66 +704,45 @@ void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type) if (!m_recordStack.isEmpty()) { TimelineRecordEntry entry = m_recordStack.last(); m_recordStack.removeLast(); - ASSERT(entry.type == type); - entry.record->setObject("data", entry.data); - entry.record->setArray("children", entry.children); - entry.record->setNumber("endTime", timestamp()); - size_t usedHeapSizeDelta = usedHeapSize() - entry.usedHeapSizeAtStart; - if (usedHeapSizeDelta) - entry.record->setNumber("usedHeapSizeDelta", usedHeapSizeDelta); - addRecordToTimeline(entry.record, type); - } -} + ASSERT_UNUSED(type, entry.type == type); -InspectorTimelineAgent::InspectorTimelineAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorMemoryAgent* memoryAgent, InspectorType type, InspectorClient* client) - : InspectorAgentBase(ASCIILiteral("Timeline"), instrumentingAgents) - , m_pageAgent(pageAgent) - , m_memoryAgent(memoryAgent) - , m_id(1) - , m_maxCallStackDepth(5) - , m_inspectorType(type) - , m_client(client) - , m_weakFactory(this) - , m_enabled(false) - , m_includeDOMCounters(false) -{ + // Don't send RenderingFrame records that have no children to reduce noise. + if (entry.type == TimelineRecordType::RenderingFrame && !entry.children->length()) + return; + + didCompleteRecordEntry(entry); + } } -void InspectorTimelineAgent::appendRecord(PassRefPtr<InspectorObject> data, TimelineRecordType type, bool captureCallStack, Frame* frame) +void InspectorTimelineAgent::appendRecord(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame) { - RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0); - record->setObject("data", data); - setFrameIdentifier(record.get(), frame); - addRecordToTimeline(record.release(), type); + Ref<InspectorObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0); + record->setObject("data", WTFMove(data)); + setFrameIdentifier(&record.get(), frame); + addRecordToTimeline(WTFMove(record), type); } -void InspectorTimelineAgent::sendEvent(PassRefPtr<InspectorObject> event) +void InspectorTimelineAgent::sendEvent(RefPtr<InspectorObject>&& event) { // FIXME: runtimeCast is a hack. We do it because we can't build TimelineEvent directly now. - RefPtr<Inspector::TypeBuilder::Timeline::TimelineEvent> recordChecked = Inspector::TypeBuilder::Timeline::TimelineEvent::runtimeCast(event); - m_frontendDispatcher->eventRecorded(recordChecked.release()); + auto recordChecked = BindingTraits<Inspector::Protocol::Timeline::TimelineEvent>::runtimeCast(WTFMove(event)); + m_frontendDispatcher->eventRecorded(WTFMove(recordChecked)); } -void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<InspectorObject> data, TimelineRecordType type, bool captureCallStack, Frame* frame) +InspectorTimelineAgent::TimelineRecordEntry InspectorTimelineAgent::createRecordEntry(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame) { - commitFrameRecord(); - RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0); - setFrameIdentifier(record.get(), frame); - m_recordStack.append(TimelineRecordEntry(record.release(), data, InspectorArray::create(), type, usedHeapSize())); + Ref<InspectorObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0); + setFrameIdentifier(&record.get(), frame); + return TimelineRecordEntry(WTFMove(record), WTFMove(data), InspectorArray::create(), type); } -void InspectorTimelineAgent::commitFrameRecord() +void InspectorTimelineAgent::pushCurrentRecord(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame) { - if (!m_pendingFrameRecord) - return; - - m_pendingFrameRecord->setObject("data", InspectorObject::create()); - innerAddRecordToTimeline(m_pendingFrameRecord.release(), TimelineRecordType::BeginFrame); + pushCurrentRecord(createRecordEntry(WTFMove(data), type, captureCallStack, frame)); } void InspectorTimelineAgent::clearRecordStack() { - m_pendingFrameRecord.clear(); m_recordStack.clear(); m_id++; } @@ -644,16 +757,4 @@ void InspectorTimelineAgent::localToPageQuad(const RenderObject& renderer, const quad->setP4(frameView.contentsToRootView(roundedIntPoint(absolute.p4()))); } -double InspectorTimelineAgent::timestamp() -{ - return m_timeConverter.fromMonotonicallyIncreasingTime(monotonicallyIncreasingTime()); -} - -Page* InspectorTimelineAgent::page() -{ - return m_pageAgent ? m_pageAgent->page() : nullptr; -} - } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorTimelineAgent.h b/Source/WebCore/inspector/InspectorTimelineAgent.h index 4c5ed2558..bf5bbbb17 100644 --- a/Source/WebCore/inspector/InspectorTimelineAgent.h +++ b/Source/WebCore/inspector/InspectorTimelineAgent.h @@ -1,5 +1,7 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. +* Copyright (C) 2014 University of Washington. +* Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,51 +30,41 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorTimelineAgent_h -#define InspectorTimelineAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" #include "LayoutRect.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <inspector/InspectorValues.h> -#include <wtf/PassOwnPtr.h> +#include <inspector/ScriptDebugListener.h> #include <wtf/Vector.h> -#include <wtf/WeakPtr.h> + +namespace Inspector { +class InspectorHeapAgent; +class InspectorScriptProfilerAgent; +} namespace WebCore { class Event; class FloatQuad; class Frame; -class InspectorClient; -class InspectorMemoryAgent; class InspectorPageAgent; -class InstrumentingAgents; -class IntRect; -class URL; -class Page; class RenderObject; -class ResourceRequest; -class ResourceResponse; +class RunLoopObserver; typedef String ErrorString; enum class TimelineRecordType { EventDispatch, - BeginFrame, ScheduleStyleRecalculation, RecalculateStyles, InvalidateLayout, Layout, Paint, - ScrollLayer, - ResizeImage, - CompositeLayers, - - ParseHTML, + Composite, + RenderingFrame, TimerInstall, TimerRemove, @@ -80,197 +72,166 @@ enum class TimelineRecordType { EvaluateScript, - MarkLoad, - MarkDOMContent, - TimeStamp, Time, TimeEnd, - ScheduleResourceRequest, - ResourceSendRequest, - ResourceReceiveResponse, - ResourceReceivedData, - ResourceFinish, - - XHRReadyStateChange, - XHRLoad, - FunctionCall, + ProbeSample, + ConsoleProfile, RequestAnimationFrame, CancelAnimationFrame, FireAnimationFrame, - - WebSocketCreate, - WebSocketSendHandshakeRequest, - WebSocketReceiveHandshakeResponse, - WebSocketDestroy }; -class TimelineTimeConverter { -public: - TimelineTimeConverter() - : m_startOffset(0) - { - } - double fromMonotonicallyIncreasingTime(double time) const { return (time - m_startOffset) * 1000.0; } - void reset(); - -private: - double m_startOffset; -}; - -class InspectorTimelineAgent +class InspectorTimelineAgent final : public InspectorAgentBase - , public Inspector::InspectorTimelineBackendDispatcherHandler { + , public Inspector::TimelineBackendDispatcherHandler + , public Inspector::ScriptDebugListener { WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); + WTF_MAKE_FAST_ALLOCATED; public: - enum InspectorType { PageInspector, WorkerInspector }; - - InspectorTimelineAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorMemoryAgent*, InspectorType, InspectorClient*); - ~InspectorTimelineAgent(); + InspectorTimelineAgent(WebAgentContext&, Inspector::InspectorScriptProfilerAgent*, Inspector::InspectorHeapAgent*, InspectorPageAgent*); + virtual ~InspectorTimelineAgent(); - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) final; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) final; - virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* includeDomCounters) override; - virtual void stop(ErrorString*) override; - virtual void canMonitorMainThread(ErrorString*, bool*) override; - virtual void supportsFrameInstrumentation(ErrorString*, bool*) override; + void start(ErrorString&, const int* const maxCallStackDepth = nullptr) final; + void stop(ErrorString&) final; + void setAutoCaptureEnabled(ErrorString&, bool) final; + void setInstruments(ErrorString&, const Inspector::InspectorArray&) final; int id() const { return m_id; } void didCommitLoad(); // Methods called from WebCore. - void willCallFunction(const String& scriptName, int scriptLine, Frame*); - void didCallFunction(); + void startFromConsole(JSC::ExecState*, const String& title); + void stopFromConsole(JSC::ExecState*, const String& title); + // InspectorInstrumentation + void didInstallTimer(int timerId, std::chrono::milliseconds timeout, bool singleShot, Frame*); + void didRemoveTimer(int timerId, Frame*); + void willFireTimer(int timerId, Frame*); + void didFireTimer(); + void willCallFunction(const String& scriptName, int scriptLine, Frame*); + void didCallFunction(Frame*); void willDispatchEvent(const Event&, Frame*); void didDispatchEvent(); - - void didBeginFrame(); - void didCancelFrame(); - - void didInvalidateLayout(Frame*); - void willLayout(Frame*); - void didLayout(RenderObject*); - - void didScheduleStyleRecalculation(Frame*); + void willEvaluateScript(const String&, int, Frame&); + void didEvaluateScript(Frame&); + void didInvalidateLayout(Frame&); + void willLayout(Frame&); + void didLayout(RenderObject&); + void willComposite(Frame&); + void didComposite(); + void willPaint(Frame&); + void didPaint(RenderObject&, const LayoutRect&); void willRecalculateStyle(Frame*); void didRecalculateStyle(); - - void willPaint(Frame*); - void didPaint(RenderObject*, const LayoutRect&); - - void willScroll(Frame*); - void didScroll(); - - void willComposite(); - void didComposite(); - - void willWriteHTML(unsigned startLine, Frame*); - void didWriteHTML(unsigned endLine); - - void didInstallTimer(int timerId, int timeout, bool singleShot, Frame*); - void didRemoveTimer(int timerId, Frame*); - void willFireTimer(int timerId, Frame*); - void didFireTimer(); - - void willDispatchXHRReadyStateChangeEvent(const String&, int, Frame*); - void didDispatchXHRReadyStateChangeEvent(); - void willDispatchXHRLoadEvent(const String&, Frame*); - void didDispatchXHRLoadEvent(); - - void willEvaluateScript(const String&, int, Frame*); - void didEvaluateScript(); - - void didTimeStamp(Frame*, const String&); - void didMarkDOMContentEvent(Frame*); - void didMarkLoadEvent(Frame*); - - void time(Frame*, const String&); - void timeEnd(Frame*, const String&); - - void didScheduleResourceRequest(const String& url, Frame*); - void willSendResourceRequest(unsigned long, const ResourceRequest&, Frame*); - void willReceiveResourceResponse(unsigned long, const ResourceResponse&, Frame*); - void didReceiveResourceResponse(); - void didFinishLoadingResource(unsigned long, bool didFail, double finishTime, Frame*); - void willReceiveResourceData(unsigned long identifier, Frame*, int length); - void didReceiveResourceData(); - + void didScheduleStyleRecalculation(Frame*); + void didTimeStamp(Frame&, const String&); void didRequestAnimationFrame(int callbackId, Frame*); void didCancelAnimationFrame(int callbackId, Frame*); void willFireAnimationFrame(int callbackId, Frame*); void didFireAnimationFrame(); - -#if ENABLE(WEB_SOCKETS) - void didCreateWebSocket(unsigned long identifier, const URL&, const String& protocol, Frame*); - void willSendWebSocketHandshakeRequest(unsigned long identifier, Frame*); - void didReceiveWebSocketHandshakeResponse(unsigned long identifier, Frame*); - void didDestroyWebSocket(unsigned long identifier, Frame*); -#endif + void time(Frame&, const String&); + void timeEnd(Frame&, const String&); + void mainFrameStartedLoading(); + void mainFrameNavigated(); private: + // ScriptDebugListener + void didParseSource(JSC::SourceID, const Script&) final { } + void failedToParseSource(const String&, const String&, int, int, const String&) final { } + void didPause(JSC::ExecState&, JSC::JSValue, JSC::JSValue) final { } + void didContinue() final { } + + void breakpointActionLog(JSC::ExecState&, const String&) final { } + void breakpointActionSound(int) final { } + void breakpointActionProbe(JSC::ExecState&, const Inspector::ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, JSC::JSValue result) final; + + void startProgrammaticCapture(); + void stopProgrammaticCapture(); + + enum class InstrumentState { Start, Stop }; + void toggleInstruments(InstrumentState); + void toggleScriptProfilerInstrument(InstrumentState); + void toggleHeapInstrument(InstrumentState); + void toggleMemoryInstrument(InstrumentState); + void toggleTimelineInstrument(InstrumentState); + void disableBreakpoints(); + void enableBreakpoints(); + friend class TimelineRecordStack; struct TimelineRecordEntry { - TimelineRecordEntry(PassRefPtr<Inspector::InspectorObject> record, PassRefPtr<Inspector::InspectorObject> data, PassRefPtr<Inspector::InspectorArray> children, TimelineRecordType type, size_t usedHeapSizeAtStart) - : record(record), data(data), children(children), type(type), usedHeapSizeAtStart(usedHeapSizeAtStart) + TimelineRecordEntry() + : type(TimelineRecordType::EventDispatch) { } + TimelineRecordEntry(RefPtr<Inspector::InspectorObject>&& record, RefPtr<Inspector::InspectorObject>&& data, RefPtr<Inspector::InspectorArray>&& children, TimelineRecordType type) + : record(WTFMove(record)) + , data(WTFMove(data)) + , children(WTFMove(children)) + , type(type) { } + RefPtr<Inspector::InspectorObject> record; RefPtr<Inspector::InspectorObject> data; RefPtr<Inspector::InspectorArray> children; TimelineRecordType type; - size_t usedHeapSizeAtStart; }; - void sendEvent(PassRefPtr<Inspector::InspectorObject>); - void appendRecord(PassRefPtr<Inspector::InspectorObject> data, TimelineRecordType, bool captureCallStack, Frame*); - void pushCurrentRecord(PassRefPtr<Inspector::InspectorObject>, TimelineRecordType, bool captureCallStack, Frame*); + void internalStart(const int* maxCallStackDepth = nullptr); + void internalStop(); + double timestamp(); + + void sendEvent(RefPtr<Inspector::InspectorObject>&&); + void appendRecord(RefPtr<Inspector::InspectorObject>&& data, TimelineRecordType, bool captureCallStack, Frame*); + void pushCurrentRecord(RefPtr<Inspector::InspectorObject>&&, TimelineRecordType, bool captureCallStack, Frame*); + void pushCurrentRecord(const TimelineRecordEntry& record) { m_recordStack.append(record); } + + TimelineRecordEntry createRecordEntry(RefPtr<Inspector::InspectorObject>&& data, TimelineRecordType, bool captureCallStack, Frame*); - void setDOMCounters(Inspector::TypeBuilder::Timeline::TimelineEvent* record); void setFrameIdentifier(Inspector::InspectorObject* record, Frame*); + void didCompleteRecordEntry(const TimelineRecordEntry&); void didCompleteCurrentRecord(TimelineRecordType); - void setHeapSizeStatistics(Inspector::InspectorObject* record); - void commitFrameRecord(); - - void addRecordToTimeline(PassRefPtr<Inspector::InspectorObject>, TimelineRecordType); - void innerAddRecordToTimeline(PassRefPtr<Inspector::InspectorObject>, TimelineRecordType); + void addRecordToTimeline(RefPtr<Inspector::InspectorObject>&&, TimelineRecordType); void clearRecordStack(); void localToPageQuad(const RenderObject&, const LayoutRect&, FloatQuad*); - const TimelineTimeConverter& timeConverter() const { return m_timeConverter; } - double timestamp(); - Page* page(); + std::unique_ptr<Inspector::TimelineFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::TimelineBackendDispatcher> m_backendDispatcher; + Inspector::InspectorScriptProfilerAgent* m_scriptProfilerAgent; + Inspector::InspectorHeapAgent* m_heapAgent; InspectorPageAgent* m_pageAgent; - InspectorMemoryAgent* m_memoryAgent; - TimelineTimeConverter m_timeConverter; - - std::unique_ptr<Inspector::InspectorTimelineFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorTimelineBackendDispatcher> m_backendDispatcher; - double m_timestampOffset; Vector<TimelineRecordEntry> m_recordStack; + Vector<TimelineRecordEntry> m_pendingConsoleProfileRecords; + + int m_id { 1 }; + int m_maxCallStackDepth { 5 }; - int m_id; - int m_maxCallStackDepth; - RefPtr<Inspector::InspectorObject> m_pendingFrameRecord; - InspectorType m_inspectorType; - InspectorClient* m_client; - WeakPtrFactory<InspectorTimelineAgent> m_weakFactory; + bool m_enabled { false }; + bool m_enabledFromFrontend { false }; + bool m_programmaticCaptureRestoreBreakpointActiveValue { false }; - bool m_enabled; - bool m_includeDOMCounters; + bool m_autoCaptureEnabled { false }; + enum class AutoCapturePhase { None, BeforeLoad, FirstNavigation, AfterFirstNavigation }; + AutoCapturePhase m_autoCapturePhase { AutoCapturePhase::None }; + Vector<Inspector::Protocol::Timeline::Instrument> m_instruments; + +#if PLATFORM(COCOA) + std::unique_ptr<WebCore::RunLoopObserver> m_frameStartObserver; + std::unique_ptr<WebCore::RunLoopObserver> m_frameStopObserver; +#endif + int m_runLoopNestingLevel { 0 }; + bool m_startedComposite { false }; }; } // namespace WebCore - -#endif // !ENABLE(INSPECTOR) -#endif // !defined(InspectorTimelineAgent_h) diff --git a/Source/WebCore/inspector/InspectorWebAgentBase.h b/Source/WebCore/inspector/InspectorWebAgentBase.h index dfcc4a845..b8d1d38d6 100644 --- a/Source/WebCore/inspector/InspectorWebAgentBase.h +++ b/Source/WebCore/inspector/InspectorWebAgentBase.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All Rights Reserved. + * Copyright (C) 2013, 2015 Apple Inc. All Rights Reserved. * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,28 +24,59 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorWebAgentBase_h -#define InspectorWebAgentBase_h +#pragma once -#include "InspectorForwarding.h" #include <inspector/InspectorAgentBase.h> #include <wtf/text/WTFString.h> namespace WebCore { class InstrumentingAgents; +class Page; +class WorkerGlobalScope; + +// FIXME: move this to Inspector namespace when remaining agents move. +struct WebAgentContext : public Inspector::AgentContext { + WebAgentContext(AgentContext& context, InstrumentingAgents& instrumentingAgents) + : AgentContext(context) + , instrumentingAgents(instrumentingAgents) + { + } + + InstrumentingAgents& instrumentingAgents; +}; + +struct PageAgentContext : public WebAgentContext { + PageAgentContext(WebAgentContext& context, Page& inspectedPage) + : WebAgentContext(context) + , inspectedPage(inspectedPage) + { + } + + Page& inspectedPage; +}; + +struct WorkerAgentContext : public WebAgentContext { + WorkerAgentContext(WebAgentContext& context, WorkerGlobalScope& workerGlobalScope) + : WebAgentContext(context) + , workerGlobalScope(workerGlobalScope) + { + } + + WorkerGlobalScope& workerGlobalScope; +}; class InspectorAgentBase : public Inspector::InspectorAgentBase { protected: - InspectorAgentBase(const String& name, InstrumentingAgents* instrumentingAgents) + InspectorAgentBase(const String& name, WebAgentContext& context) : Inspector::InspectorAgentBase(name) - , m_instrumentingAgents(instrumentingAgents) + , m_instrumentingAgents(context.instrumentingAgents) + , m_environment(context.environment) { } - InstrumentingAgents* m_instrumentingAgents; + InstrumentingAgents& m_instrumentingAgents; + Inspector::InspectorEnvironment& m_environment; }; } // namespace WebCore - -#endif // !defined(InspectorWebAgentBase_h) diff --git a/Source/WebCore/inspector/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/InspectorWorkerAgent.cpp index b8108b54f..13222c785 100644 --- a/Source/WebCore/inspector/InspectorWorkerAgent.cpp +++ b/Source/WebCore/inspector/InspectorWorkerAgent.cpp @@ -1,242 +1,174 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorWorkerAgent.h" -#include "InspectorForwarding.h" -#include "InspectorWebFrontendDispatchers.h" +#include "Document.h" #include "InstrumentingAgents.h" -#include "URL.h" -#include "WorkerGlobalScopeProxy.h" -#include <inspector/InspectorValues.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/RefPtr.h> using namespace Inspector; namespace WebCore { -class InspectorWorkerAgent::WorkerFrontendChannel : public WorkerGlobalScopeProxy::PageInspector { - WTF_MAKE_FAST_ALLOCATED; -public: - explicit WorkerFrontendChannel(InspectorWorkerFrontendDispatcher* frontendDispatcher, WorkerGlobalScopeProxy* proxy) - : m_frontendDispatcher(frontendDispatcher) - , m_proxy(proxy) - , m_id(s_nextId++) - , m_connected(false) - { - } - virtual ~WorkerFrontendChannel() - { - disconnectFromWorkerGlobalScope(); - } - - int id() const { return m_id; } - WorkerGlobalScopeProxy* proxy() const { return m_proxy; } - - void connectToWorkerGlobalScope() - { - if (m_connected) - return; - m_connected = true; - m_proxy->connectToInspector(this); - } - - void disconnectFromWorkerGlobalScope() - { - if (!m_connected) - return; - m_connected = false; - m_proxy->disconnectFromInspector(); - } - -private: - // WorkerGlobalScopeProxy::PageInspector implementation - virtual void dispatchMessageFromWorker(const String& message) override - { - RefPtr<InspectorValue> value = InspectorValue::parseJSON(message); - if (!value) - return; - RefPtr<InspectorObject> messageObject = value->asObject(); - if (!messageObject) - return; - m_frontendDispatcher->dispatchMessageFromWorker(m_id, messageObject); - } - - InspectorWorkerFrontendDispatcher* m_frontendDispatcher; - WorkerGlobalScopeProxy* m_proxy; - int m_id; - bool m_connected; - static int s_nextId; -}; - -int InspectorWorkerAgent::WorkerFrontendChannel::s_nextId = 1; - -InspectorWorkerAgent::InspectorWorkerAgent(InstrumentingAgents* instrumentingAgents) - : InspectorAgentBase(ASCIILiteral("Worker"), instrumentingAgents) - , m_enabled(false) - , m_shouldPauseDedicatedWorkerOnStart(false) +InspectorWorkerAgent::InspectorWorkerAgent(PageAgentContext& context) + : InspectorAgentBase(ASCIILiteral("Worker"), context) + , m_frontendDispatcher(std::make_unique<Inspector::WorkerFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::WorkerBackendDispatcher::create(context.backendDispatcher, this)) + , m_page(context.inspectedPage) { - m_instrumentingAgents->setInspectorWorkerAgent(this); } -InspectorWorkerAgent::~InspectorWorkerAgent() +void InspectorWorkerAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) { - m_instrumentingAgents->setInspectorWorkerAgent(nullptr); + m_instrumentingAgents.setInspectorWorkerAgent(this); } -void InspectorWorkerAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorWorkerAgent::willDestroyFrontendAndBackend(DisconnectReason) { - m_frontendDispatcher = std::make_unique<InspectorWorkerFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorWorkerBackendDispatcher::create(backendDispatcher, this); + m_instrumentingAgents.setInspectorWorkerAgent(nullptr); + + ErrorString ignored; + disable(ignored); } -void InspectorWorkerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorWorkerAgent::enable(ErrorString&) { - m_shouldPauseDedicatedWorkerOnStart = false; - disable(nullptr); + if (m_enabled) + return; - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); + m_enabled = true; + + connectToAllWorkerInspectorProxiesForPage(); } -void InspectorWorkerAgent::enable(ErrorString*) +void InspectorWorkerAgent::disable(ErrorString&) { - m_enabled = true; - if (!m_frontendDispatcher) + if (!m_enabled) return; - createWorkerFrontendChannelsForExistingWorkers(); + m_enabled = false; + + disconnectFromAllWorkerInspectorProxies(); } -void InspectorWorkerAgent::disable(ErrorString*) +void InspectorWorkerAgent::initialized(ErrorString& errorString, const String& workerId) { - m_enabled = false; - if (!m_frontendDispatcher) + WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId); + if (!proxy) { + errorString = ASCIILiteral("Worker not found."); return; + } - destroyWorkerFrontendChannels(); + proxy->resumeWorkerIfPaused(); } -void InspectorWorkerAgent::canInspectWorkers(ErrorString*, bool* result) +void InspectorWorkerAgent::sendMessageToWorker(ErrorString& errorString, const String& workerId, const String& message) { - *result = true; -} + if (!m_enabled) { + errorString = ASCIILiteral("Worker inspection must be enabled."); + return; + } -void InspectorWorkerAgent::connectToWorker(ErrorString* error, int workerId) -{ - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->connectToWorkerGlobalScope(); - else - *error = "Worker is gone"; -} + WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId); + if (!proxy) { + errorString = ASCIILiteral("Worker not found."); + return; + } -void InspectorWorkerAgent::disconnectFromWorker(ErrorString* error, int workerId) -{ - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->disconnectFromWorkerGlobalScope(); - else - *error = "Worker is gone"; + proxy->sendMessageToWorkerInspectorController(message); } -void InspectorWorkerAgent::sendMessageToWorker(ErrorString* error, int workerId, const RefPtr<InspectorObject>& message) +void InspectorWorkerAgent::sendMessageFromWorkerToFrontend(WorkerInspectorProxy* proxy, const String& message) { - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->proxy()->sendMessageToInspector(message->toJSONString()); - else - *error = "Worker is gone"; + m_frontendDispatcher->dispatchMessageFromWorker(proxy->identifier(), message); } -void InspectorWorkerAgent::setAutoconnectToWorkers(ErrorString*, bool value) +bool InspectorWorkerAgent::shouldWaitForDebuggerOnStart() const { - m_shouldPauseDedicatedWorkerOnStart = value; + return m_enabled; } -bool InspectorWorkerAgent::shouldPauseDedicatedWorkerOnStart() const +void InspectorWorkerAgent::workerStarted(WorkerInspectorProxy* proxy, const URL&) { - return m_shouldPauseDedicatedWorkerOnStart; + if (!m_enabled) + return; + + connectToWorkerInspectorProxy(proxy); } -void InspectorWorkerAgent::didStartWorkerGlobalScope(WorkerGlobalScopeProxy* workerGlobalScopeProxy, const URL& url) +void InspectorWorkerAgent::workerTerminated(WorkerInspectorProxy* proxy) { - m_dedicatedWorkers.set(workerGlobalScopeProxy, url.string()); - if (m_frontendDispatcher && m_enabled) - createWorkerFrontendChannel(workerGlobalScopeProxy, url.string()); + if (!m_enabled) + return; + + disconnectFromWorkerInspectorProxy(proxy); } -void InspectorWorkerAgent::workerGlobalScopeTerminated(WorkerGlobalScopeProxy* proxy) +void InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage() { - m_dedicatedWorkers.remove(proxy); - for (WorkerChannels::iterator it = m_idToChannel.begin(); it != m_idToChannel.end(); ++it) { - if (proxy == it->value->proxy()) { - m_frontendDispatcher->workerTerminated(it->key); - delete it->value; - m_idToChannel.remove(it); - return; - } + ASSERT(m_connectedProxies.isEmpty()); + + for (auto* proxy : WorkerInspectorProxy::allWorkerInspectorProxies()) { + if (!is<Document>(proxy->scriptExecutionContext())) + continue; + + Document& document = downcast<Document>(*proxy->scriptExecutionContext()); + if (document.page() != &m_page) + continue; + + connectToWorkerInspectorProxy(proxy); } } -void InspectorWorkerAgent::createWorkerFrontendChannelsForExistingWorkers() +void InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies() { - for (DedicatedWorkers::iterator it = m_dedicatedWorkers.begin(); it != m_dedicatedWorkers.end(); ++it) - createWorkerFrontendChannel(it->key, it->value); + Vector<WorkerInspectorProxy*> proxies; + copyValuesToVector(m_connectedProxies, proxies); + for (auto* proxy : proxies) + proxy->disconnectFromWorkerInspectorController(); + + m_connectedProxies.clear(); } -void InspectorWorkerAgent::destroyWorkerFrontendChannels() +void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy* proxy) { - for (WorkerChannels::iterator it = m_idToChannel.begin(); it != m_idToChannel.end(); ++it) { - it->value->disconnectFromWorkerGlobalScope(); - delete it->value; - } - m_idToChannel.clear(); + proxy->connectToWorkerInspectorController(this); + + m_connectedProxies.set(proxy->identifier(), proxy); + + m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url()); } -void InspectorWorkerAgent::createWorkerFrontendChannel(WorkerGlobalScopeProxy* workerGlobalScopeProxy, const String& url) +void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy* proxy) { - WorkerFrontendChannel* channel = new WorkerFrontendChannel(m_frontendDispatcher.get(), workerGlobalScopeProxy); - m_idToChannel.set(channel->id(), channel); + m_frontendDispatcher->workerTerminated(proxy->identifier()); - ASSERT(m_frontendDispatcher); - if (m_shouldPauseDedicatedWorkerOnStart) - channel->connectToWorkerGlobalScope(); - m_frontendDispatcher->workerCreated(channel->id(), url, m_shouldPauseDedicatedWorkerOnStart); -} + m_connectedProxies.remove(proxy->identifier()); -} // namespace WebCore + proxy->disconnectFromWorkerInspectorController(); +} -#endif // ENABLE(INSPECTOR) +} // namespace Inspector diff --git a/Source/WebCore/inspector/InspectorWorkerAgent.h b/Source/WebCore/inspector/InspectorWorkerAgent.h index 753c98381..400bb599c 100644 --- a/Source/WebCore/inspector/InspectorWorkerAgent.h +++ b/Source/WebCore/inspector/InspectorWorkerAgent.h @@ -1,92 +1,79 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InspectorWorkerAgent_h -#define InspectorWorkerAgent_h +#pragma once #include "InspectorWebAgentBase.h" -#include "InspectorWebBackendDispatchers.h" -#include <wtf/Forward.h> +#include "WorkerInspectorProxy.h" +#include <inspector/InspectorBackendDispatchers.h> +#include <inspector/InspectorFrontendDispatchers.h> #include <wtf/HashMap.h> -namespace Inspector { -class InspectorObject; -class InspectorWorkerFrontendDispatcher; -} - namespace WebCore { -class InstrumentingAgents; + +class Page; class URL; -class WorkerGlobalScopeProxy; typedef String ErrorString; -class InspectorWorkerAgent : public InspectorAgentBase, public Inspector::InspectorWorkerBackendDispatcherHandler { +class InspectorWorkerAgent final : public InspectorAgentBase, public Inspector::WorkerBackendDispatcherHandler, public WorkerInspectorProxy::PageChannel { + WTF_MAKE_NONCOPYABLE(InspectorWorkerAgent); + WTF_MAKE_FAST_ALLOCATED; public: - explicit InspectorWorkerAgent(InstrumentingAgents*); - ~InspectorWorkerAgent(); + InspectorWorkerAgent(PageAgentContext&); + virtual ~InspectorWorkerAgent() { } - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; - // Called from InspectorInstrumentation - bool shouldPauseDedicatedWorkerOnStart() const; - void didStartWorkerGlobalScope(WorkerGlobalScopeProxy*, const URL&); - void workerGlobalScopeTerminated(WorkerGlobalScopeProxy*); + // WorkerBackendDispatcherHandler + void enable(ErrorString&) override; + void disable(ErrorString&) override; + void initialized(ErrorString&, const String& workerId) override; + void sendMessageToWorker(ErrorString&, const String& workerId, const String& message) override; - // Called from InspectorBackendDispatcher - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - virtual void canInspectWorkers(ErrorString*, bool*) override; - virtual void connectToWorker(ErrorString*, int workerId) override; - virtual void disconnectFromWorker(ErrorString*, int workerId) override; - virtual void sendMessageToWorker(ErrorString*, int workerId, const RefPtr<Inspector::InspectorObject>& message) override; - virtual void setAutoconnectToWorkers(ErrorString*, bool value) override; + // PageChannel + void sendMessageFromWorkerToFrontend(WorkerInspectorProxy*, const String& message) override; + + // InspectorInstrumentation + bool shouldWaitForDebuggerOnStart() const; + void workerStarted(WorkerInspectorProxy*, const URL&); + void workerTerminated(WorkerInspectorProxy*); private: - void createWorkerFrontendChannelsForExistingWorkers(); - void createWorkerFrontendChannel(WorkerGlobalScopeProxy*, const String& url); - void destroyWorkerFrontendChannels(); + void connectToAllWorkerInspectorProxiesForPage(); + void disconnectFromAllWorkerInspectorProxies(); + void connectToWorkerInspectorProxy(WorkerInspectorProxy*); + void disconnectFromWorkerInspectorProxy(WorkerInspectorProxy*); - std::unique_ptr<Inspector::InspectorWorkerFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorWorkerBackendDispatcher> m_backendDispatcher; - bool m_enabled; - bool m_shouldPauseDedicatedWorkerOnStart; + std::unique_ptr<Inspector::WorkerFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::WorkerBackendDispatcher> m_backendDispatcher; - class WorkerFrontendChannel; - typedef HashMap<int, WorkerFrontendChannel*> WorkerChannels; - WorkerChannels m_idToChannel; - typedef HashMap<WorkerGlobalScopeProxy*, String> DedicatedWorkers; - DedicatedWorkers m_dedicatedWorkers; + Page& m_page; + HashMap<String, WorkerInspectorProxy*> m_connectedProxies; + bool m_enabled { false }; }; } // namespace WebCore - -#endif // !defined(InspectorWorkerAgent_h) diff --git a/Source/WebCore/inspector/InspectorWorkerResource.h b/Source/WebCore/inspector/InspectorWorkerResource.h deleted file mode 100644 index bf116b3a0..000000000 --- a/Source/WebCore/inspector/InspectorWorkerResource.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorWorkerResource_h -#define InspectorWorkerResource_h - -#if ENABLE(INSPECTOR) - -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { - -class InspectorWorkerResource : public RefCounted<InspectorWorkerResource> { -public: - static PassRefPtr<InspectorWorkerResource> create(intptr_t id, const String& url, bool isSharedWorker) - { - return adoptRef(new InspectorWorkerResource(id, url, isSharedWorker)); - } - - intptr_t id() const { return m_id; } - const String& url() const { return m_url; } - bool isSharedWorker() const { return m_isSharedWorker; } -private: - InspectorWorkerResource(intptr_t id, const String& url, bool isSharedWorker) - : m_id(id) - , m_url(url) - , m_isSharedWorker(isSharedWorker) - { - } - - intptr_t m_id; - String m_url; - bool m_isSharedWorker; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // InspectorWorkerResource_h diff --git a/Source/WebCore/inspector/InstrumentingAgents.cpp b/Source/WebCore/inspector/InstrumentingAgents.cpp index 15643931b..7118ea88b 100644 --- a/Source/WebCore/inspector/InstrumentingAgents.cpp +++ b/Source/WebCore/inspector/InstrumentingAgents.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,43 +32,12 @@ #include "config.h" #include "InstrumentingAgents.h" -#if ENABLE(INSPECTOR) - -#include "InspectorController.h" -#include "Page.h" -#include "WorkerGlobalScope.h" -#include "WorkerInspectorController.h" -#include <wtf/MainThread.h> - using namespace Inspector; namespace WebCore { InstrumentingAgents::InstrumentingAgents(InspectorEnvironment& environment) : m_environment(environment) - , m_inspectorAgent(nullptr) - , m_inspectorPageAgent(nullptr) - , m_inspectorCSSAgent(nullptr) -#if USE(ACCELERATED_COMPOSITING) - , m_inspectorLayerTreeAgent(nullptr) -#endif - , m_inspectorConsoleAgent(nullptr) - , m_inspectorDOMAgent(nullptr) - , m_inspectorResourceAgent(nullptr) - , m_pageRuntimeAgent(nullptr) - , m_workerRuntimeAgent(nullptr) - , m_inspectorTimelineAgent(nullptr) - , m_inspectorDOMStorageAgent(nullptr) -#if ENABLE(SQL_DATABASE) - , m_inspectorDatabaseAgent(nullptr) -#endif - , m_inspectorApplicationCacheAgent(nullptr) - , m_inspectorDebuggerAgent(nullptr) - , m_pageDebuggerAgent(nullptr) - , m_inspectorDOMDebuggerAgent(nullptr) - , m_inspectorProfilerAgent(nullptr) - , m_inspectorWorkerAgent(nullptr) - , m_inspectorCanvasAgent(nullptr) { } @@ -76,39 +46,27 @@ void InstrumentingAgents::reset() m_inspectorAgent = nullptr; m_inspectorPageAgent = nullptr; m_inspectorCSSAgent = nullptr; -#if USE(ACCELERATED_COMPOSITING) m_inspectorLayerTreeAgent = nullptr; -#endif - m_inspectorConsoleAgent = nullptr; + m_inspectorWorkerAgent = nullptr; + m_webConsoleAgent = nullptr; m_inspectorDOMAgent = nullptr; - m_inspectorResourceAgent = nullptr; + m_inspectorNetworkAgent = nullptr; m_pageRuntimeAgent = nullptr; - m_workerRuntimeAgent = nullptr; m_inspectorTimelineAgent = nullptr; + m_persistentInspectorTimelineAgent = nullptr; m_inspectorDOMStorageAgent = nullptr; -#if ENABLE(SQL_DATABASE) - m_inspectorDatabaseAgent = nullptr; +#if ENABLE(WEB_REPLAY) + m_inspectorReplayAgent = nullptr; #endif +#if ENABLE(RESOURCE_USAGE) + m_inspectorMemoryAgent = nullptr; +#endif + m_inspectorDatabaseAgent = nullptr; m_inspectorApplicationCacheAgent = nullptr; m_inspectorDebuggerAgent = nullptr; m_pageDebuggerAgent = nullptr; + m_pageHeapAgent = nullptr; m_inspectorDOMDebuggerAgent = nullptr; - m_inspectorProfilerAgent = nullptr; - m_inspectorWorkerAgent = nullptr; - m_inspectorCanvasAgent = nullptr; -} - -InstrumentingAgents* instrumentationForPage(Page* page) -{ - ASSERT(isMainThread()); - return page ? page->inspectorController().m_instrumentingAgents.get() : nullptr; -} - -InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope) -{ - return workerGlobalScope ? workerGlobalScope->workerInspectorController().m_instrumentingAgents.get() : nullptr; } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InstrumentingAgents.h b/Source/WebCore/inspector/InstrumentingAgents.h index d9b5d41dc..64e8138a1 100644 --- a/Source/WebCore/inspector/InstrumentingAgents.h +++ b/Source/WebCore/inspector/InstrumentingAgents.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,13 +29,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InstrumentingAgents_h -#define InstrumentingAgents_h +#pragma once #include <inspector/InspectorEnvironment.h> #include <wtf/FastMalloc.h> #include <wtf/Noncopyable.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace Inspector { @@ -46,32 +45,32 @@ namespace WebCore { class InspectorApplicationCacheAgent; class InspectorCSSAgent; -class InspectorCanvasAgent; -class InspectorConsoleAgent; class InspectorDOMAgent; class InspectorDOMDebuggerAgent; class InspectorDOMStorageAgent; class InspectorDatabaseAgent; -class InspectorHeapProfilerAgent; class InspectorLayerTreeAgent; +class InspectorWorkerAgent; +class InspectorMemoryAgent; +class InspectorNetworkAgent; class InspectorPageAgent; -class InspectorProfilerAgent; -class InspectorResourceAgent; +class InspectorReplayAgent; class InspectorTimelineAgent; -class InspectorWorkerAgent; class Page; class PageDebuggerAgent; +class PageHeapAgent; class PageRuntimeAgent; -class WorkerGlobalScope; -class WorkerRuntimeAgent; +class WebConsoleAgent; class InstrumentingAgents : public RefCounted<InstrumentingAgents> { WTF_MAKE_NONCOPYABLE(InstrumentingAgents); WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<InstrumentingAgents> create(Inspector::InspectorEnvironment& environment) + // FIXME: InstrumentingAgents could be uniquely owned by InspectorController if instrumentation + // cookies kept only a weak reference to InstrumentingAgents. Then, reset() would be unnecessary. + static Ref<InstrumentingAgents> create(Inspector::InspectorEnvironment& environment) { - return adoptRef(new InstrumentingAgents(environment)); + return adoptRef(*new InstrumentingAgents(environment)); } ~InstrumentingAgents() { } void reset(); @@ -87,31 +86,39 @@ public: InspectorCSSAgent* inspectorCSSAgent() const { return m_inspectorCSSAgent; } void setInspectorCSSAgent(InspectorCSSAgent* agent) { m_inspectorCSSAgent = agent; } - InspectorConsoleAgent* inspectorConsoleAgent() const { return m_inspectorConsoleAgent; } - void setInspectorConsoleAgent(InspectorConsoleAgent* agent) { m_inspectorConsoleAgent = agent; } + WebConsoleAgent* webConsoleAgent() const { return m_webConsoleAgent; } + void setWebConsoleAgent(WebConsoleAgent* agent) { m_webConsoleAgent = agent; } InspectorDOMAgent* inspectorDOMAgent() const { return m_inspectorDOMAgent; } void setInspectorDOMAgent(InspectorDOMAgent* agent) { m_inspectorDOMAgent = agent; } - InspectorResourceAgent* inspectorResourceAgent() const { return m_inspectorResourceAgent; } - void setInspectorResourceAgent(InspectorResourceAgent* agent) { m_inspectorResourceAgent = agent; } + InspectorNetworkAgent* inspectorNetworkAgent() const { return m_inspectorNetworkAgent; } + void setInspectorNetworkAgent(InspectorNetworkAgent* agent) { m_inspectorNetworkAgent = agent; } PageRuntimeAgent* pageRuntimeAgent() const { return m_pageRuntimeAgent; } void setPageRuntimeAgent(PageRuntimeAgent* agent) { m_pageRuntimeAgent = agent; } - WorkerRuntimeAgent* workerRuntimeAgent() const { return m_workerRuntimeAgent; } - void setWorkerRuntimeAgent(WorkerRuntimeAgent* agent) { m_workerRuntimeAgent = agent; } - InspectorTimelineAgent* inspectorTimelineAgent() const { return m_inspectorTimelineAgent; } void setInspectorTimelineAgent(InspectorTimelineAgent* agent) { m_inspectorTimelineAgent = agent; } + InspectorTimelineAgent* persistentInspectorTimelineAgent() const { return m_persistentInspectorTimelineAgent; } + void setPersistentInspectorTimelineAgent(InspectorTimelineAgent* agent) { m_persistentInspectorTimelineAgent = agent; } + InspectorDOMStorageAgent* inspectorDOMStorageAgent() const { return m_inspectorDOMStorageAgent; } void setInspectorDOMStorageAgent(InspectorDOMStorageAgent* agent) { m_inspectorDOMStorageAgent = agent; } -#if ENABLE(SQL_DATABASE) +#if ENABLE(WEB_REPLAY) + InspectorReplayAgent* inspectorReplayAgent() const { return m_inspectorReplayAgent; } + void setInspectorReplayAgent(InspectorReplayAgent* agent) { m_inspectorReplayAgent = agent; } +#endif + +#if ENABLE(RESOURCE_USAGE) + InspectorMemoryAgent* inspectorMemoryAgent() const { return m_inspectorMemoryAgent; } + void setInspectorMemoryAgent(InspectorMemoryAgent* agent) { m_inspectorMemoryAgent = agent; } +#endif + InspectorDatabaseAgent* inspectorDatabaseAgent() const { return m_inspectorDatabaseAgent; } void setInspectorDatabaseAgent(InspectorDatabaseAgent* agent) { m_inspectorDatabaseAgent = agent; } -#endif InspectorApplicationCacheAgent* inspectorApplicationCacheAgent() const { return m_inspectorApplicationCacheAgent; } void setInspectorApplicationCacheAgent(InspectorApplicationCacheAgent* agent) { m_inspectorApplicationCacheAgent = agent; } @@ -122,60 +129,47 @@ public: PageDebuggerAgent* pageDebuggerAgent() const { return m_pageDebuggerAgent; } void setPageDebuggerAgent(PageDebuggerAgent* agent) { m_pageDebuggerAgent = agent; } + PageHeapAgent* pageHeapAgent() const { return m_pageHeapAgent; } + void setPageHeapAgent(PageHeapAgent* agent) { m_pageHeapAgent = agent; } + InspectorDOMDebuggerAgent* inspectorDOMDebuggerAgent() const { return m_inspectorDOMDebuggerAgent; } void setInspectorDOMDebuggerAgent(InspectorDOMDebuggerAgent* agent) { m_inspectorDOMDebuggerAgent = agent; } - InspectorProfilerAgent* inspectorProfilerAgent() const { return m_inspectorProfilerAgent; } - void setInspectorProfilerAgent(InspectorProfilerAgent* agent) { m_inspectorProfilerAgent = agent; } - - InspectorHeapProfilerAgent* inspectorHeapProfilerAgent() const { return m_inspectorHeapProfilerAgent; } - void setInspectorHeapProfilerAgent(InspectorHeapProfilerAgent* agent) { m_inspectorHeapProfilerAgent = agent; } + InspectorLayerTreeAgent* inspectorLayerTreeAgent() const { return m_inspectorLayerTreeAgent; } + void setInspectorLayerTreeAgent(InspectorLayerTreeAgent* agent) { m_inspectorLayerTreeAgent = agent; } InspectorWorkerAgent* inspectorWorkerAgent() const { return m_inspectorWorkerAgent; } void setInspectorWorkerAgent(InspectorWorkerAgent* agent) { m_inspectorWorkerAgent = agent; } - InspectorCanvasAgent* inspectorCanvasAgent() const { return m_inspectorCanvasAgent; } - void setInspectorCanvasAgent(InspectorCanvasAgent* agent) { m_inspectorCanvasAgent = agent; } - -#if USE(ACCELERATED_COMPOSITING) - InspectorLayerTreeAgent* inspectorLayerTreeAgent() const { return m_inspectorLayerTreeAgent; } - void setInspectorLayerTreeAgent(InspectorLayerTreeAgent* agent) { m_inspectorLayerTreeAgent = agent; } -#endif - private: InstrumentingAgents(Inspector::InspectorEnvironment&); Inspector::InspectorEnvironment& m_environment; - Inspector::InspectorAgent* m_inspectorAgent; - InspectorPageAgent* m_inspectorPageAgent; - InspectorCSSAgent* m_inspectorCSSAgent; -#if USE(ACCELERATED_COMPOSITING) - InspectorLayerTreeAgent* m_inspectorLayerTreeAgent; + Inspector::InspectorAgent* m_inspectorAgent { nullptr }; + InspectorPageAgent* m_inspectorPageAgent { nullptr }; + InspectorCSSAgent* m_inspectorCSSAgent { nullptr }; + InspectorLayerTreeAgent* m_inspectorLayerTreeAgent { nullptr }; + InspectorWorkerAgent* m_inspectorWorkerAgent { nullptr }; + WebConsoleAgent* m_webConsoleAgent { nullptr }; + InspectorDOMAgent* m_inspectorDOMAgent { nullptr }; + InspectorNetworkAgent* m_inspectorNetworkAgent { nullptr }; + PageRuntimeAgent* m_pageRuntimeAgent { nullptr }; + InspectorTimelineAgent* m_inspectorTimelineAgent { nullptr }; + InspectorTimelineAgent* m_persistentInspectorTimelineAgent { nullptr }; + InspectorDOMStorageAgent* m_inspectorDOMStorageAgent { nullptr }; +#if ENABLE(WEB_REPLAY) + InspectorReplayAgent* m_inspectorReplayAgent { nullptr }; #endif - InspectorConsoleAgent* m_inspectorConsoleAgent; - InspectorDOMAgent* m_inspectorDOMAgent; - InspectorResourceAgent* m_inspectorResourceAgent; - PageRuntimeAgent* m_pageRuntimeAgent; - WorkerRuntimeAgent* m_workerRuntimeAgent; - InspectorTimelineAgent* m_inspectorTimelineAgent; - InspectorDOMStorageAgent* m_inspectorDOMStorageAgent; -#if ENABLE(SQL_DATABASE) - InspectorDatabaseAgent* m_inspectorDatabaseAgent; +#if ENABLE(RESOURCE_USAGE) + InspectorMemoryAgent* m_inspectorMemoryAgent { nullptr }; #endif - InspectorApplicationCacheAgent* m_inspectorApplicationCacheAgent; - Inspector::InspectorDebuggerAgent* m_inspectorDebuggerAgent; - PageDebuggerAgent* m_pageDebuggerAgent; - InspectorDOMDebuggerAgent* m_inspectorDOMDebuggerAgent; - InspectorProfilerAgent* m_inspectorProfilerAgent; - InspectorHeapProfilerAgent* m_inspectorHeapProfilerAgent; - InspectorWorkerAgent* m_inspectorWorkerAgent; - InspectorCanvasAgent* m_inspectorCanvasAgent; + InspectorDatabaseAgent* m_inspectorDatabaseAgent { nullptr }; + InspectorApplicationCacheAgent* m_inspectorApplicationCacheAgent { nullptr }; + Inspector::InspectorDebuggerAgent* m_inspectorDebuggerAgent { nullptr }; + PageDebuggerAgent* m_pageDebuggerAgent { nullptr }; + PageHeapAgent* m_pageHeapAgent { nullptr }; + InspectorDOMDebuggerAgent* m_inspectorDOMDebuggerAgent { nullptr }; }; -InstrumentingAgents* instrumentationForPage(Page*); -InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope*); - -} - -#endif // !defined(InstrumentingAgents_h) +} // namespace WebCore diff --git a/Source/WebCore/inspector/NetworkResourcesData.cpp b/Source/WebCore/inspector/NetworkResourcesData.cpp index 2af001c5a..c17d8e1f7 100644 --- a/Source/WebCore/inspector/NetworkResourcesData.cpp +++ b/Source/WebCore/inspector/NetworkResourcesData.cpp @@ -27,50 +27,20 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "NetworkResourcesData.h" #include "CachedResource.h" -#include "DOMImplementation.h" #include "ResourceResponse.h" #include "SharedBuffer.h" #include "TextResourceDecoder.h" -namespace { -// 100MB -static size_t maximumResourcesContentSize = 100 * 1000 * 1000; - -// 10MB -static size_t maximumSingleResourceContentSize = 10 * 1000 * 1000; -} - using namespace Inspector; namespace WebCore { +static const size_t maximumResourcesContentSize = 100 * 1000 * 1000; // 100MB +static const size_t maximumSingleResourceContentSize = 10 * 1000 * 1000; // 10MB -PassRefPtr<XHRReplayData> XHRReplayData::create(const String &method, const URL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials) -{ - return adoptRef(new XHRReplayData(method, url, async, formData, includeCredentials)); -} - -void XHRReplayData::addHeader(const AtomicString& key, const String& value) -{ - m_headers.set(key, value); -} - -XHRReplayData::XHRReplayData(const String &method, const URL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials) - : m_method(method) - , m_url(url) - , m_async(async) - , m_formData(formData) - , m_includeCredentials(includeCredentials) -{ -} - -// ResourceData NetworkResourcesData::ResourceData::ResourceData(const String& requestId, const String& loaderId) : m_requestId(requestId) , m_loaderId(loaderId) @@ -135,13 +105,11 @@ size_t NetworkResourcesData::ResourceData::decodeDataToContent() { ASSERT(!hasContent()); size_t dataLength = m_dataBuffer->size(); - m_content = m_decoder->decode(m_dataBuffer->data(), m_dataBuffer->size()); - m_content.append(m_decoder->flush()); + m_content = m_decoder->decodeAndFlush(m_dataBuffer->data(), m_dataBuffer->size()); m_dataBuffer = nullptr; return contentSizeInBytes(m_content) - dataLength; } -// NetworkResourcesData NetworkResourcesData::NetworkResourcesData() : m_contentSize(0) , m_maximumResourcesContentSize(maximumResourcesContentSize) @@ -160,21 +128,6 @@ void NetworkResourcesData::resourceCreated(const String& requestId, const String m_requestIdToResourceDataMap.set(requestId, new ResourceData(requestId, loaderId)); } -static PassRefPtr<TextResourceDecoder> createOtherResourceTextDecoder(const String& mimeType, const String& textEncodingName) -{ - RefPtr<TextResourceDecoder> decoder; - if (!textEncodingName.isEmpty()) - decoder = TextResourceDecoder::create("text/plain", textEncodingName); - else if (DOMImplementation::isXMLMIMEType(mimeType.lower())) { - decoder = TextResourceDecoder::create("application/xml"); - decoder->useLenientXMLDecoding(); - } else if (equalIgnoringCase(mimeType, "text/html")) - decoder = TextResourceDecoder::create("text/html", "UTF-8"); - else if (mimeType == "text/plain") - decoder = TextResourceDecoder::create("text/plain", "ISO-8859-1"); - return decoder; -} - void NetworkResourcesData::responseReceived(const String& requestId, const String& frameId, const ResourceResponse& response) { ResourceData* resourceData = resourceDataForRequestId(requestId); @@ -182,7 +135,7 @@ void NetworkResourcesData::responseReceived(const String& requestId, const Strin return; resourceData->setFrameId(frameId); resourceData->setUrl(response.url()); - resourceData->setDecoder(createOtherResourceTextDecoder(response.mimeType(), response.textEncodingName())); + resourceData->setDecoder(InspectorPageAgent::createTextDecoder(response.mimeType(), response.textEncodingName())); resourceData->setHTTPStatusCode(response.httpStatusCode()); } @@ -214,7 +167,7 @@ void NetworkResourcesData::setResourceContent(const String& requestId, const Str return; if (ensureFreeSpace(dataLength) && !resourceData->isContentEvicted()) { // We can not be sure that we didn't try to save this request data while it was loading, so remove it, if any. - if (resourceData->hasContent()) + if (resourceData->hasContent() || resourceData->hasData()) m_contentSize -= resourceData->removeContent(); m_requestIdsDeque.append(requestId); resourceData->setContent(content, base64Encoded); @@ -261,12 +214,12 @@ void NetworkResourcesData::addCachedResource(const String& requestId, CachedReso resourceData->setCachedResource(cachedResource); } -void NetworkResourcesData::addResourceSharedBuffer(const String& requestId, PassRefPtr<SharedBuffer> buffer, const String& textEncodingName) +void NetworkResourcesData::addResourceSharedBuffer(const String& requestId, RefPtr<SharedBuffer>&& buffer, const String& textEncodingName) { ResourceData* resourceData = resourceDataForRequestId(requestId); if (!resourceData) return; - resourceData->setBuffer(buffer); + resourceData->setBuffer(WTFMove(buffer)); resourceData->setTextEncodingName(textEncodingName); } @@ -275,56 +228,14 @@ NetworkResourcesData::ResourceData const* NetworkResourcesData::data(const Strin return resourceDataForRequestId(requestId); } -XHRReplayData* NetworkResourcesData::xhrReplayData(const String& requestId) -{ - if (m_reusedXHRReplayDataRequestIds.contains(requestId)) - return xhrReplayData(m_reusedXHRReplayDataRequestIds.get(requestId)); - - ResourceData* resourceData = resourceDataForRequestId(requestId); - if (!resourceData) - return nullptr; - return resourceData->xhrReplayData(); -} - -void NetworkResourcesData::setXHRReplayData(const String& requestId, XHRReplayData* xhrReplayData) -{ - ResourceData* resourceData = resourceDataForRequestId(requestId); - if (!resourceData) { - Vector<String> result; - ReusedRequestIds::iterator it; - ReusedRequestIds::iterator end = m_reusedXHRReplayDataRequestIds.end(); - for (it = m_reusedXHRReplayDataRequestIds.begin(); it != end; ++it) { - if (it->value == requestId) - setXHRReplayData(it->key, xhrReplayData); - } - return; - } - - resourceData->setXHRReplayData(xhrReplayData); -} - -void NetworkResourcesData::reuseXHRReplayData(const String& requestId, const String& reusedRequestId) -{ - ResourceData* reusedResourceData = resourceDataForRequestId(reusedRequestId); - ResourceData* resourceData = resourceDataForRequestId(requestId); - if (!reusedResourceData || !resourceData) { - m_reusedXHRReplayDataRequestIds.set(requestId, reusedRequestId); - return; - } - - resourceData->setXHRReplayData(reusedResourceData->xhrReplayData()); -} - Vector<String> NetworkResourcesData::removeCachedResource(CachedResource* cachedResource) { Vector<String> result; - ResourceDataMap::iterator it; - ResourceDataMap::iterator end = m_requestIdToResourceDataMap.end(); - for (it = m_requestIdToResourceDataMap.begin(); it != end; ++it) { - ResourceData* resourceData = it->value; + for (auto& entry : m_requestIdToResourceDataMap) { + ResourceData* resourceData = entry.value; if (resourceData->cachedResource() == cachedResource) { resourceData->setCachedResource(nullptr); - result.append(it->key); + result.append(entry.key); } } @@ -338,25 +249,22 @@ void NetworkResourcesData::clear(const String& preservedLoaderId) ResourceDataMap preservedMap; - ResourceDataMap::iterator it; - ResourceDataMap::iterator end = m_requestIdToResourceDataMap.end(); - for (it = m_requestIdToResourceDataMap.begin(); it != end; ++it) { - ResourceData* resourceData = it->value; + for (auto& entry : m_requestIdToResourceDataMap) { + ResourceData* resourceData = entry.value; + ASSERT(resourceData); if (!preservedLoaderId.isNull() && resourceData->loaderId() == preservedLoaderId) - preservedMap.set(it->key, it->value); + preservedMap.set(entry.key, entry.value); else delete resourceData; } m_requestIdToResourceDataMap.swap(preservedMap); - - m_reusedXHRReplayDataRequestIds.clear(); } -void NetworkResourcesData::setResourcesDataSizeLimits(size_t maximumResourcesContentSize, size_t maximumSingleResourceContentSize) +Vector<NetworkResourcesData::ResourceData*> NetworkResourcesData::resources() { - clear(); - m_maximumResourcesContentSize = maximumResourcesContentSize; - m_maximumSingleResourceContentSize = maximumSingleResourceContentSize; + Vector<NetworkResourcesData::ResourceData*> resources; + copyValuesToVector(m_requestIdToResourceDataMap, resources); + return resources; } NetworkResourcesData::ResourceData* NetworkResourcesData::resourceDataForRequestId(const String& requestId) @@ -392,5 +300,3 @@ bool NetworkResourcesData::ensureFreeSpace(size_t size) } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/NetworkResourcesData.h b/Source/WebCore/inspector/NetworkResourcesData.h index 1a429481a..52dce685d 100644 --- a/Source/WebCore/inspector/NetworkResourcesData.h +++ b/Source/WebCore/inspector/NetworkResourcesData.h @@ -26,50 +26,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef NetworkResourcesData_h -#define NetworkResourcesData_h +#pragma once -#include "HTTPHeaderMap.h" #include "InspectorPageAgent.h" -#include "URL.h" #include "TextResourceDecoder.h" #include <wtf/Deque.h> #include <wtf/HashMap.h> -#include <wtf/RefCounted.h> -#include <wtf/text/StringBuilder.h> #include <wtf/text/WTFString.h> -#if ENABLE(INSPECTOR) - namespace WebCore { class CachedResource; -class FormData; class ResourceResponse; class SharedBuffer; -class TextResourceDecoder; - -class XHRReplayData : public RefCounted<XHRReplayData> { -public: - static PassRefPtr<XHRReplayData> create(const String &method, const URL&, bool async, PassRefPtr<FormData>, bool includeCredentials); - - void addHeader(const AtomicString& key, const String& value); - const String& method() const { return m_method; } - const URL& url() const { return m_url; } - bool async() const { return m_async; } - PassRefPtr<FormData> formData() const { return m_formData; } - const HTTPHeaderMap& headers() const { return m_headers; } - bool includeCredentials() const { return m_includeCredentials; } -private: - XHRReplayData(const String &method, const URL&, bool async, PassRefPtr<FormData>, bool includeCredentials); - - String m_method; - URL m_url; - bool m_async; - RefPtr<FormData> m_formData; - HTTPHeaderMap m_headers; - bool m_includeCredentials; -}; class NetworkResourcesData { WTF_MAKE_FAST_ALLOCATED; @@ -108,18 +77,15 @@ public: String textEncodingName() const { return m_textEncodingName; } void setTextEncodingName(const String& textEncodingName) { m_textEncodingName = textEncodingName; } - PassRefPtr<TextResourceDecoder> decoder() const { return m_decoder; } - void setDecoder(PassRefPtr<TextResourceDecoder> decoder) { m_decoder = decoder; } + RefPtr<TextResourceDecoder> decoder() const { return m_decoder.copyRef(); } + void setDecoder(RefPtr<TextResourceDecoder>&& decoder) { m_decoder = WTFMove(decoder); } - PassRefPtr<SharedBuffer> buffer() const { return m_buffer; } - void setBuffer(PassRefPtr<SharedBuffer> buffer) { m_buffer = buffer; } + RefPtr<SharedBuffer> buffer() const { return m_buffer.copyRef(); } + void setBuffer(RefPtr<SharedBuffer>&& buffer) { m_buffer = WTFMove(buffer); } CachedResource* cachedResource() const { return m_cachedResource; } void setCachedResource(CachedResource* cachedResource) { m_cachedResource = cachedResource; } - XHRReplayData* xhrReplayData() const { return m_xhrReplayData.get(); } - void setXHRReplayData(XHRReplayData* xhrReplayData) { m_xhrReplayData = xhrReplayData; } - private: bool hasData() const { return m_dataBuffer; } size_t dataLength() const; @@ -131,7 +97,6 @@ public: String m_frameId; String m_url; String m_content; - RefPtr<XHRReplayData> m_xhrReplayData; bool m_base64Encoded; RefPtr<SharedBuffer> m_dataBuffer; bool m_isContentEvicted; @@ -157,15 +122,11 @@ public: void maybeAddResourceData(const String& requestId, const char* data, size_t dataLength); void maybeDecodeDataToContent(const String& requestId); void addCachedResource(const String& requestId, CachedResource*); - void addResourceSharedBuffer(const String& requestId, PassRefPtr<SharedBuffer>, const String& textEncodingName); + void addResourceSharedBuffer(const String& requestId, RefPtr<SharedBuffer>&&, const String& textEncodingName); ResourceData const* data(const String& requestId); Vector<String> removeCachedResource(CachedResource*); void clear(const String& preservedLoaderId = String()); - - void setResourcesDataSizeLimits(size_t maximumResourcesContentSize, size_t maximumSingleResourceContentSize); - void setXHRReplayData(const String& requestId, XHRReplayData*); - void reuseXHRReplayData(const String& requestId, const String& reusedRequestId); - XHRReplayData* xhrReplayData(const String& requestId); + Vector<ResourceData*> resources(); private: ResourceData* resourceDataForRequestId(const String& requestId); @@ -174,8 +135,6 @@ private: Deque<String> m_requestIdsDeque; - typedef HashMap<String, String> ReusedRequestIds; - ReusedRequestIds m_reusedXHRReplayDataRequestIds; typedef HashMap<String, ResourceData*> ResourceDataMap; ResourceDataMap m_requestIdToResourceDataMap; size_t m_contentSize; @@ -184,7 +143,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(NetworkResourcesData_h) diff --git a/Source/WebCore/inspector/PageConsoleAgent.cpp b/Source/WebCore/inspector/PageConsoleAgent.cpp index 1adb449d2..cb15c88b9 100644 --- a/Source/WebCore/inspector/PageConsoleAgent.cpp +++ b/Source/WebCore/inspector/PageConsoleAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,58 +32,49 @@ #include "config.h" #include "PageConsoleAgent.h" -#if ENABLE(INSPECTOR) - #include "CommandLineAPIHost.h" -#include "DOMWindow.h" #include "InspectorDOMAgent.h" #include "Node.h" -#include "PageInjectedScriptManager.h" +#include "WebInjectedScriptManager.h" using namespace Inspector; namespace WebCore { -PageConsoleAgent::PageConsoleAgent(InstrumentingAgents* instrumentingAgents, PageInjectedScriptManager* injectedScriptManager, InspectorDOMAgent* domAgent) - : InspectorConsoleAgent(instrumentingAgents, injectedScriptManager) +PageConsoleAgent::PageConsoleAgent(WebAgentContext& context, InspectorHeapAgent* heapAgent, InspectorDOMAgent* domAgent) + : WebConsoleAgent(context, heapAgent) , m_inspectorDOMAgent(domAgent) { } -PageConsoleAgent::~PageConsoleAgent() -{ - m_inspectorDOMAgent = nullptr; -} - -void PageConsoleAgent::clearMessages(ErrorString* errorString) +void PageConsoleAgent::clearMessages(ErrorString& errorString) { m_inspectorDOMAgent->releaseDanglingNodes(); - InspectorConsoleAgent::clearMessages(errorString); + + WebConsoleAgent::clearMessages(errorString); } class InspectableNode final : public CommandLineAPIHost::InspectableObject { public: explicit InspectableNode(Node* node) : m_node(node) { } - virtual Deprecated::ScriptValue get(JSC::ExecState* state) override + JSC::JSValue get(JSC::ExecState& state) final { - return InspectorDOMAgent::nodeAsScriptValue(state, m_node); + return InspectorDOMAgent::nodeAsScriptValue(state, m_node.get()); } private: - Node* m_node; + RefPtr<Node> m_node; }; -void PageConsoleAgent::addInspectedNode(ErrorString* errorString, int nodeId) +void PageConsoleAgent::addInspectedNode(ErrorString& errorString, int nodeId) { Node* node = m_inspectorDOMAgent->nodeForId(nodeId); - if (!node || node->isInShadowTree()) { - *errorString = ASCIILiteral("nodeId is not valid"); + if (!node || node->isInUserAgentShadowTree()) { + errorString = ASCIILiteral("nodeId is not valid"); return; } - if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) - commandLineAPIHost->addInspectedObject(adoptPtr(new InspectableNode(node))); + if (CommandLineAPIHost* commandLineAPIHost = static_cast<WebInjectedScriptManager&>(m_injectedScriptManager).commandLineAPIHost()) + commandLineAPIHost->addInspectedObject(std::make_unique<InspectableNode>(node)); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/PageConsoleAgent.h b/Source/WebCore/inspector/PageConsoleAgent.h index d557f1a8b..3177dc0fc 100644 --- a/Source/WebCore/inspector/PageConsoleAgent.h +++ b/Source/WebCore/inspector/PageConsoleAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,35 +29,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageConsoleAgent_h -#define PageConsoleAgent_h +#pragma once -#include "InspectorConsoleAgent.h" -#include <wtf/PassOwnPtr.h> - -#if ENABLE(INSPECTOR) +#include "InspectorWebAgentBase.h" +#include "WebConsoleAgent.h" namespace WebCore { class InspectorDOMAgent; -class PageConsoleAgent : public InspectorConsoleAgent { +class PageConsoleAgent final : public WebConsoleAgent { WTF_MAKE_NONCOPYABLE(PageConsoleAgent); + WTF_MAKE_FAST_ALLOCATED; public: - PageConsoleAgent(InstrumentingAgents*, PageInjectedScriptManager*, InspectorDOMAgent*); - virtual ~PageConsoleAgent(); - - virtual bool isWorkerAgent() override { return false; } + PageConsoleAgent(WebAgentContext&, Inspector::InspectorHeapAgent*, InspectorDOMAgent*); + virtual ~PageConsoleAgent() { } private: - virtual void clearMessages(ErrorString*) override; - virtual void addInspectedNode(ErrorString*, int nodeId) override; + void clearMessages(ErrorString&) override; + void addInspectedNode(ErrorString&, int nodeId) override; InspectorDOMAgent* m_inspectorDOMAgent; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(PageConsoleAgent_h) diff --git a/Source/WebCore/inspector/PageDebuggerAgent.cpp b/Source/WebCore/inspector/PageDebuggerAgent.cpp index 67f4951ac..a86ed135b 100644 --- a/Source/WebCore/inspector/PageDebuggerAgent.cpp +++ b/Source/WebCore/inspector/PageDebuggerAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,25 +32,28 @@ #include "config.h" #include "PageDebuggerAgent.h" -#if ENABLE(INSPECTOR) - #include "CachedResource.h" #include "InspectorOverlay.h" #include "InspectorPageAgent.h" #include "InstrumentingAgents.h" +#include "MainFrame.h" #include "Page.h" -#include "PageConsole.h" +#include "PageConsoleClient.h" #include "PageScriptDebugServer.h" #include "ScriptState.h" #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> +#include <inspector/ScriptCallStack.h> +#include <inspector/ScriptCallStackFactory.h> +#include <wtf/NeverDestroyed.h> using namespace Inspector; namespace WebCore { -PageDebuggerAgent::PageDebuggerAgent(InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorOverlay* overlay) - : WebDebuggerAgent(injectedScriptManager, instrumentingAgents) +PageDebuggerAgent::PageDebuggerAgent(PageAgentContext& context, InspectorPageAgent* pageAgent, InspectorOverlay* overlay) + : WebDebuggerAgent(context) + , m_page(context.inspectedPage) , m_pageAgent(pageAgent) , m_overlay(overlay) { @@ -58,22 +62,22 @@ PageDebuggerAgent::PageDebuggerAgent(InjectedScriptManager* injectedScriptManage void PageDebuggerAgent::enable() { WebDebuggerAgent::enable(); - m_instrumentingAgents->setPageDebuggerAgent(this); + m_instrumentingAgents.setPageDebuggerAgent(this); } void PageDebuggerAgent::disable(bool isBeingDestroyed) { WebDebuggerAgent::disable(isBeingDestroyed); - m_instrumentingAgents->setPageDebuggerAgent(nullptr); + m_instrumentingAgents.setPageDebuggerAgent(nullptr); } String PageDebuggerAgent::sourceMapURLForScript(const Script& script) { - DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeader, (ASCIILiteral("SourceMap"))); - DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeaderDeprecated, (ASCIILiteral("X-SourceMap"))); + static NeverDestroyed<String> sourceMapHTTPHeader(ASCIILiteral("SourceMap")); + static NeverDestroyed<String> sourceMapHTTPHeaderDeprecated(ASCIILiteral("X-SourceMap")); if (!script.url.isEmpty()) { - CachedResource* resource = m_pageAgent->cachedResource(m_pageAgent->mainFrame(), URL(ParsedURLString, script.url)); + CachedResource* resource = m_pageAgent->cachedResource(&m_page.mainFrame(), URL(ParsedURLString, script.url)); if (resource) { String sourceMapHeader = resource->response().httpHeaderField(sourceMapHTTPHeader); if (!sourceMapHeader.isEmpty()) @@ -88,51 +92,36 @@ String PageDebuggerAgent::sourceMapURLForScript(const Script& script) return InspectorDebuggerAgent::sourceMapURLForScript(script); } -void PageDebuggerAgent::startListeningScriptDebugServer() -{ - scriptDebugServer().addListener(this, m_pageAgent->page()); -} - -void PageDebuggerAgent::stopListeningScriptDebugServer(bool isBeingDestroyed) -{ - scriptDebugServer().removeListener(this, m_pageAgent->page(), isBeingDestroyed); -} - -PageScriptDebugServer& PageDebuggerAgent::scriptDebugServer() -{ - return PageScriptDebugServer::shared(); -} - void PageDebuggerAgent::muteConsole() { - PageConsole::mute(); + PageConsoleClient::mute(); } void PageDebuggerAgent::unmuteConsole() { - PageConsole::unmute(); + PageConsoleClient::unmute(); } -void PageDebuggerAgent::breakpointActionLog(JSC::ExecState*, const String& message) +void PageDebuggerAgent::breakpointActionLog(JSC::ExecState& state, const String& message) { - m_pageAgent->page()->console().addMessage(JSMessageSource, LogMessageLevel, message); + m_pageAgent->page().console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(&state, ScriptCallStack::maxCallStackSizeToCapture)); } -InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId) +InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId) { if (!executionContextId) { - JSC::ExecState* scriptState = mainWorldExecState(m_pageAgent->mainFrame()); - return injectedScriptManager()->injectedScriptFor(scriptState); + JSC::ExecState* scriptState = mainWorldExecState(&m_pageAgent->mainFrame()); + return injectedScriptManager().injectedScriptFor(scriptState); } - InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId); + InjectedScript injectedScript = injectedScriptManager().injectedScriptForId(*executionContextId); if (injectedScript.hasNoValue()) - *errorString = ASCIILiteral("Execution context with given id not found."); + errorString = ASCIILiteral("Execution context with given id not found."); return injectedScript; } -void PageDebuggerAgent::setOverlayMessage(ErrorString*, const String* message) +void PageDebuggerAgent::setOverlayMessage(ErrorString&, const String* message) { m_overlay->setPausedInDebuggerMessage(message); } @@ -142,6 +131,23 @@ void PageDebuggerAgent::didClearMainFrameWindowObject() didClearGlobalObject(); } -} // namespace WebCore +void PageDebuggerAgent::mainFrameStartedLoading() +{ + if (isPaused()) { + setSuppressAllPauses(true); + ErrorString unused; + resume(unused); + } +} + +void PageDebuggerAgent::mainFrameStoppedLoading() +{ + setSuppressAllPauses(false); +} -#endif // ENABLE(INSPECTOR) +void PageDebuggerAgent::mainFrameNavigated() +{ + setSuppressAllPauses(false); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/PageDebuggerAgent.h b/Source/WebCore/inspector/PageDebuggerAgent.h index 9bf78a312..5220054a9 100644 --- a/Source/WebCore/inspector/PageDebuggerAgent.h +++ b/Source/WebCore/inspector/PageDebuggerAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,55 +29,48 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageDebuggerAgent_h -#define PageDebuggerAgent_h +#pragma once -#if ENABLE(INSPECTOR) - -#include "PageScriptDebugServer.h" #include "WebDebuggerAgent.h" namespace WebCore { class InspectorOverlay; class InspectorPageAgent; -class InstrumentingAgents; class Page; -class PageScriptDebugServer; class PageDebuggerAgent final : public WebDebuggerAgent { WTF_MAKE_NONCOPYABLE(PageDebuggerAgent); WTF_MAKE_FAST_ALLOCATED; public: - PageDebuggerAgent(Inspector::InjectedScriptManager*, InstrumentingAgents*, InspectorPageAgent*, InspectorOverlay*); + PageDebuggerAgent(PageAgentContext&, InspectorPageAgent*, InspectorOverlay*); virtual ~PageDebuggerAgent() { } void didClearMainFrameWindowObject(); + void mainFrameStartedLoading(); + void mainFrameStoppedLoading(); + void mainFrameNavigated(); + protected: - virtual void enable() override; - virtual void disable(bool isBeingDestroyed) override; + void enable() override; + void disable(bool isBeingDestroyed) override; - virtual String sourceMapURLForScript(const Script&) override; + String sourceMapURLForScript(const Script&) override; private: - virtual void startListeningScriptDebugServer() override; - virtual void stopListeningScriptDebugServer(bool isBeingDestroyed) override; - virtual PageScriptDebugServer& scriptDebugServer() override; - virtual void muteConsole() override; - virtual void unmuteConsole() override; + void muteConsole() override; + void unmuteConsole() override; + + void breakpointActionLog(JSC::ExecState&, const String&) override; - virtual void breakpointActionLog(JSC::ExecState*, const String&) override; + Inspector::InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override; + void setOverlayMessage(ErrorString&, const String* const) final; - virtual Inspector::InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override; - virtual void setOverlayMessage(ErrorString*, const String*) override; + Page& m_page; InspectorPageAgent* m_pageAgent; - InspectorOverlay* m_overlay; + InspectorOverlay* m_overlay { nullptr }; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(PageDebuggerAgent_h) diff --git a/Source/WebCore/inspector/PageHeapAgent.cpp b/Source/WebCore/inspector/PageHeapAgent.cpp new file mode 100644 index 000000000..4a3454335 --- /dev/null +++ b/Source/WebCore/inspector/PageHeapAgent.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PageHeapAgent.h" + +using namespace Inspector; + +namespace WebCore { + +PageHeapAgent::PageHeapAgent(PageAgentContext& context) + : WebHeapAgent(context) + , m_instrumentingAgents(context.instrumentingAgents) +{ +} + +void PageHeapAgent::enable(ErrorString& errorString) +{ + WebHeapAgent::enable(errorString); + m_instrumentingAgents.setPageHeapAgent(this); +} + +void PageHeapAgent::disable(ErrorString& errorString) +{ + WebHeapAgent::disable(errorString); + m_instrumentingAgents.setPageHeapAgent(nullptr); +} + +void PageHeapAgent::mainFrameNavigated() +{ + clearHeapSnapshots(); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/PageHeapAgent.h b/Source/WebCore/inspector/PageHeapAgent.h new file mode 100644 index 000000000..1004a197d --- /dev/null +++ b/Source/WebCore/inspector/PageHeapAgent.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "InspectorWebAgentBase.h" +#include "InstrumentingAgents.h" +#include "WebHeapAgent.h" + +namespace WebCore { + +typedef String ErrorString; + +class PageHeapAgent final : public WebHeapAgent { + WTF_MAKE_NONCOPYABLE(PageHeapAgent); + WTF_MAKE_FAST_ALLOCATED; +public: + PageHeapAgent(PageAgentContext&); + virtual ~PageHeapAgent() { } + + void enable(ErrorString&) override; + void disable(ErrorString&) override; + + void mainFrameNavigated(); + +private: + InstrumentingAgents& m_instrumentingAgents; +}; + +} // namespace WebCore diff --git a/Source/WebCore/inspector/PageRuntimeAgent.cpp b/Source/WebCore/inspector/PageRuntimeAgent.cpp index 9e8427ba8..4f4fa25fe 100644 --- a/Source/WebCore/inspector/PageRuntimeAgent.cpp +++ b/Source/WebCore/inspector/PageRuntimeAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,8 +32,6 @@ #include "config.h" #include "PageRuntimeAgent.h" -#if ENABLE(INSPECTOR) - #include "Document.h" #include "Frame.h" #include "InspectorPageAgent.h" @@ -40,43 +39,41 @@ #include "JSDOMWindowBase.h" #include "MainFrame.h" #include "Page.h" -#include "PageConsole.h" +#include "PageConsoleClient.h" #include "ScriptController.h" #include "ScriptState.h" #include "SecurityOrigin.h" #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> -using Inspector::TypeBuilder::Runtime::ExecutionContextDescription; +using Inspector::Protocol::Runtime::ExecutionContextDescription; using namespace Inspector; namespace WebCore { -PageRuntimeAgent::PageRuntimeAgent(InjectedScriptManager* injectedScriptManager, Page* page, InspectorPageAgent* pageAgent) - : InspectorRuntimeAgent(injectedScriptManager) - , m_inspectedPage(page) +PageRuntimeAgent::PageRuntimeAgent(PageAgentContext& context, InspectorPageAgent* pageAgent) + : InspectorRuntimeAgent(context) + , m_frontendDispatcher(std::make_unique<Inspector::RuntimeFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::RuntimeBackendDispatcher::create(context.backendDispatcher, this)) , m_pageAgent(pageAgent) - , m_mainWorldContextCreated(false) + , m_inspectedPage(context.inspectedPage) { } -void PageRuntimeAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void PageRuntimeAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorRuntimeFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this); } -void PageRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void PageRuntimeAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason reason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); + String unused; + disable(unused); - String errorString; - disable(&errorString); + InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason); } -void PageRuntimeAgent::enable(ErrorString* errorString) +void PageRuntimeAgent::enable(ErrorString& errorString) { if (enabled()) return; @@ -90,7 +87,7 @@ void PageRuntimeAgent::enable(ErrorString* errorString) reportExecutionContextCreation(); } -void PageRuntimeAgent::disable(ErrorString* errorString) +void PageRuntimeAgent::disable(ErrorString& errorString) { if (!enabled()) return; @@ -98,64 +95,48 @@ void PageRuntimeAgent::disable(ErrorString* errorString) InspectorRuntimeAgent::disable(errorString); } -void PageRuntimeAgent::didCreateMainWorldContext(Frame* frame) +void PageRuntimeAgent::didCreateMainWorldContext(Frame& frame) { m_mainWorldContextCreated = true; if (!enabled()) return; - ASSERT(m_frontendDispatcher); - String frameId = m_pageAgent->frameId(frame); - JSC::ExecState* scriptState = mainWorldExecState(frame); + String frameId = m_pageAgent->frameId(&frame); + JSC::ExecState* scriptState = mainWorldExecState(&frame); notifyContextCreated(frameId, scriptState, nullptr, true); } -void PageRuntimeAgent::didCreateIsolatedContext(Frame* frame, JSC::ExecState* scriptState, SecurityOrigin* origin) -{ - if (!enabled()) - return; - - ASSERT(m_frontendDispatcher); - String frameId = m_pageAgent->frameId(frame); - notifyContextCreated(frameId, scriptState, origin, false); -} - -JSC::VM* PageRuntimeAgent::globalVM() -{ - return JSDOMWindowBase::commonVM(); -} - -InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId) +InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId) { if (!executionContextId) { - JSC::ExecState* scriptState = mainWorldExecState(&m_inspectedPage->mainFrame()); - InjectedScript result = injectedScriptManager()->injectedScriptFor(scriptState); + JSC::ExecState* scriptState = mainWorldExecState(&m_inspectedPage.mainFrame()); + InjectedScript result = injectedScriptManager().injectedScriptFor(scriptState); if (result.hasNoValue()) - *errorString = ASCIILiteral("Internal error: main world execution context not found."); + errorString = ASCIILiteral("Internal error: main world execution context not found."); return result; } - InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId); + InjectedScript injectedScript = injectedScriptManager().injectedScriptForId(*executionContextId); if (injectedScript.hasNoValue()) - *errorString = ASCIILiteral("Execution context with given id not found."); + errorString = ASCIILiteral("Execution context with given id not found."); return injectedScript; } void PageRuntimeAgent::muteConsole() { - PageConsole::mute(); + PageConsoleClient::mute(); } void PageRuntimeAgent::unmuteConsole() { - PageConsole::unmute(); + PageConsoleClient::unmute(); } void PageRuntimeAgent::reportExecutionContextCreation() { Vector<std::pair<JSC::ExecState*, SecurityOrigin*>> isolatedContexts; - for (Frame* frame = &m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) { + for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) { if (!frame->script().canExecuteScripts(NotAboutToExecuteScript)) continue; String frameId = m_pageAgent->frameId(frame); @@ -165,8 +146,8 @@ void PageRuntimeAgent::reportExecutionContextCreation() frame->script().collectIsolatedContexts(isolatedContexts); if (isolatedContexts.isEmpty()) continue; - for (size_t i = 0; i< isolatedContexts.size(); i++) - notifyContextCreated(frameId, isolatedContexts[i].first, isolatedContexts[i].second, false); + for (auto& context : isolatedContexts) + notifyContextCreated(frameId, context.first, context.second, false); isolatedContexts.clear(); } } @@ -174,8 +155,13 @@ void PageRuntimeAgent::reportExecutionContextCreation() void PageRuntimeAgent::notifyContextCreated(const String& frameId, JSC::ExecState* scriptState, SecurityOrigin* securityOrigin, bool isPageContext) { ASSERT(securityOrigin || isPageContext); - int executionContextId = injectedScriptManager()->injectedScriptIdFor(scriptState); - String name = securityOrigin ? securityOrigin->toRawString() : ""; + + InjectedScript result = injectedScriptManager().injectedScriptFor(scriptState); + if (result.hasNoValue()) + return; + + int executionContextId = injectedScriptManager().injectedScriptIdFor(scriptState); + String name = securityOrigin ? securityOrigin->toRawString() : String(); m_frontendDispatcher->executionContextCreated(ExecutionContextDescription::create() .setId(executionContextId) .setIsPageContext(isPageContext) @@ -185,5 +171,3 @@ void PageRuntimeAgent::notifyContextCreated(const String& frameId, JSC::ExecStat } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/PageRuntimeAgent.h b/Source/WebCore/inspector/PageRuntimeAgent.h index 02058d6f4..c6d2ee3d2 100644 --- a/Source/WebCore/inspector/PageRuntimeAgent.h +++ b/Source/WebCore/inspector/PageRuntimeAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,23 +29,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageRuntimeAgent_h -#define PageRuntimeAgent_h +#pragma once -#if ENABLE(INSPECTOR) - -#include <inspector/InspectorJSFrontendDispatchers.h> +#include "InspectorWebAgentBase.h" +#include <inspector/InspectorFrontendDispatchers.h> #include <inspector/agents/InspectorRuntimeAgent.h> -#include <wtf/PassOwnPtr.h> namespace JSC { class ExecState; } -namespace Inspector { -class InjectedScriptManager; -} - namespace WebCore { class InspectorPageAgent; @@ -54,35 +48,33 @@ class SecurityOrigin; typedef String ErrorString; class PageRuntimeAgent final : public Inspector::InspectorRuntimeAgent { + WTF_MAKE_FAST_ALLOCATED; public: - PageRuntimeAgent(Inspector::InjectedScriptManager*, Page*, InspectorPageAgent*); + PageRuntimeAgent(PageAgentContext&, InspectorPageAgent*); virtual ~PageRuntimeAgent() { } - - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; - virtual void enable(ErrorString*) override; - virtual void disable(ErrorString*) override; - void didCreateMainWorldContext(Frame*); - void didCreateIsolatedContext(Frame*, JSC::ExecState*, SecurityOrigin*); + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; + void enable(ErrorString&) override; + void disable(ErrorString&) override; + + // InspectorInstrumentation + void didCreateMainWorldContext(Frame&); private: - virtual JSC::VM* globalVM() override; - virtual Inspector::InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override; - virtual void muteConsole() override; - virtual void unmuteConsole() override; + Inspector::InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override; + void muteConsole() override; + void unmuteConsole() override; void reportExecutionContextCreation(); void notifyContextCreated(const String& frameId, JSC::ExecState*, SecurityOrigin*, bool isPageContext); - Page* m_inspectedPage; + std::unique_ptr<Inspector::RuntimeFrontendDispatcher> m_frontendDispatcher; + RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher; InspectorPageAgent* m_pageAgent; - std::unique_ptr<Inspector::InspectorRuntimeFrontendDispatcher> m_frontendDispatcher; - RefPtr<Inspector::InspectorRuntimeBackendDispatcher> m_backendDispatcher; - bool m_mainWorldContextCreated; -}; -} // namespace WebCore + Page& m_inspectedPage; -#endif // ENABLE(INSPECTOR) + bool m_mainWorldContextCreated { false }; +}; -#endif // !defined(InspectorPagerAgent_h) +} // namespace WebCore diff --git a/Source/WebCore/inspector/PageScriptDebugServer.cpp b/Source/WebCore/inspector/PageScriptDebugServer.cpp new file mode 100644 index 000000000..b3ae44b4a --- /dev/null +++ b/Source/WebCore/inspector/PageScriptDebugServer.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2013-2014 Apple Inc. All rights reserved. + * Copyright (c) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PageScriptDebugServer.h" + +#include "CommonVM.h" +#include "Document.h" +#include "EventLoop.h" +#include "FrameView.h" +#include "InspectorController.h" +#include "InspectorFrontendClient.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMWindowCustom.h" +#include "MainFrame.h" +#include "Page.h" +#include "PageGroup.h" +#include "PluginViewBase.h" +#include "ScriptController.h" +#include "Timer.h" +#include <runtime/JSLock.h> +#include <wtf/MainThread.h> +#include <wtf/StdLibExtras.h> + +#if PLATFORM(IOS) +#include "WebCoreThreadInternal.h" +#endif + +using namespace JSC; +using namespace Inspector; + +namespace WebCore { + +PageScriptDebugServer::PageScriptDebugServer(Page& page) + : ScriptDebugServer(WebCore::commonVM()) + , m_page(page) +{ +} + +void PageScriptDebugServer::attachDebugger() +{ + m_page.setDebugger(this); +} + +void PageScriptDebugServer::detachDebugger(bool isBeingDestroyed) +{ + m_page.setDebugger(nullptr); + if (!isBeingDestroyed) + recompileAllJSFunctions(); +} + +void PageScriptDebugServer::recompileAllJSFunctions() +{ + JSLockHolder lock(vm()); + Debugger::recompileAllJSFunctions(); +} + +void PageScriptDebugServer::didPause(JSGlobalObject*) +{ + setJavaScriptPaused(m_page.group(), true); +} + +void PageScriptDebugServer::didContinue(JSGlobalObject*) +{ + setJavaScriptPaused(m_page.group(), false); +} + +void PageScriptDebugServer::runEventLoopWhilePaused() +{ +#if PLATFORM(IOS) + // On iOS, running an EventLoop causes us to run a nested WebRunLoop. + // Since the WebThread is autoreleased at the end of run loop iterations + // we need to gracefully handle releasing and reacquiring the lock. + if (WebThreadIsEnabled()) { + ASSERT(WebThreadIsLockedOrDisabled()); + JSC::JSLock::DropAllLocks dropAllLocks(vm()); + WebRunLoopEnableNested(); + + runEventLoopWhilePausedInternal(); + + WebRunLoopDisableNested(); + ASSERT(WebThreadIsLockedOrDisabled()); + return; + } +#endif + + runEventLoopWhilePausedInternal(); +} + +void PageScriptDebugServer::runEventLoopWhilePausedInternal() +{ + TimerBase::fireTimersInNestedEventLoop(); + + m_page.incrementNestedRunLoopCount(); + + EventLoop loop; + while (!m_doneProcessingDebuggerEvents && !loop.ended()) + loop.cycle(); + + m_page.decrementNestedRunLoopCount(); +} + +bool PageScriptDebugServer::isContentScript(ExecState* exec) const +{ + return ¤tWorld(exec) != &mainThreadNormalWorld(); +} + +void PageScriptDebugServer::reportException(ExecState* exec, JSC::Exception* exception) const +{ + WebCore::reportException(exec, exception); +} + +void PageScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused) +{ + setMainThreadCallbacksPaused(paused); + + for (auto& page : pageGroup.pages()) { + page->setDefersLoading(paused); + + for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) + setJavaScriptPaused(*frame, paused); + + if (auto* frontendClient = page->inspectorController().inspectorFrontendClient()) { + if (paused) + frontendClient->pagePaused(); + else + frontendClient->pageUnpaused(); + } + } +} + +void PageScriptDebugServer::setJavaScriptPaused(Frame& frame, bool paused) +{ + if (!frame.script().canExecuteScripts(NotAboutToExecuteScript)) + return; + + frame.script().setPaused(paused); + + ASSERT(frame.document()); + auto& document = *frame.document(); + if (paused) { + document.suspendScriptedAnimationControllerCallbacks(); + document.suspendActiveDOMObjects(ActiveDOMObject::JavaScriptDebuggerPaused); + } else { + document.resumeActiveDOMObjects(ActiveDOMObject::JavaScriptDebuggerPaused); + document.resumeScriptedAnimationControllerCallbacks(); + } + + if (auto* view = frame.view()) { + for (auto& child : view->children()) { + if (!is<PluginViewBase>(child.get())) + continue; + downcast<PluginViewBase>(child.get()).setJavaScriptPaused(paused); + } + } +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/IdentifiersFactory.h b/Source/WebCore/inspector/PageScriptDebugServer.h index b1a9c48b2..7f58c6c8b 100644 --- a/Source/WebCore/inspector/IdentifiersFactory.h +++ b/Source/WebCore/inspector/PageScriptDebugServer.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (c) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -23,28 +24,40 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef IdentifiersFactory_h -#define IdentifiersFactory_h +#pragma once -#include <wtf/text/WTFString.h> - -#if ENABLE(INSPECTOR) +#include <inspector/ScriptDebugServer.h> namespace WebCore { -class IdentifiersFactory { +class Frame; +class Page; +class PageGroup; + +class PageScriptDebugServer final : public Inspector::ScriptDebugServer { + WTF_MAKE_NONCOPYABLE(PageScriptDebugServer); public: - static void setProcessId(long processId) { s_processId = processId; } - static String createIdentifier(); - static String requestId(unsigned long identifier); + PageScriptDebugServer(Page&); + virtual ~PageScriptDebugServer() { } + + void recompileAllJSFunctions() override; + private: - static String addProcessIdPrefixTo(const String& id); + void attachDebugger() override; + void detachDebugger(bool isBeingDestroyed) override; - static long s_processId; -}; + void didPause(JSC::JSGlobalObject*) override; + void didContinue(JSC::JSGlobalObject*) override; + void runEventLoopWhilePaused() override; + bool isContentScript(JSC::ExecState*) const override; + void reportException(JSC::ExecState*, JSC::Exception*) const override; -} // namespace WebCore + void runEventLoopWhilePausedInternal(); + + void setJavaScriptPaused(const PageGroup&, bool paused); + void setJavaScriptPaused(Frame&, bool paused); -#endif // !defined(IdentifiersFactory_h) + Page& m_page; +}; -#endif // ENABLE(INSPECTOR) +} // namespace WebCore diff --git a/Source/WebCore/inspector/ScriptArguments.cpp b/Source/WebCore/inspector/ScriptArguments.cpp deleted file mode 100644 index 9e65f7ef9..000000000 --- a/Source/WebCore/inspector/ScriptArguments.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScriptArguments.h" - -#include <bindings/ScriptValue.h> - -namespace WebCore { - -PassRefPtr<ScriptArguments> ScriptArguments::create(JSC::ExecState* scriptState, Vector<Deprecated::ScriptValue>& arguments) -{ - return adoptRef(new ScriptArguments(scriptState, arguments)); -} - -ScriptArguments::ScriptArguments(JSC::ExecState* scriptState, Vector<Deprecated::ScriptValue>& arguments) - : m_globalObject(scriptState->vm(), scriptState->lexicalGlobalObject()) -{ - m_arguments.swap(arguments); -} - -ScriptArguments::~ScriptArguments() -{ -} - -const Deprecated::ScriptValue &ScriptArguments::argumentAt(size_t index) const -{ - ASSERT(m_arguments.size() > index); - return m_arguments[index]; -} - -JSC::ExecState* ScriptArguments::globalState() const -{ - if (m_globalObject) - return const_cast<JSC::JSGlobalObject*>(m_globalObject.get())->globalExec(); - return nullptr; -} - -bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNullOrUndefined) -{ - if (!argumentCount()) - return false; - - const Deprecated::ScriptValue& value = argumentAt(0); - if (checkForNullOrUndefined && (value.isNull() || value.isUndefined())) - return false; - - if (!globalState()) { - ASSERT_NOT_REACHED(); - return false; - } - - result = value.toString(globalState()); - return true; -} - -bool ScriptArguments::isEqual(ScriptArguments* other) const -{ - if (!other) - return false; - - if (m_arguments.size() != other->m_arguments.size()) - return false; - if (!globalState() && m_arguments.size()) - return false; - - for (size_t i = 0; i < m_arguments.size(); ++i) { - if (!m_arguments[i].isEqual(other->globalState(), other->m_arguments[i])) - return false; - } - return true; -} - -} // namespace WebCore diff --git a/Source/WebCore/inspector/ScriptArguments.h b/Source/WebCore/inspector/ScriptArguments.h deleted file mode 100644 index 47a96238b..000000000 --- a/Source/WebCore/inspector/ScriptArguments.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ScriptArguments_h -#define ScriptArguments_h - -#include <heap/Strong.h> -#include <wtf/Forward.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> -#include <wtf/text/WTFString.h> - -namespace Deprecated { -class ScriptValue; -} - -namespace JSC { -class ExecState; -class JSGlobalObject; -} - -namespace WebCore { - -class ScriptArguments : public RefCounted<ScriptArguments> { -public: - static PassRefPtr<ScriptArguments> create(JSC::ExecState*, Vector<Deprecated::ScriptValue>& arguments); - - ~ScriptArguments(); - - const Deprecated::ScriptValue& argumentAt(size_t) const; - size_t argumentCount() const { return m_arguments.size(); } - - JSC::ExecState* globalState() const; - - bool getFirstArgumentAsString(WTF::String& result, bool checkForNullOrUndefined = false); - bool isEqual(ScriptArguments*) const; - -private: - ScriptArguments(JSC::ExecState*, Vector<Deprecated::ScriptValue>& arguments); - - JSC::Strong<JSC::JSGlobalObject> m_globalObject; - Vector<Deprecated::ScriptValue> m_arguments; -}; - -} // namespace WebCore - -#endif // ScriptArguments_h diff --git a/Source/WebCore/inspector/ScriptCallFrame.cpp b/Source/WebCore/inspector/ScriptCallFrame.cpp deleted file mode 100644 index 69c28f99f..000000000 --- a/Source/WebCore/inspector/ScriptCallFrame.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScriptCallFrame.h" - -#include "InspectorWebFrontendDispatchers.h" -#include <inspector/InspectorValues.h> -#include <wtf/RefPtr.h> - -using namespace Inspector; - -namespace WebCore { - -ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column) - : m_functionName(functionName) - , m_scriptName(scriptName) - , m_lineNumber(lineNumber) - , m_column(column) -{ -} - -ScriptCallFrame::~ScriptCallFrame() -{ -} - -bool ScriptCallFrame::isEqual(const ScriptCallFrame& o) const -{ - return m_functionName == o.m_functionName - && m_scriptName == o.m_scriptName - && m_lineNumber == o.m_lineNumber - && m_column == o.m_column; -} - -#if ENABLE(INSPECTOR) -PassRefPtr<Inspector::TypeBuilder::Console::CallFrame> ScriptCallFrame::buildInspectorObject() const -{ - return Inspector::TypeBuilder::Console::CallFrame::create() - .setFunctionName(m_functionName) - .setUrl(m_scriptName) - .setLineNumber(m_lineNumber) - .setColumnNumber(m_column) - .release(); -} -#endif - -} // namespace WebCore diff --git a/Source/WebCore/inspector/ScriptCallFrame.h b/Source/WebCore/inspector/ScriptCallFrame.h deleted file mode 100644 index d6dcfa3f2..000000000 --- a/Source/WebCore/inspector/ScriptCallFrame.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ScriptCallFrame_h -#define ScriptCallFrame_h - -#if ENABLE(INSPECTOR) -#include "InspectorWebTypeBuilders.h" -#endif - -#include <wtf/Forward.h> -#include <wtf/text/WTFString.h> - -namespace Inspector { -class InspectorObject; -} - -namespace WebCore { - -class ScriptCallFrame { -public: - ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column); - ~ScriptCallFrame(); - - const String& functionName() const { return m_functionName; } - const String& sourceURL() const { return m_scriptName; } - unsigned lineNumber() const { return m_lineNumber; } - unsigned columnNumber() const { return m_column; } - - bool isEqual(const ScriptCallFrame&) const; - -#if ENABLE(INSPECTOR) - PassRefPtr<Inspector::TypeBuilder::Console::CallFrame> buildInspectorObject() const; -#endif - -private: - String m_functionName; - String m_scriptName; - unsigned m_lineNumber; - unsigned m_column; -}; - -} // namespace WebCore - -#endif // ScriptCallFrame_h diff --git a/Source/WebCore/inspector/ScriptProfile.idl b/Source/WebCore/inspector/ScriptProfile.idl deleted file mode 100644 index fb231bde8..000000000 --- a/Source/WebCore/inspector/ScriptProfile.idl +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -[ - NoInterfaceObject, -] interface ScriptProfile { - readonly attribute DOMString title; - readonly attribute unsigned long uid; - readonly attribute ScriptProfileNode head; - readonly attribute double idleTime; -}; - diff --git a/Source/WebCore/inspector/ScriptProfileNode.idl b/Source/WebCore/inspector/ScriptProfileNode.idl deleted file mode 100644 index b0769de7e..000000000 --- a/Source/WebCore/inspector/ScriptProfileNode.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -[ - NoInterfaceObject, - ImplementationLacksVTable -] interface ScriptProfileNode { - readonly attribute DOMString functionName; - readonly attribute DOMString url; - readonly attribute unsigned long lineNumber; - readonly attribute double totalTime; - readonly attribute double selfTime; - readonly attribute unsigned long numberOfCalls; - sequence<ScriptProfileNode> children(); - readonly attribute unsigned long callUID; -}; - diff --git a/Source/WebCore/inspector/TimelineRecordFactory.cpp b/Source/WebCore/inspector/TimelineRecordFactory.cpp index 9f2f7fccc..a216593f8 100644 --- a/Source/WebCore/inspector/TimelineRecordFactory.cpp +++ b/Source/WebCore/inspector/TimelineRecordFactory.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2014 University of Washington. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,228 +30,125 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "TimelineRecordFactory.h" #include "Event.h" #include "FloatQuad.h" -#include "IntRect.h" -#include "LayoutRect.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "ScriptCallStack.h" -#include "ScriptCallStackFactory.h" -#include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> +#include "JSMainThreadExecState.h" +#include <inspector/InspectorProtocolObjects.h> +#include <inspector/ScriptBreakpoint.h> +#include <inspector/ScriptCallStack.h> +#include <inspector/ScriptCallStackFactory.h> using namespace Inspector; namespace WebCore { -PassRefPtr<InspectorObject> TimelineRecordFactory::createGenericRecord(double startTime, int maxCallStackDepth) +Ref<InspectorObject> TimelineRecordFactory::createGenericRecord(double startTime, int maxCallStackDepth) { - RefPtr<InspectorObject> record = InspectorObject::create(); - record->setNumber("startTime", startTime); + Ref<InspectorObject> record = InspectorObject::create(); + record->setDouble(ASCIILiteral("startTime"), startTime); if (maxCallStackDepth) { - RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(maxCallStackDepth, true); - if (stackTrace && stackTrace->size()) - record->setValue("stackTrace", stackTrace->buildInspectorArray()); + Ref<ScriptCallStack> stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), maxCallStackDepth); + if (stackTrace->size()) + record->setValue(ASCIILiteral("stackTrace"), stackTrace->buildInspectorArray()); } - return record.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createBackgroundRecord(double startTime, const String& threadName) -{ - RefPtr<InspectorObject> record = InspectorObject::create(); - record->setNumber("startTime", startTime); - record->setString("thread", threadName); - return record.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createGCEventData(const size_t usedHeapSizeDelta) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("usedHeapSizeDelta", usedHeapSizeDelta); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createFunctionCallData(const String& scriptName, int scriptLine) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("scriptName", scriptName); - data->setNumber("scriptLine", scriptLine); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createEventDispatchData(const Event& event) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("type", event.type().string()); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createGenericTimerData(int timerId) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("timerId", timerId); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createTimerInstallData(int timerId, int timeout, bool singleShot) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("timerId", timerId); - data->setNumber("timeout", timeout); - data->setBoolean("singleShot", singleShot); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createXHRReadyStateChangeData(const String& url, int readyState) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("url", url); - data->setNumber("readyState", readyState); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createXHRLoadData(const String& url) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("url", url); - return data.release(); + return record; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createEvaluateScriptData(const String& url, double lineNumber) +Ref<InspectorObject> TimelineRecordFactory::createFunctionCallData(const String& scriptName, int scriptLine) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("url", url); - data->setNumber("lineNumber", lineNumber); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setString(ASCIILiteral("scriptName"), scriptName); + data->setInteger(ASCIILiteral("scriptLine"), scriptLine); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createTimeStampData(const String& message) +Ref<InspectorObject> TimelineRecordFactory::createConsoleProfileData(const String& title) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("message", message); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setString(ASCIILiteral("title"), title); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createScheduleResourceRequestData(const String& url) +Ref<InspectorObject> TimelineRecordFactory::createProbeSampleData(const ScriptBreakpointAction& action, unsigned sampleId) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("url", url); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setInteger(ASCIILiteral("probeId"), action.identifier); + data->setInteger(ASCIILiteral("sampleId"), sampleId); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceSendRequestData(const String& requestId, const ResourceRequest& request) +Ref<InspectorObject> TimelineRecordFactory::createEventDispatchData(const Event& event) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("requestId", requestId); - data->setString("url", request.url().string()); - data->setString("requestMethod", request.httpMethod()); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setString(ASCIILiteral("type"), event.type().string()); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceReceiveResponseData(const String& requestId, const ResourceResponse& response) +Ref<InspectorObject> TimelineRecordFactory::createGenericTimerData(int timerId) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("requestId", requestId); - data->setNumber("statusCode", response.httpStatusCode()); - data->setString("mimeType", response.mimeType()); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setInteger(ASCIILiteral("timerId"), timerId); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceFinishData(const String& requestId, bool didFail, double finishTime) +Ref<InspectorObject> TimelineRecordFactory::createTimerInstallData(int timerId, std::chrono::milliseconds timeout, bool singleShot) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("requestId", requestId); - data->setBoolean("didFail", didFail); - if (finishTime) - data->setNumber("networkTime", finishTime); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setInteger(ASCIILiteral("timerId"), timerId); + data->setInteger(ASCIILiteral("timeout"), (int)timeout.count()); + data->setBoolean(ASCIILiteral("singleShot"), singleShot); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createReceiveResourceData(const String& requestId, int length) +Ref<InspectorObject> TimelineRecordFactory::createEvaluateScriptData(const String& url, double lineNumber) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("requestId", requestId); - data->setNumber("encodedDataLength", length); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setString(ASCIILiteral("url"), url); + data->setInteger(ASCIILiteral("lineNumber"), lineNumber); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createLayoutData(unsigned dirtyObjects, unsigned totalObjects, bool partialLayout) +Ref<InspectorObject> TimelineRecordFactory::createTimeStampData(const String& message) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("dirtyObjects", dirtyObjects); - data->setNumber("totalObjects", totalObjects); - data->setBoolean("partialLayout", partialLayout); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createDecodeImageData(const String& imageType) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setString("imageType", imageType); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setString(ASCIILiteral("message"), message); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createResizeImageData(bool shouldCache) +Ref<InspectorObject> TimelineRecordFactory::createAnimationFrameData(int callbackId) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setBoolean("cached", shouldCache); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setInteger(ASCIILiteral("id"), callbackId); + return data; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createMarkData(bool isMainFrame) +static Ref<InspectorArray> createQuad(const FloatQuad& quad) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setBoolean("isMainFrame", isMainFrame); - return data.release(); + Ref<InspectorArray> array = InspectorArray::create(); + array->pushDouble(quad.p1().x()); + array->pushDouble(quad.p1().y()); + array->pushDouble(quad.p2().x()); + array->pushDouble(quad.p2().y()); + array->pushDouble(quad.p3().x()); + array->pushDouble(quad.p3().y()); + array->pushDouble(quad.p4().x()); + array->pushDouble(quad.p4().y()); + return array; } -PassRefPtr<InspectorObject> TimelineRecordFactory::createParseHTMLData(unsigned startLine) +Ref<InspectorObject> TimelineRecordFactory::createPaintData(const FloatQuad& quad) { - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("startLine", startLine); - return data.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createAnimationFrameData(int callbackId) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setNumber("id", callbackId); - return data.release(); -} - -static PassRefPtr<InspectorArray> createQuad(const FloatQuad& quad) -{ - RefPtr<InspectorArray> array = InspectorArray::create(); - array->pushNumber(quad.p1().x()); - array->pushNumber(quad.p1().y()); - array->pushNumber(quad.p2().x()); - array->pushNumber(quad.p2().y()); - array->pushNumber(quad.p3().x()); - array->pushNumber(quad.p3().y()); - array->pushNumber(quad.p4().x()); - array->pushNumber(quad.p4().y()); - return array.release(); -} - -PassRefPtr<InspectorObject> TimelineRecordFactory::createPaintData(const FloatQuad& quad) -{ - RefPtr<InspectorObject> data = InspectorObject::create(); - data->setArray("clip", createQuad(quad)); - return data.release(); + Ref<InspectorObject> data = InspectorObject::create(); + data->setArray(ASCIILiteral("clip"), createQuad(quad)); + return data; } void TimelineRecordFactory::appendLayoutRoot(InspectorObject* data, const FloatQuad& quad) { - data->setArray("root", createQuad(quad)); + data->setArray(ASCIILiteral("root"), createQuad(quad)); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/TimelineRecordFactory.h b/Source/WebCore/inspector/TimelineRecordFactory.h index e4bf90a97..fb705d1ea 100644 --- a/Source/WebCore/inspector/TimelineRecordFactory.h +++ b/Source/WebCore/inspector/TimelineRecordFactory.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2014 University of Washington. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,92 +29,40 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TimelineRecordFactory_h -#define TimelineRecordFactory_h +#pragma once -#include "URL.h" #include <inspector/InspectorValues.h> #include <wtf/Forward.h> #include <wtf/text/WTFString.h> -namespace WebCore { - - class Event; - class FloatQuad; - class ResourceRequest; - class ResourceResponse; - - class TimelineRecordFactory { - public: - static PassRefPtr<Inspector::InspectorObject> createGenericRecord(double startTime, int maxCallStackDepth); - static PassRefPtr<Inspector::InspectorObject> createBackgroundRecord(double startTime, const String& thread); - - static PassRefPtr<Inspector::InspectorObject> createGCEventData(const size_t usedHeapSizeDelta); - - static PassRefPtr<Inspector::InspectorObject> createFunctionCallData(const String& scriptName, int scriptLine); - - static PassRefPtr<Inspector::InspectorObject> createEventDispatchData(const Event&); - - static PassRefPtr<Inspector::InspectorObject> createGenericTimerData(int timerId); - - static PassRefPtr<Inspector::InspectorObject> createTimerInstallData(int timerId, int timeout, bool singleShot); - - static PassRefPtr<Inspector::InspectorObject> createXHRReadyStateChangeData(const String& url, int readyState); - - static PassRefPtr<Inspector::InspectorObject> createXHRLoadData(const String& url); - - static PassRefPtr<Inspector::InspectorObject> createEvaluateScriptData(const String&, double lineNumber); - - static PassRefPtr<Inspector::InspectorObject> createTimeStampData(const String&); +namespace Inspector { +struct ScriptBreakpointAction; +} - static PassRefPtr<Inspector::InspectorObject> createResourceSendRequestData(const String& requestId, const ResourceRequest&); - - static PassRefPtr<Inspector::InspectorObject> createScheduleResourceRequestData(const String&); - - static PassRefPtr<Inspector::InspectorObject> createResourceReceiveResponseData(const String& requestId, const ResourceResponse&); - - static PassRefPtr<Inspector::InspectorObject> createReceiveResourceData(const String& requestId, int length); - - static PassRefPtr<Inspector::InspectorObject> createResourceFinishData(const String& requestId, bool didFail, double finishTime); - - static PassRefPtr<Inspector::InspectorObject> createLayoutData(unsigned dirtyObjects, unsigned totalObjects, bool partialLayout); - - static PassRefPtr<Inspector::InspectorObject> createDecodeImageData(const String& imageType); - - static PassRefPtr<Inspector::InspectorObject> createResizeImageData(bool shouldCache); - - static PassRefPtr<Inspector::InspectorObject> createMarkData(bool isMainFrame); - - static PassRefPtr<Inspector::InspectorObject> createParseHTMLData(unsigned startLine); +namespace WebCore { - static PassRefPtr<Inspector::InspectorObject> createAnimationFrameData(int callbackId); +class Event; +class FloatQuad; - static PassRefPtr<Inspector::InspectorObject> createPaintData(const FloatQuad&); +class TimelineRecordFactory { +public: + static Ref<Inspector::InspectorObject> createGenericRecord(double startTime, int maxCallStackDepth); - static void appendLayoutRoot(Inspector::InspectorObject* data, const FloatQuad&); + static Ref<Inspector::InspectorObject> createFunctionCallData(const String& scriptName, int scriptLine); + static Ref<Inspector::InspectorObject> createConsoleProfileData(const String& title); + static Ref<Inspector::InspectorObject> createProbeSampleData(const Inspector::ScriptBreakpointAction&, unsigned sampleId); + static Ref<Inspector::InspectorObject> createEventDispatchData(const Event&); + static Ref<Inspector::InspectorObject> createGenericTimerData(int timerId); + static Ref<Inspector::InspectorObject> createTimerInstallData(int timerId, std::chrono::milliseconds timeout, bool singleShot); + static Ref<Inspector::InspectorObject> createEvaluateScriptData(const String&, double lineNumber); + static Ref<Inspector::InspectorObject> createTimeStampData(const String&); + static Ref<Inspector::InspectorObject> createAnimationFrameData(int callbackId); + static Ref<Inspector::InspectorObject> createPaintData(const FloatQuad&); -#if ENABLE(WEB_SOCKETS) - static inline PassRefPtr<Inspector::InspectorObject> createWebSocketCreateData(unsigned long identifier, const URL& url, const String& protocol) - { - RefPtr<Inspector::InspectorObject> data = Inspector::InspectorObject::create(); - data->setNumber("identifier", identifier); - data->setString("url", url.string()); - if (!protocol.isNull()) - data->setString("webSocketProtocol", protocol); - return data.release(); - } + static void appendLayoutRoot(Inspector::InspectorObject* data, const FloatQuad&); - static inline PassRefPtr<Inspector::InspectorObject> createGenericWebSocketData(unsigned long identifier) - { - RefPtr<Inspector::InspectorObject> data = Inspector::InspectorObject::create(); - data->setNumber("identifier", identifier); - return data.release(); - } -#endif - private: - TimelineRecordFactory() { } - }; +private: + TimelineRecordFactory() { } +}; } // namespace WebCore - -#endif // !defined(TimelineRecordFactory_h) diff --git a/Source/WebCore/inspector/WebConsoleAgent.cpp b/Source/WebCore/inspector/WebConsoleAgent.cpp new file mode 100644 index 000000000..89052700e --- /dev/null +++ b/Source/WebCore/inspector/WebConsoleAgent.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "config.h" +#include "WebConsoleAgent.h" + +#include "CommandLineAPIHost.h" +#include "DOMWindow.h" +#include "ResourceError.h" +#include "ResourceResponse.h" +#include "ScriptState.h" +#include "WebInjectedScriptManager.h" +#include <inspector/ConsoleMessage.h> +#include <runtime/JSCInlines.h> +#include <wtf/text/StringBuilder.h> + +using namespace Inspector; + +namespace WebCore { + +WebConsoleAgent::WebConsoleAgent(AgentContext& context, InspectorHeapAgent* heapAgent) + : InspectorConsoleAgent(context, heapAgent) +{ +} + +void WebConsoleAgent::setMonitoringXHREnabled(ErrorString&, bool enabled) +{ + m_monitoringXHREnabled = enabled; +} + +void WebConsoleAgent::frameWindowDiscarded(DOMWindow* window) +{ + for (auto& message : m_consoleMessages) { + JSC::ExecState* exec = message->scriptState(); + if (!exec) + continue; + if (domWindowFromExecState(exec) != window) + continue; + message->clear(); + } + + static_cast<WebInjectedScriptManager&>(m_injectedScriptManager).discardInjectedScriptsFor(window); +} + +void WebConsoleAgent::didFinishXHRLoading(unsigned long requestIdentifier, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber) +{ + if (!m_injectedScriptManager.inspectorEnvironment().developerExtrasEnabled()) + return; + + if (m_monitoringXHREnabled) { + String message = "XHR finished loading: \"" + url + "\"."; + addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::Network, MessageType::Log, MessageLevel::Debug, message, sendURL, sendLineNumber, sendColumnNumber, nullptr, requestIdentifier)); + } +} + +void WebConsoleAgent::didReceiveResponse(unsigned long requestIdentifier, const ResourceResponse& response) +{ + if (!m_injectedScriptManager.inspectorEnvironment().developerExtrasEnabled()) + return; + + if (response.httpStatusCode() >= 400) { + String message = "Failed to load resource: the server responded with a status of " + String::number(response.httpStatusCode()) + " (" + response.httpStatusText() + ')'; + addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::Network, MessageType::Log, MessageLevel::Error, message, response.url().string(), 0, 0, nullptr, requestIdentifier)); + } +} + +void WebConsoleAgent::didFailLoading(unsigned long requestIdentifier, const ResourceError& error) +{ + if (!m_injectedScriptManager.inspectorEnvironment().developerExtrasEnabled()) + return; + + // Report failures only. + if (error.isCancellation()) + return; + + StringBuilder message; + message.appendLiteral("Failed to load resource"); + if (!error.localizedDescription().isEmpty()) { + message.appendLiteral(": "); + message.append(error.localizedDescription()); + } + + addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::Network, MessageType::Log, MessageLevel::Error, message.toString(), error.failingURL(), 0, 0, nullptr, requestIdentifier)); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/ConsoleAPITypes.h b/Source/WebCore/inspector/WebConsoleAgent.h index 11f65ec21..a4ffc9e91 100644 --- a/Source/WebCore/inspector/ConsoleAPITypes.h +++ b/Source/WebCore/inspector/WebConsoleAgent.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,27 +23,34 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ConsoleAPITypes_h -#define ConsoleAPITypes_h +#pragma once + +#include <inspector/agents/InspectorConsoleAgent.h> namespace WebCore { -enum MessageType { - LogMessageType, - DirMessageType, - DirXMLMessageType, - TableMessageType, - TraceMessageType, - StartGroupMessageType, - StartGroupCollapsedMessageType, - EndGroupMessageType, - ClearMessageType, - AssertMessageType, - TimingMessageType, - ProfileMessageType, - ProfileEndMessageType +class DOMWindow; +class ResourceError; +class ResourceResponse; +typedef String ErrorString; + +class WebConsoleAgent : public Inspector::InspectorConsoleAgent { + WTF_MAKE_NONCOPYABLE(WebConsoleAgent); + WTF_MAKE_FAST_ALLOCATED; +public: + WebConsoleAgent(Inspector::AgentContext&, Inspector::InspectorHeapAgent*); + virtual ~WebConsoleAgent() { } + + void setMonitoringXHREnabled(ErrorString&, bool enabled) final; + + void frameWindowDiscarded(DOMWindow*); + + void didFinishXHRLoading(unsigned long requestIdentifier, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber); + void didReceiveResponse(unsigned long requestIdentifier, const ResourceResponse&); + void didFailLoading(unsigned long requestIdentifier, const ResourceError&); + +protected: + bool m_monitoringXHREnabled { false }; }; } // namespace WebCore - -#endif // ConsoleAPITypes_h diff --git a/Source/WebCore/inspector/WebDebuggerAgent.cpp b/Source/WebCore/inspector/WebDebuggerAgent.cpp index 57d21744c..e6648e757 100644 --- a/Source/WebCore/inspector/WebDebuggerAgent.cpp +++ b/Source/WebCore/inspector/WebDebuggerAgent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,32 +26,28 @@ #include "config.h" #include "WebDebuggerAgent.h" -#if ENABLE(INSPECTOR) - #include "InstrumentingAgents.h" using namespace Inspector; namespace WebCore { -WebDebuggerAgent::WebDebuggerAgent(InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents) - : InspectorDebuggerAgent(injectedScriptManager) - , m_instrumentingAgents(instrumentingAgents) +WebDebuggerAgent::WebDebuggerAgent(WebAgentContext& context) + : InspectorDebuggerAgent(context) + , m_instrumentingAgents(context.instrumentingAgents) { } void WebDebuggerAgent::enable() { InspectorDebuggerAgent::enable(); - m_instrumentingAgents->setInspectorDebuggerAgent(this); + m_instrumentingAgents.setInspectorDebuggerAgent(this); } void WebDebuggerAgent::disable(bool isBeingDestroyed) { InspectorDebuggerAgent::disable(isBeingDestroyed); - m_instrumentingAgents->setInspectorDebuggerAgent(nullptr); + m_instrumentingAgents.setInspectorDebuggerAgent(nullptr); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/WebDebuggerAgent.h b/Source/WebCore/inspector/WebDebuggerAgent.h index 0e425ea7f..7724bbecb 100644 --- a/Source/WebCore/inspector/WebDebuggerAgent.h +++ b/Source/WebCore/inspector/WebDebuggerAgent.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,11 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebDebuggerAgent_h -#define WebDebuggerAgent_h - -#if ENABLE(INSPECTOR) +#pragma once +#include "InspectorWebAgentBase.h" #include <inspector/agents/InspectorDebuggerAgent.h> namespace WebCore { @@ -39,18 +37,14 @@ class WebDebuggerAgent : public Inspector::InspectorDebuggerAgent { WTF_MAKE_NONCOPYABLE(WebDebuggerAgent); WTF_MAKE_FAST_ALLOCATED; public: - WebDebuggerAgent(Inspector::InjectedScriptManager*, InstrumentingAgents*); + WebDebuggerAgent(WebAgentContext&); virtual ~WebDebuggerAgent() { } protected: - virtual void enable() override; - virtual void disable(bool isBeingDestroyed) override; + void enable() override; + void disable(bool isBeingDestroyed) override; - InstrumentingAgents* m_instrumentingAgents; + InstrumentingAgents& m_instrumentingAgents; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(WebDebuggerAgent_h) diff --git a/Source/WebCore/inspector/WebHeapAgent.cpp b/Source/WebCore/inspector/WebHeapAgent.cpp new file mode 100644 index 000000000..d887fb75a --- /dev/null +++ b/Source/WebCore/inspector/WebHeapAgent.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebHeapAgent.h" + +#include <wtf/RunLoop.h> + +using namespace Inspector; + +namespace WebCore { + +struct GarbageCollectionData { + Inspector::Protocol::Heap::GarbageCollection::Type type; + double startTime; + double endTime; +}; + +class SendGarbageCollectionEventsTask { +public: + SendGarbageCollectionEventsTask(WebHeapAgent&); + void addGarbageCollection(GarbageCollectionData&&); + void reset(); +private: + void timerFired(); + + WebHeapAgent& m_agent; + Vector<GarbageCollectionData> m_collections; + RunLoop::Timer<SendGarbageCollectionEventsTask> m_timer; + Lock m_mutex; +}; + +SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask(WebHeapAgent& agent) + : m_agent(agent) + , m_timer(RunLoop::main(), this, &SendGarbageCollectionEventsTask::timerFired) +{ +} + +void SendGarbageCollectionEventsTask::addGarbageCollection(GarbageCollectionData&& collection) +{ + { + std::lock_guard<Lock> lock(m_mutex); + m_collections.append(WTFMove(collection)); + } + + if (!m_timer.isActive()) + m_timer.startOneShot(0); +} + +void SendGarbageCollectionEventsTask::reset() +{ + { + std::lock_guard<Lock> lock(m_mutex); + m_collections.clear(); + } + + m_timer.stop(); +} + +void SendGarbageCollectionEventsTask::timerFired() +{ + Vector<GarbageCollectionData> collectionsToSend; + + { + std::lock_guard<Lock> lock(m_mutex); + m_collections.swap(collectionsToSend); + } + + m_agent.dispatchGarbageCollectionEventsAfterDelay(WTFMove(collectionsToSend)); +} + +WebHeapAgent::WebHeapAgent(Inspector::AgentContext& context) + : InspectorHeapAgent(context) + , m_sendGarbageCollectionEventsTask(std::make_unique<SendGarbageCollectionEventsTask>(*this)) +{ +} + +WebHeapAgent::~WebHeapAgent() +{ + m_sendGarbageCollectionEventsTask->reset(); +} + +void WebHeapAgent::disable(ErrorString& errorString) +{ + m_sendGarbageCollectionEventsTask->reset(); + + InspectorHeapAgent::disable(errorString); +} + +void WebHeapAgent::dispatchGarbageCollectedEvent(Inspector::Protocol::Heap::GarbageCollection::Type type, double startTime, double endTime) +{ + // Dispatch the event asynchronously because this method may be + // called between collection and sweeping and we don't want to + // create unexpected JavaScript allocations that the Sweeper does + // not expect to encounter. JavaScript allocations could happen + // with WebKitLegacy's in process inspector which shares the same + // VM as the inspected page. + + GarbageCollectionData data = {type, startTime, endTime}; + m_sendGarbageCollectionEventsTask->addGarbageCollection(WTFMove(data)); +} + +void WebHeapAgent::dispatchGarbageCollectionEventsAfterDelay(Vector<GarbageCollectionData>&& collections) +{ + for (auto& collection : collections) + InspectorHeapAgent::dispatchGarbageCollectedEvent(collection.type, collection.startTime, collection.endTime); +} + +} // namespace WebCore diff --git a/Source/WebCore/inspector/WebHeapAgent.h b/Source/WebCore/inspector/WebHeapAgent.h new file mode 100644 index 000000000..30a889658 --- /dev/null +++ b/Source/WebCore/inspector/WebHeapAgent.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <inspector/agents/InspectorHeapAgent.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class SendGarbageCollectionEventsTask; +struct GarbageCollectionData; +typedef String ErrorString; + +class WebHeapAgent : public Inspector::InspectorHeapAgent { + WTF_MAKE_NONCOPYABLE(WebHeapAgent); + WTF_MAKE_FAST_ALLOCATED; + friend class SendGarbageCollectionEventsTask; +public: + WebHeapAgent(Inspector::AgentContext&); + virtual ~WebHeapAgent(); + +protected: + void disable(ErrorString&) override; + + void dispatchGarbageCollectedEvent(Inspector::Protocol::Heap::GarbageCollection::Type, double startTime, double endTime) override; + + void dispatchGarbageCollectionEventsAfterDelay(Vector<GarbageCollectionData>&& collections); + + std::unique_ptr<SendGarbageCollectionEventsTask> m_sendGarbageCollectionEventsTask; +}; + +} // namespace WebCore diff --git a/Source/WebCore/inspector/PageInjectedScriptHost.cpp b/Source/WebCore/inspector/WebInjectedScriptHost.cpp index f6a5e65f7..0c504d392 100644 --- a/Source/WebCore/inspector/PageInjectedScriptHost.cpp +++ b/Source/WebCore/inspector/WebInjectedScriptHost.cpp @@ -24,10 +24,10 @@ */ #include "config.h" -#include "PageInjectedScriptHost.h" - -#if ENABLE(INSPECTOR) +#include "WebInjectedScriptHost.h" +#include "ExceptionHeaders.h" +#include "ExceptionInterfaces.h" #include "JSHTMLAllCollection.h" #include "JSHTMLCollection.h" #include "JSNode.h" @@ -36,24 +36,29 @@ using namespace JSC; namespace WebCore { + +#define RETURN_ERROR_IF_VALUE_INHERITS_EXCEPTION_TYPE(interfaceName) \ + if (value.inherits(vm, JS##interfaceName::info())) \ + return jsNontrivialString(exec, ASCIILiteral("error")); -JSValue PageInjectedScriptHost::type(JSC::ExecState* exec, JSC::JSValue value) +JSValue WebInjectedScriptHost::subtype(JSC::ExecState* exec, JSC::JSValue value) { - if (value.inherits(JSNode::info())) + VM& vm = exec->vm(); + if (value.inherits(vm, JSNode::info())) return jsNontrivialString(exec, ASCIILiteral("node")); - if (value.inherits(JSNodeList::info())) + if (value.inherits(vm, JSNodeList::info())) return jsNontrivialString(exec, ASCIILiteral("array")); - if (value.inherits(JSHTMLCollection::info())) + if (value.inherits(vm, JSHTMLCollection::info())) return jsNontrivialString(exec, ASCIILiteral("array")); + DOM_EXCEPTION_INTERFACES_FOR_EACH(RETURN_ERROR_IF_VALUE_INHERITS_EXCEPTION_TYPE) + return jsUndefined(); } -bool PageInjectedScriptHost::isHTMLAllCollection(JSC::JSValue value) +bool WebInjectedScriptHost::isHTMLAllCollection(JSC::VM& vm, JSC::JSValue value) { - return value.inherits(JSHTMLAllCollection::info()); + return value.inherits(vm, JSHTMLAllCollection::info()); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/PageInjectedScriptHost.h b/Source/WebCore/inspector/WebInjectedScriptHost.h index 6582188ff..17436ea0c 100644 --- a/Source/WebCore/inspector/PageInjectedScriptHost.h +++ b/Source/WebCore/inspector/WebInjectedScriptHost.h @@ -23,25 +23,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageInjectedScriptHost_h -#define PageInjectedScriptHost_h - -#if ENABLE(INSPECTOR) +#pragma once #include <inspector/InjectedScriptHost.h> namespace WebCore { -class PageInjectedScriptHost final : public Inspector::InjectedScriptHost { +class WebInjectedScriptHost final : public Inspector::InjectedScriptHost { public: - static PassRefPtr<PageInjectedScriptHost> create() { return adoptRef(new PageInjectedScriptHost); } + static Ref<WebInjectedScriptHost> create() { return adoptRef(*new WebInjectedScriptHost); } - virtual JSC::JSValue type(JSC::ExecState*, JSC::JSValue) override; - virtual bool isHTMLAllCollection(JSC::JSValue) override; + JSC::JSValue subtype(JSC::ExecState*, JSC::JSValue) override; + bool isHTMLAllCollection(JSC::VM&, JSC::JSValue) override; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(PageInjectedScriptHost_h) diff --git a/Source/WebCore/inspector/PageInjectedScriptManager.cpp b/Source/WebCore/inspector/WebInjectedScriptManager.cpp index 60c66f770..c7f82ff11 100644 --- a/Source/WebCore/inspector/PageInjectedScriptManager.cpp +++ b/Source/WebCore/inspector/WebInjectedScriptManager.cpp @@ -24,9 +24,7 @@ */ #include "config.h" -#include "PageInjectedScriptManager.h" - -#if ENABLE(INSPECTOR) +#include "WebInjectedScriptManager.h" #include "CommandLineAPIModule.h" #include "ScriptState.h" @@ -35,54 +33,59 @@ using namespace Inspector; namespace WebCore { -PageInjectedScriptManager::PageInjectedScriptManager(InspectorEnvironment& environment, PassRefPtr<InjectedScriptHost> host) - : InjectedScriptManager(environment, host) +WebInjectedScriptManager::WebInjectedScriptManager(InspectorEnvironment& environment, Ref<InjectedScriptHost>&& host) + : InjectedScriptManager(environment, WTFMove(host)) , m_commandLineAPIHost(CommandLineAPIHost::create()) { } -void PageInjectedScriptManager::disconnect() +void WebInjectedScriptManager::disconnect() { InjectedScriptManager::disconnect(); m_commandLineAPIHost->disconnect(); - m_commandLineAPIHost.clear(); + m_commandLineAPIHost = nullptr; } -void PageInjectedScriptManager::didCreateInjectedScript(InjectedScript injectedScript) +void WebInjectedScriptManager::discardInjectedScripts() +{ + InjectedScriptManager::discardInjectedScripts(); + + m_commandLineAPIHost->clearAllWrappers(); +} + +void WebInjectedScriptManager::didCreateInjectedScript(const Inspector::InjectedScript& injectedScript) { CommandLineAPIModule::injectIfNeeded(this, injectedScript); } -void PageInjectedScriptManager::discardInjectedScriptsFor(DOMWindow* window) +void WebInjectedScriptManager::discardInjectedScriptsFor(DOMWindow* window) { if (m_scriptStateToId.isEmpty()) return; Vector<long> idsToRemove; - for (auto it = m_idToInjectedScript.begin(), end = m_idToInjectedScript.end(); it != end; ++it) { - JSC::ExecState* scriptState = it->value.scriptState(); + for (const auto& it : m_idToInjectedScript) { + JSC::ExecState* scriptState = it.value.scriptState(); if (window != domWindowFromExecState(scriptState)) continue; m_scriptStateToId.remove(scriptState); - idsToRemove.append(it->key); + idsToRemove.append(it.key); } - for (size_t i = 0; i < idsToRemove.size(); i++) - m_idToInjectedScript.remove(idsToRemove[i]); + for (auto& id : idsToRemove) + m_idToInjectedScript.remove(id); // Now remove script states that have id but no injected script. Vector<JSC::ExecState*> scriptStatesToRemove; - for (auto it = m_scriptStateToId.begin(), end = m_scriptStateToId.end(); it != end; ++it) { - JSC::ExecState* scriptState = it->key; + for (const auto& it : m_scriptStateToId) { + JSC::ExecState* scriptState = it.key; if (window == domWindowFromExecState(scriptState)) scriptStatesToRemove.append(scriptState); } - for (size_t i = 0; i < scriptStatesToRemove.size(); i++) - m_scriptStateToId.remove(scriptStatesToRemove[i]); + for (auto& scriptState : scriptStatesToRemove) + m_scriptStateToId.remove(scriptState); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/PageInjectedScriptManager.h b/Source/WebCore/inspector/WebInjectedScriptManager.h index 1f8707e6f..6b4ad7cb9 100644 --- a/Source/WebCore/inspector/PageInjectedScriptManager.h +++ b/Source/WebCore/inspector/WebInjectedScriptManager.h @@ -23,8 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageInjectedScriptManager_h -#define PageInjectedScriptManager_h +#pragma once #include "CommandLineAPIHost.h" #include <inspector/InjectedScriptManager.h> @@ -34,24 +33,23 @@ namespace WebCore { class DOMWindow; -class PageInjectedScriptManager final : public Inspector::InjectedScriptManager { +class WebInjectedScriptManager final : public Inspector::InjectedScriptManager { public: - PageInjectedScriptManager(Inspector::InspectorEnvironment&, PassRefPtr<Inspector::InjectedScriptHost>); - virtual ~PageInjectedScriptManager() { } + WebInjectedScriptManager(Inspector::InspectorEnvironment&, Ref<Inspector::InjectedScriptHost>&&); + virtual ~WebInjectedScriptManager() { } CommandLineAPIHost* commandLineAPIHost() const { return m_commandLineAPIHost.get(); } - virtual void disconnect() override; + void disconnect() override; + void discardInjectedScripts() override; void discardInjectedScriptsFor(DOMWindow*); protected: - virtual void didCreateInjectedScript(Inspector::InjectedScript) override; + void didCreateInjectedScript(const Inspector::InjectedScript&) override; private: RefPtr<CommandLineAPIHost> m_commandLineAPIHost; }; } // namespace WebCore - -#endif // !defined(PageInjectedScriptManager_h) diff --git a/Source/WebCore/inspector/WorkerConsoleAgent.cpp b/Source/WebCore/inspector/WorkerConsoleAgent.cpp index 9f1056d4b..af7142949 100644 --- a/Source/WebCore/inspector/WorkerConsoleAgent.cpp +++ b/Source/WebCore/inspector/WorkerConsoleAgent.cpp @@ -1,57 +1,43 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "WorkerConsoleAgent.h" using namespace Inspector; namespace WebCore { -WorkerConsoleAgent::WorkerConsoleAgent(InstrumentingAgents* instrumentingAgents, PageInjectedScriptManager* injectedScriptManager) - : InspectorConsoleAgent(instrumentingAgents, injectedScriptManager) +WorkerConsoleAgent::WorkerConsoleAgent(WorkerAgentContext& context, InspectorHeapAgent* heapAgent) + : WebConsoleAgent(context, heapAgent) { } -WorkerConsoleAgent::~WorkerConsoleAgent() +void WorkerConsoleAgent::addInspectedNode(ErrorString& errorString, int) { -} - -void WorkerConsoleAgent::addInspectedNode(ErrorString* error, int) -{ - *error = "addInspectedNode is not supported for workers"; + errorString = ASCIILiteral("Unsupported for Workers."); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/WorkerConsoleAgent.h b/Source/WebCore/inspector/WorkerConsoleAgent.h index 99ad56221..d2078b8cc 100644 --- a/Source/WebCore/inspector/WorkerConsoleAgent.h +++ b/Source/WebCore/inspector/WorkerConsoleAgent.h @@ -1,57 +1,44 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WorkerConsoleAgent_h -#define WorkerConsoleAgent_h - -#include "InspectorConsoleAgent.h" -#include <wtf/PassOwnPtr.h> +#pragma once -#if ENABLE(INSPECTOR) +#include "InspectorWebAgentBase.h" +#include "WebConsoleAgent.h" namespace WebCore { -class WorkerConsoleAgent : public InspectorConsoleAgent { +class WorkerConsoleAgent final : public WebConsoleAgent { WTF_MAKE_NONCOPYABLE(WorkerConsoleAgent); + WTF_MAKE_FAST_ALLOCATED; public: - WorkerConsoleAgent(InstrumentingAgents*, PageInjectedScriptManager*); - virtual ~WorkerConsoleAgent(); - - virtual bool isWorkerAgent() override { return true; } + WorkerConsoleAgent(WorkerAgentContext&, Inspector::InspectorHeapAgent*); + ~WorkerConsoleAgent() { } private: - virtual void addInspectedNode(ErrorString*, int nodeId) override; + void addInspectedNode(ErrorString&, int nodeId) override; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(WorkerConsoleAgent_h) diff --git a/Source/WebCore/inspector/WorkerDebuggerAgent.cpp b/Source/WebCore/inspector/WorkerDebuggerAgent.cpp index 5053a4c12..e4050ed47 100644 --- a/Source/WebCore/inspector/WorkerDebuggerAgent.cpp +++ b/Source/WebCore/inspector/WorkerDebuggerAgent.cpp @@ -1,163 +1,68 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "WorkerDebuggerAgent.h" -#if ENABLE(INSPECTOR) - +#include "ScriptState.h" #include "WorkerGlobalScope.h" -#include "WorkerThread.h" +#include <inspector/ConsoleMessage.h> #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> -#include <inspector/ScriptDebugServer.h> -#include <mutex> -#include <wtf/MessageQueue.h> -#include <wtf/NeverDestroyed.h> +#include <inspector/ScriptCallStack.h> +#include <inspector/ScriptCallStackFactory.h> +using namespace JSC; using namespace Inspector; namespace WebCore { -namespace { - -std::mutex& workerDebuggerAgentsMutex() -{ - static std::once_flag onceFlag; - static std::mutex* mutex; - - std::call_once(onceFlag, []{ - mutex = std::make_unique<std::mutex>().release(); - }); - - return *mutex; -} - -typedef HashMap<WorkerThread*, WorkerDebuggerAgent*> WorkerDebuggerAgents; - -WorkerDebuggerAgents& workerDebuggerAgents() -{ - static NeverDestroyed<WorkerDebuggerAgents> agents; - - return agents; -} - -class RunInspectorCommandsTask : public ScriptDebugServer::Task { -public: - RunInspectorCommandsTask(WorkerThread* thread, WorkerGlobalScope* workerGlobalScope) - : m_thread(thread) - , m_workerGlobalScope(workerGlobalScope) { } - virtual ~RunInspectorCommandsTask() { } - virtual void run() override - { - // Process all queued debugger commands. It is safe to use m_workerGlobalScope here - // because it is alive if RunWorkerLoop is not terminated, otherwise it will - // just be ignored. WorkerThread is certainly alive if this task is being executed. - while (MessageQueueMessageReceived == m_thread->runLoop().runInMode(m_workerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode, WorkerRunLoop::DontWaitForMessage)) { } - } - -private: - WorkerThread* m_thread; - WorkerGlobalScope* m_workerGlobalScope; -}; - -} // namespace - -const char* WorkerDebuggerAgent::debuggerTaskMode = "debugger"; - -WorkerDebuggerAgent::WorkerDebuggerAgent(InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents, WorkerGlobalScope* inspectedWorkerGlobalScope) - : WebDebuggerAgent(injectedScriptManager, instrumentingAgents) - , m_scriptDebugServer(inspectedWorkerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode) - , m_inspectedWorkerGlobalScope(inspectedWorkerGlobalScope) +WorkerDebuggerAgent::WorkerDebuggerAgent(WorkerAgentContext& context) + : WebDebuggerAgent(context) + , m_workerGlobalScope(context.workerGlobalScope) { - std::lock_guard<std::mutex> lock(workerDebuggerAgentsMutex()); - workerDebuggerAgents().set(inspectedWorkerGlobalScope->thread(), this); } WorkerDebuggerAgent::~WorkerDebuggerAgent() { - std::lock_guard<std::mutex> lock(workerDebuggerAgentsMutex()); - - ASSERT(workerDebuggerAgents().contains(m_inspectedWorkerGlobalScope->thread())); - workerDebuggerAgents().remove(m_inspectedWorkerGlobalScope->thread()); } -void WorkerDebuggerAgent::interruptAndDispatchInspectorCommands(WorkerThread* thread) +void WorkerDebuggerAgent::breakpointActionLog(ExecState& state, const String& message) { - std::lock_guard<std::mutex> lock(workerDebuggerAgentsMutex()); - - if (WorkerDebuggerAgent* agent = workerDebuggerAgents().get(thread)) - agent->m_scriptDebugServer.interruptAndRunTask(adoptPtr(new RunInspectorCommandsTask(thread, agent->m_inspectedWorkerGlobalScope))); + m_workerGlobalScope.addConsoleMessage(std::make_unique<ConsoleMessage>(MessageSource::JS, MessageType::Log, MessageLevel::Log, message, createScriptCallStack(&state, ScriptCallStack::maxCallStackSizeToCapture))); } -void WorkerDebuggerAgent::startListeningScriptDebugServer() -{ - scriptDebugServer().addListener(this); -} - -void WorkerDebuggerAgent::stopListeningScriptDebugServer(bool isBeingDestroyed) -{ - scriptDebugServer().removeListener(this, isBeingDestroyed); -} - -void WorkerDebuggerAgent::breakpointActionLog(JSC::ExecState*, const String& message) -{ - m_inspectedWorkerGlobalScope->addConsoleMessage(JSMessageSource, LogMessageLevel, message); -} - -WorkerScriptDebugServer& WorkerDebuggerAgent::scriptDebugServer() -{ - return m_scriptDebugServer; -} - -InjectedScript WorkerDebuggerAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId) +InjectedScript WorkerDebuggerAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId) { if (executionContextId) { - *error = ASCIILiteral("Execution context id is not supported for workers as there is only one execution context."); + errorString = ASCIILiteral("Execution context id is not supported for workers as there is only one execution context."); return InjectedScript(); } - JSC::ExecState* scriptState = execStateFromWorkerGlobalScope(m_inspectedWorkerGlobalScope); - return injectedScriptManager()->injectedScriptFor(scriptState); -} - -void WorkerDebuggerAgent::muteConsole() -{ - // We don't need to mute console for workers. -} - -void WorkerDebuggerAgent::unmuteConsole() -{ - // We don't need to mute console for workers. + JSC::ExecState* scriptState = execStateFromWorkerGlobalScope(&m_workerGlobalScope); + return injectedScriptManager().injectedScriptFor(scriptState); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/WorkerDebuggerAgent.h b/Source/WebCore/inspector/WorkerDebuggerAgent.h index 6d41aa588..5094e6ca6 100644 --- a/Source/WebCore/inspector/WorkerDebuggerAgent.h +++ b/Source/WebCore/inspector/WorkerDebuggerAgent.h @@ -1,72 +1,52 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WorkerDebuggerAgent_h -#define WorkerDebuggerAgent_h - -#if ENABLE(INSPECTOR) +#pragma once #include "WebDebuggerAgent.h" -#include "WorkerScriptDebugServer.h" namespace WebCore { class WorkerGlobalScope; -class WorkerThread; class WorkerDebuggerAgent final : public WebDebuggerAgent { WTF_MAKE_NONCOPYABLE(WorkerDebuggerAgent); WTF_MAKE_FAST_ALLOCATED; public: - WorkerDebuggerAgent(Inspector::InjectedScriptManager*, InstrumentingAgents*, WorkerGlobalScope*); - virtual ~WorkerDebuggerAgent(); + WorkerDebuggerAgent(WorkerAgentContext&); + ~WorkerDebuggerAgent(); - static const char* debuggerTaskMode; - static void interruptAndDispatchInspectorCommands(WorkerThread*); - - virtual void startListeningScriptDebugServer() override; - virtual void stopListeningScriptDebugServer(bool isBeingDestroyed) override; - virtual WorkerScriptDebugServer& scriptDebugServer() override; - virtual Inspector::InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override; - virtual void muteConsole() override; - virtual void unmuteConsole() override; +private: + // We don't need to mute console for workers. + void muteConsole() override { } + void unmuteConsole() override { } - virtual void breakpointActionLog(JSC::ExecState*, const String&) override; + void breakpointActionLog(JSC::ExecState&, const String&) override; + Inspector::InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override; -private: - WorkerScriptDebugServer m_scriptDebugServer; - WorkerGlobalScope* m_inspectedWorkerGlobalScope; + WorkerGlobalScope& m_workerGlobalScope; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(WorkerDebuggerAgent_h) diff --git a/Source/WebCore/inspector/WorkerInspectorController.cpp b/Source/WebCore/inspector/WorkerInspectorController.cpp index 749c88152..d4aa76d63 100644 --- a/Source/WebCore/inspector/WorkerInspectorController.cpp +++ b/Source/WebCore/inspector/WorkerInspectorController.cpp @@ -1,152 +1,144 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "WorkerInspectorController.h" #include "CommandLineAPIHost.h" -#include "InspectorClient.h" -#include "InspectorConsoleAgent.h" -#include "InspectorForwarding.h" -#include "InspectorHeapProfilerAgent.h" -#include "InspectorInstrumentation.h" -#include "InspectorProfilerAgent.h" -#include "InspectorTimelineAgent.h" -#include "InspectorWebBackendDispatchers.h" -#include "InspectorWebFrontendDispatchers.h" #include "InstrumentingAgents.h" #include "JSMainThreadExecState.h" -#include "PageInjectedScriptHost.h" -#include "PageInjectedScriptManager.h" +#include "WebHeapAgent.h" +#include "WebInjectedScriptHost.h" +#include "WebInjectedScriptManager.h" #include "WorkerConsoleAgent.h" #include "WorkerDebuggerAgent.h" #include "WorkerGlobalScope.h" -#include "WorkerReportingProxy.h" #include "WorkerRuntimeAgent.h" #include "WorkerThread.h" +#include "WorkerToPageFrontendChannel.h" +#include <inspector/InspectorAgentBase.h> #include <inspector/InspectorBackendDispatcher.h> +#include <inspector/InspectorFrontendChannel.h> +#include <inspector/InspectorFrontendDispatchers.h> +#include <inspector/InspectorFrontendRouter.h> +using namespace JSC; using namespace Inspector; namespace WebCore { -namespace { - -class PageInspectorProxy : public InspectorFrontendChannel { - WTF_MAKE_FAST_ALLOCATED; -public: - explicit PageInspectorProxy(WorkerGlobalScope& workerGlobalScope) - : m_workerGlobalScope(workerGlobalScope) { } - virtual ~PageInspectorProxy() { } -private: - virtual bool sendMessageToFrontend(const String& message) override - { - m_workerGlobalScope.thread()->workerReportingProxy().postMessageToPageInspector(message); - return true; - } - WorkerGlobalScope& m_workerGlobalScope; -}; - -} - WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope) - : m_workerGlobalScope(workerGlobalScope) - , m_instrumentingAgents(InstrumentingAgents::create(*this)) - , m_injectedScriptManager(std::make_unique<PageInjectedScriptManager>(*this, PageInjectedScriptHost::create())) - , m_runtimeAgent(nullptr) + : m_instrumentingAgents(InstrumentingAgents::create(*this)) + , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create())) + , m_frontendRouter(FrontendRouter::create()) + , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) + , m_executionStopwatch(Stopwatch::create()) + , m_scriptDebugServer(workerGlobalScope) + , m_workerGlobalScope(workerGlobalScope) { - auto runtimeAgent = std::make_unique<WorkerRuntimeAgent>(m_injectedScriptManager.get(), &workerGlobalScope); - m_runtimeAgent = runtimeAgent.get(); - m_instrumentingAgents->setWorkerRuntimeAgent(m_runtimeAgent); - m_agents.append(std::move(runtimeAgent)); + AgentContext baseContext = { + *this, + *m_injectedScriptManager, + m_frontendRouter.get(), + m_backendDispatcher.get(), + }; - auto consoleAgent = std::make_unique<WorkerConsoleAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get()); - auto debuggerAgent = std::make_unique<WorkerDebuggerAgent>(m_injectedScriptManager.get(), m_instrumentingAgents.get(), &workerGlobalScope); - m_runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); - m_agents.append(std::move(debuggerAgent)); + WebAgentContext webContext = { + baseContext, + m_instrumentingAgents.get(), + }; - m_agents.append(InspectorProfilerAgent::create(m_instrumentingAgents.get(), consoleAgent.get(), &workerGlobalScope, m_injectedScriptManager.get())); - m_agents.append(std::make_unique<InspectorHeapProfilerAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get())); - m_agents.append(std::make_unique<InspectorTimelineAgent>(m_instrumentingAgents.get(), nullptr, nullptr, InspectorTimelineAgent::WorkerInspector, nullptr)); - m_agents.append(std::move(consoleAgent)); + WorkerAgentContext workerContext = { + webContext, + workerGlobalScope, + }; + + auto heapAgent = std::make_unique<WebHeapAgent>(workerContext); + + m_agents.append(std::make_unique<WorkerRuntimeAgent>(workerContext)); + m_agents.append(std::make_unique<WorkerDebuggerAgent>(workerContext)); + + auto consoleAgent = std::make_unique<WorkerConsoleAgent>(workerContext, heapAgent.get()); + m_instrumentingAgents->setWebConsoleAgent(consoleAgent.get()); + m_agents.append(WTFMove(consoleAgent)); + + m_agents.append(WTFMove(heapAgent)); if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) { - commandLineAPIHost->init(nullptr - , nullptr - , nullptr - , nullptr -#if ENABLE(SQL_DATABASE) - , nullptr -#endif + commandLineAPIHost->init( + nullptr // InspectorAgent + , m_instrumentingAgents->webConsoleAgent() + , nullptr // InspectorDOMAgent + , nullptr // InspectorDOMStorageAgent + , nullptr // InspectorDatabaseAgent ); } } - + WorkerInspectorController::~WorkerInspectorController() { + ASSERT(!m_frontendRouter->hasFrontends()); + ASSERT(!m_forwardingChannel); + m_instrumentingAgents->reset(); - disconnectFrontend(InspectorDisconnectReason::InspectedTargetDestroyed); +} + +void WorkerInspectorController::workerTerminating() +{ + m_injectedScriptManager->disconnect(); + + disconnectFrontend(Inspector::DisconnectReason::InspectedTargetDestroyed); + + m_agents.discardValues(); } void WorkerInspectorController::connectFrontend() { - ASSERT(!m_frontendChannel); - m_frontendChannel = std::make_unique<PageInspectorProxy>(m_workerGlobalScope); - m_backendDispatcher = InspectorBackendDispatcher::create(m_frontendChannel.get()); - m_agents.didCreateFrontendAndBackend(m_frontendChannel.get(), m_backendDispatcher.get()); + ASSERT(!m_frontendRouter->hasFrontends()); + ASSERT(!m_forwardingChannel); + + m_forwardingChannel = std::make_unique<WorkerToPageFrontendChannel>(m_workerGlobalScope); + m_frontendRouter->connectFrontend(m_forwardingChannel.get()); + m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get()); } -void WorkerInspectorController::disconnectFrontend(InspectorDisconnectReason reason) +void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason) { - if (!m_frontendChannel) + if (!m_frontendRouter->hasFrontends()) return; + ASSERT(m_forwardingChannel); + m_agents.willDestroyFrontendAndBackend(reason); - m_backendDispatcher->clearFrontend(); - m_backendDispatcher.clear(); - m_frontendChannel = nullptr; + m_frontendRouter->disconnectFrontend(m_forwardingChannel.get()); + m_forwardingChannel = nullptr; } void WorkerInspectorController::dispatchMessageFromFrontend(const String& message) { - if (m_backendDispatcher) - m_backendDispatcher->dispatch(message); -} - -void WorkerInspectorController::resume() -{ - ErrorString unused; - m_runtimeAgent->run(&unused); + m_backendDispatcher->dispatch(message); } InspectorFunctionCallHandler WorkerInspectorController::functionCallHandler() const @@ -159,20 +151,9 @@ InspectorEvaluateHandler WorkerInspectorController::evaluateHandler() const return WebCore::evaluateHandlerFromAnyThread; } -void WorkerInspectorController::willCallInjectedScriptFunction(JSC::ExecState* scriptState, const String& scriptName, int scriptLine) -{ - ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(scriptState); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(scriptExecutionContext, scriptName, scriptLine); - m_injectedScriptInstrumentationCookies.append(cookie); -} - -void WorkerInspectorController::didCallInjectedScriptFunction() +VM& WorkerInspectorController::vm() { - ASSERT(!m_injectedScriptInstrumentationCookies.isEmpty()); - InspectorInstrumentationCookie cookie = m_injectedScriptInstrumentationCookies.takeLast(); - InspectorInstrumentation::didCallFunction(cookie); + return m_workerGlobalScope.vm(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/WorkerInspectorController.h b/Source/WebCore/inspector/WorkerInspectorController.h index 7984088b1..f92d5efec 100644 --- a/Source/WebCore/inspector/WorkerInspectorController.h +++ b/Source/WebCore/inspector/WorkerInspectorController.h @@ -1,94 +1,84 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WorkerInspectorController_h -#define WorkerInspectorController_h - -#if ENABLE(INSPECTOR) +#pragma once -#include "InspectorInstrumentationCookie.h" -#include "InspectorWebAgentBase.h" +#include "WorkerScriptDebugServer.h" #include <inspector/InspectorAgentRegistry.h> #include <inspector/InspectorEnvironment.h> -#include <wtf/FastMalloc.h> #include <wtf/Forward.h> #include <wtf/Noncopyable.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> +#include <wtf/Stopwatch.h> namespace Inspector { -class InspectorBackendDispatcher; -} +class FrontendChannel; +class FrontendRouter; +}; namespace WebCore { -class InspectorInstrumentation; class InstrumentingAgents; -class PageInjectedScriptManager; +class WebInjectedScriptManager; class WorkerGlobalScope; -class WorkerRuntimeAgent; class WorkerInspectorController final : public Inspector::InspectorEnvironment { WTF_MAKE_NONCOPYABLE(WorkerInspectorController); WTF_MAKE_FAST_ALLOCATED; public: explicit WorkerInspectorController(WorkerGlobalScope&); - ~WorkerInspectorController(); + virtual ~WorkerInspectorController(); + + void workerTerminating(); void connectFrontend(); - void disconnectFrontend(Inspector::InspectorDisconnectReason); + void disconnectFrontend(Inspector::DisconnectReason); + void dispatchMessageFromFrontend(const String&); - void resume(); - virtual bool developerExtrasEnabled() const override { return true; } - virtual bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; } - virtual Inspector::InspectorFunctionCallHandler functionCallHandler() const override; - virtual Inspector::InspectorEvaluateHandler evaluateHandler() const override; - virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String& scriptName, int scriptLine) override; - virtual void didCallInjectedScriptFunction() override; + // InspectorEnvironment + bool developerExtrasEnabled() const override { return true; } + bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; } + Inspector::InspectorFunctionCallHandler functionCallHandler() const override; + Inspector::InspectorEvaluateHandler evaluateHandler() const override; + void frontendInitialized() override { } + Ref<WTF::Stopwatch> executionStopwatch() override { return m_executionStopwatch.copyRef(); } + WorkerScriptDebugServer& scriptDebugServer() override { return m_scriptDebugServer; } + JSC::VM& vm() override; private: - friend InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope*); + friend class InspectorInstrumentation; + Ref<InstrumentingAgents> m_instrumentingAgents; + std::unique_ptr<WebInjectedScriptManager> m_injectedScriptManager; + Ref<Inspector::FrontendRouter> m_frontendRouter; + Ref<Inspector::BackendDispatcher> m_backendDispatcher; + Ref<WTF::Stopwatch> m_executionStopwatch; + WorkerScriptDebugServer m_scriptDebugServer; + Inspector::AgentRegistry m_agents; WorkerGlobalScope& m_workerGlobalScope; - RefPtr<InstrumentingAgents> m_instrumentingAgents; - std::unique_ptr<PageInjectedScriptManager> m_injectedScriptManager; - WorkerRuntimeAgent* m_runtimeAgent; - Inspector::InspectorAgentRegistry m_agents; - std::unique_ptr<InspectorFrontendChannel> m_frontendChannel; - RefPtr<Inspector::InspectorBackendDispatcher> m_backendDispatcher; - Vector<InspectorInstrumentationCookie, 2> m_injectedScriptInstrumentationCookies; + std::unique_ptr<Inspector::FrontendChannel> m_forwardingChannel; }; -} - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(WorkerInspectorController_h) +} // namespace WebCore diff --git a/Source/WebCore/inspector/WorkerRuntimeAgent.cpp b/Source/WebCore/inspector/WorkerRuntimeAgent.cpp index 6e264cd21..34f91125a 100644 --- a/Source/WebCore/inspector/WorkerRuntimeAgent.cpp +++ b/Source/WebCore/inspector/WorkerRuntimeAgent.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,15 +32,8 @@ #include "config.h" #include "WorkerRuntimeAgent.h" -#if ENABLE(INSPECTOR) - -#include "InstrumentingAgents.h" -#include "JSDOMWindowBase.h" #include "ScriptState.h" -#include "WorkerDebuggerAgent.h" #include "WorkerGlobalScope.h" -#include "WorkerRunLoop.h" -#include "WorkerThread.h" #include <inspector/InjectedScript.h> #include <inspector/InjectedScriptManager.h> @@ -47,64 +41,31 @@ using namespace Inspector; namespace WebCore { -WorkerRuntimeAgent::WorkerRuntimeAgent(InjectedScriptManager* injectedScriptManager, WorkerGlobalScope* workerGlobalScope) - : InspectorRuntimeAgent(injectedScriptManager) - , m_workerGlobalScope(workerGlobalScope) - , m_paused(false) +WorkerRuntimeAgent::WorkerRuntimeAgent(WorkerAgentContext& context) + : InspectorRuntimeAgent(context) + , m_backendDispatcher(RuntimeBackendDispatcher::create(context.backendDispatcher, this)) + , m_workerGlobalScope(context.workerGlobalScope) { } -void WorkerRuntimeAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, InspectorBackendDispatcher* backendDispatcher) +void WorkerRuntimeAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) { - m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this); } -void WorkerRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void WorkerRuntimeAgent::willDestroyFrontendAndBackend(DisconnectReason reason) { - m_backendDispatcher.clear(); + InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason); } -InjectedScript WorkerRuntimeAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId) +InjectedScript WorkerRuntimeAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId) { if (executionContextId) { - *error = ASCIILiteral("Execution context id is not supported for workers as there is only one execution context."); + errorString = ASCIILiteral("Execution context id is not supported for workers as there is only one execution context."); return InjectedScript(); } - JSC::ExecState* scriptState = execStateFromWorkerGlobalScope(m_workerGlobalScope); - return injectedScriptManager()->injectedScriptFor(scriptState); -} - -void WorkerRuntimeAgent::muteConsole() -{ - // We don't need to mute console for workers. -} - -void WorkerRuntimeAgent::unmuteConsole() -{ - // We don't need to mute console for workers. -} - -void WorkerRuntimeAgent::run(ErrorString*) -{ - m_paused = false; -} - -JSC::VM* WorkerRuntimeAgent::globalVM() -{ - return JSDOMWindowBase::commonVM(); -} - -void WorkerRuntimeAgent::pauseWorkerGlobalScope(WorkerGlobalScope* context) -{ - m_paused = true; - MessageQueueWaitResult result; - do { - result = context->thread()->runLoop().runInMode(context, WorkerDebuggerAgent::debuggerTaskMode); - // Keep waiting until execution is resumed. - } while (result == MessageQueueMessageReceived && m_paused); + JSC::ExecState* scriptState = execStateFromWorkerGlobalScope(&m_workerGlobalScope); + return injectedScriptManager().injectedScriptFor(scriptState); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/WorkerRuntimeAgent.h b/Source/WebCore/inspector/WorkerRuntimeAgent.h index 95e254dcd..b3649c1e3 100644 --- a/Source/WebCore/inspector/WorkerRuntimeAgent.h +++ b/Source/WebCore/inspector/WorkerRuntimeAgent.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,13 +29,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WorkerRuntimeAgent_h -#define WorkerRuntimeAgent_h - -#if ENABLE(INSPECTOR) +#pragma once +#include "InspectorWebAgentBase.h" #include <inspector/agents/InspectorRuntimeAgent.h> -#include <wtf/PassOwnPtr.h> namespace WebCore { @@ -43,28 +41,21 @@ typedef String ErrorString; class WorkerRuntimeAgent final : public Inspector::InspectorRuntimeAgent { public: - WorkerRuntimeAgent(Inspector::InjectedScriptManager*, WorkerGlobalScope*); - virtual ~WorkerRuntimeAgent() { } + WorkerRuntimeAgent(WorkerAgentContext&); + ~WorkerRuntimeAgent() { } - virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override; - virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override; + void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; + void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; - virtual void run(ErrorString*) override; +private: + Inspector::InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) override; - void pauseWorkerGlobalScope(WorkerGlobalScope*); + // We don't need to mute console for workers. + void muteConsole() override { } + void unmuteConsole() override { } -private: - virtual JSC::VM* globalVM() override; - virtual Inspector::InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) override; - virtual void muteConsole() override; - virtual void unmuteConsole() override; - WorkerGlobalScope* m_workerGlobalScope; - RefPtr<Inspector::InspectorRuntimeBackendDispatcher> m_backendDispatcher; - bool m_paused; + RefPtr<Inspector::RuntimeBackendDispatcher> m_backendDispatcher; + WorkerGlobalScope& m_workerGlobalScope; }; } // namespace WebCore - -#endif // ENABLE(INSPECTOR) - -#endif // !defined(InspectorPagerAgent_h) diff --git a/Source/WebCore/inspector/ScriptCallStack.cpp b/Source/WebCore/inspector/WorkerScriptDebugServer.cpp index c4af1b426..53d85a381 100644 --- a/Source/WebCore/inspector/ScriptCallStack.cpp +++ b/Source/WebCore/inspector/WorkerScriptDebugServer.cpp @@ -1,10 +1,11 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. - * + * Copyright (c) 2011 Google Inc. All rights reserved. + * Copyright (c) 2013-2016 Apple Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +15,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -29,65 +30,57 @@ */ #include "config.h" -#include "ScriptCallStack.h" +#include "WorkerScriptDebugServer.h" -#include "InspectorWebTypeBuilders.h" -#include <inspector/InspectorValues.h> +#include "JSDOMExceptionHandling.h" +#include "Timer.h" +#include "WorkerGlobalScope.h" +#include "WorkerRunLoop.h" +#include "WorkerThread.h" +#include <runtime/VM.h> using namespace Inspector; namespace WebCore { -PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames) +WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope& context) + : ScriptDebugServer(context.script()->vm()) + , m_workerGlobalScope(context) { - return adoptRef(new ScriptCallStack(frames)); } -ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames) +void WorkerScriptDebugServer::attachDebugger() { - m_frames.swap(frames); + m_workerGlobalScope.script()->attachDebugger(this); } -ScriptCallStack::~ScriptCallStack() +void WorkerScriptDebugServer::detachDebugger(bool isBeingDestroyed) { + if (m_workerGlobalScope.script()) + m_workerGlobalScope.script()->detachDebugger(this); + if (!isBeingDestroyed) + recompileAllJSFunctions(); } -const ScriptCallFrame &ScriptCallStack::at(size_t index) const +void WorkerScriptDebugServer::recompileAllJSFunctions() { - ASSERT(m_frames.size() > index); - return m_frames[index]; + JSC::JSLockHolder lock(vm()); + JSC::Debugger::recompileAllJSFunctions(); } -size_t ScriptCallStack::size() const +void WorkerScriptDebugServer::runEventLoopWhilePaused() { - return m_frames.size(); -} - -bool ScriptCallStack::isEqual(ScriptCallStack* o) const -{ - if (!o) - return false; - - size_t frameCount = o->m_frames.size(); - if (frameCount != m_frames.size()) - return false; - - for (size_t i = 0; i < frameCount; ++i) { - if (!m_frames[i].isEqual(o->m_frames[i])) - return false; - } + TimerBase::fireTimersInNestedEventLoop(); - return true; + MessageQueueWaitResult result; + do { + result = m_workerGlobalScope.thread().runLoop().runInMode(&m_workerGlobalScope, WorkerRunLoop::debuggerMode()); + } while (result != MessageQueueTerminated && !m_doneProcessingDebuggerEvents); } -#if ENABLE(INSPECTOR) -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> ScriptCallStack::buildInspectorArray() const +void WorkerScriptDebugServer::reportException(JSC::ExecState* exec, JSC::Exception* exception) const { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> frames = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>::create(); - for (size_t i = 0; i < m_frames.size(); i++) - frames->addItem(m_frames.at(i).buildInspectorObject()); - return frames; + WebCore::reportException(exec, exception); } -#endif } // namespace WebCore diff --git a/Source/WebCore/inspector/ScriptCallStack.h b/Source/WebCore/inspector/WorkerScriptDebugServer.h index 1975da5c8..c49d09dec 100644 --- a/Source/WebCore/inspector/ScriptCallStack.h +++ b/Source/WebCore/inspector/WorkerScriptDebugServer.h @@ -1,10 +1,11 @@ /* - * Copyright (c) 2008, 2010 Google Inc. All rights reserved. - * + * Copyright (c) 2011 Google Inc. All rights reserved. + * Copyright (c) 2016 Apple Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +15,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -28,43 +29,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ScriptCallStack_h -#define ScriptCallStack_h +#pragma once -#if ENABLE(INSPECTOR) -#include "InspectorWebTypeBuilders.h" -#endif - -#include "ScriptCallFrame.h" -#include <wtf/Forward.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> +#include <inspector/ScriptDebugServer.h> namespace WebCore { -class ScriptCallStack : public RefCounted<ScriptCallStack> { -public: - static const size_t maxCallStackSizeToCapture = 200; - - static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&); - - ~ScriptCallStack(); - - const ScriptCallFrame &at(size_t) const; - size_t size() const; +class WorkerGlobalScope; - bool isEqual(ScriptCallStack*) const; +class WorkerScriptDebugServer final : public Inspector::ScriptDebugServer { + WTF_MAKE_NONCOPYABLE(WorkerScriptDebugServer); +public: + WorkerScriptDebugServer(WorkerGlobalScope&); + ~WorkerScriptDebugServer() { } -#if ENABLE(INSPECTOR) - PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Console::CallFrame>> buildInspectorArray() const; -#endif + void recompileAllJSFunctions() override; private: - ScriptCallStack(Vector<ScriptCallFrame>&); + void attachDebugger() override; + void detachDebugger(bool isBeingDestroyed) override; + + void didPause(JSC::JSGlobalObject*) override { } + void didContinue(JSC::JSGlobalObject*) override { } + void runEventLoopWhilePaused() override; + bool isContentScript(JSC::ExecState*) const override { return false; } + void reportException(JSC::ExecState*, JSC::Exception*) const override; - Vector<ScriptCallFrame> m_frames; + WorkerGlobalScope& m_workerGlobalScope; }; } // namespace WebCore - -#endif // ScriptCallStack_h diff --git a/Source/WebCore/inspector/WorkerToPageFrontendChannel.h b/Source/WebCore/inspector/WorkerToPageFrontendChannel.h new file mode 100644 index 000000000..a37d6da30 --- /dev/null +++ b/Source/WebCore/inspector/WorkerToPageFrontendChannel.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "WorkerGlobalScope.h" +#include "WorkerReportingProxy.h" +#include "WorkerThread.h" +#include <inspector/InspectorFrontendChannel.h> + +namespace WebCore { + +class WorkerToPageFrontendChannel final : public Inspector::FrontendChannel { + WTF_MAKE_FAST_ALLOCATED; +public: + explicit WorkerToPageFrontendChannel(WorkerGlobalScope& workerGlobalScope) + : m_workerGlobalScope(workerGlobalScope) + { + } + ~WorkerToPageFrontendChannel() { } + +private: + ConnectionType connectionType() const override { return ConnectionType::Local; } + + void sendMessageToFrontend(const String& message) override + { + m_workerGlobalScope.thread().workerReportingProxy().postMessageToPageInspector(message); + } + + WorkerGlobalScope& m_workerGlobalScope; +}; + +} // namespace WebCore diff --git a/Source/WebCore/inspector/protocol/ApplicationCache.json b/Source/WebCore/inspector/protocol/ApplicationCache.json deleted file mode 100644 index 3755480a5..000000000 --- a/Source/WebCore/inspector/protocol/ApplicationCache.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "domain": "ApplicationCache", - "types": [ - { - "id": "ApplicationCacheResource", - "type": "object", - "description": "Detailed application cache resource information.", - "properties": [ - { "name": "url", "type": "string", "description": "Resource url." }, - { "name": "size", "type": "integer", "description": "Resource size." }, - { "name": "type", "type": "string", "description": "Resource type." } - ] - }, - { - "id": "ApplicationCache", - "type": "object", - "description": "Detailed application cache information.", - "properties": [ - { "name": "manifestURL", "type": "string", "description": "Manifest URL." }, - { "name": "size", "type": "number", "description": "Application cache size." }, - { "name": "creationTime", "type": "number", "description": "Application cache creation time." }, - { "name": "updateTime", "type": "number", "description": "Application cache update time." }, - { "name": "resources", "type": "array", "items": { "$ref": "ApplicationCacheResource" }, "description": "Application cache resources." } - ] - }, - { - "id": "FrameWithManifest", - "type": "object", - "description": "Frame identifier - manifest URL pair.", - "properties": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame identifier." }, - { "name": "manifestURL", "type": "string", "description": "Manifest URL." }, - { "name": "status", "type": "integer", "description": "Application cache status." } - ] - } - ], - "commands": [ - { - "name": "getFramesWithManifests", - "returns": [ - { "name": "frameIds", "type": "array", "items": { "$ref": "FrameWithManifest" }, "description": "Array of frame identifiers with manifest urls for each frame containing a document associated with some application cache." } - ], - "description": "Returns array of frame identifiers with manifest urls for each frame containing a document associated with some application cache." - }, - { - "name": "enable", - "description": "Enables application cache domain notifications." - }, - { - "name": "getManifestForFrame", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose manifest is retrieved." } - ], - "returns": [ - { "name": "manifestURL", "type": "string", "description": "Manifest URL for document in the given frame." } - ], - "description": "Returns manifest URL for document in the given frame." - }, - { - "name": "getApplicationCacheForFrame", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose application cache is retrieved." } - ], - "returns": [ - { "name": "applicationCache", "$ref": "ApplicationCache", "description": "Relevant application cache data for the document in given frame." } - ], - "description": "Returns relevant application cache data for the document in given frame." - } - ], - "events": [ - { - "name": "applicationCacheStatusUpdated", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing document whose application cache updated status." }, - { "name": "manifestURL", "type": "string", "description": "Manifest URL." }, - { "name": "status", "type": "integer", "description": "Updated application cache status." } - ] - }, - { - "name": "networkStateUpdated", - "parameters": [ - { "name": "isNowOnline", "type": "boolean" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/CSS.json b/Source/WebCore/inspector/protocol/CSS.json deleted file mode 100644 index f9c2629bc..000000000 --- a/Source/WebCore/inspector/protocol/CSS.json +++ /dev/null @@ -1,437 +0,0 @@ -{ - "domain": "CSS", - "description": "This domain exposes CSS read/write operations. All CSS objects, like stylesheets, rules, and styles, have an associated <code>id</code> used in subsequent operations on the related object. Each object type has a specific <code>id</code> structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the <code>get*ForNode()</code> calls (which accept a DOM node id). Alternatively, a client can discover all the existing stylesheets with the <code>getAllStyleSheets()</code> method and subsequently load the required stylesheet contents using the <code>getStyleSheet[Text]()</code> methods.", - "types": [ - { - "id": "StyleSheetId", - "type": "string" - }, - { - "id": "CSSStyleId", - "type": "object", - "properties": [ - { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "Enclosing stylesheet identifier." }, - { "name": "ordinal", "type": "integer", "description": "The style ordinal within the stylesheet." } - ], - "description": "This object identifies a CSS style in a unique way." - }, - { - "id": "StyleSheetOrigin", - "type": "string", - "enum": ["user", "user-agent", "inspector", "regular"], - "description": "Stylesheet type: \"user\" for user stylesheets, \"user-agent\" for user-agent stylesheets, \"inspector\" for stylesheets created by the inspector (i.e. those holding the \"via inspector\" rules), \"regular\" for regular stylesheets." - }, - { - "id": "CSSRuleId", - "type": "object", - "properties": [ - { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "Enclosing stylesheet identifier." }, - { "name": "ordinal", "type": "integer", "description": "The rule ordinal within the stylesheet." } - ], - "description": "This object identifies a CSS rule in a unique way." - }, - { - "id": "PseudoIdMatches", - "type": "object", - "properties": [ - { "name": "pseudoId", "type": "integer", "description": "Pseudo style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."}, - { "name": "matches", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules applicable to the pseudo style."} - ], - "description": "CSS rule collection for a single pseudo style." - }, - { - "id": "InheritedStyleEntry", - "type": "object", - "properties": [ - { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "The ancestor node's inline style, if any, in the style inheritance chain." }, - { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "description": "Matches of CSS rules matching the ancestor node in the style inheritance chain." } - ], - "description": "CSS rule collection for a single pseudo style." - }, - { - "id": "RuleMatch", - "type": "object", - "properties": [ - { "name": "rule", "$ref": "CSSRule", "description": "CSS rule in the match." }, - { "name": "matchingSelectors", "type": "array", "items": { "type": "integer" }, "description": "Matching selector indices in the rule's selectorList selectors (0-based)." } - ], - "description": "Match data for a CSS rule." - }, - { - "id": "SelectorList", - "type": "object", - "properties": [ - { "name": "selectors", "type": "array", "items": { "type": "string" }, "description": "Selectors in the list." }, - { "name": "text", "type": "string", "description": "Rule selector text." }, - { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Rule selector range in the underlying resource (if available)." } - ], - "description": "Selector list data." - }, - { - "id": "CSSStyleAttribute", - "type": "object", - "properties": [ - { "name": "name", "type": "string", "description": "DOM attribute name (e.g. \"width\")."}, - { "name": "style", "$ref": "CSSStyle", "description": "CSS style generated by the respective DOM attribute."} - ], - "description": "CSS style information for a DOM style attribute." - }, - { - "id": "CSSStyleSheetHeader", - "type": "object", - "properties": [ - { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "The stylesheet identifier."}, - { "name": "frameId", "$ref": "Network.FrameId", "description": "Owner frame identifier."}, - { "name": "sourceURL", "type": "string", "description": "Stylesheet resource URL."}, - { "name": "origin", "$ref": "StyleSheetOrigin", "description": "Stylesheet origin."}, - { "name": "title", "type": "string", "description": "Stylesheet title."}, - { "name": "disabled", "type": "boolean", "description": "Denotes whether the stylesheet is disabled."} - ], - "description": "CSS stylesheet metainformation." - }, - { - "id": "CSSStyleSheetBody", - "type": "object", - "properties": [ - { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "The stylesheet identifier."}, - { "name": "rules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "Stylesheet resource URL."}, - { "name": "text", "type": "string", "optional": true, "description": "Stylesheet resource contents (if available)."} - ], - "description": "CSS stylesheet contents." - }, - { - "id": "CSSRule", - "type": "object", - "properties": [ - { "name": "ruleId", "$ref": "CSSRuleId", "optional": true, "description": "The CSS rule identifier (absent for user agent stylesheet and user-specified stylesheet rules)."}, - { "name": "selectorList", "$ref": "SelectorList", "description": "Rule selector data." }, - { "name": "sourceURL", "type": "string", "optional": true, "description": "Parent stylesheet resource URL (for regular rules)."}, - { "name": "sourceLine", "type": "integer", "description": "Line ordinal of the rule selector start character in the resource."}, - { "name": "origin", "$ref": "StyleSheetOrigin", "description": "Parent stylesheet's origin."}, - { "name": "style", "$ref": "CSSStyle", "description": "Associated style declaration." }, - { "name": "media", "type": "array", "items": { "$ref": "CSSMedia" }, "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards." } - ], - "description": "CSS rule representation." - }, - { - "id": "SourceRange", - "type": "object", - "properties": [ - { "name": "startLine", "type": "integer", "description": "Start line of range." }, - { "name": "startColumn", "type": "integer", "description": "Start column of range (inclusive)." }, - { "name": "endLine", "type": "integer", "description": "End line of range" }, - { "name": "endColumn", "type": "integer", "description": "End column of range (exclusive)." } - ], - "description": "Text range within a resource." - }, - { - "id": "ShorthandEntry", - "type": "object", - "properties": [ - { "name": "name", "type": "string", "description": "Shorthand name." }, - { "name": "value", "type": "string", "description": "Shorthand value." } - ] - }, - { - "id": "CSSPropertyInfo", - "type": "object", - "properties": [ - { "name": "name", "type": "string", "description": "Property name." }, - { "name": "longhands", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Longhand property names." } - ] - }, - { - "id": "CSSComputedStyleProperty", - "type": "object", - "properties": [ - { "name": "name", "type": "string", "description": "Computed style property name." }, - { "name": "value", "type": "string", "description": "Computed style property value." } - ] - }, - { - "id": "CSSStyle", - "type": "object", - "properties": [ - { "name": "styleId", "$ref": "CSSStyleId", "optional": true, "description": "The CSS style identifier (absent for attribute styles)." }, - { "name": "cssProperties", "type": "array", "items": { "$ref": "CSSProperty" }, "description": "CSS properties in the style." }, - { "name": "shorthandEntries", "type": "array", "items": { "$ref": "ShorthandEntry" }, "description": "Computed values for all shorthands found in the style." }, - { "name": "cssText", "type": "string", "optional": true, "description": "Style declaration text (if available)." }, - { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Style declaration range in the enclosing stylesheet (if available)." }, - { "name": "width", "type": "string", "optional": true, "description": "The effective \"width\" property value from this style." }, - { "name": "height", "type": "string", "optional": true, "description": "The effective \"height\" property value from this style." } - ], - "description": "CSS style representation." - }, - { - "id": "CSSProperty", - "type": "object", - "properties": [ - { "name": "name", "type": "string", "description": "The property name." }, - { "name": "value", "type": "string", "description": "The property value." }, - { "name": "priority", "type": "string", "optional": true, "description": "The property priority (implies \"\" if absent)." }, - { "name": "implicit", "type": "boolean", "optional": true, "description": "Whether the property is implicit (implies <code>false</code> if absent)." }, - { "name": "text", "type": "string", "optional": true, "description": "The full property text as specified in the style." }, - { "name": "parsedOk", "type": "boolean", "optional": true, "description": "Whether the property is understood by the browser (implies <code>true</code> if absent)." }, - { "name": "status", "type": "string", "enum": ["active", "inactive", "disabled", "style"], "optional": true, "description": "The property status: \"active\" if the property is effective in the style, \"inactive\" if the property is overridden by a same-named property in this style later on, \"disabled\" if the property is disabled by the user, \"style\" (implied if absent) if the property is reported by the browser rather than by the CSS source parser." }, - { "name": "range", "$ref": "SourceRange", "optional": true, "description": "The entire property range in the enclosing style declaration (if available)." } - ], - "description": "CSS style effective visual dimensions and source offsets." - }, - { - "id": "CSSMedia", - "type": "object", - "properties": [ - { "name": "text", "type": "string", "description": "Media query text." }, - { "name": "source", "type": "string", "enum": ["mediaRule", "importRule", "linkedSheet", "inlineSheet"], "description": "Source of the media query: \"mediaRule\" if specified by a @media rule, \"importRule\" if specified by an @import rule, \"linkedSheet\" if specified by a \"media\" attribute in a linked stylesheet's LINK tag, \"inlineSheet\" if specified by a \"media\" attribute in an inline stylesheet's STYLE tag." }, - { "name": "sourceURL", "type": "string", "optional": true, "description": "URL of the document containing the media query description." }, - { "name": "sourceLine", "type": "integer", "optional": true, "description": "Line in the document containing the media query (not defined for the \"stylesheet\" source)." } - ], - "description": "CSS media query descriptor." - }, - { - "id": "Region", - "type": "object", - "properties": [ - { "name": "regionOverset", "type": "string", "enum": ["overset", "fit", "empty"], "description": "The \"overset\" attribute of a Named Flow." }, - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The corresponding DOM node id." } - ], - "description": "This object represents a region that flows from a Named Flow." - }, - { - "id": "NamedFlow", - "type": "object", - "properties": [ - { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." }, - { "name": "name", "type": "string", "description": "Named Flow identifier." }, - { "name": "overset", "type": "boolean", "description": "The \"overset\" attribute of a Named Flow." }, - { "name": "content", "type": "array", "items": { "$ref": "DOM.NodeId" }, "description": "An array of nodes that flow into the Named Flow." }, - { "name": "regions", "type": "array", "items": { "$ref": "Region" }, "description": "An array of regions associated with the Named Flow." } - ], - "description": "This object represents a Named Flow." - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been enabled until the result of this command is received." - }, - { - "name": "disable", - "description": "Disables the CSS agent for the given page." - }, - { - "name": "getMatchedStylesForNode", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId" }, - { "name": "includePseudo", "type": "boolean", "optional": true, "description": "Whether to include pseudo styles (default: true)." }, - { "name": "includeInherited", "type": "boolean", "optional": true, "description": "Whether to include inherited styles (default: true)." } - ], - "returns": [ - { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "RuleMatch" }, "optional": true, "description": "CSS rules matching this node, from all applicable stylesheets." }, - { "name": "pseudoElements", "type": "array", "items": { "$ref": "PseudoIdMatches" }, "optional": true, "description": "Pseudo style matches for this node." }, - { "name": "inherited", "type": "array", "items": { "$ref": "InheritedStyleEntry" }, "optional": true, "description": "A chain of inherited styles (from the immediate node parent up to the DOM tree root)." } - ], - "description": "Returns requested styles for a DOM node identified by <code>nodeId</code>." - }, - { - "name": "getInlineStylesForNode", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId" } - ], - "returns": [ - { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "Inline style for the specified DOM node." }, - { "name": "attributesStyle", "$ref": "CSSStyle", "optional": true, "description": "Attribute-defined element style (e.g. resulting from \"width=20 height=100%\")."} - ], - "description": "Returns the styles defined inline (explicitly in the \"style\" attribute and implicitly, using DOM attributes) for a DOM node identified by <code>nodeId</code>." - }, - { - "name": "getComputedStyleForNode", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId" } - ], - "returns": [ - { "name": "computedStyle", "type": "array", "items": { "$ref": "CSSComputedStyleProperty" }, "description": "Computed style for the specified DOM node." } - ], - "description": "Returns the computed style for a DOM node identified by <code>nodeId</code>." - }, - { - "name": "getAllStyleSheets", - "returns": [ - { "name": "headers", "type": "array", "items": { "$ref": "CSSStyleSheetHeader" }, "description": "Descriptor entries for all available stylesheets." } - ], - "description": "Returns metainfo entries for all known stylesheets." - }, - { - "name": "getStyleSheet", - "parameters": [ - { "name": "styleSheetId", "$ref": "StyleSheetId" } - ], - "returns": [ - { "name": "styleSheet", "$ref": "CSSStyleSheetBody", "description": "Stylesheet contents for the specified <code>styleSheetId</code>." } - ], - "description": "Returns stylesheet data for the specified <code>styleSheetId</code>." - }, - { - "name": "getStyleSheetText", - "parameters": [ - { "name": "styleSheetId", "$ref": "StyleSheetId" } - ], - "returns": [ - { "name": "text", "type": "string", "description": "The stylesheet text." } - ], - "description": "Returns the current textual content and the URL for a stylesheet." - }, - { - "name": "setStyleSheetText", - "parameters": [ - { "name": "styleSheetId", "$ref": "StyleSheetId" }, - { "name": "text", "type": "string" } - ], - "description": "Sets the new stylesheet text, thereby invalidating all existing <code>CSSStyleId</code>'s and <code>CSSRuleId</code>'s contained by this stylesheet." - }, - { - "name": "setStyleText", - "parameters": [ - { "name": "styleId", "$ref": "CSSStyleId" }, - { "name": "text", "type": "string" } - ], - "returns": [ - { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the text modification." } - ], - "description": "Sets the new <code>text</code> for the respective style." - }, - { - "name": "setPropertyText", - "parameters": [ - { "name": "styleId", "$ref": "CSSStyleId" }, - { "name": "propertyIndex", "type": "integer" }, - { "name": "text", "type": "string" }, - { "name": "overwrite", "type": "boolean" } - ], - "returns": [ - { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the property text modification." } - ], - "description": "Sets the new <code>text</code> for a property in the respective style, at offset <code>propertyIndex</code>. If <code>overwrite</code> is <code>true</code>, a property at the given offset is overwritten, otherwise inserted. <code>text</code> entirely replaces the property <code>name: value</code>." - }, - { - "name": "toggleProperty", - "parameters": [ - { "name": "styleId", "$ref": "CSSStyleId" }, - { "name": "propertyIndex", "type": "integer" }, - { "name": "disable", "type": "boolean" } - ], - "returns": [ - { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the property toggling." } - ], - "description": "Toggles the property in the respective style, at offset <code>propertyIndex</code>. The <code>disable</code> parameter denotes whether the property should be disabled (i.e. removed from the style declaration). If <code>disable == false</code>, the property gets put back into its original place in the style declaration." - }, - { - "name": "setRuleSelector", - "parameters": [ - { "name": "ruleId", "$ref": "CSSRuleId" }, - { "name": "selector", "type": "string" } - ], - "returns": [ - { "name": "rule", "$ref": "CSSRule", "description": "The resulting rule after the selector modification." } - ], - "description": "Modifies the rule selector." - }, - { - "name": "addRule", - "parameters": [ - { "name": "contextNodeId", "$ref": "DOM.NodeId" }, - { "name": "selector", "type": "string" } - ], - "returns": [ - { "name": "rule", "$ref": "CSSRule", "description": "The newly created rule." } - ], - "description": "Creates a new empty rule with the given <code>selector</code> in a special \"inspector\" stylesheet in the owner document of the context node." - }, - { - "name": "getSupportedCSSProperties", - "returns": [ - { "name": "cssProperties", "type": "array", "items": { "$ref": "CSSPropertyInfo" }, "description": "Supported property metainfo." } - ], - "description": "Returns all supported CSS property names." - }, - { - "name": "forcePseudoState", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The element id for which to force the pseudo state." }, - { "name": "forcedPseudoClasses", "type": "array", "items": { "type": "string", "enum": ["active", "focus", "hover", "visited"] }, "description": "Element pseudo classes to force when computing the element's style." } - ], - "description": "Ensures that the given node will have specified pseudo-classes whenever its style is computed by the browser." - }, - { - "name": "getNamedFlowCollection", - "parameters": [ - { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id for which to get the Named Flow Collection." } - ], - "returns": [ - { "name": "namedFlows", "type": "array", "items": { "$ref": "NamedFlow" }, "description": "An array containing the Named Flows in the document." } - ], - "description": "Returns the Named Flows from the document." - } - ], - "events": [ - { - "name": "mediaQueryResultChanged", - "description": "Fires whenever a MediaQuery result changes (for example, after a browser window has been resized.) The current implementation considers only viewport-dependent media features." - }, - { - "name": "styleSheetChanged", - "parameters": [ - { "name": "styleSheetId", "$ref": "StyleSheetId" } - ], - "description": "Fired whenever a stylesheet is changed as a result of the client operation." - }, - { - "name": "namedFlowCreated", - "parameters": [ - { "name": "namedFlow", "$ref": "NamedFlow", "description": "The new Named Flow." } - ], - "description": "Fires when a Named Flow is created." - }, - { - "name": "namedFlowRemoved", - "parameters": [ - { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." }, - { "name": "flowName", "type": "string", "description": "Identifier of the removed Named Flow." } - ], - "description": "Fires when a Named Flow is removed: has no associated content nodes and regions." - }, - { - "name": "regionLayoutUpdated", - "parameters": [ - { "name": "namedFlow", "$ref": "NamedFlow", "description": "The Named Flow whose layout may have changed." } - ], - "description": "Fires when a Named Flow's layout may have changed." - }, - { - "name": "regionOversetChanged", - "parameters": [ - { "name": "namedFlow", "$ref": "NamedFlow", "description": "The Named Flow containing the regions whose regionOverset values changed." } - ], - "description": "Fires if any of the regionOverset values changed in a Named Flow's region chain." - }, - { - "name": "registeredNamedFlowContentElement", - "parameters": [ - { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." }, - { "name": "flowName", "type": "string", "description": "Named Flow identifier for which the new content element was registered." }, - { "name": "contentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the registered content node." }, - { "name": "nextContentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the element following the registered content node." } - ], - "description": "Fires when a Named Flow's has been registered with a new content node." - }, - { - "name": "unregisteredNamedFlowContentElement", - "parameters": [ - { "name": "documentNodeId", "$ref": "DOM.NodeId", "description": "The document node id." }, - { "name": "flowName", "type": "string", "description": "Named Flow identifier for which the new content element was unregistered." }, - { "name": "contentNodeId", "$ref": "DOM.NodeId", "description": "The node id of the unregistered content node." } - ], - "description": "Fires when a Named Flow's has been registered with a new content node." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Canvas.json b/Source/WebCore/inspector/protocol/Canvas.json deleted file mode 100644 index e023a3b77..000000000 --- a/Source/WebCore/inspector/protocol/Canvas.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "domain": "Canvas", - "types": [ - { - "id": "ResourceId", - "type": "string", - "description": "Unique resource identifier." - }, - { - "id": "ResourceInfo", - "type": "object", - "properties": [ - { "name": "id", "$ref": "ResourceId" }, - { "name": "description", "type": "string" } - ] - }, - { - "id": "ResourceState", - "type": "object", - "properties": [ - { "name": "id", "$ref": "ResourceId" }, - { "name": "traceLogId", "$ref": "TraceLogId" }, - { "name": "imageURL", "type": "string", "optional": true, "description": "Screenshot image data URL." } - ] - }, - { - "id": "CallArgument", - "type": "object", - "properties": [ - { "name": "description", "type": "string" } - ] - }, - { - "id": "Call", - "type": "object", - "properties": [ - { "name": "contextId", "$ref": "ResourceId" }, - { "name": "functionName", "type": "string", "optional": true }, - { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument" }, "optional": true }, - { "name": "result", "$ref": "CallArgument", "optional": true }, - { "name": "isDrawingCall", "type": "boolean", "optional": true }, - { "name": "isFrameEndCall", "type": "boolean", "optional": true }, - { "name": "property", "type": "string", "optional": true }, - { "name": "value", "$ref": "CallArgument", "optional": true }, - { "name": "sourceURL", "type": "string", "optional": true }, - { "name": "lineNumber", "type": "integer", "optional": true }, - { "name": "columnNumber", "type": "integer", "optional": true } - ] - }, - { - "id": "TraceLogId", - "type": "string", - "description": "Unique trace log identifier." - }, - { - "id": "TraceLog", - "type": "object", - "properties": [ - { "name": "id", "$ref": "TraceLogId" }, - { "name": "calls", "type": "array", "items": { "$ref": "Call" } }, - { "name": "startOffset", "type": "integer" }, - { "name": "alive", "type": "boolean" }, - { "name": "totalAvailableCalls", "type": "number" } - ] - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables Canvas inspection." - }, - { - "name": "disable", - "description": "Disables Canvas inspection." - }, - { - "name": "dropTraceLog", - "parameters": [ - { "name": "traceLogId", "$ref": "TraceLogId" } - ] - }, - { - "name": "hasUninstrumentedCanvases", - "returns": [ - { "name": "result", "type": "boolean" } - ], - "description": "Checks if there is any uninstrumented canvas in the inspected page." - }, - { - "name": "captureFrame", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Identifier of the frame containing document whose canvases are to be captured. If omitted, main frame is assumed." } - ], - "returns": [ - { "name": "traceLogId", "$ref": "TraceLogId", "description": "Identifier of the trace log containing captured canvas calls." } - ], - "description": "Starts (or continues) a canvas frame capturing which will be stopped automatically after the next frame is prepared." - }, - { - "name": "startCapturing", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Identifier of the frame containing document whose canvases are to be captured. If omitted, main frame is assumed." } - ], - "returns": [ - { "name": "traceLogId", "$ref": "TraceLogId", "description": "Identifier of the trace log containing captured canvas calls." } - ], - "description": "Starts (or continues) consecutive canvas frames capturing. The capturing is stopped by the corresponding stopCapturing command." - }, - { - "name": "stopCapturing", - "parameters": [ - { "name": "traceLogId", "$ref": "TraceLogId" } - ] - }, - { - "name": "getTraceLog", - "parameters": [ - { "name": "traceLogId", "$ref": "TraceLogId" }, - { "name": "startOffset", "type": "integer", "optional": true }, - { "name": "maxLength", "type": "integer", "optional": true } - ], - "returns": [ - { "name": "traceLog", "$ref": "TraceLog" } - ] - }, - { - "name": "replayTraceLog", - "parameters": [ - { "name": "traceLogId", "$ref": "TraceLogId" }, - { "name": "stepNo", "type": "integer" } - ], - "returns": [ - { "name": "resourceState", "$ref": "ResourceState" } - ] - }, - { - "name": "getResourceInfo", - "parameters": [ - { "name": "resourceId", "$ref": "ResourceId" } - ], - "returns": [ - { "name": "resourceInfo", "$ref": "ResourceInfo" } - ] - }, - { - "name": "getResourceState", - "parameters": [ - { "name": "traceLogId", "$ref": "TraceLogId" }, - { "name": "resourceId", "$ref": "ResourceId" } - ], - "returns": [ - { "name": "resourceState", "$ref": "ResourceState" } - ] - } - ], - "events": [ - { - "name": "contextCreated", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame containing a canvas with a context." } - ], - "description": "Fired when a canvas context has been created in the given frame. The context may not be instrumented (see hasUninstrumentedCanvases command)." - }, - { - "name": "traceLogsRemoved", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "If given, trace logs from the given frame were removed." }, - { "name": "traceLogId", "$ref": "TraceLogId", "optional": true, "description": "If given, trace log with the given ID was removed." } - ], - "description": "Fired when a set of trace logs were removed from the backend. If no parameters are given, all trace logs were removed." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Console.json b/Source/WebCore/inspector/protocol/Console.json deleted file mode 100644 index 35bd11af9..000000000 --- a/Source/WebCore/inspector/protocol/Console.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "domain": "Console", - "description": "Console domain defines methods and events for interaction with the JavaScript console. Console collects messages created by means of the <a href='http://getfirebug.com/wiki/index.php/Console_API'>JavaScript Console API</a>. One needs to enable this domain using <code>enable</code> command in order to start receiving the console messages. Browser collects messages issued while console domain is not enabled as well and reports them using <code>messageAdded</code> notification upon enabling.", - "types": [ - { - "id": "ConsoleMessage", - "type": "object", - "description": "Console message.", - "properties": [ - { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "css", "security", "other"], "description": "Message source." }, - { "name": "level", "type": "string", "enum": ["log", "warning", "error", "debug"], "description": "Message severity." }, - { "name": "text", "type": "string", "description": "Message text." }, - { "name": "type", "type": "string", "optional": true, "enum": ["log", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "timing", "profile", "profileEnd"], "description": "Console message type." }, - { "name": "url", "type": "string", "optional": true, "description": "URL of the message origin." }, - { "name": "line", "type": "integer", "optional": true, "description": "Line number in the resource that generated this message." }, - { "name": "column", "type": "integer", "optional": true, "description": "Column number on the line in the resource that generated this message." }, - { "name": "repeatCount", "type": "integer", "optional": true, "description": "Repeat count for repeated messages." }, - { "name": "parameters", "type": "array", "items": { "$ref": "Runtime.RemoteObject" }, "optional": true, "description": "Message parameters in case of the formatted message." }, - { "name": "stackTrace", "$ref": "StackTrace", "optional": true, "description": "JavaScript stack trace for assertions and error messages." }, - { "name": "networkRequestId", "$ref": "Network.RequestId", "optional": true, "description": "Identifier of the network request associated with this message." } - ] - }, - { - "id": "CallFrame", - "type": "object", - "description": "Stack entry for console errors and assertions.", - "properties": [ - { "name": "functionName", "type": "string", "description": "JavaScript function name." }, - { "name": "url", "type": "string", "description": "JavaScript script name or url." }, - { "name": "lineNumber", "type": "integer", "description": "JavaScript script line number." }, - { "name": "columnNumber", "type": "integer", "description": "JavaScript script column number." } - ] - }, - { - "id": "StackTrace", - "type": "array", - "items": { "$ref": "CallFrame" }, - "description": "Call frames for assertions or error messages." - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables console domain, sends the messages collected so far to the client by means of the <code>messageAdded</code> notification." - }, - { - "name": "disable", - "description": "Disables console domain, prevents further console messages from being reported to the client." - }, - { - "name": "clearMessages", - "description": "Clears console messages collected in the browser." - }, - { - "name": "setMonitoringXHREnabled", - "parameters": [ - { "name": "enabled", "type": "boolean", "description": "Monitoring enabled state." } - ], - "description": "Toggles monitoring of XMLHttpRequest. If <code>true</code>, console will receive messages upon each XHR issued." - }, - { - "name": "addInspectedNode", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "DOM node id to be accessible by means of $x command line API." } - ], - "description": "Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions)." - }, - { - "name": "addInspectedHeapObject", - "parameters": [ - { "name": "heapObjectId", "type": "integer" } - ] - } - ], - "events": [ - { - "name": "messageAdded", - "parameters": [ - { "name": "message", "$ref": "ConsoleMessage", "description": "Console message that has been added." } - ], - "description": "Issued when new console message is added." - }, - { - "name": "messageRepeatCountUpdated", - "parameters": [ - { "name": "count", "type": "integer", "description": "New repeat count value." } - ], - "description": "Issued when subsequent message(s) are equal to the previous one(s)." - }, - { - "name": "messagesCleared", - "description": "Issued when console is cleared. This happens either upon <code>clearMessages</code> command or after page navigation." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/DOM.json b/Source/WebCore/inspector/protocol/DOM.json deleted file mode 100644 index eb0c182a0..000000000 --- a/Source/WebCore/inspector/protocol/DOM.json +++ /dev/null @@ -1,469 +0,0 @@ -{ - "domain": "DOM", - "description": "This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object that has an <code>id</code>. This <code>id</code> can be used to get additional information on the Node, resolve it into the JavaScript object wrapper, etc. It is important that client receives DOM events only for the nodes that are known to the client. Backend keeps track of the nodes that were sent to the client and never sends the same node twice. It is client's responsibility to collect information about the nodes that were sent to the client.<p>Note that <code>iframe</code> owner elements will return corresponding document elements as their child nodes.</p>", - "types": [ - { - "id": "NodeId", - "type": "integer", - "description": "Unique DOM node identifier." - }, - { - "id": "BackendNodeId", - "type": "integer", - "description": "Unique DOM node identifier used to reference a node that may not have been pushed to the front-end." - }, - { - "id": "Node", - "type": "object", - "properties": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Node identifier that is passed into the rest of the DOM messages as the <code>nodeId</code>. Backend will only push node with given <code>id</code> once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client." }, - { "name": "nodeType", "type": "integer", "description": "<code>Node</code>'s nodeType." }, - { "name": "nodeName", "type": "string", "description": "<code>Node</code>'s nodeName." }, - { "name": "localName", "type": "string", "description": "<code>Node</code>'s localName." }, - { "name": "nodeValue", "type": "string", "description": "<code>Node</code>'s nodeValue." }, - { "name": "childNodeCount", "type": "integer", "optional": true, "description": "Child count for <code>Container</code> nodes." }, - { "name": "children", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Child nodes of this node when requested with children." }, - { "name": "attributes", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Attributes of the <code>Element</code> node in the form of flat array <code>[name1, value1, name2, value2]</code>." }, - { "name": "documentURL", "type": "string", "optional": true, "description": "Document URL that <code>Document</code> or <code>FrameOwner</code> node points to." }, - { "name": "baseURL", "type": "string", "optional": true, "description": "Base URL that <code>Document</code> or <code>FrameOwner</code> node uses for URL completion." }, - { "name": "publicId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s publicId." }, - { "name": "systemId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s systemId." }, - { "name": "internalSubset", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s internalSubset." }, - { "name": "xmlVersion", "type": "string", "optional": true, "description": "<code>Document</code>'s XML version in case of XML documents." }, - { "name": "name", "type": "string", "optional": true, "description": "<code>Attr</code>'s name." }, - { "name": "value", "type": "string", "optional": true, "description": "<code>Attr</code>'s value." }, - { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." }, - { "name": "contentDocument", "$ref": "Node", "optional": true, "description": "Content document for frame owner elements." }, - { "name": "shadowRoots", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Shadow root list for given element host." }, - { "name": "templateContent", "$ref": "Node", "optional": true, "description": "Content document fragment for template elements" } - ], - "description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type." - }, - { - "id": "EventListener", - "type": "object", - "properties": [ - { "name": "type", "type": "string", "description": "<code>EventListener</code>'s type." }, - { "name": "useCapture", "type": "boolean", "description": "<code>EventListener</code>'s useCapture." }, - { "name": "isAttribute", "type": "boolean", "description": "<code>EventListener</code>'s isAttribute." }, - { "name": "nodeId", "$ref": "NodeId", "description": "Target <code>DOMNode</code> id." }, - { "name": "handlerBody", "type": "string", "description": "Event handler function body." }, - { "name": "location", "$ref": "Debugger.Location", "optional": true, "description": "Handler code location." }, - { "name": "sourceName", "type": "string", "optional": true, "description": "Source script URL." }, - { "name": "handler", "$ref": "Runtime.RemoteObject", "optional": true, "description": "Event handler function value." } - ], - "description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type." - }, - { - "id": "RGBA", - "type": "object", - "properties": [ - { "name": "r", "type": "integer", "description": "The red component, in the [0-255] range." }, - { "name": "g", "type": "integer", "description": "The green component, in the [0-255] range." }, - { "name": "b", "type": "integer", "description": "The blue component, in the [0-255] range." }, - { "name": "a", "type": "number", "optional": true, "description": "The alpha component, in the [0-1] range (default: 1)." } - ], - "description": "A structure holding an RGBA color." - }, - { - "id": "Quad", - "type": "array", - "items": { "type": "number" }, - "minItems": 8, - "maxItems": 8, - "description": "An array of quad vertices, x immediately followed by y for each point, points clock-wise." - }, - { - "id": "HighlightConfig", - "type": "object", - "properties": [ - { "name": "showInfo", "type": "boolean", "optional": true, "description": "Whether the node info tooltip should be shown (default: false)." }, - { "name": "contentColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." }, - { "name": "paddingColor", "$ref": "RGBA", "optional": true, "description": "The padding highlight fill color (default: transparent)." }, - { "name": "borderColor", "$ref": "RGBA", "optional": true, "description": "The border highlight fill color (default: transparent)." }, - { "name": "marginColor", "$ref": "RGBA", "optional": true, "description": "The margin highlight fill color (default: transparent)." } - ], - "description": "Configuration data for the highlighting of page elements." - } - ], - "commands": [ - { - "name": "getDocument", - "returns": [ - { "name": "root", "$ref": "Node", "description": "Resulting node." } - ], - "description": "Returns the root DOM node to the caller." - }, - { - "name": "requestChildNodes", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get children for." }, - { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0." } - ], - "description": "Requests that children of the node with given id are returned to the caller in form of <code>setChildNodes</code> events where not only immediate children are retrieved, but all children down to the specified depth." - }, - { - "name": "querySelector", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to query upon." }, - { "name": "selector", "type": "string", "description": "Selector string." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Query selector result." } - ], - "description": "Executes <code>querySelector</code> on a given node." - }, - { - "name": "querySelectorAll", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to query upon." }, - { "name": "selector", "type": "string", "description": "Selector string." } - ], - "returns": [ - { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Query selector result." } - ], - "description": "Executes <code>querySelectorAll</code> on a given node." - }, - { - "name": "setNodeName", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set name for." }, - { "name": "name", "type": "string", "description": "New node's name." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "New node's id." } - ], - "description": "Sets node name for a node with given id." - }, - { - "name": "setNodeValue", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set value for." }, - { "name": "value", "type": "string", "description": "New node's value." } - ], - "description": "Sets node value for a node with given id." - }, - { - "name": "removeNode", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to remove." } - ], - "description": "Removes node with given id." - }, - { - "name": "setAttributeValue", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to set attribute for." }, - { "name": "name", "type": "string", "description": "Attribute name." }, - { "name": "value", "type": "string", "description": "Attribute value." } - ], - "description": "Sets attribute for an element with given id." - }, - { - "name": "setAttributesAsText", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to set attributes for." }, - { "name": "text", "type": "string", "description": "Text with a number of attributes. Will parse this text using HTML parser." }, - { "name": "name", "type": "string", "optional": true, "description": "Attribute name to replace with new attributes derived from text in case text parsed successfully." } - ], - "description": "Sets attributes on element with given id. This method is useful when user edits some existing attribute value and types in several attribute name/value pairs." - }, - { - "name": "removeAttribute", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the element to remove attribute from." }, - { "name": "name", "type": "string", "description": "Name of the attribute to remove." } - ], - "description": "Removes attribute with given name from an element with given id." - }, - { - "name": "getEventListenersForNode", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get listeners for." }, - { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name for handler value. Handler value is not returned without this parameter specified." } - ], - "returns": [ - { "name": "listeners", "type": "array", "items": { "$ref": "EventListener"}, "description": "Array of relevant listeners." } - ], - "description": "Returns event listeners relevant to the node." - }, - { - "name": "getOuterHTML", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get markup for." } - ], - "returns": [ - { "name": "outerHTML", "type": "string", "description": "Outer HTML markup." } - ], - "description": "Returns node's HTML markup." - }, - { - "name": "setOuterHTML", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to set markup for." }, - { "name": "outerHTML", "type": "string", "description": "Outer HTML markup to set." } - ], - "description": "Sets node HTML markup, returns new node id." - }, - { - "name": "performSearch", - "parameters": [ - { "name": "query", "type": "string", "description": "Plain text or query selector or XPath search query." }, - { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Ids of nodes to use as starting points for the search." } - ], - "returns": [ - { "name": "searchId", "type": "string", "description": "Unique search session identifier." }, - { "name": "resultCount", "type": "integer", "description": "Number of search results." } - ], - "description": "Searches for a given string in the DOM tree. Use <code>getSearchResults</code> to access search results or <code>cancelSearch</code> to end this search session." - }, - { - "name": "getSearchResults", - "parameters": [ - { "name": "searchId", "type": "string", "description": "Unique search session identifier." }, - { "name": "fromIndex", "type": "integer", "description": "Start index of the search result to be returned." }, - { "name": "toIndex", "type": "integer", "description": "End index of the search result to be returned." } - ], - "returns": [ - { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Ids of the search result nodes." } - ], - "description": "Returns search results from given <code>fromIndex</code> to given <code>toIndex</code> from the sarch with the given identifier." - }, - { - "name": "discardSearchResults", - "parameters": [ - { "name": "searchId", "type": "string", "description": "Unique search session identifier." } - ], - "description": "Discards search results from the session with the given id. <code>getSearchResults</code> should no longer be called for that search." - }, - { - "name": "requestNode", - "parameters": [ - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "JavaScript object id to convert into node." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Node id for given object." } - ], - "description": "Requests that the node is sent to the caller given the JavaScript node object reference. All nodes that form the path from the node to the root are also sent to the client as a series of <code>setChildNodes</code> notifications." - }, - { - "name": "setInspectModeEnabled", - "parameters": [ - { "name": "enabled", "type": "boolean", "description": "True to enable inspection mode, false to disable it." }, - { "name": "highlightConfig", "$ref": "HighlightConfig", "optional": true, "description": "A descriptor for the highlight appearance of hovered-over nodes. May be omitted if <code>enabled == false</code>." } - ], - "description": "Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspect' command upon element selection." - }, - { - "name": "highlightRect", - "parameters": [ - { "name": "x", "type": "integer", "description": "X coordinate" }, - { "name": "y", "type": "integer", "description": "Y coordinate" }, - { "name": "width", "type": "integer", "description": "Rectangle width" }, - { "name": "height", "type": "integer", "description": "Rectangle height" }, - { "name": "color", "$ref": "RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." }, - { "name": "outlineColor", "$ref": "RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }, - { "name": "usePageCoordinates", "type": "boolean", "optional": true, "description": "Indicates whether the provided parameters are in page coordinates or in viewport coordinates (the default)." } - ], - "description": "Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport." - }, - { - "name": "highlightQuad", - "parameters": [ - { "name": "quad", "$ref": "Quad", "description": "Quad to highlight" }, - { "name": "color", "$ref": "RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." }, - { "name": "outlineColor", "$ref": "RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }, - { "name": "usePageCoordinates", "type": "boolean", "optional": true, "description": "Indicates whether the provided parameters are in page coordinates or in viewport coordinates (the default)." } - ], - "description": "Highlights given quad. Coordinates are absolute with respect to the main frame viewport." - }, - { - "name": "highlightNode", - "parameters": [ - { "name": "highlightConfig", "$ref": "HighlightConfig", "description": "A descriptor for the highlight appearance." }, - { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "Identifier of the node to highlight." }, - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "JavaScript object id of the node to be highlighted." } - ], - "description": "Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified." - }, - { - "name": "hideHighlight", - "description": "Hides DOM node highlight." - }, - { - "name": "highlightFrame", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Identifier of the frame to highlight." }, - { "name": "contentColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." }, - { "name": "contentOutlineColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight outline color (default: transparent)." } - ], - "description": "Highlights owner element of the frame with given id." - }, - { - "name": "pushNodeByPathToFrontend", - "parameters": [ - { "name": "path", "type": "string", "description": "Path to node in the proprietary format." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node for given path." } - ], - "description": "Requests that the node is sent to the caller given its path. // FIXME, use XPath" - }, - { - "name": "pushNodeByBackendIdToFrontend", - "parameters": [ - { "name": "backendNodeId", "$ref": "BackendNodeId", "description": "The backend node id of the node." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "The pushed node's id." } - ], - "description": "Requests that the node is sent to the caller given its backend node id." - }, - { - "name": "releaseBackendNodeIds", - "parameters": [ - { "name": "nodeGroup", "type": "string", "description": "The backend node ids group name." } - ], - "description": "Requests that group of <code>BackendNodeIds</code> is released." - }, - { - "name": "resolveNode", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to resolve." }, - { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." } - ], - "returns": [ - { "name": "object", "$ref": "Runtime.RemoteObject", "description": "JavaScript object wrapper for given node." } - ], - "description": "Resolves JavaScript node object for given node id." - }, - { - "name": "getAttributes", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to retrieve attibutes for." } - ], - "returns": [ - { "name": "attributes", "type": "array", "items": { "type": "string" }, "description": "An interleaved array of node attribute names and values." } - ], - "description": "Returns attributes for the specified node." - }, - { - "name": "moveTo", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to drop." }, - { "name": "targetNodeId", "$ref": "NodeId", "description": "Id of the element to drop into." }, - { "name": "insertBeforeNodeId", "$ref": "NodeId", "optional": true, "description": "Drop node before given one." } - ], - "returns": [ - { "name": "nodeId", "$ref": "NodeId", "description": "New id of the moved node." } - ], - "description": "Moves node into the new container, places it before the given anchor." - }, - { - "name": "undo", - "description": "Undoes the last performed action." - }, - { - "name": "redo", - "description": "Re-does the last undone action." - }, - { - "name": "markUndoableState", - "description": "Marks last undoable state." - }, - { - "name": "focus", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to focus." } - ], - "description": "Focuses the given element." - } - ], - "events": [ - { - "name": "documentUpdated", - "description": "Fired when <code>Document</code> has been totally updated. Node ids are no longer valid." - }, - { - "name": "setChildNodes", - "parameters": [ - { "name": "parentId", "$ref": "NodeId", "description": "Parent node id to populate with children." }, - { "name": "nodes", "type": "array", "items": { "$ref": "Node"}, "description": "Child nodes array." } - ], - "description": "Fired when backend wants to provide client with the missing DOM structure. This happens upon most of the calls requesting node ids." - }, - { - "name": "attributeModified", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." }, - { "name": "name", "type": "string", "description": "Attribute name." }, - { "name": "value", "type": "string", "description": "Attribute value." } - ], - "description": "Fired when <code>Element</code>'s attribute is modified." - }, - { - "name": "attributeRemoved", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." }, - { "name": "name", "type": "string", "description": "A ttribute name." } - ], - "description": "Fired when <code>Element</code>'s attribute is removed." - }, - { - "name": "inlineStyleInvalidated", - "parameters": [ - { "name": "nodeIds", "type": "array", "items": { "$ref": "NodeId" }, "description": "Ids of the nodes for which the inline styles have been invalidated." } - ], - "description": "Fired when <code>Element</code>'s inline style is modified via a CSS property modification." - }, - { - "name": "characterDataModified", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." }, - { "name": "characterData", "type": "string", "description": "New text value." } - ], - "description": "Mirrors <code>DOMCharacterDataModified</code> event." - }, - { - "name": "childNodeCountUpdated", - "parameters": [ - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has changed." }, - { "name": "childNodeCount", "type": "integer", "description": "New node count." } - ], - "description": "Fired when <code>Container</code>'s child node count has changed." - }, - { - "name": "childNodeInserted", - "parameters": [ - { "name": "parentNodeId", "$ref": "NodeId", "description": "Id of the node that has changed." }, - { "name": "previousNodeId", "$ref": "NodeId", "description": "If of the previous siblint." }, - { "name": "node", "$ref": "Node", "description": "Inserted node data." } - ], - "description": "Mirrors <code>DOMNodeInserted</code> event." - }, - { - "name": "childNodeRemoved", - "parameters": [ - { "name": "parentNodeId", "$ref": "NodeId", "description": "Parent id." }, - { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node that has been removed." } - ], - "description": "Mirrors <code>DOMNodeRemoved</code> event." - }, - { - "name": "shadowRootPushed", - "parameters": [ - { "name": "hostId", "$ref": "NodeId", "description": "Host element id." }, - { "name": "root", "$ref": "Node", "description": "Shadow root." } - ], - "description": "Called when shadow root is pushed into the element." - }, - { - "name": "shadowRootPopped", - "parameters": [ - { "name": "hostId", "$ref": "NodeId", "description": "Host element id." }, - { "name": "rootId", "$ref": "NodeId", "description": "Shadow root id." } - ], - "description": "Called when shadow root is popped from the element." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/DOMDebugger.json b/Source/WebCore/inspector/protocol/DOMDebugger.json deleted file mode 100644 index 0bfc76320..000000000 --- a/Source/WebCore/inspector/protocol/DOMDebugger.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "domain": "DOMDebugger", - "description": "DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript execution will stop on these operations as if there was a regular breakpoint set.", - "types": [ - { - "id": "DOMBreakpointType", - "type": "string", - "enum": ["subtree-modified", "attribute-modified", "node-removed"], - "description": "DOM breakpoint type." - } - ], - "commands": [ - { - "name": "setDOMBreakpoint", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Identifier of the node to set breakpoint on." }, - { "name": "type", "$ref": "DOMBreakpointType", "description": "Type of the operation to stop upon." } - ], - "description": "Sets breakpoint on particular operation with DOM." - }, - { - "name": "removeDOMBreakpoint", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Identifier of the node to remove breakpoint from." }, - { "name": "type", "$ref": "DOMBreakpointType", "description": "Type of the breakpoint to remove." } - ], - "description": "Removes DOM breakpoint that was set using <code>setDOMBreakpoint</code>." - }, - { - "name": "setEventListenerBreakpoint", - "parameters": [ - { "name": "eventName", "type": "string", "description": "DOM Event name to stop on (any DOM event will do)." } - ], - "description": "Sets breakpoint on particular DOM event." - }, - { - "name": "removeEventListenerBreakpoint", - "parameters": [ - { "name": "eventName", "type": "string", "description": "Event name." } - ], - "description": "Removes breakpoint on particular DOM event." - }, - { - "name": "setInstrumentationBreakpoint", - "parameters": [ - { "name": "eventName", "type": "string", "description": "Instrumentation name to stop on." } - ], - "description": "Sets breakpoint on particular native event." - }, - { - "name": "removeInstrumentationBreakpoint", - "parameters": [ - { "name": "eventName", "type": "string", "description": "Instrumentation name to stop on." } - ], - "description": "Sets breakpoint on particular native event." - }, - { - "name": "setXHRBreakpoint", - "parameters": [ - { "name": "url", "type": "string", "description": "Resource URL substring. All XHRs having this substring in the URL will get stopped upon." } - ], - "description": "Sets breakpoint on XMLHttpRequest." - }, - { - "name": "removeXHRBreakpoint", - "parameters": [ - { "name": "url", "type": "string", "description": "Resource URL substring." } - ], - "description": "Removes breakpoint from XMLHttpRequest." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/DOMStorage.json b/Source/WebCore/inspector/protocol/DOMStorage.json deleted file mode 100644 index b8f1ebca3..000000000 --- a/Source/WebCore/inspector/protocol/DOMStorage.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "domain": "DOMStorage", - "description": "Query and modify DOM storage.", - "types": [ - { - "id": "StorageId", - "type": "object", - "description": "DOM Storage identifier.", - "properties": [ - { "name": "securityOrigin", "type": "string", "description": "Security origin for the storage." }, - { "name": "isLocalStorage", "type": "boolean", "description": "Whether the storage is local storage (not session storage)." } - ] - }, - { - "id": "Item", - "type": "array", - "description": "DOM Storage item.", - "items": { "type": "string" } - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables storage tracking, storage events will now be delivered to the client." - }, - { - "name": "disable", - "description": "Disables storage tracking, prevents storage events from being sent to the client." - }, - { - "name": "getDOMStorageItems", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" } - ], - "returns": [ - { "name": "entries", "type": "array", "items": { "$ref": "Item" } } - ] - }, - { - "name": "setDOMStorageItem", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" }, - { "name": "key", "type": "string" }, - { "name": "value", "type": "string" } - ] - }, - { - "name": "removeDOMStorageItem", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" }, - { "name": "key", "type": "string" } - ] - } - ], - "events": [ - { - "name": "domStorageItemsCleared", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" } - ] - }, - { - "name": "domStorageItemRemoved", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" }, - { "name": "key", "type": "string" } - ] - }, - { - "name": "domStorageItemAdded", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" }, - { "name": "key", "type": "string" }, - { "name": "newValue", "type": "string" } - ] - }, - { - "name": "domStorageItemUpdated", - "parameters": [ - { "name": "storageId", "$ref": "StorageId" }, - { "name": "key", "type": "string" }, - { "name": "oldValue", "type": "string" }, - { "name": "newValue", "type": "string" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Database.json b/Source/WebCore/inspector/protocol/Database.json deleted file mode 100644 index e6ce228e1..000000000 --- a/Source/WebCore/inspector/protocol/Database.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "domain": "Database", - "types": [ - { - "id": "DatabaseId", - "type": "string", - "description": "Unique identifier of Database object." - }, - { - "id": "Database", - "type": "object", - "description": "Database object.", - "properties": [ - { "name": "id", "$ref": "DatabaseId", "description": "Database ID." }, - { "name": "domain", "type": "string", "description": "Database domain." }, - { "name": "name", "type": "string", "description": "Database name." }, - { "name": "version", "type": "string", "description": "Database version." } - ] - }, - { - "id": "Error", - "type": "object", - "description": "Database error.", - "properties": [ - { "name": "message", "type": "string", "description": "Error message." }, - { "name": "code", "type": "integer", "description": "Error code." } - ] - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables database tracking, database events will now be delivered to the client." - }, - { - "name": "disable", - "description": "Disables database tracking, prevents database events from being sent to the client." - }, - { - "name": "getDatabaseTableNames", - "parameters": [ - { "name": "databaseId", "$ref": "DatabaseId" } - ], - "returns": [ - { "name": "tableNames", "type": "array", "items": { "type": "string" } } - ] - }, - { - "name": "executeSQL", - "async": true, - "parameters": [ - { "name": "databaseId", "$ref": "DatabaseId" }, - { "name": "query", "type": "string" } - ], - "returns": [ - { "name": "columnNames", "type": "array", "optional": true, "items": { "type": "string" } }, - { "name": "values", "type": "array", "optional": true, "items": { "type": "any" }}, - { "name": "sqlError", "$ref": "Error", "optional": true } - ] - } - ], - "events": [ - { - "name": "addDatabase", - "parameters": [ - { "name": "database", "$ref": "Database" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/HeapProfiler.json b/Source/WebCore/inspector/protocol/HeapProfiler.json deleted file mode 100644 index 56e6772d3..000000000 --- a/Source/WebCore/inspector/protocol/HeapProfiler.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "domain": "HeapProfiler", - "types": [ - { - "id": "ProfileHeader", - "type": "object", - "description": "Profile header.", - "properties": [ - { "name": "title", "type": "string", "description": "Profile title." }, - { "name": "uid", "type": "integer", "description": "Unique identifier of the profile." }, - { "name": "maxJSObjectId", "type": "integer", "optional": true, "description": "Last seen JS object Id." } - ] - }, - { - "id": "HeapSnapshotObjectId", - "type": "string", - "description": "Heap snashot object id." - } - ], - "commands": [ - { - "name": "hasHeapProfiler", - "returns": [ - { "name": "result", "type": "boolean" } - ] - }, - { - "name": "getProfileHeaders", - "returns": [ - { "name": "headers", "type": "array", "items": { "$ref": "ProfileHeader"} } - ] - }, - { - "name": "getHeapSnapshot", - "parameters": [ - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "removeProfile", - "parameters": [ - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "clearProfiles" - }, - { - "name": "takeHeapSnapshot", - "parameters": [ - { "name": "reportProgress", "type": "boolean", "optional": true, "description": "If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken." } - ] - }, - { - "name": "collectGarbage" - }, - { - "name": "getObjectByHeapObjectId", - "parameters": [ - { "name": "objectId", "$ref": "HeapSnapshotObjectId" }, - { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." } - ], - "returns": [ - { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Evaluation result." } - ] - }, - { - "name": "getHeapObjectId", - "parameters": [ - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Identifier of the object to get heap object id for." } - ], - "returns": [ - { "name": "heapSnapshotObjectId", "$ref": "HeapSnapshotObjectId", "description": "Id of the heap snapshot object corresponding to the passed remote object id." } - ] - } - ], - "events": [ - { - "name": "addProfileHeader", - "parameters": [ - { "name": "header", "$ref": "ProfileHeader" } - ] - }, - { - "name": "addHeapSnapshotChunk", - "parameters": [ - { "name": "uid", "type": "integer" }, - { "name": "chunk", "type": "string" } - ] - }, - { - "name": "finishHeapSnapshot", - "parameters": [ - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "resetProfiles" - }, - { - "name": "reportHeapSnapshotProgress", - "parameters": [ - { "name": "done", "type": "integer" }, - { "name": "total", "type": "integer" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/IndexedDB.json b/Source/WebCore/inspector/protocol/IndexedDB.json deleted file mode 100644 index 6c1649fa5..000000000 --- a/Source/WebCore/inspector/protocol/IndexedDB.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "domain": "IndexedDB", - "types": [ - { - "id": "DatabaseWithObjectStores", - "type": "object", - "description": "Database with an array of object stores.", - "properties": [ - { "name": "name", "type": "string", "description": "Database name." }, - { "name": "version", "type": "string", "description": "Deprecated string database version." }, - { "name": "intVersion", "type": "integer", "description": "Integer database version." }, - { "name": "objectStores", "type": "array", "items": { "$ref": "ObjectStore" }, "description": "Object stores in this database." } - ] - }, - { - "id": "ObjectStore", - "type": "object", - "description": "Object store.", - "properties": [ - { "name": "name", "type": "string", "description": "Object store name." }, - { "name": "keyPath", "$ref": "KeyPath", "description": "Object store key path." }, - { "name": "autoIncrement", "type": "boolean", "description": "If true, object store has auto increment flag set." }, - { "name": "indexes", "type": "array", "items": { "$ref": "ObjectStoreIndex" }, "description": "Indexes in this object store." } - ] - }, - { - "id": "ObjectStoreIndex", - "type": "object", - "description": "Object store index.", - "properties": [ - { "name": "name", "type": "string", "description": "Index name." }, - { "name": "keyPath", "$ref": "KeyPath", "description": "Index key path." }, - { "name": "unique", "type": "boolean", "description": "If true, index is unique." }, - { "name": "multiEntry", "type": "boolean", "description": "If true, index allows multiple entries for a key." } - ] - }, - { - "id": "Key", - "type": "object", - "description": "Key.", - "properties": [ - { "name": "type", "type": "string", "enum": ["number", "string", "date", "array"], "description": "Key type." }, - { "name": "number", "type": "number", "optional": true, "description": "Number value." }, - { "name": "string", "type": "string", "optional": true, "description": "String value." }, - { "name": "date", "type": "number", "optional": true, "description": "Date value." }, - { "name": "array", "type": "array", "optional": true, "items": { "$ref": "Key" }, "description": "Array value." } - ] - }, - { - "id": "KeyRange", - "type": "object", - "description": "Key range.", - "properties": [ - { "name": "lower", "$ref": "Key", "optional": true, "description": "Lower bound." }, - { "name": "upper", "$ref": "Key", "optional": true, "description": "Upper bound." }, - { "name": "lowerOpen", "type": "boolean", "description": "If true lower bound is open." }, - { "name": "upperOpen", "type": "boolean", "description": "If true upper bound is open." } - ] - }, - { - "id": "DataEntry", - "type": "object", - "description": "Data entry.", - "properties": [ - { "name": "key", "$ref": "Runtime.RemoteObject", "description": "Key." }, - { "name": "primaryKey", "$ref": "Runtime.RemoteObject", "description": "Primary key." }, - { "name": "value", "$ref": "Runtime.RemoteObject", "description": "Value." } - ] - }, - { - "id": "KeyPath", - "type": "object", - "description": "Key path.", - "properties": [ - { "name": "type", "type": "string", "enum": ["null", "string", "array"], "description": "Key path type." }, - { "name": "string", "type": "string", "optional": true, "description": "String value." }, - { "name": "array", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Array value." } - ] - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables events from backend." - }, - { - "name": "disable", - "description": "Disables events from backend." - }, - { - "name": "requestDatabaseNames", - "async": true, - "parameters": [ - { "name": "securityOrigin", "type": "string", "description": "Security origin." } - ], - "returns": [ - { "name": "databaseNames", "type": "array", "items": { "type": "string" }, "description": "Database names for origin." } - ], - "description": "Requests database names for given security origin." - }, - { - "name": "requestDatabase", - "async": true, - "parameters": [ - { "name": "securityOrigin", "type": "string", "description": "Security origin." }, - { "name": "databaseName", "type": "string", "description": "Database name." } - ], - "returns": [ - { "name": "databaseWithObjectStores", "$ref": "DatabaseWithObjectStores", "description": "Database with an array of object stores." } - ], - "description": "Requests database with given name in given frame." - }, - { - "name": "requestData", - "async": true, - "parameters": [ - { "name": "securityOrigin", "type": "string", "description": "Security origin." }, - { "name": "databaseName", "type": "string", "description": "Database name." }, - { "name": "objectStoreName", "type": "string", "description": "Object store name." }, - { "name": "indexName", "type": "string", "description": "Index name, empty string for object store data requests." }, - { "name": "skipCount", "type": "integer", "description": "Number of records to skip." }, - { "name": "pageSize", "type": "integer", "description": "Number of records to fetch." }, - { "name": "keyRange", "$ref": "KeyRange", "optional": true, "description": "Key range." } - ], - "returns": [ - { "name": "objectStoreDataEntries", "type": "array", "items": { "$ref": "DataEntry" }, "description": "Array of object store data entries." }, - { "name": "hasMore", "type": "boolean", "description": "If true, there are more entries to fetch in the given range." } - ], - "description": "Requests data from object store or index." - }, - { - "name": "clearObjectStore", - "async": true, - "parameters": [ - { "name": "securityOrigin", "type": "string", "description": "Security origin." }, - { "name": "databaseName", "type": "string", "description": "Database name." }, - { "name": "objectStoreName", "type": "string", "description": "Object store name." } - ], - "returns": [ - ], - "description": "Clears all entries from an object store." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Input.json b/Source/WebCore/inspector/protocol/Input.json deleted file mode 100644 index 7e3619bf7..000000000 --- a/Source/WebCore/inspector/protocol/Input.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "domain": "Input", - "types": [], - "commands": [ - { - "name": "dispatchKeyEvent", - "parameters": [ - { "name": "type", "type": "string", "enum": ["keyDown", "keyUp", "rawKeyDown", "char"], "description": "Type of the key event." }, - { "name": "modifiers", "type": "integer", "optional": true, "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)." }, - { "name": "timestamp", "type": "number", "optional": true, "description": "Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)." }, - { "name": "text", "type": "string", "optional": true, "description": "Text as generated by processing a virtual key code with a keyboard layout. Not needed for for <code>keyUp</code> and <code>rawKeyDown</code> events (default: \"\")" }, - { "name": "unmodifiedText", "type": "string", "optional": true, "description": "Text that would have been generated by the keyboard if no modifiers were pressed (except for shift). Useful for shortcut (accelerator) key handling (default: \"\")." }, - { "name": "keyIdentifier", "type": "string", "optional": true, "description": "Unique key identifier (e.g., 'U+0041') (default: \"\")." }, - { "name": "windowsVirtualKeyCode", "type": "integer", "optional": true, "description": "Windows virtual key code (default: 0)." }, - { "name": "nativeVirtualKeyCode", "type": "integer", "optional": true, "description": "Native virtual key code (default: 0)." }, - { "name": "macCharCode", "type": "integer", "optional": true, "description": "Mac character code (default: 0)." }, - { "name": "autoRepeat", "type": "boolean", "optional": true, "description": "Whether the event was generated from auto repeat (default: false)." }, - { "name": "isKeypad", "type": "boolean", "optional": true, "description": "Whether the event was generated from the keypad (default: false)." }, - { "name": "isSystemKey", "type": "boolean", "optional": true, "description": "Whether the event was a system key event (default: false)." } - ], - "description": "Dispatches a key event to the page." - }, - { - "name": "dispatchMouseEvent", - "parameters": [ - { "name": "type", "type": "string", "enum": ["mousePressed", "mouseReleased", "mouseMoved"], "description": "Type of the mouse event." }, - { "name": "x", "type": "integer", "description": "X coordinate of the event relative to the main frame's viewport."}, - { "name": "y", "type": "integer", "description": "Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."}, - { "name": "modifiers", "type": "integer", "optional": true, "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)." }, - { "name": "timestamp", "type": "number", "optional": true, "description": "Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)." }, - { "name": "button", "type": "string", "enum": ["none", "left", "middle", "right"], "optional": true, "description": "Mouse button (default: \"none\")." }, - { "name": "clickCount", "type": "integer", "optional": true, "description": "Number of times the mouse button was clicked (default: 0)." } - ], - "description": "Dispatches a mouse event to the page." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/LayerTree.json b/Source/WebCore/inspector/protocol/LayerTree.json deleted file mode 100644 index 33f7dbf03..000000000 --- a/Source/WebCore/inspector/protocol/LayerTree.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "domain": "LayerTree", - "types": [ - { - "id": "LayerId", - "type": "string", - "description": "Unique RenderLayer identifier." - }, - { - "id": "PseudoElementId", - "type": "string", - "description": "Unique PseudoElement identifier." - }, - { - "id": "IntRect", - "type": "object", - "description": "A rectangle.", - "properties": [ - { "name": "x", "type": "integer", "description": "The x position." }, - { "name": "y", "type": "integer", "description": "The y position." }, - { "name": "width", "type": "integer", "description": "The width metric." }, - { "name": "height", "type": "integer", "description": "The height metric." } - ] - }, - { - "id": "Layer", - "type": "object", - "description": "Information about a compositing layer.", - "properties": [ - { "name": "layerId", "$ref": "LayerId", "description": "The unique id for this layer." }, - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "The id for the node associated with this layer." }, - { "name": "bounds", "$ref": "IntRect", "description": "Bounds of the layer in absolute page coordinates." }, - { "name": "paintCount", "type": "integer", "description": "Indicates how many time this layer has painted." }, - { "name": "memory", "type": "integer", "description": "Estimated memory used by this layer." }, - { "name": "compositedBounds", "$ref": "IntRect", "description": "The bounds of the composited layer." }, - { "name": "isInShadowTree", "type": "boolean", "optional": true, "description": "Indicates whether this layer is associated with an element hosted in a shadow tree." }, - { "name": "isReflection", "type": "boolean", "optional": true, "description": "Indicates whether this layer was used to provide a reflection for the element." }, - { "name": "isGeneratedContent", "type": "boolean", "optional": true, "description": "Indicates whether the layer is attached to a pseudo element that is CSS generated content." }, - { "name": "isAnonymous", "type": "boolean", "optional": true, "description": "Indicates whether the layer was created for a CSS anonymous block or box." }, - { "name": "pseudoElementId", "$ref": "PseudoElementId", "optional": true, "description": "The id for the pseudo element associated with this layer." }, - { "name": "pseudoElement", "type": "string", "optional": true, "description": "The name of the CSS pseudo-element that prompted the layer to be generated." } - ] - }, - { - "id": "CompositingReasons", - "type": "object", - "description": "An object containing the reasons why the layer was composited as properties.", - "properties": [ - { "name": "transform3D", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a CSS 3D transform." }, - { "name": "video", "type": "boolean", "optional": true, "description": "Composition due to association with a <video> element." }, - { "name": "canvas", "type": "boolean", "optional": true, "description": "Composition due to the element being a <canvas> element." }, - { "name": "plugin", "type": "boolean", "optional": true, "description": "Composition due to association with a plugin." }, - { "name": "iFrame", "type": "boolean", "optional": true, "description": "Composition due to association with an <iframe> element." }, - { "name": "backfaceVisibilityHidden", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"backface-visibility: hidden\" style." }, - { "name": "clipsCompositingDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element clipping compositing descendants." }, - { "name": "animation", "type": "boolean", "optional": true, "description": "Composition due to association with an animated element." }, - { "name": "filters", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS filters applied." }, - { "name": "positionFixed", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"position: fixed\" style." }, - { "name": "positionSticky", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"position: sticky\" style." }, - { "name": "overflowScrollingTouch", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"overflow-scrolling: touch\" style." }, - { "name": "stacking", "type": "boolean", "optional": true, "description": "Composition due to association with an element establishing a stacking context." }, - { "name": "overlap", "type": "boolean", "optional": true, "description": "Composition due to association with an element overlapping other composited elements." }, - { "name": "negativeZIndexChildren", "type": "boolean", "optional": true, "description": "Composition due to association with an element with descendants that have a negative z-index." }, - { "name": "transformWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with composited descendants." }, - { "name": "opacityWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with opacity applied and composited descendants." }, - { "name": "maskWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with a masked element and composited descendants." }, - { "name": "reflectionWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a reflection and composited descendants." }, - { "name": "filterWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS filters applied and composited descendants." }, - { "name": "blendingWithCompositedDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element with CSS blending applied and composited descendants." }, - { "name": "perspective", "type": "boolean", "optional": true, "description": "Composition due to association with an element with perspective applied." }, - { "name": "preserve3D", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"transform-style: preserve-3d\" style." }, - { "name": "root", "type": "boolean", "optional": true, "description": "Composition due to association with the root element." }, - { "name": "blending", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"blend-mode\" style." } - ] - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables compositing tree inspection." - }, - { - "name": "disable", - "description": "Disables compositing tree inspection." - }, - { - "name": "layersForNode", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Root of the subtree for which we want to gather layers." } ], - "description": "Returns the layer tree structure of the current page.", - "returns": [ - { "name": "layers", "type": "array", "items": { "$ref": "Layer" }, "description": "Child layers." } - ] - }, - { - "name": "reasonsForCompositingLayer", - "parameters": [ - { "name": "layerId", "$ref": "LayerId", "description": "The id of the layer for which we want to get the reasons it was composited." } - ], - "description": "Provides the reasons why the given layer was composited.", - "returns": [ - { "name": "compositingReasons", "$ref": "CompositingReasons", "description": "An object containing the reasons why the layer was composited as properties." } - ] - } - ], - "events": [ - { - "name": "layerTreeDidChange" - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Memory.json b/Source/WebCore/inspector/protocol/Memory.json deleted file mode 100644 index 4077e83f4..000000000 --- a/Source/WebCore/inspector/protocol/Memory.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "domain": "Memory", - "types": [ - { - "id": "MemoryBlock", - "type": "object", - "properties": [ - { "name": "size", "type": "number", "optional": true, "description": "Size of the block in bytes if available" }, - { "name": "name", "type": "string", "description": "Unique name used to identify the component that allocated this block" }, - { "name": "children", "type": "array", "optional": true, "items": { "$ref": "MemoryBlock" }} - ] - } - ], - "commands": [ - { - "name": "getDOMCounters", - "returns": [ - { "name": "documents", "type": "integer" }, - { "name": "nodes", "type": "integer" }, - { "name": "jsEventListeners", "type": "integer" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Network.json b/Source/WebCore/inspector/protocol/Network.json deleted file mode 100644 index 79bab7a9e..000000000 --- a/Source/WebCore/inspector/protocol/Network.json +++ /dev/null @@ -1,334 +0,0 @@ -{ - "domain": "Network", - "description": "Network domain allows tracking network activities of the page. It exposes information about http, file, data and other requests and responses, their headers, bodies, timing, etc.", - "types": [ - { - "id": "LoaderId", - "type": "string", - "description": "Unique loader identifier." - }, - { - "id": "FrameId", - "type": "string", - "description": "Unique frame identifier." - }, - { - "id": "RequestId", - "type": "string", - "description": "Unique request identifier." - }, - { - "id": "Timestamp", - "type": "number", - "description": "Number of seconds since epoch." - }, - { - "id": "Headers", - "type": "object", - "description": "Request / response headers as keys / values of JSON object." - }, - { - "id": "ResourceTiming", - "type": "object", - "description": "Timing information for the request.", - "properties": [ - { "name": "requestTime", "type": "number", "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime." }, - { "name": "proxyStart", "type": "number", "description": "Started resolving proxy." }, - { "name": "proxyEnd", "type": "number", "description": "Finished resolving proxy." }, - { "name": "dnsStart", "type": "number", "description": "Started DNS address resolve." }, - { "name": "dnsEnd", "type": "number", "description": "Finished DNS address resolve." }, - { "name": "connectStart", "type": "number", "description": "Started connecting to the remote host." }, - { "name": "connectEnd", "type": "number", "description": "Connected to the remote host." }, - { "name": "sslStart", "type": "number", "description": "Started SSL handshake." }, - { "name": "sslEnd", "type": "number", "description": "Finished SSL handshake." }, - { "name": "sendStart", "type": "number", "description": "Started sending request." }, - { "name": "sendEnd", "type": "number", "description": "Finished sending request." }, - { "name": "receiveHeadersEnd", "type": "number", "description": "Finished receiving response headers." } - ] - }, - { - "id": "Request", - "type": "object", - "description": "HTTP request data.", - "properties": [ - { "name": "url", "type": "string", "description": "Request URL." }, - { "name": "method", "type": "string", "description": "HTTP request method." }, - { "name": "headers", "$ref": "Headers", "description": "HTTP request headers." }, - { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." } - ] - }, - { - "id": "Response", - "type": "object", - "description": "HTTP response data.", - "properties": [ - { "name": "url", "type": "string", "description": "Response URL. This URL can be different from CachedResource.url in case of redirect." }, - { "name": "status", "type": "number", "description": "HTTP response status code." }, - { "name": "statusText", "type": "string", "description": "HTTP response status text." }, - { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." }, - { "name": "headersText", "type": "string", "optional": true, "description": "HTTP response headers text." }, - { "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." }, - { "name": "requestHeaders", "$ref": "Headers", "optional": true, "description": "Refined HTTP request headers that were actually transmitted over the network." }, - { "name": "requestHeadersText", "type": "string", "optional": true, "description": "HTTP request headers text." }, - { "name": "connectionReused", "type": "boolean", "description": "Specifies whether physical connection was actually reused for this request." }, - { "name": "connectionId", "type": "number", "description": "Physical connection id that was actually used for this request." }, - { "name": "fromDiskCache", "type": "boolean", "optional": true, "description": "Specifies that the request was served from the disk cache." }, - { "name": "timing", "$ref": "ResourceTiming", "optional": true, "description": "Timing information for the given request." } - ] - }, - { - "id": "WebSocketRequest", - "type": "object", - "description": "WebSocket request data.", - "properties": [ - { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." } - ] - }, - { - "id": "WebSocketResponse", - "type": "object", - "description": "WebSocket response data.", - "properties": [ - { "name": "status", "type": "number", "description": "HTTP response status code." }, - { "name": "statusText", "type": "string", "description": "HTTP response status text." }, - { "name": "headers", "$ref": "Headers", "description": "HTTP response headers." } - ] - }, - { - "id": "WebSocketFrame", - "type": "object", - "description": "WebSocket frame data.", - "properties": [ - { "name": "opcode", "type": "number", "description": "WebSocket frame opcode." }, - { "name": "mask", "type": "boolean", "description": "WebSocket frame mask." }, - { "name": "payloadData", "type": "string", "description": "WebSocket frame payload data." } - ] - }, - { - "id": "CachedResource", - "type": "object", - "description": "Information about the cached resource.", - "properties": [ - { "name": "url", "type": "string", "description": "Resource URL. This is the url of the original network request." }, - { "name": "type", "$ref": "Page.ResourceType", "description": "Type of this resource." }, - { "name": "response", "$ref": "Response", "optional": true, "description": "Cached response data." }, - { "name": "bodySize", "type": "number", "description": "Cached response body size." }, - { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." } - ] - }, - { - "id": "Initiator", - "type": "object", - "description": "Information about the request initiator.", - "properties": [ - { "name": "type", "type": "string", "enum": ["parser", "script", "other"], "description": "Type of this initiator." }, - { "name": "stackTrace", "$ref": "Console.StackTrace", "optional": true, "description": "Initiator JavaScript stack trace, set for Script only." }, - { "name": "url", "type": "string", "optional": true, "description": "Initiator URL, set for Parser type only." }, - { "name": "lineNumber", "type": "number", "optional": true, "description": "Initiator line number, set for Parser type only." } - ] - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables network tracking, network events will now be delivered to the client." - }, - { - "name": "disable", - "description": "Disables network tracking, prevents network events from being sent to the client." - }, - { - "name": "setExtraHTTPHeaders", - "description": "Specifies whether to always send extra HTTP headers with the requests from this page.", - "parameters": [ - { "name": "headers", "$ref": "Headers", "description": "Map with extra HTTP headers." } - ] - }, - { - "name": "getResponseBody", - "description": "Returns content served for the given request.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Identifier of the network request to get content for." } - ], - "returns": [ - { "name": "body", "type": "string", "description": "Response body." }, - { "name": "base64Encoded", "type": "boolean", "description": "True, if content was sent as base64." } - ] - }, - { - "name": "replayXHR", - "description": "This method sends a new XMLHttpRequest which is identical to the original one. The following parameters should be identical: method, url, async, request body, extra headers, withCredentials attribute, user, password.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Identifier of XHR to replay." } - ] - }, - { - "name": "canClearBrowserCache", - "description": "Tells whether clearing browser cache is supported.", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if browser cache can be cleared." } - ] - }, - { - "name": "clearBrowserCache", - "description": "Clears browser cache." - }, - { - "name": "canClearBrowserCookies", - "description": "Tells whether clearing browser cookies is supported.", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if browser cookies can be cleared." } - ] - }, - { - "name": "clearBrowserCookies", - "description": "Clears browser cookies." - }, - { - "name": "setCacheDisabled", - "parameters": [ - { "name": "cacheDisabled", "type": "boolean", "description": "Cache disabled state." } - ], - "description": "Toggles ignoring cache for each request. If <code>true</code>, cache will not be used." - } - ], - "events": [ - { - "name": "requestWillBeSent", - "description": "Fired when page is about to send HTTP request.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." }, - { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." }, - { "name": "documentURL", "type": "string", "description": "URL of the document this request is loaded for." }, - { "name": "request", "$ref": "Request", "description": "Request data." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "initiator", "$ref": "Initiator", "description": "Request initiator." }, - { "name": "redirectResponse", "optional": true, "$ref": "Response", "description": "Redirect response data." }, - { "name": "type", "$ref": "Page.ResourceType", "optional": true, "description": "Resource type." } - ] - }, - { - "name": "requestServedFromCache", - "description": "Fired if request ended up loading from cache.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." } - ] - }, - { - "name": "responseReceived", - "description": "Fired when HTTP response is available.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." }, - { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "type", "$ref": "Page.ResourceType", "description": "Resource type." }, - { "name": "response", "$ref": "Response", "description": "Response data." } - ] - }, - { - "name": "dataReceived", - "description": "Fired when data chunk was received over the network.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "dataLength", "type": "integer", "description": "Data chunk length." }, - { "name": "encodedDataLength", "type": "integer", "description": "Actual bytes received (might be less than dataLength for compressed encodings)." } - ] - }, - { - "name": "loadingFinished", - "description": "Fired when HTTP request has finished loading.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." } - ] - }, - { - "name": "loadingFailed", - "description": "Fired when HTTP request has failed to load.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "errorText", "type": "string", "description": "User friendly error message." }, - { "name": "canceled", "type": "boolean", "optional": true, "description": "True if loading was canceled." } - ] - }, - { - "name": "requestServedFromMemoryCache", - "description": "Fired when HTTP request has been served from memory cache.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "frameId", "$ref": "FrameId", "description": "Frame identifier." }, - { "name": "loaderId", "$ref": "LoaderId", "description": "Loader identifier." }, - { "name": "documentURL", "type": "string", "description": "URL of the document this request is loaded for." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "initiator", "$ref": "Initiator", "description": "Request initiator." }, - { "name": "resource", "$ref": "CachedResource", "description": "Cached resource data." } - ] - }, - { - "name": "webSocketWillSendHandshakeRequest", - "description": "Fired when WebSocket is about to initiate handshake.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." } - ] - }, - { - "name": "webSocketHandshakeResponseReceived", - "description": "Fired when WebSocket handshake response becomes available.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." } - ] - }, - { - "name": "webSocketCreated", - "description": "Fired upon WebSocket creation.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "url", "type": "string", "description": "WebSocket request URL." } - ] - }, - { - "name": "webSocketClosed", - "description": "Fired when WebSocket is closed.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." } - ] - }, - { - "name": "webSocketFrameReceived", - "description": "Fired when WebSocket frame is received.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "response", "$ref": "WebSocketFrame", "description": "WebSocket response data." } - ] - }, - { - "name": "webSocketFrameError", - "description": "Fired when WebSocket frame error occurs.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "errorMessage", "type": "string", "description": "WebSocket frame error message." } - ] - }, - { - "name": "webSocketFrameSent", - "description": "Fired when WebSocket frame is sent.", - "parameters": [ - { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." }, - { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." }, - { "name": "response", "$ref": "WebSocketFrame", "description": "WebSocket response data." } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Page.json b/Source/WebCore/inspector/protocol/Page.json deleted file mode 100644 index 3afdbc0cd..000000000 --- a/Source/WebCore/inspector/protocol/Page.json +++ /dev/null @@ -1,399 +0,0 @@ -{ - "domain": "Page", - "description": "Actions and events related to the inspected page belong to the page domain.", - "types": [ - { - "id": "ResourceType", - "type": "string", - "enum": ["Document", "Stylesheet", "Image", "Font", "Script", "XHR", "WebSocket", "Other"], - "description": "Resource type as it was perceived by the rendering engine." - }, - { - "id": "CoordinateSystem", - "type": "string", - "enum": ["Viewport", "Page"], - "description": "Coordinate system used by supplied coordinates." - }, - { - "id": "Frame", - "type": "object", - "description": "Information about the Frame on the page.", - "properties": [ - { "name": "id", "type": "string", "description": "Frame unique identifier." }, - { "name": "parentId", "type": "string", "optional": true, "description": "Parent frame identifier." }, - { "name": "loaderId", "$ref": "Network.LoaderId", "description": "Identifier of the loader associated with this frame." }, - { "name": "name", "type": "string", "optional": true, "description": "Frame's name as specified in the tag." }, - { "name": "url", "type": "string", "description": "Frame document's URL." }, - { "name": "securityOrigin", "type": "string", "description": "Frame document's security origin." }, - { "name": "mimeType", "type": "string", "description": "Frame document's mimeType as determined by the browser." } - ] - }, - { - "id": "FrameResourceTree", - "type": "object", - "description": "Information about the Frame hierarchy along with their cached resources.", - "properties": [ - { "name": "frame", "$ref": "Frame", "description": "Frame information for this tree item." }, - { "name": "childFrames", "type": "array", "optional": true, "items": { "$ref": "FrameResourceTree" }, "description": "Child frames." }, - { "name": "resources", "type": "array", - "items": { - "type": "object", - "properties": [ - { "name": "url", "type": "string", "description": "Resource URL." }, - { "name": "type", "$ref": "ResourceType", "description": "Type of this resource." }, - { "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." }, - { "name": "failed", "type": "boolean", "optional": true, "description": "True if the resource failed to load." }, - { "name": "canceled", "type": "boolean", "optional": true, "description": "True if the resource was canceled during loading." }, - { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with this resource (if any)." } - ] - }, - "description": "Information about frame resources." - } - ] - }, - { - "id": "SearchResult", - "type": "object", - "description": "Search result for resource.", - "properties": [ - { "name": "url", "type": "string", "description": "Resource URL." }, - { "name": "frameId", "$ref": "Network.FrameId", "description": "Resource frame id." }, - { "name": "matchesCount", "type": "number", "description": "Number of matches in the resource content." } - ] - }, - { - "id": "Cookie", - "type": "object", - "description": "Cookie object", - "properties": [ - { "name": "name", "type": "string", "description": "Cookie name." }, - { "name": "value", "type": "string", "description": "Cookie value." }, - { "name": "domain", "type": "string", "description": "Cookie domain." }, - { "name": "path", "type": "string", "description": "Cookie path." }, - { "name": "expires", "type": "number", "description": "Cookie expires." }, - { "name": "size", "type": "integer", "description": "Cookie size." }, - { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." }, - { "name": "secure", "type": "boolean", "description": "True if cookie is secure." }, - { "name": "session", "type": "boolean", "description": "True in case of session cookie." } - ] - }, - { - "id": "ScriptIdentifier", - "type": "string", - "description": "Unique script identifier." - } - ], - "commands": [ - { - "name": "enable", - "description": "Enables page domain notifications." - }, - { - "name": "disable", - "description": "Disables page domain notifications." - }, - { - "name": "addScriptToEvaluateOnLoad", - "parameters": [ - { "name": "scriptSource", "type": "string" } - ], - "returns": [ - { "name": "identifier", "$ref": "ScriptIdentifier", "description": "Identifier of the added script." } - ] - }, - { - "name": "removeScriptToEvaluateOnLoad", - "parameters": [ - { "name": "identifier", "$ref": "ScriptIdentifier" } - ] - }, - { - "name": "reload", - "parameters": [ - { "name": "ignoreCache", "type": "boolean", "optional": true, "description": "If true, browser cache is ignored (as if the user pressed Shift+refresh)." }, - { "name": "scriptToEvaluateOnLoad", "type": "string", "optional": true, "description": "If set, the script will be injected into all frames of the inspected page after reload." } - ], - "description": "Reloads given page optionally ignoring the cache." - }, - { - "name": "navigate", - "parameters": [ - { "name": "url", "type": "string", "description": "URL to navigate the page to." } - ], - "description": "Navigates current page to the given URL." - }, - { - "name": "getCookies", - "returns": [ - { "name": "cookies", "type": "array", "items": { "$ref": "Cookie"}, "description": "Array of cookie objects." } - ], - "description": "Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the <code>cookies</code> field." - }, - { - "name": "deleteCookie", - "parameters": [ - { "name": "cookieName", "type": "string", "description": "Name of the cookie to remove." }, - { "name": "url", "type": "string", "description": "URL to match cooke domain and path." } - ], - "description": "Deletes browser cookie with given name, domain and path." - }, - { - "name": "getResourceTree", - "description": "Returns present frame / resource tree structure.", - "returns": [ - { "name": "frameTree", "$ref": "FrameResourceTree", "description": "Present frame / resource tree structure." } - ] - }, - { - "name": "getResourceContent", - "description": "Returns content of the given resource.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id to get resource for." }, - { "name": "url", "type": "string", "description": "URL of the resource to get content for." } - ], - "returns": [ - { "name": "content", "type": "string", "description": "Resource content." }, - { "name": "base64Encoded", "type": "boolean", "description": "True, if content was served as base64." } - ] - }, - { - "name": "searchInResource", - "description": "Searches for given string in resource content.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id for resource to search in." }, - { "name": "url", "type": "string", "description": "URL of the resource to search in." }, - { "name": "query", "type": "string", "description": "String to search for." }, - { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive." }, - { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex." } - ], - "returns": [ - { "name": "result", "type": "array", "items": { "$ref": "GenericTypes.SearchMatch" }, "description": "List of search matches." } - ] - }, - { - "name": "searchInResources", - "description": "Searches for given string in frame / resource tree structure.", - "parameters": [ - { "name": "text", "type": "string", "description": "String to search for." }, - { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive." }, - { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex." } - ], - "returns": [ - { "name": "result", "type": "array", "items": { "$ref": "SearchResult" }, "description": "List of search results." } - ] - }, - { - "name": "setDocumentContent", - "description": "Sets given markup as the document's HTML.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Frame id to set HTML for." }, - { "name": "html", "type": "string", "description": "HTML content to set." } - ] - }, - { - "name": "setShowPaintRects", - "description": "Requests that backend shows paint rectangles", - "parameters": [ - { "name": "result", "type": "boolean", "description": "True for showing paint rectangles" } - ] - }, - { - "name": "canShowDebugBorders", - "description": "Tells if backend supports debug borders on layers", - "returns": [ - { "name": "show", "type": "boolean", "description": "True if the debug borders can be shown" } - ] - }, - { - "name": "setShowDebugBorders", - "description": "Requests that backend shows debug borders on layers", - "parameters": [ - { "name": "show", "type": "boolean", "description": "True for showing debug borders" } - ] - }, - { - "name": "canShowFPSCounter", - "description": "Tells if backend supports a FPS counter display", - "returns": [ - { "name": "show", "type": "boolean", "description": "True if the FPS count can be shown" } - ] - }, - { - "name": "setShowFPSCounter", - "description": "Requests that backend shows the FPS counter", - "parameters": [ - { "name": "show", "type": "boolean", "description": "True for showing the FPS counter" } - ] - }, - { - "name": "canContinuouslyPaint", - "description": "Tells if backend supports continuous painting", - "returns": [ - { "name": "value", "type": "boolean", "description": "True if continuous painting is available" } - ] - }, - { - "name": "setContinuousPaintingEnabled", - "description": "Requests that backend enables continuous painting", - "parameters": [ - { "name": "enabled", "type": "boolean", "description": "True for enabling cointinuous painting" } - ] - }, - { - "name": "getScriptExecutionStatus", - "description": "Determines if scripts can be executed in the page.", - "returns": [ - { "name": "result", "type": "string", "enum": ["allowed", "disabled", "forbidden"], "description": "Script execution status: \"allowed\" if scripts can be executed, \"disabled\" if script execution has been disabled through page settings, \"forbidden\" if script execution for the given page is not possible for other reasons." } - ] - }, - { - "name": "setScriptExecutionDisabled", - "description": "Switches script execution in the page.", - "parameters": [ - { "name": "value", "type": "boolean", "description": "Whether script execution should be disabled in the page." } - ] - }, - { - "name": "setTouchEmulationEnabled", - "parameters": [ - { "name": "enabled", "type": "boolean", "description": "Whether the touch event emulation should be enabled." } - ], - "description": "Toggles mouse event-based touch event emulation." - }, - { - "name": "setEmulatedMedia", - "parameters": [ - { "name": "media", "type": "string", "description": "Media type to emulate. Empty string disables the override." } - ], - "description": "Emulates the given media for CSS media queries." - }, - { - "name": "getCompositingBordersVisible", - "description": "Indicates the visibility of compositing borders.", - "returns": [ - { "name": "result", "type": "boolean", "description": "If true, compositing borders are visible." } - ] - }, - { - "name": "setCompositingBordersVisible", - "description": "Controls the visibility of compositing borders.", - "parameters": [ - { "name": "visible", "type": "boolean", "description": "True for showing compositing borders." } - ] - }, - { - "name": "snapshotNode", - "description": "Capture a snapshot of the specified node that does not include unrelated layers.", - "parameters": [ - { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Id of the node to snapshot." } - ], - "returns": [ - { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." } - ] - }, - { - "name": "snapshotRect", - "description": "Capture a snapshot of the page within the specified rectangle and coordinate system.", - "parameters": [ - { "name": "x", "type": "integer", "description": "X coordinate" }, - { "name": "y", "type": "integer", "description": "Y coordinate" }, - { "name": "width", "type": "integer", "description": "Rectangle width" }, - { "name": "height", "type": "integer", "description": "Rectangle height" }, - { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." } - ], - "returns": [ - { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." } - ] - }, - { - "name": "handleJavaScriptDialog", - "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).", - "parameters": [ - { "name": "accept", "type": "boolean", "description": "Whether to accept or dismiss the dialog." }, - { "name": "promptText", "type": "string", "optional": true, "description": "The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog." } - ] - }, - { - "name": "archive", - "description": "Grab an archive of the page.", - "returns": [ - { "name": "data", "type": "string", "description": "Base64-encoded web archive." } - ] - } - ], - "events": [ - { - "name": "domContentEventFired", - "parameters": [ - { "name": "timestamp", "type": "number" } - ] - }, - { - "name": "loadEventFired", - "parameters": [ - { "name": "timestamp", "type": "number" } - ] - }, - { - "name": "frameNavigated", - "description": "Fired once navigation of the frame has completed. Frame is now associated with the new loader.", - "parameters": [ - { "name": "frame", "$ref": "Frame", "description": "Frame object." } - ] - }, - { - "name": "frameDetached", - "description": "Fired when frame has been detached from its parent.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." } - ] - }, - { - "name": "frameStartedLoading", - "description": "Fired when frame has started loading.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has started loading." } - ] - }, - { - "name": "frameStoppedLoading", - "description": "Fired when frame has stopped loading.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has stopped loading." } - ] - }, - { - "name": "frameScheduledNavigation", - "description": "Fired when frame schedules a potential navigation.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has scheduled a navigation." }, - { "name": "delay", "type": "number", "description": "Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start." } - ] - }, - { - "name": "frameClearedScheduledNavigation", - "description": "Fired when frame no longer has a scheduled navigation.", - "parameters": [ - { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." } - ] - }, - { - "name": "javascriptDialogOpening", - "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.", - "parameters": [ - { "name": "message", "type": "string", "description": "Message that will be displayed by the dialog." } - ] - }, - { - "name": "javascriptDialogClosed", - "description": "Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed." - }, - { - "name": "scriptsEnabled", - "description": "Fired when the JavaScript is enabled/disabled on the page", - "parameters": [ - { "name": "isEnabled", "type": "boolean", "description": "Whether script execution is enabled or disabled on the page." } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Profiler.json b/Source/WebCore/inspector/protocol/Profiler.json deleted file mode 100644 index 791d50acc..000000000 --- a/Source/WebCore/inspector/protocol/Profiler.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "domain": "Profiler", - "types": [ - { - "id": "ProfileHeader", - "type": "object", - "description": "Profile header.", - "properties": [ - { "name": "typeId", "type": "string", "enum": ["CPU", "CSS", "HEAP"], "description": "Profile type name." }, - { "name": "title", "type": "string", "description": "Profile title." }, - { "name": "uid", "type": "integer", "description": "Unique identifier of the profile." }, - { "name": "maxJSObjectId", "type": "integer", "optional": true, "description": "Last seen JS object Id." } - ] - }, - { - "id": "CPUProfileNode", - "type": "object", - "description": "CPU Profile node. Holds callsite information, execution statistics and child nodes.", - "properties": [ - { "name": "functionName", "type": "string", "description": "Function name." }, - { "name": "url", "type": "string", "description": "URL." }, - { "name": "lineNumber", "type": "integer", "description": "Line number." }, - { "name": "totalTime", "type": "number", "description": "Total execution time." }, - { "name": "selfTime", "type": "number", "description": "Self time." }, - { "name": "numberOfCalls", "type": "integer", "description": "Number of calls." }, - { "name": "callUID", "type": "number", "description": "Call UID." }, - { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Child nodes." }, - { "name": "id", "optional": true, "type": "integer", "description": "Unique id of the node." } - ] - }, - { - "id": "CPUProfile", - "type": "object", - "description": "Profile.", - "properties": [ - { "name": "head", "$ref": "CPUProfileNode", "optional": true }, - { "name": "idleTime", "type": "number", "optional": true }, - { "name": "samples", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Ids of samples top nodes." } - ] - }, - { - "id": "HeapSnapshotObjectId", - "type": "string", - "description": "Heap snashot object id." - } - ], - "commands": [ - { - "name": "isSampling", - "returns": [ - { "name": "result", "type": "boolean" } - ] - }, - { - "name": "hasHeapProfiler", - "returns": [ - { "name": "result", "type": "boolean" } - ] - }, - { - "name": "enable" - }, - { - "name": "disable" - }, - { - "name": "start" - }, - { - "name": "stop" - }, - { - "name": "getProfileHeaders", - "returns": [ - { "name": "headers", "type": "array", "items": { "$ref": "ProfileHeader"} } - ] - }, - { - "name": "getCPUProfile", - "parameters": [ - { "name": "uid", "type": "integer" } - ], - "returns": [ - { "name": "profile", "$ref": "CPUProfile" } - ] - }, - { - "name": "getHeapSnapshot", - "parameters": [ - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "removeProfile", - "parameters": [ - { "name": "type", "type": "string" }, - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "clearProfiles" - }, - { - "name": "takeHeapSnapshot", - "parameters": [ - { "name": "reportProgress", "type": "boolean", "optional": true, "description": "If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken." } - ] - }, - { - "name": "collectGarbage" - }, - { - "name": "getObjectByHeapObjectId", - "parameters": [ - { "name": "objectId", "$ref": "HeapSnapshotObjectId" }, - { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." } - ], - "returns": [ - { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Evaluation result." } - ] - }, - { - "name": "getHeapObjectId", - "parameters": [ - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Identifier of the object to get heap object id for." } - ], - "returns": [ - { "name": "heapSnapshotObjectId", "$ref": "HeapSnapshotObjectId", "description": "Id of the heap snapshot object corresponding to the passed remote object id." } - ] - } - ], - "events": [ - { - "name": "addProfileHeader", - "parameters": [ - { "name": "header", "$ref": "ProfileHeader" } - ] - }, - { - "name": "addHeapSnapshotChunk", - "parameters": [ - { "name": "uid", "type": "integer" }, - { "name": "chunk", "type": "string" } - ] - }, - { - "name": "finishHeapSnapshot", - "parameters": [ - { "name": "uid", "type": "integer" } - ] - }, - { - "name": "setRecordingProfile", - "parameters": [ - { "name": "isProfiling", "type": "boolean" } - ] - }, - { - "name": "resetProfiles" - }, - { - "name": "reportHeapSnapshotProgress", - "parameters": [ - { "name": "done", "type": "integer" }, - { "name": "total", "type": "integer" } - ] - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Timeline.json b/Source/WebCore/inspector/protocol/Timeline.json deleted file mode 100644 index f8f07944b..000000000 --- a/Source/WebCore/inspector/protocol/Timeline.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "domain": "Timeline", - "description": "Timeline provides its clients with instrumentation records that are generated during the page runtime. Timeline instrumentation can be started and stopped using corresponding commands. While timeline is started, it is generating timeline event records.", - "types": [ - { - "id": "DOMCounters", - "type": "object", - "properties": [ - { "name": "documents", "type": "integer" }, - { "name": "nodes", "type": "integer" }, - { "name": "jsEventListeners", "type": "integer" } - ], - "description": "Current values of DOM counters." - }, - { - "id": "EventType", - "type": "string", - "enum": ["EventDispatch", "BeginFrame", "ScheduleStyleRecalculation", "RecalculateStyles", "InvalidateLayout", "Layout", "Paint", "ScrollLayer", "ResizeImage", "CompositeLayers", "ParseHTML", "TimerInstall", "TimerRemove", "TimerFire", "EvaluateScript", "MarkLoad", "MarkDOMContent", "TimeStamp", "Time", "TimeEnd", "ScheduleResourceRequest", "ResourceSendRequest", "ResourceReceiveResponse", "ResourceReceivedData", "ResourceFinish", "XHRReadyStateChange", "XHRLoad", "FunctionCall", "GCEvent", "RequestAnimationFrame", "CancelAnimationFrame", "FireAnimationFrame", "WebSocketCreate", "WebSocketSendHandshakeRequest", "WebSocketReceiveHandshakeResponse", "WebSocketDestroy"], - "description": "Timeline record type." - }, - { - "id": "TimelineEvent", - "type": "object", - "properties": [ - { "name": "type", "$ref": "EventType", "description": "Event type." }, - { "name": "thread", "type": "string", "optional": true, "description": "If present, identifies the thread that produced the event." }, - { "name": "data", "type": "object", "description": "Event data." }, - { "name": "children", "type": "array", "optional": true, "items": { "$ref": "TimelineEvent" }, "description": "Nested records." }, - { "name": "counters", "$ref": "DOMCounters", "optional": true, "description": "Current values of DOM counters." }, - { "name": "usedHeapSize", "type": "integer", "optional": true, "description": "Current size of JS heap." } - ], - "description": "Timeline record contains information about the recorded activity." - } - ], - "commands": [ - { - "name": "start", - "parameters": [ - { "name": "maxCallStackDepth", "optional": true, "type": "integer", "description": "Samples JavaScript stack traces up to <code>maxCallStackDepth</code>, defaults to 5." }, - { "name": "includeDomCounters", "optional": true, "type": "boolean", "description": "Whether DOM counters data should be included into timeline events." } - ], - "description": "Starts capturing instrumentation events." - }, - { - "name": "stop", - "description": "Stops capturing instrumentation events." - }, - { - "name": "supportsFrameInstrumentation", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if timeline supports frame instrumentation." } - ], - "description": "Tells whether timeline agent supports frame instrumentation." - }, - { - "name": "canMonitorMainThread", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if timeline supports main thread CPU utilization instrumentation." } - ], - "description": "Tells whether timeline agent supports main thread CPU utilization instrumentation." - } - ], - "events": [ - { - "name": "eventRecorded", - "parameters": [ - { "name": "record", "$ref": "TimelineEvent", "description": "Timeline event record data." } - ], - "description": "Fired for every instrumentation event while timeline is started." - } - ] -} diff --git a/Source/WebCore/inspector/protocol/Worker.json b/Source/WebCore/inspector/protocol/Worker.json deleted file mode 100644 index f9714e0fd..000000000 --- a/Source/WebCore/inspector/protocol/Worker.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "domain": "Worker", - "types": [], - "commands": [ - { - "name": "enable" - }, - { - "name": "disable" - }, - { - "name": "sendMessageToWorker", - "parameters": [ - { "name": "workerId", "type": "integer" }, - { "name": "message", "type": "object" } - ] - }, - { - "name": "canInspectWorkers", - "description": "Tells whether browser supports workers inspection.", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if browser has workers support." } - ] - }, - { - "name": "connectToWorker", - "parameters": [ - { "name": "workerId", "type": "integer" } - ] - }, - { - "name": "disconnectFromWorker", - "parameters": [ - { "name": "workerId", "type": "integer" } - ] - }, - { - "name": "setAutoconnectToWorkers", - "parameters": [ - { "name": "value", "type": "boolean" } - ] - } - ], - "events": [ - { - "name": "workerCreated", - "parameters": [ - { "name": "workerId", "type": "integer" }, - { "name": "url", "type": "string" }, - { "name": "inspectorConnected", "type": "boolean" } - ] - }, - { - "name": "workerTerminated", - "parameters": [ - { "name": "workerId", "type": "integer" } - ] - }, - { - "name": "dispatchMessageFromWorker", - "parameters": [ - { "name": "workerId", "type": "integer" }, - { "name": "message", "type": "object" } - ] - }, - { - "name": "disconnectedFromWorker" - } - ] -} |