From 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 27 Jun 2017 06:07:23 +0000 Subject: webkitgtk-2.16.5 --- Source/WebCore/inspector/CommandLineAPIHost.cpp | 103 +- Source/WebCore/inspector/CommandLineAPIHost.h | 61 +- Source/WebCore/inspector/CommandLineAPIHost.idl | 3 +- Source/WebCore/inspector/CommandLineAPIModule.cpp | 30 +- Source/WebCore/inspector/CommandLineAPIModule.h | 16 +- .../inspector/CommandLineAPIModuleSource.js | 134 +- Source/WebCore/inspector/ConsoleAPITypes.h | 48 - Source/WebCore/inspector/ConsoleMessage.cpp | 290 -- Source/WebCore/inspector/ConsoleMessage.h | 93 - Source/WebCore/inspector/DOMEditor.cpp | 364 ++- Source/WebCore/inspector/DOMEditor.h | 53 +- Source/WebCore/inspector/DOMPatchSupport.cpp | 334 +- Source/WebCore/inspector/DOMPatchSupport.h | 49 +- Source/WebCore/inspector/IdentifiersFactory.cpp | 69 - Source/WebCore/inspector/IdentifiersFactory.h | 50 - .../inspector/InjectedScriptCanvasModule.cpp | 216 -- .../WebCore/inspector/InjectedScriptCanvasModule.h | 84 - .../inspector/InjectedScriptCanvasModuleSource.js | 3216 -------------------- Source/WebCore/inspector/InspectorAllInOne.cpp | 71 + .../inspector/InspectorApplicationCacheAgent.cpp | 145 +- .../inspector/InspectorApplicationCacheAgent.h | 50 +- Source/WebCore/inspector/InspectorCSSAgent.cpp | 1187 ++++---- Source/WebCore/inspector/InspectorCSSAgent.h | 159 +- Source/WebCore/inspector/InspectorCanvasAgent.cpp | 328 -- Source/WebCore/inspector/InspectorCanvasAgent.h | 117 - .../inspector/InspectorCanvasInstrumentation.h | 73 - Source/WebCore/inspector/InspectorClient.cpp | 19 +- Source/WebCore/inspector/InspectorClient.h | 63 +- Source/WebCore/inspector/InspectorConsoleAgent.cpp | 341 --- Source/WebCore/inspector/InspectorConsoleAgent.h | 117 - .../inspector/InspectorConsoleInstrumentation.h | 227 -- Source/WebCore/inspector/InspectorController.cpp | 417 +-- Source/WebCore/inspector/InspectorController.h | 140 +- Source/WebCore/inspector/InspectorCounters.cpp | 66 - Source/WebCore/inspector/InspectorCounters.h | 118 - Source/WebCore/inspector/InspectorDOMAgent.cpp | 1364 ++++++--- Source/WebCore/inspector/InspectorDOMAgent.h | 248 +- .../inspector/InspectorDOMDebuggerAgent.cpp | 175 +- .../WebCore/inspector/InspectorDOMDebuggerAgent.h | 80 +- .../WebCore/inspector/InspectorDOMStorageAgent.cpp | 107 +- .../WebCore/inspector/InspectorDOMStorageAgent.h | 54 +- .../WebCore/inspector/InspectorDatabaseAgent.cpp | 240 +- Source/WebCore/inspector/InspectorDatabaseAgent.h | 50 +- .../inspector/InspectorDatabaseInstrumentation.h | 58 - .../inspector/InspectorDatabaseResource.cpp | 23 +- .../WebCore/inspector/InspectorDatabaseResource.h | 21 +- Source/WebCore/inspector/InspectorForwarding.h | 36 - Source/WebCore/inspector/InspectorFrontendClient.h | 43 +- .../inspector/InspectorFrontendClientLocal.cpp | 139 +- .../inspector/InspectorFrontendClientLocal.h | 88 +- Source/WebCore/inspector/InspectorFrontendHost.cpp | 182 +- Source/WebCore/inspector/InspectorFrontendHost.h | 46 +- Source/WebCore/inspector/InspectorFrontendHost.idl | 36 +- .../inspector/InspectorHeapProfilerAgent.cpp | 233 -- .../WebCore/inspector/InspectorHeapProfilerAgent.h | 96 - Source/WebCore/inspector/InspectorHistory.cpp | 91 +- Source/WebCore/inspector/InspectorHistory.h | 56 +- .../WebCore/inspector/InspectorIndexedDBAgent.cpp | 669 ++-- Source/WebCore/inspector/InspectorIndexedDBAgent.h | 41 +- Source/WebCore/inspector/InspectorInputAgent.cpp | 173 -- Source/WebCore/inspector/InspectorInputAgent.h | 69 - .../WebCore/inspector/InspectorInstrumentation.cpp | 1151 ++++--- .../WebCore/inspector/InspectorInstrumentation.h | 1954 +++++------- .../inspector/InspectorInstrumentationCookie.cpp | 11 +- .../inspector/InspectorInstrumentationCookie.h | 10 +- .../WebCore/inspector/InspectorLayerTreeAgent.cpp | 113 +- Source/WebCore/inspector/InspectorLayerTreeAgent.h | 67 +- Source/WebCore/inspector/InspectorMemoryAgent.cpp | 189 +- Source/WebCore/inspector/InspectorMemoryAgent.h | 88 +- Source/WebCore/inspector/InspectorNetworkAgent.cpp | 740 +++++ Source/WebCore/inspector/InspectorNetworkAgent.h | 142 + Source/WebCore/inspector/InspectorNodeFinder.cpp | 85 +- Source/WebCore/inspector/InspectorNodeFinder.h | 15 +- Source/WebCore/inspector/InspectorOverlay.cpp | 733 +++-- Source/WebCore/inspector/InspectorOverlay.h | 84 +- Source/WebCore/inspector/InspectorOverlayPage.css | 13 +- Source/WebCore/inspector/InspectorOverlayPage.html | 3 +- Source/WebCore/inspector/InspectorOverlayPage.js | 309 +- Source/WebCore/inspector/InspectorPageAgent.cpp | 669 ++-- Source/WebCore/inspector/InspectorPageAgent.h | 154 +- .../WebCore/inspector/InspectorProfilerAgent.cpp | 458 --- Source/WebCore/inspector/InspectorProfilerAgent.h | 139 - Source/WebCore/inspector/InspectorReplayAgent.cpp | 513 ++++ Source/WebCore/inspector/InspectorReplayAgent.h | 125 + .../WebCore/inspector/InspectorResourceAgent.cpp | 658 ---- Source/WebCore/inspector/InspectorResourceAgent.h | 165 - Source/WebCore/inspector/InspectorStyleSheet.cpp | 1374 +++++---- Source/WebCore/inspector/InspectorStyleSheet.h | 166 +- .../WebCore/inspector/InspectorStyleTextEditor.cpp | 275 -- .../WebCore/inspector/InspectorStyleTextEditor.h | 67 - .../WebCore/inspector/InspectorTimelineAgent.cpp | 745 +++-- Source/WebCore/inspector/InspectorTimelineAgent.h | 271 +- Source/WebCore/inspector/InspectorWebAgentBase.h | 49 +- Source/WebCore/inspector/InspectorWorkerAgent.cpp | 278 +- Source/WebCore/inspector/InspectorWorkerAgent.h | 119 +- Source/WebCore/inspector/InspectorWorkerResource.h | 70 - Source/WebCore/inspector/InstrumentingAgents.cpp | 66 +- Source/WebCore/inspector/InstrumentingAgents.h | 120 +- Source/WebCore/inspector/NetworkResourcesData.cpp | 130 +- Source/WebCore/inspector/NetworkResourcesData.h | 59 +- Source/WebCore/inspector/PageConsoleAgent.cpp | 38 +- Source/WebCore/inspector/PageConsoleAgent.h | 27 +- Source/WebCore/inspector/PageDebuggerAgent.cpp | 80 +- Source/WebCore/inspector/PageDebuggerAgent.h | 42 +- Source/WebCore/inspector/PageHeapAgent.cpp | 56 + Source/WebCore/inspector/PageHeapAgent.h | 52 + .../WebCore/inspector/PageInjectedScriptHost.cpp | 59 - Source/WebCore/inspector/PageInjectedScriptHost.h | 47 - .../inspector/PageInjectedScriptManager.cpp | 88 - .../WebCore/inspector/PageInjectedScriptManager.h | 57 - Source/WebCore/inspector/PageRuntimeAgent.cpp | 88 +- Source/WebCore/inspector/PageRuntimeAgent.h | 52 +- Source/WebCore/inspector/PageScriptDebugServer.cpp | 181 ++ Source/WebCore/inspector/PageScriptDebugServer.h | 63 + Source/WebCore/inspector/ScriptArguments.cpp | 101 - Source/WebCore/inspector/ScriptArguments.h | 74 - Source/WebCore/inspector/ScriptCallFrame.cpp | 74 - Source/WebCore/inspector/ScriptCallFrame.h | 72 - Source/WebCore/inspector/ScriptCallStack.cpp | 93 - Source/WebCore/inspector/ScriptCallStack.h | 70 - Source/WebCore/inspector/ScriptProfile.idl | 35 - Source/WebCore/inspector/ScriptProfileNode.idl | 40 - Source/WebCore/inspector/TimelineRecordFactory.cpp | 242 +- Source/WebCore/inspector/TimelineRecordFactory.h | 101 +- Source/WebCore/inspector/WebConsoleAgent.cpp | 109 + Source/WebCore/inspector/WebConsoleAgent.h | 56 + Source/WebCore/inspector/WebDebuggerAgent.cpp | 16 +- Source/WebCore/inspector/WebDebuggerAgent.h | 20 +- Source/WebCore/inspector/WebHeapAgent.cpp | 131 + Source/WebCore/inspector/WebHeapAgent.h | 55 + Source/WebCore/inspector/WebInjectedScriptHost.cpp | 64 + Source/WebCore/inspector/WebInjectedScriptHost.h | 40 + .../WebCore/inspector/WebInjectedScriptManager.cpp | 91 + .../WebCore/inspector/WebInjectedScriptManager.h | 55 + Source/WebCore/inspector/WorkerConsoleAgent.cpp | 60 +- Source/WebCore/inspector/WorkerConsoleAgent.h | 67 +- Source/WebCore/inspector/WorkerDebuggerAgent.cpp | 161 +- Source/WebCore/inspector/WorkerDebuggerAgent.h | 78 +- .../inspector/WorkerInspectorController.cpp | 207 +- .../WebCore/inspector/WorkerInspectorController.h | 110 +- Source/WebCore/inspector/WorkerRuntimeAgent.cpp | 63 +- Source/WebCore/inspector/WorkerRuntimeAgent.h | 37 +- .../WebCore/inspector/WorkerScriptDebugServer.cpp | 86 + Source/WebCore/inspector/WorkerScriptDebugServer.h | 61 + .../inspector/WorkerToPageFrontendChannel.h | 55 + .../inspector/protocol/ApplicationCache.json | 86 - Source/WebCore/inspector/protocol/CSS.json | 437 --- Source/WebCore/inspector/protocol/Canvas.json | 173 -- Source/WebCore/inspector/protocol/Console.json | 95 - Source/WebCore/inspector/protocol/DOM.json | 469 --- Source/WebCore/inspector/protocol/DOMDebugger.json | 72 - Source/WebCore/inspector/protocol/DOMStorage.json | 87 - Source/WebCore/inspector/protocol/Database.json | 70 - .../WebCore/inspector/protocol/HeapProfiler.json | 108 - Source/WebCore/inspector/protocol/IndexedDB.json | 144 - Source/WebCore/inspector/protocol/Input.json | 37 - Source/WebCore/inspector/protocol/LayerTree.json | 111 - Source/WebCore/inspector/protocol/Memory.json | 24 - Source/WebCore/inspector/protocol/Network.json | 334 -- Source/WebCore/inspector/protocol/Page.json | 399 --- Source/WebCore/inspector/protocol/Profiler.json | 169 - Source/WebCore/inspector/protocol/Timeline.json | 72 - Source/WebCore/inspector/protocol/Worker.json | 70 - 163 files changed, 10972 insertions(+), 21085 deletions(-) delete mode 100644 Source/WebCore/inspector/ConsoleAPITypes.h delete mode 100644 Source/WebCore/inspector/ConsoleMessage.cpp delete mode 100644 Source/WebCore/inspector/ConsoleMessage.h delete mode 100644 Source/WebCore/inspector/IdentifiersFactory.cpp delete mode 100644 Source/WebCore/inspector/IdentifiersFactory.h delete mode 100644 Source/WebCore/inspector/InjectedScriptCanvasModule.cpp delete mode 100644 Source/WebCore/inspector/InjectedScriptCanvasModule.h delete mode 100644 Source/WebCore/inspector/InjectedScriptCanvasModuleSource.js create mode 100644 Source/WebCore/inspector/InspectorAllInOne.cpp delete mode 100644 Source/WebCore/inspector/InspectorCanvasAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorCanvasAgent.h delete mode 100644 Source/WebCore/inspector/InspectorCanvasInstrumentation.h delete mode 100644 Source/WebCore/inspector/InspectorConsoleAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorConsoleAgent.h delete mode 100644 Source/WebCore/inspector/InspectorConsoleInstrumentation.h delete mode 100644 Source/WebCore/inspector/InspectorCounters.cpp delete mode 100644 Source/WebCore/inspector/InspectorCounters.h delete mode 100644 Source/WebCore/inspector/InspectorDatabaseInstrumentation.h delete mode 100644 Source/WebCore/inspector/InspectorForwarding.h delete mode 100644 Source/WebCore/inspector/InspectorHeapProfilerAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorHeapProfilerAgent.h delete mode 100644 Source/WebCore/inspector/InspectorInputAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorInputAgent.h create mode 100644 Source/WebCore/inspector/InspectorNetworkAgent.cpp create mode 100644 Source/WebCore/inspector/InspectorNetworkAgent.h delete mode 100644 Source/WebCore/inspector/InspectorProfilerAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorProfilerAgent.h create mode 100644 Source/WebCore/inspector/InspectorReplayAgent.cpp create mode 100644 Source/WebCore/inspector/InspectorReplayAgent.h delete mode 100644 Source/WebCore/inspector/InspectorResourceAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorResourceAgent.h delete mode 100644 Source/WebCore/inspector/InspectorStyleTextEditor.cpp delete mode 100644 Source/WebCore/inspector/InspectorStyleTextEditor.h delete mode 100644 Source/WebCore/inspector/InspectorWorkerResource.h create mode 100644 Source/WebCore/inspector/PageHeapAgent.cpp create mode 100644 Source/WebCore/inspector/PageHeapAgent.h delete mode 100644 Source/WebCore/inspector/PageInjectedScriptHost.cpp delete mode 100644 Source/WebCore/inspector/PageInjectedScriptHost.h delete mode 100644 Source/WebCore/inspector/PageInjectedScriptManager.cpp delete mode 100644 Source/WebCore/inspector/PageInjectedScriptManager.h create mode 100644 Source/WebCore/inspector/PageScriptDebugServer.cpp create mode 100644 Source/WebCore/inspector/PageScriptDebugServer.h delete mode 100644 Source/WebCore/inspector/ScriptArguments.cpp delete mode 100644 Source/WebCore/inspector/ScriptArguments.h delete mode 100644 Source/WebCore/inspector/ScriptCallFrame.cpp delete mode 100644 Source/WebCore/inspector/ScriptCallFrame.h delete mode 100644 Source/WebCore/inspector/ScriptCallStack.cpp delete mode 100644 Source/WebCore/inspector/ScriptCallStack.h delete mode 100644 Source/WebCore/inspector/ScriptProfile.idl delete mode 100644 Source/WebCore/inspector/ScriptProfileNode.idl create mode 100644 Source/WebCore/inspector/WebConsoleAgent.cpp create mode 100644 Source/WebCore/inspector/WebConsoleAgent.h create mode 100644 Source/WebCore/inspector/WebHeapAgent.cpp create mode 100644 Source/WebCore/inspector/WebHeapAgent.h create mode 100644 Source/WebCore/inspector/WebInjectedScriptHost.cpp create mode 100644 Source/WebCore/inspector/WebInjectedScriptHost.h create mode 100644 Source/WebCore/inspector/WebInjectedScriptManager.cpp create mode 100644 Source/WebCore/inspector/WebInjectedScriptManager.h create mode 100644 Source/WebCore/inspector/WorkerScriptDebugServer.cpp create mode 100644 Source/WebCore/inspector/WorkerScriptDebugServer.h create mode 100644 Source/WebCore/inspector/WorkerToPageFrontendChannel.h delete mode 100644 Source/WebCore/inspector/protocol/ApplicationCache.json delete mode 100644 Source/WebCore/inspector/protocol/CSS.json delete mode 100644 Source/WebCore/inspector/protocol/Canvas.json delete mode 100644 Source/WebCore/inspector/protocol/Console.json delete mode 100644 Source/WebCore/inspector/protocol/DOM.json delete mode 100644 Source/WebCore/inspector/protocol/DOMDebugger.json delete mode 100644 Source/WebCore/inspector/protocol/DOMStorage.json delete mode 100644 Source/WebCore/inspector/protocol/Database.json delete mode 100644 Source/WebCore/inspector/protocol/HeapProfiler.json delete mode 100644 Source/WebCore/inspector/protocol/IndexedDB.json delete mode 100644 Source/WebCore/inspector/protocol/Input.json delete mode 100644 Source/WebCore/inspector/protocol/LayerTree.json delete mode 100644 Source/WebCore/inspector/protocol/Memory.json delete mode 100644 Source/WebCore/inspector/protocol/Network.json delete mode 100644 Source/WebCore/inspector/protocol/Page.json delete mode 100644 Source/WebCore/inspector/protocol/Profiler.json delete mode 100644 Source/WebCore/inspector/protocol/Timeline.json delete mode 100644 Source/WebCore/inspector/protocol/Worker.json (limited to 'Source/WebCore/inspector') 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 #include #include +#include +#include #include #include -#if ENABLE(SQL_DATABASE) -#include "Database.h" -#endif - +using namespace JSC; using namespace Inspector; namespace WebCore { -PassRefPtr CommandLineAPIHost::create() +Ref 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()) { - 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 object, PassRefPtr hints) +void CommandLineAPIHost::inspectImpl(RefPtr&& object, RefPtr&& hints) { - if (m_inspectorAgent) { - RefPtr remoteObject = Inspector::TypeBuilder::Runtime::RemoteObject::runtimeCast(object); - m_inspectorAgent->inspect(remoteObject, hints->asObject()); - } + if (!m_inspectorAgent) + return; + + RefPtr hintsObject; + if (!hints->asObject(hintsObject)) + return; + + auto remoteObject = BindingTraits::runtimeCast(WTFMove(object)); + m_inspectorAgent->inspect(WTFMove(remoteObject), WTFMove(hintsObject)); } void CommandLineAPIHost::getEventListenersImpl(Node* node, Vector& listenersArray) @@ -109,8 +96,8 @@ void CommandLineAPIHost::getEventListenersImpl(Node* node, VectorclearMessages(&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 object) -{ - m_inspectedObjects.insert(0, object); - while (m_inspectedObjects.size() > 5) - m_inspectedObjects.removeLast(); + return { }; } -void CommandLineAPIHost::clearInspectedObjects() +void CommandLineAPIHost::addInspectedObject(std::unique_ptr 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(); +} + +} // 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 #include #include #include -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 { public: - static PassRefPtr create(); + static Ref 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); - void clearInspectedObjects(); - InspectableObject* inspectedObject(unsigned index); - void inspectImpl(PassRefPtr objectToInspect, PassRefPtr hints); + void addInspectedObject(std::unique_ptr); + InspectableObject* inspectedObject(); + void inspectImpl(RefPtr&& objectToInspect, RefPtr&& hints); void getEventListenersImpl(Node*, Vector& 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> m_inspectedObjects; - OwnPtr m_defaultInspectableObject; + std::unique_ptr 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 #include 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(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(injectedScriptManager); + // CommandLineAPIModule should only ever be used by a WebInjectedScriptManager. + WebInjectedScriptManager* pageInjectedScriptManager = static_cast(injectedScriptManager); ASSERT(pageInjectedScriptManager->commandLineAPIHost()); + JSDOMGlobalObject* globalObject = jsCast(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 -#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: 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=} 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/ConsoleAPITypes.h b/Source/WebCore/inspector/ConsoleAPITypes.h deleted file mode 100644 index 11f65ec21..000000000 --- a/Source/WebCore/inspector/ConsoleAPITypes.h +++ /dev/null @@ -1,48 +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: - * 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 ConsoleAPITypes_h -#define ConsoleAPITypes_h - -namespace WebCore { - -enum MessageType { - LogMessageType, - DirMessageType, - DirXMLMessageType, - TableMessageType, - TraceMessageType, - StartGroupMessageType, - StartGroupCollapsedMessageType, - EndGroupMessageType, - ClearMessageType, - AssertMessageType, - TimingMessageType, - ProfileMessageType, - ProfileEndMessageType -}; - -} // namespace WebCore - -#endif // ConsoleAPITypes_h 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 - * 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 -#include -#include -#include -#include - -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 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 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 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(m_line)); - jsonObj->setColumn(static_cast(m_column)); - jsonObj->setUrl(m_url); - jsonObj->setRepeatCount(static_cast(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> jsonArgs = Inspector::TypeBuilder::Array::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 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 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 = ""; - 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 - * 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 -#include - -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, unsigned long requestIdentifier = 0); - ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr, 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 m_arguments; - RefPtr 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 perform() final { m_anchorNode = m_node->nextSibling(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr 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 redo() final { - return m_parentNode->removeChild(m_node.get(), ec); + return m_parentNode->removeChild(m_node); } private: - RefPtr m_parentNode; - RefPtr m_node; + Ref m_parentNode; + Ref m_node; RefPtr 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* anchorNode) - : InspectorHistory::Action("InsertBefore") + InsertBeforeAction(Node& parentNode, Ref&& 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 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(*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 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 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 m_parentNode; - RefPtr m_node; + Ref m_parentNode; + Ref m_node; RefPtr m_anchorNode; - OwnPtr m_removeChildAction; + std::unique_ptr 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 perform() final { m_value = m_element->getAttribute(m_name); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr 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 redo() final { m_element->removeAttribute(m_name); - return true; + return { }; } -private: - RefPtr m_element; + Ref 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 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 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 redo() final { - m_element->setAttribute(m_name, m_value, ec); - return true; + return m_element->setAttribute(m_name, m_value); } -private: - RefPtr m_element; - String m_name; - String m_value; - bool m_hadAttribute; - String m_oldValue; + Ref 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 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 undo() final { - return m_history->redo(ec); + return m_history.undo(); } - Node* newNode() + ExceptionOr redo() final { - return m_newNode; + return m_history.redo(); } -private: Ref m_node; RefPtr m_nextSibling; String m_html; String m_oldHTML; - Node* m_newNode; - OwnPtr m_history; - OwnPtr m_domEditor; + RefPtr 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 perform() final { m_oldText = m_textNode->wholeText(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr undo() final { - m_textNode->replaceWholeText(m_oldText, ec); - return true; + m_textNode->replaceWholeText(m_oldText); + return { }; } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr redo() final { - m_textNode->replaceWholeText(m_text, ec); - return true; + m_textNode->replaceWholeText(m_text); + return { }; } -private: - RefPtr m_textNode; + Ref 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 newNode, Node* oldNode) - : InspectorHistory::Action("ReplaceChildNode") + ReplaceChildNodeAction(Node& parentNode, Ref&& 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 perform() final { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr 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 redo() final { - return m_parentNode->replaceChild(m_newNode, m_oldNode.get(), ec); + return m_parentNode->replaceChild(m_newNode, m_oldNode); } -private: - RefPtr m_parentNode; - RefPtr m_newNode; - RefPtr m_oldNode; + Ref m_parentNode; + Ref m_newNode; + Ref 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 perform() final { m_oldValue = m_node->nodeValue(); - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) override + ExceptionOr undo() final { - m_node->setNodeValue(m_oldValue, ec); - return !ec; + return m_node->setNodeValue(m_oldValue); } - virtual bool redo(ExceptionCode& ec) override + ExceptionOr redo() final { - m_node->setNodeValue(m_value, ec); - return !ec; + return m_node->setNodeValue(m_value); } -private: - RefPtr m_node; + Ref 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* anchorNode, ExceptionCode& ec) +ExceptionOr DOMEditor::insertBefore(Node& parentNode, Ref&& node, Node* anchorNode) { - return m_history->perform(adoptPtr(new InsertBeforeAction(parentNode, node, anchorNode)), ec); + return m_history.perform(std::make_unique(parentNode, WTFMove(node), anchorNode)); } -bool DOMEditor::removeChild(Node* parentNode, Node* node, ExceptionCode& ec) +ExceptionOr DOMEditor::removeChild(Node& parentNode, Node& node) { - return m_history->perform(adoptPtr(new RemoveChildAction(parentNode, node)), ec); + return m_history.perform(std::make_unique(parentNode, node)); } -bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ExceptionCode& ec) +ExceptionOr 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(element, name, value)); } -bool DOMEditor::removeAttribute(Element* element, const String& name, ExceptionCode& ec) +ExceptionOr DOMEditor::removeAttribute(Element& element, const String& name) { - return m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), ec); + return m_history.perform(std::make_unique(element, name)); } -bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ExceptionCode& ec) +ExceptionOr DOMEditor::setOuterHTML(Node& node, const String& html, Node*& newNode) { - OwnPtr 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(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 DOMEditor::replaceWholeText(Text& textNode, const String& text) { - return m_history->perform(adoptPtr(new ReplaceWholeTextAction(textNode, text)), ec); + return m_history.perform(std::make_unique(textNode, text)); } -bool DOMEditor::replaceChild(Node* parentNode, PassRefPtr newNode, Node* oldNode, ExceptionCode& ec) +ExceptionOr DOMEditor::replaceChild(Node& parentNode, Ref&& newNode, Node& oldNode) { - return m_history->perform(adoptPtr(new ReplaceChildNodeAction(parentNode, newNode, oldNode)), ec); + return m_history.perform(std::make_unique(parentNode, WTFMove(newNode), oldNode)); } -bool DOMEditor::setNodeValue(Node* node, const String& value, ExceptionCode& ec) +ExceptionOr DOMEditor::setNodeValue(Node& node, const String& value) { - return m_history->perform(adoptPtr(new SetNodeValueAction(node, value)), ec); + return m_history.perform(std::make_unique(node, value)); } -static void populateErrorString(const ExceptionCode& ec, ErrorString* errorString) +static bool populateErrorString(ExceptionOr&& 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* anchorNode, ErrorString* errorString) +bool DOMEditor::insertBefore(Node& parentNode, Ref&& 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 +#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* 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 newNode, Node* oldNode, ExceptionCode&); - bool setNodeValue(Node* parentNode, const String& value, ExceptionCode&); + ExceptionOr insertBefore(Node& parentNode, Ref&&, Node* anchorNode); + ExceptionOr removeChild(Node& parentNode, Node&); + ExceptionOr setAttribute(Element&, const String& name, const String& value); + ExceptionOr removeAttribute(Element&, const String& name); + ExceptionOr setOuterHTML(Node&, const String& html, Node*& newNode); + ExceptionOr replaceWholeText(Text&, const String& text); + ExceptionOr replaceChild(Node& parentNode, Ref&& newNode, Node& oldNode); + ExceptionOr setNodeValue(Node& parentNode, const String& value); - bool insertBefore(Node* parentNode, PassRefPtr, 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* 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 #include #include @@ -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> m_children; + String sha1; + String attrsSHA1; + Node* node; + Vector> 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 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 parser; @@ -107,17 +90,17 @@ void DOMPatchSupport::patchDocument(const String& markup) parser->finish(); parser->detach(); - OwnPtr oldInfo = createDigest(m_document->documentElement(), nullptr); - OwnPtr newInfo = createDigest(newDocument->documentElement(), &m_unusedNodesMap); + std::unique_ptr oldInfo = createDigest(*m_document.documentElement(), nullptr); + std::unique_ptr 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 DOMPatchSupport::patchNode(Node& node, const String& markup) { // Don't parse 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 fragment = DocumentFragment::create(*m_document); - if (m_document->isHTMLDocument()) - fragment->parseHTML(markup, node.parentElement() ? node.parentElement() : m_document->documentElement()); + RefPtr 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> oldList; + auto* parentNode = node.parentNode(); + Vector> 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> newList; + Vector> 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("") == notFound) + if (child->hasTagName(headTag) && !child->firstChild() && !markup.containsIgnoringASCIICase("")) continue; // HTML5 parser inserts empty tag whenever it parses - if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.find("") == notFound) + if (child->hasTagName(bodyTag) && !child->firstChild() && !markup.containsIgnoringASCIICase("")) continue; // HTML5 parser inserts empty tag whenever it parses - 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 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(oldNode)) + return { }; // Patch attributes - Element* oldElement = toElement(oldNode); - Element* newElement = toElement(newNode); - if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) { + auto& oldElement = downcast(oldNode); + auto& newElement = downcast(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::diff(const Vector>& oldList, const Vector>& newList) +DOMPatchSupport::diff(const Vector>& oldList, const Vector>& 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>& oldList, const Vectorm_sha1, Vector()).iterator; - it->value.append(i); - } + for (size_t i = 0; i < newList.size(); ++i) + newTable.add(newList[i]->sha1, Vector()).iterator->value.append(i); - for (size_t i = 0; i < oldList.size(); ++i) { - DiffTable::iterator it = oldTable.add(oldList[i]->m_sha1, Vector()).iterator; - it->value.append(i); - } + for (size_t i = 0; i < oldList.size(); ++i) + oldTable.add(oldList[i]->sha1, Vector()).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>& oldList, const Vectorm_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>& oldList, const Vectorm_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>& oldList, const Vector>& oldList, const Vector>& newList, ExceptionCode& ec) +ExceptionOr DOMPatchSupport::innerPatchChildren(ContainerNode& parentNode, const Vector>& oldList, const Vector>& newList) { - std::pair 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 and 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, WTF::UnsignedWithZeroKeyHashTraits> usedOldOrdinals; + HashSet, WTF::UnsignedWithZeroKeyHashTraits> 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 and 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::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 = oldMap[i].first->m_node; - Node* anchorNode = parentNode->childNode(oldMap[i].second); - if (node.get() == anchorNode) + RefPtr 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(cString.data()), cString.length()); } -PassOwnPtr DOMPatchSupport::createDigest(Node* node, UnusedNodesMap* unusedNodesMap) +std::unique_ptr DOMPatchSupport::createDigest(Node& node, UnusedNodesMap* unusedNodesMap) { - Digest* digest = new Digest(node); - + auto digest = std::make_unique(); + digest->node = &node; SHA1 sha1; - Node::NodeType nodeType = node->nodeType(); + auto nodeType = node.nodeType(); sha1.addBytes(reinterpret_cast(&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 childInfo = createDigest(child, unusedNodesMap); - addStringToSHA1(sha1, childInfo->m_sha1); + std::unique_ptr 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(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 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 DOMPatchSupport::removeChildAndMoveToNew(Digest& oldDigest) { - RefPtr oldNode = oldDigest->m_node; - if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), ec)) - return false; + Ref 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 "
" (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 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 -#include -#include #include -#include 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 patchNode(Node&, const String& markup); private: struct Digest; - typedef Vector> ResultMap; - typedef HashMap UnusedNodesMap; - bool innerPatchNode(Digest* oldNode, Digest* newNode, ExceptionCode&); - std::pair diff(const Vector>& oldChildren, const Vector>& newChildren); - bool innerPatchChildren(ContainerNode*, const Vector>& oldChildren, const Vector>& newChildren, ExceptionCode&); - PassOwnPtr createDigest(Node*, UnusedNodesMap*); - bool insertBeforeAndMarkAsUsed(ContainerNode*, Digest*, Node* anchor, ExceptionCode&); - bool removeChildAndMoveToNew(Digest*, ExceptionCode&); - void markNodeAsUsed(Digest*); + using ResultMap = Vector>; + using UnusedNodesMap = HashMap; + + ExceptionOr innerPatchNode(Digest& oldNode, Digest& newNode); + std::pair diff(const Vector>& oldChildren, const Vector>& newChildren); + ExceptionOr innerPatchChildren(ContainerNode&, const Vector>& oldChildren, const Vector>& newChildren); + std::unique_ptr createDigest(Node&, UnusedNodesMap*); + ExceptionOr insertBeforeAndMarkAsUsed(ContainerNode&, Digest&, Node* anchor); + ExceptionOr 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 - -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/IdentifiersFactory.h b/Source/WebCore/inspector/IdentifiersFactory.h deleted file mode 100644 index b1a9c48b2..000000000 --- a/Source/WebCore/inspector/IdentifiersFactory.h +++ /dev/null @@ -1,50 +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. - */ - -#ifndef IdentifiersFactory_h -#define IdentifiersFactory_h - -#include - -#if ENABLE(INSPECTOR) - -namespace WebCore { - -class IdentifiersFactory { -public: - static void setProcessId(long processId) { s_processId = processId; } - static String createIdentifier(); - static String requestId(unsigned long identifier); -private: - static String addProcessIdPrefixTo(const String& id); - - static long s_processId; -}; - -} // namespace WebCore - -#endif // !defined(IdentifiersFactory_h) - -#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 -#include -#include -#include -#include - -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(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 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 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) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "traceLog", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - if (startOffset) - function.appendArgument(*startOffset); - if (maxLength) - function.appendArgument(*maxLength); - RefPtr 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* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "replayTraceLog", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - function.appendArgument(stepNo); - RefPtr 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* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "resourceInfo", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(resourceId); - RefPtr 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* result) -{ - Deprecated::ScriptFunctionCall function(injectedScriptObject(), "resourceState", WebCore::functionCallHandlerFromAnyThread); - function.appendArgument(traceLogId); - function.appendArgument(resourceId); - RefPtr 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 -#include - -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*); - void replayTraceLog(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, int, RefPtr*); - void resourceInfo(ErrorString*, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr*); - void resourceState(ErrorString*, const Inspector::TypeBuilder::Canvas::TraceLogId&, const Inspector::TypeBuilder::Canvas::ResourceId&, RefPtr*); - -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.} - */ - _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.} - */ - _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.} names - * @return {!Object.} - */ - 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.} */ - 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.} */ - 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.} args - * @param {ReplayableResource|*} result - * @param {StackTrace} stackTrace - * @param {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.} - */ - args: function() - { - return this._args; - }, - - /** - * @return {ReplayableResource|*} - */ - result: function() - { - return this._result; - }, - - /** - * @return {StackTrace} - */ - stackTrace: function() - { - return this._stackTrace; - }, - - /** - * @return {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.} */ - 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.} - */ - this._boundResources = Object.create(null); - this.setWrappedObject(wrappedObject); -} - -/** - * @type {number} - */ -Resource._uniqueId = 0; - -/** - * @type {!Object.} - */ -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.} - */ - 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.} - */ - _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.} - */ - _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.} */ - 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.>} */ - 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.} */ (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.} */ - this._customErrors = null; - /** @type {!Object.} */ - this._extensions = {}; -} - -/** - * @const - * @type {!Array.} - */ -WebGLRenderingContextResource.GLCapabilities = [ - "BLEND", - "CULL_FACE", - "DEPTH_TEST", - "DITHER", - "POLYGON_OFFSET_FILL", - "SAMPLE_ALPHA_TO_COVERAGE", - "SAMPLE_COVERAGE", - "SCISSOR_TEST", - "STENCIL_TEST" -]; - -/** - * @const - * @type {!Array.} - */ -WebGLRenderingContextResource.PixelStoreParameters = [ - "PACK_ALIGNMENT", - "UNPACK_ALIGNMENT", - "UNPACK_COLORSPACE_CONVERSION_WEBGL", - "UNPACK_FLIP_Y_WEBGL", - "UNPACK_PREMULTIPLY_ALPHA_WEBGL" -]; - -/** - * @const - * @type {!Array.} - */ -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.} - */ -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.} - */ - 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.} 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.} - */ - _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.} - */ -CanvasRenderingContext2DResource.AttributeProperties = [ - "strokeStyle", - "fillStyle", - "globalAlpha", - "lineWidth", - "lineCap", - "lineJoin", - "miterLimit", - "shadowOffsetX", - "shadowOffsetY", - "shadowBlur", - "shadowColor", - "globalCompositeOperation", - "font", - "textAlign", - "textBaseline", - "lineDashOffset", - "webkitLineDash", - "webkitLineDashOffset" -]; - -/** - * @const - * @type {!Array.} - */ -CanvasRenderingContext2DResource.PathMethods = [ - "beginPath", - "moveTo", - "closePath", - "lineTo", - "quadraticCurveTo", - "bezierCurveTo", - "arcTo", - "arc", - "rect" -]; - -/** - * @const - * @type {!Array.} - */ -CanvasRenderingContext2DResource.TransformationMatrixMethods = [ - "scale", - "rotate", - "translate", - "transform", - "setTransform" -]; - -/** - * @const - * @type {!Object.} - */ -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.} 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.} 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.} - */ - _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.=} 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.} - */ - _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.=} 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.} - */ -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.} */ - this._replayableCalls = []; - /** @type {!Cache} */ - this._replayablesCache = new Cache(); - /** @type {!Object.} */ - this._frameEndCallIndexes = {}; -} - -TraceLog.prototype = { - /** - * @return {number} - */ - size: function() - { - return this._replayableCalls.length; - }, - - /** - * @return {!Array.} - */ - 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.} */ - this._traceLogs = {}; - /** @type {!Object.} */ - 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.} */ - 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 +#include 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(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(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(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>& result) +void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString&, RefPtr>& result) { - result = Inspector::TypeBuilder::Array::create(); + result = Inspector::Protocol::Array::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 value = Inspector::TypeBuilder::ApplicationCache::FrameWithManifest::create() + result->addItem(Inspector::Protocol::ApplicationCache::FrameWithManifest::create() .setFrameId(m_pageAgent->frameId(frame)) .setManifestURL(manifestURL) - .setStatus(static_cast(host->status())); - result->addItem(value); + .setStatus(static_cast(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& applicationCache) +void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString& errorString, const String& frameId, RefPtr& 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 InspectorApplicationCacheAgent::buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo) +Ref InspectorApplicationCacheAgent::buildObjectForApplicationCache(const Vector& 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> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources) +Ref> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const Vector& applicationCacheResources) { - RefPtr> resources = Inspector::TypeBuilder::Array::create(); - - for (const auto& resourceInfo : applicationCacheResources) - resources->addItem(buildObjectForApplicationCacheResource(resourceInfo)); - - return resources; + auto result = Inspector::Protocol::Array::create(); + for (auto& info : applicationCacheResources) + result->addItem(buildObjectForApplicationCacheResource(info)); + return result; } -PassRefPtr InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo) +Ref 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 value = Inspector::TypeBuilder::ApplicationCache::ApplicationCacheResource::create() - .setUrl(resourceInfo.m_resource.string()) - .setSize(static_cast(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(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 +#include #include -#include 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>& result) override; - virtual void getManifestForFrame(ErrorString*, const String& frameId, String* manifestURL) override; - virtual void getApplicationCacheForFrame(ErrorString*, const String& frameId, RefPtr&) override; + void enable(ErrorString&) override; + void getFramesWithManifests(ErrorString&, RefPtr>& result) override; + void getManifestForFrame(ErrorString&, const String& frameId, String* manifestURL) override; + void getApplicationCacheForFrame(ErrorString&, const String& frameId, RefPtr&) override; private: - PassRefPtr buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList&, const ApplicationCacheHost::CacheInfo&); - PassRefPtr> buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList&); - PassRefPtr buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); + Ref buildObjectForApplicationCache(const Vector&, const ApplicationCacheHost::CacheInfo&); + Ref> buildArrayForApplicationCacheResources(const Vector&); + Ref buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); - DocumentLoader* assertFrameWithDocumentLoader(ErrorString*, String frameId); + DocumentLoader* assertFrameWithDocumentLoader(ErrorString&, const String& frameId); - InspectorPageAgent* m_pageAgent; - std::unique_ptr m_frontendDispatcher; - RefPtr m_backendDispatcher; + std::unique_ptr m_frontendDispatcher; + RefPtr 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 -#include -#include +#include #include #include #include @@ -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 pseudoClassValue = pseudoClassArray->get(i); + static NeverDestroyed active(ASCIILiteral("active")); + static NeverDestroyed hover(ASCIILiteral("hover")); + static NeverDestroyed focus(ASCIILiteral("focus")); + static NeverDestroyed 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&); - -private: - InspectorCSSAgent* m_cssAgent; - Timer m_timer; - HashMap 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&) -{ - // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed. - Vector> namedFlows; - - for (HashMap::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&); - + void timerFired(); + private: InspectorCSSAgent* m_cssAgent; - Timer m_timer; + Timer m_timer; HashMap 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&) +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::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 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 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 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 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) + void merge(std::unique_ptr action) override { ASSERT(action->mergeId() == mergeId()); - - SetStyleSheetTextAction* other = static_cast(action.get()); - m_text = other->m_text; + m_text = static_cast(*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 perform() override { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr 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 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) + void merge(std::unique_ptr 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) - { - ASSERT(action->mergeId() == mergeId()); - - SetPropertyTextAction* other = static_cast(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 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 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 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 perform() final { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr undo() final { - return m_styleSheet->deleteRule(m_newId, ec); + return m_styleSheet->deleteRule(m_newId); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr 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(rule); + if (!is(rule)) + return nullptr; + return downcast(&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(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(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 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 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& activeStyleSheets) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); - if (!documentNodeId) - return; + HashSet& previouslyKnownActiveStyleSheets = m_documentToKnownCSSStyleSheets.add(&document, HashSet()).iterator->value; - if (m_updateRegionLayoutTask) - m_updateRegionLayoutTask->unschedule(namedFlow); - - if (m_changeRegionOversetTask) - m_changeRegionOversetTask->unschedule(namedFlow); + HashSet removedStyleSheets(previouslyKnownActiveStyleSheets); + Vector 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 = 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 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(this); + m_changeRegionOversetTask->scheduleFor(&namedFlow, documentNodeId); } void InspectorCSSAgent::regionOversetChanged(WebKitNamedFlow* namedFlow, int documentNodeId) { if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull) return; - - ErrorString errorString; + + ErrorString unused; Ref 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>& matchedCSSRules, RefPtr>& pseudoIdMatches, RefPtr>& inheritedEntries) +void InspectorCSSAgent::getMatchedStylesForNode(ErrorString& errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr>& matchedCSSRules, RefPtr>& pseudoIdMatches, RefPtr>& inheritedEntries) { Element* element = elementForId(errorString, nodeId); if (!element) return; - // Matched rules. - StyleResolver& styleResolver = element->document().ensureStyleResolver(); - Vector> matchedRules = styleResolver.styleRulesForElement(element, StyleResolver::AllCSSRules); - matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, element); - - // Pseudo elements. - if (!includePseudo || *includePseudo) { - RefPtr> pseudoElements = Inspector::TypeBuilder::Array::create(); - for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast(pseudoId + 1)) { - Vector> matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); - if (!matchedRules.isEmpty()) { - RefPtr matches = Inspector::TypeBuilder::CSS::PseudoIdMatches::create() - .setPseudoId(static_cast(pseudoId)) - .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, element)); - pseudoElements->addItem(matches.release()); - } + Element* originalElement = element; + PseudoId elementPseudoId = element->pseudoId(); + if (elementPseudoId) { + element = downcast(*element).hostElement(); + if (!element) { + errorString = ASCIILiteral("Pseudo element has no parent"); + return; } - - pseudoIdMatches = pseudoElements.release(); } - // Inherited styles. - if (!includeInherited || *includeInherited) { - RefPtr> entries = Inspector::TypeBuilder::Array::create(); - Element* parentElement = element->parentElement(); - while (parentElement) { - StyleResolver& parentStyleResolver = parentElement->document().ensureStyleResolver(); - Vector> parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules); - RefPtr 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::create(); + for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast(pseudoId + 1)) { + auto matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); + if (!matchedRules.isEmpty()) { + auto matches = Inspector::Protocol::CSS::PseudoIdMatches::create() + .setPseudoId(static_cast(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::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& inlineStyle, RefPtr& attributesStyle) +void InspectorCSSAgent::getInlineStylesForNode(ErrorString& errorString, int nodeId, RefPtr& inlineStyle, RefPtr& 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 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>& style) +void InspectorCSSAgent::getComputedStyleForNode(ErrorString& errorString, int nodeId, RefPtr>& style) { Element* element = elementForId(errorString, nodeId); if (!element) return; - RefPtr computedStyleInfo = CSSComputedStyleDeclaration::create(element, true); - RefPtr inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0); + RefPtr computedStyleInfo = CSSComputedStyleDeclaration::create(*element, true); + Ref inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, nullptr); style = inspectorStyle->buildArrayForComputedStyle(); } -void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr>& styleInfos) +void InspectorCSSAgent::getAllStyleSheets(ErrorString&, RefPtr>& styleInfos) +{ + styleInfos = Inspector::Protocol::Array::create(); + + Vector inspectorStyleSheets; + collectAllStyleSheets(inspectorStyleSheets); + for (auto* inspectorStyleSheet : inspectorStyleSheets) + styleInfos->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo()); +} + +void InspectorCSSAgent::collectAllStyleSheets(Vector& result) +{ + Vector cssStyleSheets; + for (auto* document : m_domAgent->documents()) + collectAllDocumentStyleSheets(*document, cssStyleSheets); + + for (auto* cssStyleSheet : cssStyleSheets) + result.append(bindStyleSheet(cssStyleSheet)); +} + +void InspectorCSSAgent::collectAllDocumentStyleSheets(Document& document, Vector& result) { - styleInfos = Inspector::TypeBuilder::Array::create(); - Vector documents = m_domAgent->documents(); - for (Vector::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(styleSheet), styleInfos.get()); + auto cssStyleSheets = document.styleScope().activeStyleSheetsForInspector(); + for (auto& cssStyleSheet : cssStyleSheets) + collectStyleSheets(cssStyleSheet.get(), result); +} + +void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector& result) +{ + result.append(styleSheet); + + for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { + CSSRule* rule = styleSheet->item(i); + if (is(*rule)) { + if (CSSStyleSheet* importedStyleSheet = downcast(*rule).styleSheet()) + collectStyleSheets(importedStyleSheet, result); } } } -void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr& styleSheetObject) +void InspectorCSSAgent::getStyleSheet(ErrorString& errorString, const String& styleSheetId, RefPtr& 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(inspectorStyleSheet, text)); + if (result.hasException()) + errorString = InspectorDOMAgent::toErrorString(result.releaseException()); } -void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr& fullStyleId, const String& text, RefPtr& result) +void InspectorCSSAgent::setStyleText(ErrorString& errorString, const InspectorObject& fullStyleId, const String& text, RefPtr& result) { InspectorCSSId compoundId(fullStyleId); ASSERT(!compoundId.isEmpty()); @@ -816,133 +728,182 @@ void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtrhistory()->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(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& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr& result) +void InspectorCSSAgent::setRuleSelector(ErrorString& errorString, const InspectorObject& fullRuleId, const String& selector, RefPtr& 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(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& fullStyleId, int propertyIndex, bool disable, RefPtr& 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& fullRuleId, const String& selector, RefPtr& 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