WebKit Bugzilla
Attachment 373720 Details for
Bug 199611
: Web Inspector: Canvas: replace WTF::Vector with std::initializer_list in CallTracer to avoid dynamic allocations
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-199611-20190709084232.patch (text/plain), 44.76 KB, created by
Devin Rousso
on 2019-07-09 08:42:33 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-07-09 08:42:33 PDT
Size:
44.76 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 5efb91fa521f03ab132b5122b71c3a931f19011d..bdccb34cdaf61051fbb15a2e9956825a39849c24 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,45 @@ >+2019-07-09 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Canvas: replace WTF::Vector with std::initializer_list in CallTracer to avoid dynamic allocations >+ https://bugs.webkit.org/show_bug.cgi?id=199611 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The number of arguments for each member function is known at build time, so there's no need >+ to dynamically allocate a `WTF::Vector` when capturing the arguments. One downside to using >+ a `std::initializer_list` is that we can no longer "flatten" `WTF::Variant` arguments into >+ a `RecordCanvasActionVariant`, but this is acceptable because `WTF::Variant` supports having >+ yet another `WTF::Variant` as one of it's types, which the `InspectorCanvas` can then figure >+ out when it finally gets the data. The same applies to `nullptr`/`Optional` checks as well. >+ >+ * bindings/scripts/CodeGeneratorJS.pm: >+ (GenerateAttributeSetterBodyDefinition): >+ (GenerateImplementationFunctionCall): >+ (GenerateCallTracer): >+ (GenerateCallTracerParameter): Deleted. >+ * bindings/scripts/test/JS/JSTestCallTracer.cpp: >+ >+ * bindings/js/CallTracerTypes.h: >+ * bindings/js/CallTracer.h: >+ * bindings/js/CallTracer.cpp: >+ (WebCore::CallTracer::recordCanvasAction): >+ >+ * inspector/InspectorInstrumentation.h: >+ (WebCore::InspectorInstrumentation::recordCanvasAction): >+ * inspector/InspectorInstrumentation.cpp: >+ (WebCore::InspectorInstrumentation::recordCanvasActionImpl): >+ >+ * inspector/agents/InspectorCanvasAgent.h: >+ * inspector/agents/InspectorCanvasAgent.cpp: >+ (WebCore::InspectorCanvasAgent::recordCanvasAction): >+ >+ * inspector/InspectorCanvas.h: >+ * inspector/InspectorCanvas.cpp: >+ (WebCore::InspectorCanvas::recordAction): >+ (WebCore::InspectorCanvas::buildAction): >+ Drive-by: handle the situation where a parameter is an array of deduplicated strings, which >+ would otherwise be treated as an array of numbers. >+ > 2019-07-08 Saam Barati <sbarati@apple.com> > > [WHLSL Import 23 new JS reference spec tests >diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 5641b18254fd0308678c89a5ee1d5a98470c02fe..ec3a89b6984949852d736a42c7703a3933c075a2 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,15 @@ >+2019-07-09 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Canvas: replace WTF::Vector with std::initializer_list in CallTracer to avoid dynamic allocations >+ https://bugs.webkit.org/show_bug.cgi?id=199611 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UserInterface/Models/Recording.js: >+ (WI.Recording.prototype.async swizzle): >+ Drive-by: handle the situation where a parameter is an array of deduplicated strings, which >+ would otherwise be treated as an array of numbers. >+ > 2019-07-08 Devin Rousso <drousso@apple.com> > > Web Inspector: Debugger: special breakpoints and event targets should be sorted into separate "areas" >diff --git a/Source/WebCore/bindings/js/CallTracer.cpp b/Source/WebCore/bindings/js/CallTracer.cpp >index 807116d5b9194bea00b83281bf640a37a8969d06..9b05c39d52466fdabcd730d380b2d336a38acc48 100644 >--- a/Source/WebCore/bindings/js/CallTracer.cpp >+++ b/Source/WebCore/bindings/js/CallTracer.cpp >@@ -32,13 +32,13 @@ > > namespace WebCore { > >-void CallTracer::recordCanvasAction(const HTMLCanvasElement& canvasElement, const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+void CallTracer::recordCanvasAction(const HTMLCanvasElement& canvasElement, const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > if (auto* canvasRenderingContext = canvasElement.renderingContext()) > InspectorInstrumentation::recordCanvasAction(*canvasRenderingContext, name, WTFMove(parameters)); > } > >-void CallTracer::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+void CallTracer::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > InspectorInstrumentation::recordCanvasAction(canvasRenderingContext, name, WTFMove(parameters)); > } >diff --git a/Source/WebCore/bindings/js/CallTracer.h b/Source/WebCore/bindings/js/CallTracer.h >index db264f33329be2c6934778cd421b17480247d4ab..fd571f9b2d516742589590a0e964c71a3a62925c 100644 >--- a/Source/WebCore/bindings/js/CallTracer.h >+++ b/Source/WebCore/bindings/js/CallTracer.h >@@ -26,7 +26,7 @@ > #pragma once > > #include "CallTracerTypes.h" >-#include <wtf/Vector.h> >+#include <initializer_list> > #include <wtf/text/WTFString.h> > > namespace WebCore { >@@ -36,8 +36,8 @@ class HTMLCanvasElement; > > class CallTracer { > public: >- static void recordCanvasAction(const HTMLCanvasElement&, const String&, Vector<RecordCanvasActionVariant>&& = { }); >- static void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ static void recordCanvasAction(const HTMLCanvasElement&, const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); >+ static void recordCanvasAction(CanvasRenderingContext&, const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > }; > > } // namespace WebCore >diff --git a/Source/WebCore/bindings/js/CallTracerTypes.h b/Source/WebCore/bindings/js/CallTracerTypes.h >index 7bc5406e87e2cf1a163c96af1cf628deb4e607ae..e730a761b89fb5fc0ec037903edce4429a1aad14 100644 >--- a/Source/WebCore/bindings/js/CallTracerTypes.h >+++ b/Source/WebCore/bindings/js/CallTracerTypes.h >@@ -42,6 +42,7 @@ > #include <JavaScriptCore/Float32Array.h> > #include <JavaScriptCore/Int32Array.h> > #include <JavaScriptCore/Uint32Array.h> >+#include <wtf/Optional.h> > #include <wtf/RefPtr.h> > #include <wtf/Variant.h> > #include <wtf/Vector.h> >@@ -53,6 +54,7 @@ > #include "WebGLProgram.h" > #include "WebGLQuery.h" > #include "WebGLRenderbuffer.h" >+#include "WebGLRenderingContextBase.h" > #include "WebGLSampler.h" > #include "WebGLShader.h" > #include "WebGLSync.h" >@@ -62,21 +64,30 @@ > #include "WebGLVertexArrayObject.h" > #endif > >+#if ENABLE(WEBGL2) >+#include "WebGL2RenderingContext.h" >+#endif >+ > namespace WebCore { > > using RecordCanvasActionVariant = Variant< >+ // enum > CanvasDirection, > CanvasFillRule, > CanvasLineCap, > CanvasLineJoin, > CanvasTextAlign, > CanvasTextBaseline, >+ ImageSmoothingQuality, >+ >+ // struct > DOMMatrix2DInit, >+ >+ // pointer > Element*, > HTMLImageElement*, > ImageBitmap*, > ImageData*, >- ImageSmoothingQuality, > Path2D*, > #if ENABLE(WEBGL) > WebGLBuffer*, >@@ -109,13 +120,35 @@ using RecordCanvasActionVariant = Variant< > RefPtr<ImageData>, > RefPtr<Int32Array>, > RefPtr<Uint32Array>, >+ >+ // variant >+ CanvasImageSource, >+ CanvasRenderingContext2DBase::Style, >+#if ENABLE(WEBGL) >+ WebGLRenderingContextBase::BufferDataSource, >+ Optional<WebGLRenderingContextBase::BufferDataSource>, >+ WebGLRenderingContextBase::TexImageSource, >+ Optional<WebGLRenderingContextBase::TexImageSource>, >+#endif >+ >+ // array > Vector<String>, > Vector<float>, > Vector<uint32_t>, > Vector<int32_t>, >+#if ENABLE(WEBGL) >+ WebGLRenderingContextBase::Float32List::VariantType, >+ WebGLRenderingContextBase::Int32List::VariantType, >+#endif >+#if ENABLE(WEBGL2) >+ WebGL2RenderingContext::Uint32List::VariantType, >+#endif >+ >+ // basic > String, > double, > float, >+ Optional<float>, > uint64_t, > int64_t, > uint32_t, >diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm >index d0982deb5310076356a9cd1a36686e38b1b8c4a7..0b6332b580f2748b25fad55144b6c324f5464229 100644 >--- a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm >+++ b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm >@@ -5063,8 +5063,7 @@ sub GenerateAttributeSetterBodyDefinition > my $callTracingCallback = $attribute->extendedAttributes->{CallTracingCallback} || $interface->extendedAttributes->{CallTracingCallback}; > if ($callTracingCallback) { > my $indent = " "; >- my @callTracerArguments = (); >- push(@callTracerArguments, GenerateCallTracerParameter("nativeValue", $attribute->type, 0, $indent)); >+ my @callTracerArguments = ("nativeValue"); > GenerateCallTracer($outputArray, $callTracingCallback, $attribute->name, \@callTracerArguments, $indent); > } > >@@ -6262,10 +6261,7 @@ sub GenerateImplementationFunctionCall > > my $callTracingCallback = $operation->extendedAttributes->{CallTracingCallback} || $interface->extendedAttributes->{CallTracingCallback}; > if ($callTracingCallback) { >- my @callTracerArguments = (); >- foreach my $argument (@{$operation->arguments}) { >- push(@callTracerArguments, GenerateCallTracerParameter($argument->name, $argument->type, $argument->isOptional && !defined($argument->default), $indent)); >- } >+ my @callTracerArguments = map { $_->name } @{$operation->arguments}; > GenerateCallTracer($outputArray, $callTracingCallback, $operation->name, \@callTracerArguments, $indent); > } > >@@ -7505,57 +7501,18 @@ sub AddJSBuiltinIncludesIfNeeded() > } > } > >-sub GenerateCallTracerParameter() >-{ >- my ($name, $type, $optional, $indent) = @_; >- >- my $result = ""; >- >- if ($optional || $type->isNullable) { >- $result .= $indent . " if (" . $name . ")\n"; >- $result .= " "; >- } >- >- $result .= $indent . " "; >- >- if ($type->isUnion) { >- $result .= "WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, "; >- } else { >- $result .= "callTracerParameters.append("; >- } >- >- if ($optional || ($type->isUnion && $type->isNullable)) { >- $result .= "*"; >- } >- >- $result .= $name . ");"; >- >- return $result; >-} >- > sub GenerateCallTracer() > { > my ($outputArray, $callTracingCallback, $name, $arguments, $indent) = @_; > > AddToImplIncludes("CallTracer.h"); > >- my $count = scalar(@$arguments); >- >- push(@$outputArray, $indent . "if (UNLIKELY(impl.callTracingActive()))"); >- if ($count) { >- push(@$outputArray, " {\n"); >- push(@$outputArray, $indent . " Vector<" . $codeGenerator->WK_ucfirst($callTracingCallback) . "Variant> callTracerParameters;\n"); >- push(@$outputArray, join("\n", @$arguments)); >- } >- push(@$outputArray, "\n"); >+ push(@$outputArray, $indent . "if (UNLIKELY(impl.callTracingActive()))\n"); > push(@$outputArray, $indent . " CallTracer::" . $callTracingCallback . "(impl, \"" . $name . "\"_s"); >- if ($count) { >- push(@$outputArray, ", WTFMove(callTracerParameters)"); >+ if (scalar(@$arguments)) { >+ push(@$outputArray, ", { " . join(", ", @$arguments) . " }"); > } > push(@$outputArray, ");\n"); >- if ($count) { >- push(@$outputArray, $indent . "}\n") >- } > } > > sub GenerateCustomElementReactionsStackIfNeeded >diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp >index 6b81bffe495e500bcba3451c7fd7b6bee7754250..1b266af884b7903a61283f8cac6e98196256562e 100644 >--- a/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp >+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp >@@ -242,11 +242,8 @@ static inline bool setJSTestCallTracerTestAttributeInterfaceSetter(ExecState& st > auto& impl = thisObject.wrapped(); > auto nativeValue = convert<IDLBoolean>(state, value); > RETURN_IF_EXCEPTION(throwScope, false); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- callTracerParameters.append(nativeValue); >- CallTracer::testCallTracerInterface(impl, "testAttributeInterface"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testAttributeInterface"_s, { nativeValue }); > AttributeSetter::call(state, throwScope, [&] { > return impl.setTestAttributeInterface(WTFMove(nativeValue)); > }); >@@ -280,11 +277,8 @@ static inline bool setJSTestCallTracerTestAttributeSpecifiedSetter(ExecState& st > auto& impl = thisObject.wrapped(); > auto nativeValue = convert<IDLBoolean>(state, value); > RETURN_IF_EXCEPTION(throwScope, false); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerAttributeVariant> callTracerParameters; >- callTracerParameters.append(nativeValue); >- CallTracer::testCallTracerAttribute(impl, "testAttributeSpecified"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerAttribute(impl, "testAttributeSpecified"_s, { nativeValue }); > AttributeSetter::call(state, throwScope, [&] { > return impl.setTestAttributeSpecified(WTFMove(nativeValue)); > }); >@@ -318,11 +312,8 @@ static inline bool setJSTestCallTracerTestAttributeWithVariantSetter(ExecState& > auto& impl = thisObject.wrapped(); > auto nativeValue = convert<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>(state, value); > RETURN_IF_EXCEPTION(throwScope, false); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, nativeValue); >- CallTracer::testCallTracerInterface(impl, "testAttributeWithVariant"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testAttributeWithVariant"_s, { nativeValue }); > AttributeSetter::call(state, throwScope, [&] { > return impl.setTestAttributeWithVariant(WTFMove(nativeValue)); > }); >@@ -393,13 +384,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); > auto c = convert<IDLDOMString>(*state, state->uncheckedArgument(2)); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- callTracerParameters.append(a); >- callTracerParameters.append(b); >- callTracerParameters.append(c); >- CallTracer::testCallTracerInterface(impl, "testOperationWithArguments"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithArguments"_s, { a, b, c }); > impl.testOperationWithArguments(WTFMove(a), WTFMove(b), WTFMove(c)); > return JSValue::encode(jsUndefined()); > } >@@ -418,12 +404,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > return throwVMError(state, throwScope, createNotEnoughArgumentsError(state)); > auto nodeNullableArg = convert<IDLNullable<IDLInterface<Node>>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 0, "nodeNullableArg", "TestCallTracer", "testOperationWithNullableArgument", "Node"); }); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- if (nodeNullableArg) >- callTracerParameters.append(nodeNullableArg); >- CallTracer::testCallTracerInterface(impl, "testOperationWithNullableArgument"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithNullableArgument"_s, { nodeNullableArg }); > impl.testOperationWithNullableArgument(WTFMove(nodeNullableArg)); > return JSValue::encode(jsUndefined()); > } >@@ -442,11 +424,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > return throwVMError(state, throwScope, createNotEnoughArgumentsError(state)); > auto variantArg = convert<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>(*state, state->uncheckedArgument(0)); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, variantArg); >- CallTracer::testCallTracerInterface(impl, "testOperationWithVariantArgument"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithVariantArgument"_s, { variantArg }); > impl.testOperationWithVariantArgument(WTFMove(variantArg)); > return JSValue::encode(jsUndefined()); > } >@@ -465,12 +444,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > return throwVMError(state, throwScope, createNotEnoughArgumentsError(state)); > auto variantNullableArg = convert<IDLNullable<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>>(*state, state->uncheckedArgument(0)); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- if (variantNullableArg) >- WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, *variantNullableArg); >- CallTracer::testCallTracerInterface(impl, "testOperationWithNullableVariantArgument"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithNullableVariantArgument"_s, { variantNullableArg }); > impl.testOperationWithNullableVariantArgument(WTFMove(variantNullableArg)); > return JSValue::encode(jsUndefined()); > } >@@ -487,12 +462,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > auto& impl = castedThis->wrapped(); > auto variantOptionalArg = state->argument(0).isUndefined() ? Optional<Converter<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>::ReturnType>() : Optional<Converter<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>::ReturnType>(convert<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>(*state, state->uncheckedArgument(0))); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- if (variantOptionalArg) >- WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, *variantOptionalArg); >- CallTracer::testCallTracerInterface(impl, "testOperationWithOptionalVariantArgument"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithOptionalVariantArgument"_s, { variantOptionalArg }); > impl.testOperationWithOptionalVariantArgument(WTFMove(variantOptionalArg)); > return JSValue::encode(jsUndefined()); > } >@@ -509,11 +480,8 @@ static inline JSC::EncodedJSValue jsTestCallTracerPrototypeFunctionTestOperation > auto& impl = castedThis->wrapped(); > auto variantDefaultArg = state->argument(0).isUndefined() ? "" : convert<IDLUnion<IDLBoolean, IDLFloat, IDLDOMString>>(*state, state->uncheckedArgument(0)); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); >- if (UNLIKELY(impl.callTracingActive())) { >- Vector<TestCallTracerInterfaceVariant> callTracerParameters; >- WTF::visit([&] (auto& value) { callTracerParameters.append(value); }, variantDefaultArg); >- CallTracer::testCallTracerInterface(impl, "testOperationWithDefaultVariantArgument"_s, WTFMove(callTracerParameters)); >- } >+ if (UNLIKELY(impl.callTracingActive())) >+ CallTracer::testCallTracerInterface(impl, "testOperationWithDefaultVariantArgument"_s, { variantDefaultArg }); > impl.testOperationWithDefaultVariantArgument(WTFMove(variantDefaultArg)); > return JSValue::encode(jsUndefined()); > } >diff --git a/Source/WebCore/inspector/InspectorCanvas.cpp b/Source/WebCore/inspector/InspectorCanvas.cpp >index 4b22d5d2796e9856f55d69f00c15f021eae3278f..29be2a0e691079eb65e45e8f28bc237cf69be00c 100644 >--- a/Source/WebCore/inspector/InspectorCanvas.cpp >+++ b/Source/WebCore/inspector/InspectorCanvas.cpp >@@ -71,6 +71,7 @@ > #endif > #include <JavaScriptCore/IdentifiersFactory.h> > #include <JavaScriptCore/ScriptCallStackFactory.h> >+#include <wtf/Function.h> > > namespace WebCore { > >@@ -158,7 +159,7 @@ static bool shouldSnapshotWebGL2Action(const String& name) > } > #endif > >-void InspectorCanvas::recordAction(const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+void InspectorCanvas::recordAction(const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > if (!m_initialState) { > // We should only construct the initial state for the first action of the recording. >@@ -655,7 +656,7 @@ Ref<Inspector::Protocol::Recording::InitialState> InspectorCanvas::buildInitialS > return initialStatePayload; > } > >-Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > auto action = JSON::ArrayOf<JSON::Value>::create(); > action->addItem(indexForData(name)); >@@ -668,14 +669,17 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, > swizzleTypes->addItem(static_cast<int>(swizzleType)); > }; > >- for (auto& item : parameters) { >- WTF::switchOn(item, >+ // Declared before it's initialized so it can be used recursively. >+ Function<void(const RecordCanvasActionVariant&)> parseParameter; >+ parseParameter = [&] (const auto& parameter) { >+ WTF::switchOn(parameter, > [&] (CanvasDirection value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (CanvasFillRule value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (CanvasLineCap value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (CanvasLineJoin value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (CanvasTextAlign value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (CanvasTextBaseline value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, >+ [&] (ImageSmoothingQuality value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, > [&] (const DOMMatrix2DInit& value) { > auto array = JSON::ArrayOf<double>::create(); > array->addItem(value.a.valueOr(1)); >@@ -686,53 +690,159 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, > array->addItem(value.f.valueOr(0)); > addParameter(array.ptr(), RecordingSwizzleTypes::DOMMatrix); > }, >- [&] (const Element*) { >- // Elements are not serializable, so add a string as a placeholder since the actual >- // element cannot be reconstructed in the frontend. >- addParameter(indexForData("Element"), RecordingSwizzleTypes::None); >+ [&] (const Element* value) { >+ if (value) { >+ // Elements are not serializable, so add a string as a placeholder since the actual >+ // element cannot be reconstructed in the frontend. >+ addParameter(indexForData("Element"), RecordingSwizzleTypes::None); >+ } > }, >- [&] (HTMLImageElement* value) { addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >- [&] (ImageBitmap* value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageBitmap); }, >- [&] (ImageData* value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageData); }, >- [&] (ImageSmoothingQuality value) { addParameter(indexForData(convertEnumerationToString(value)), RecordingSwizzleTypes::String); }, >- [&] (const Path2D* value) { addParameter(indexForData(buildStringFromPath(value->path())), RecordingSwizzleTypes::Path2D); }, >+ [&] (HTMLImageElement* value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >+ [&] (ImageBitmap* value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::ImageBitmap); }, >+ [&] (ImageData* value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::ImageData); }, >+ [&] (const Path2D* value) { >+ if (value) >+ addParameter(indexForData(buildStringFromPath(value->path())), RecordingSwizzleTypes::Path2D); }, > #if ENABLE(WEBGL) > // FIXME: <https://webkit.org/b/176009> Web Inspector: send data for WebGL objects during a recording instead of a placeholder string >- [&] (const WebGLBuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLBuffer); }, >- [&] (const WebGLFramebuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLFramebuffer); }, >- [&] (const WebGLProgram*) { addParameter(0, RecordingSwizzleTypes::WebGLProgram); }, >- [&] (const WebGLQuery*) { addParameter(0, RecordingSwizzleTypes::WebGLQuery); }, >- [&] (const WebGLRenderbuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLRenderbuffer); }, >- [&] (const WebGLSampler*) { addParameter(0, RecordingSwizzleTypes::WebGLSampler); }, >- [&] (const WebGLShader*) { addParameter(0, RecordingSwizzleTypes::WebGLShader); }, >- [&] (const WebGLSync*) { addParameter(0, RecordingSwizzleTypes::WebGLSync); }, >- [&] (const WebGLTexture*) { addParameter(0, RecordingSwizzleTypes::WebGLTexture); }, >- [&] (const WebGLTransformFeedback*) { addParameter(0, RecordingSwizzleTypes::WebGLTransformFeedback); }, >- [&] (const WebGLUniformLocation*) { addParameter(0, RecordingSwizzleTypes::WebGLUniformLocation); }, >- [&] (const WebGLVertexArrayObject*) { addParameter(0, RecordingSwizzleTypes::WebGLVertexArrayObject); }, >+ [&] (const WebGLBuffer* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLBuffer); >+ }, >+ [&] (const WebGLFramebuffer* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLFramebuffer); >+ }, >+ [&] (const WebGLProgram* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLProgram); >+ }, >+ [&] (const WebGLQuery* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLQuery); >+ }, >+ [&] (const WebGLRenderbuffer* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLRenderbuffer); >+ }, >+ [&] (const WebGLSampler* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLSampler); >+ }, >+ [&] (const WebGLShader* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLShader); >+ }, >+ [&] (const WebGLSync* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLSync); >+ }, >+ [&] (const WebGLTexture* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLTexture); >+ }, >+ [&] (const WebGLTransformFeedback* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLTransformFeedback); >+ }, >+ [&] (const WebGLUniformLocation* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLUniformLocation); >+ }, >+ [&] (const WebGLVertexArrayObject* value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::WebGLVertexArrayObject); >+ }, > #endif >- [&] (const RefPtr<ArrayBuffer>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); }, >- [&] (const RefPtr<ArrayBufferView>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); }, >- [&] (const RefPtr<CanvasGradient>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::CanvasGradient); }, >- [&] (const RefPtr<CanvasPattern>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::CanvasPattern); }, >- [&] (const RefPtr<Float32Array>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); }, >- [&] (const RefPtr<HTMLCanvasElement>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >- [&] (const RefPtr<HTMLImageElement>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >+ [&] (const RefPtr<ArrayBuffer>& value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::TypedArray); >+ }, >+ [&] (const RefPtr<ArrayBufferView>& value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::TypedArray); >+ }, >+ [&] (const RefPtr<CanvasGradient>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::CanvasGradient); >+ }, >+ [&] (const RefPtr<CanvasPattern>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::CanvasPattern); >+ }, >+ [&] (const RefPtr<Float32Array>& value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::TypedArray); >+ }, >+ [&] (const RefPtr<HTMLCanvasElement>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::Image); >+ }, >+ [&] (const RefPtr<HTMLImageElement>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::Image); >+ }, > #if ENABLE(VIDEO) >- [&] (const RefPtr<HTMLVideoElement>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >+ [&] (const RefPtr<HTMLVideoElement>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::Image); >+ }, > #endif > #if ENABLE(CSS_TYPED_OM) >- [&] (const RefPtr<TypedOMCSSImageValue>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::Image); }, >+ [&] (const RefPtr<TypedOMCSSImageValue>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::Image); >+ }, >+#endif >+ [&] (const RefPtr<ImageBitmap>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::ImageBitmap); >+ }, >+ [&] (const RefPtr<ImageData>& value) { >+ if (value) >+ addParameter(indexForData(value), RecordingSwizzleTypes::ImageData); >+ }, >+ [&] (const RefPtr<Int32Array>& value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::TypedArray); >+ }, >+ [&] (const RefPtr<Uint32Array>& value) { >+ if (value) >+ addParameter(0, RecordingSwizzleTypes::TypedArray); >+ }, >+ [&] (const CanvasImageSource& value) { >+ WTF::visit(parseParameter, value); >+ }, >+ [&] (const CanvasRenderingContext2DBase::Style& value) { >+ WTF::visit(parseParameter, value); >+ }, >+#if ENABLE(WEBGL) >+ [&] (const WebGLRenderingContextBase::BufferDataSource& value) { >+ WTF::visit(parseParameter, value); >+ }, >+ [&] (const Optional<WebGLRenderingContextBase::BufferDataSource>& value) { >+ if (value) >+ parseParameter(value.value()); >+ }, >+ [&] (const WebGLRenderingContextBase::TexImageSource& value) { >+ WTF::visit(parseParameter, value); >+ }, >+ [&] (const Optional<WebGLRenderingContextBase::TexImageSource>& value) { >+ if (value) >+ parseParameter(value.value()); >+ }, > #endif >- [&] (const RefPtr<ImageBitmap>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageBitmap); }, >- [&] (const RefPtr<ImageData>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageData); }, >- [&] (const RefPtr<Int32Array>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); }, >- [&] (const RefPtr<Uint32Array>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); }, > [&] (const Vector<String>& value) { > auto deduplicated = value.map([&] (const String& item) { > return indexForData(item); > }); >- addParameter(buildArrayForVector(deduplicated).ptr(), RecordingSwizzleTypes::Array); >+ addParameter(buildArrayForVector(deduplicated).ptr(), RecordingSwizzleTypes::String); > }, > [&] (const Vector<float>& value) { addParameter(buildArrayForVector(value).ptr(), RecordingSwizzleTypes::Array); }, > [&] (const Vector<uint32_t>& value) { >@@ -742,9 +852,26 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, > addParameter(buildArrayForVector(mapped).ptr(), RecordingSwizzleTypes::Array); > }, > [&] (const Vector<int32_t>& value) { addParameter(buildArrayForVector(value).ptr(), RecordingSwizzleTypes::Array); }, >+#if ENABLE(WEBGL) >+ [&] (const WebGLRenderingContextBase::Float32List::VariantType& value) { >+ WTF::visit(parseParameter, value); >+ }, >+ [&] (const WebGLRenderingContextBase::Int32List::VariantType& value) { >+ WTF::visit(parseParameter, value); >+ }, >+#endif >+#if ENABLE(WEBGL2) >+ [&] (const WebGL2RenderingContext::Uint32List::VariantType& value) { >+ WTF::visit(parseParameter, value); >+ }, >+#endif > [&] (const String& value) { addParameter(indexForData(value), RecordingSwizzleTypes::String); }, > [&] (double value) { addParameter(value, RecordingSwizzleTypes::Number); }, > [&] (float value) { addParameter(value, RecordingSwizzleTypes::Number); }, >+ [&] (const Optional<float>& value) { >+ if (value) >+ parseParameter(value.value()); >+ }, > [&] (uint64_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); }, > [&] (int64_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); }, > [&] (uint32_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); }, >@@ -752,7 +879,9 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name, > [&] (uint8_t value) { addParameter(static_cast<int>(value), RecordingSwizzleTypes::Number); }, > [&] (bool value) { addParameter(value, RecordingSwizzleTypes::Boolean); } > ); >- } >+ }; >+ for (auto& parameter : parameters) >+ parseParameter(parameter); > > action->addItem(WTFMove(parametersData)); > action->addItem(WTFMove(swizzleTypes)); >diff --git a/Source/WebCore/inspector/InspectorCanvas.h b/Source/WebCore/inspector/InspectorCanvas.h >index 6886e626c67fef8c8917f15e091296af634ed853..38542fb576be621e21d6e6eafc76c9d1af7f2631 100644 >--- a/Source/WebCore/inspector/InspectorCanvas.h >+++ b/Source/WebCore/inspector/InspectorCanvas.h >@@ -29,6 +29,7 @@ > #include <JavaScriptCore/InspectorProtocolObjects.h> > #include <JavaScriptCore/ScriptCallFrame.h> > #include <JavaScriptCore/ScriptCallStack.h> >+#include <initializer_list> > #include <wtf/Variant.h> > #include <wtf/Vector.h> > #include <wtf/text/WTFString.h> >@@ -63,7 +64,7 @@ public: > void resetRecordingData(); > bool hasRecordingData() const; > bool currentFrameHasData() const; >- void recordAction(const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ void recordAction(const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > > Ref<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>> releaseFrames() { return m_frames.releaseNonNull(); } > >@@ -109,7 +110,7 @@ private: > int indexForData(DuplicateDataVariant); > String stringIndexForKey(const String&); > Ref<Inspector::Protocol::Recording::InitialState> buildInitialState(); >- Ref<JSON::ArrayOf<JSON::Value>> buildAction(const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ Ref<JSON::ArrayOf<JSON::Value>> buildAction(const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > Ref<JSON::ArrayOf<JSON::Value>> buildArrayForCanvasGradient(const CanvasGradient&); > Ref<JSON::ArrayOf<JSON::Value>> buildArrayForCanvasPattern(const CanvasPattern&); > Ref<JSON::ArrayOf<JSON::Value>> buildArrayForImageData(const ImageData&); >diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp >index fbb8af4a82ea0fdf792e4a1fd310f79c9d60450d..a904c03db9893b4e80a5463bd94a4ecc99532b4c 100644 >--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp >+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp >@@ -1036,7 +1036,7 @@ void InspectorInstrumentation::didChangeCanvasMemoryImpl(InstrumentingAgents& in > canvasAgent->didChangeCanvasMemory(context); > } > >-void InspectorInstrumentation::recordCanvasActionImpl(InstrumentingAgents& instrumentingAgents, CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+void InspectorInstrumentation::recordCanvasActionImpl(InstrumentingAgents& instrumentingAgents, CanvasRenderingContext& canvasRenderingContext, const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent()) > canvasAgent->recordCanvasAction(canvasRenderingContext, name, WTFMove(parameters)); >diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h >index 9791a8650b499f4b0bf5fbad3cb8aa6d360ee273..9cadfb1e8c1f6f938b4d0560b432bf146f3712c1 100644 >--- a/Source/WebCore/inspector/InspectorInstrumentation.h >+++ b/Source/WebCore/inspector/InspectorInstrumentation.h >@@ -50,6 +50,7 @@ > #include "WorkerGlobalScope.h" > #include "WorkerInspectorController.h" > #include <JavaScriptCore/JSCInlines.h> >+#include <initializer_list> > #include <wtf/MemoryPressureHandler.h> > #include <wtf/RefPtr.h> > >@@ -269,7 +270,7 @@ public: > static void didChangeCSSCanvasClientNodes(CanvasBase&); > static void didCreateCanvasRenderingContext(CanvasRenderingContext&); > static void didChangeCanvasMemory(CanvasRenderingContext&); >- static void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ static void recordCanvasAction(CanvasRenderingContext&, const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > static void didFinishRecordingCanvasFrame(CanvasRenderingContext&, bool forceDispatch = false); > #if ENABLE(WEBGL) > static void didEnableExtension(WebGLRenderingContextBase&, const String&); >@@ -452,7 +453,7 @@ private: > static void didChangeCSSCanvasClientNodesImpl(InstrumentingAgents&, CanvasBase&); > static void didCreateCanvasRenderingContextImpl(InstrumentingAgents&, CanvasRenderingContext&); > static void didChangeCanvasMemoryImpl(InstrumentingAgents&, CanvasRenderingContext&); >- static void recordCanvasActionImpl(InstrumentingAgents&, CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ static void recordCanvasActionImpl(InstrumentingAgents&, CanvasRenderingContext&, const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > static void didFinishRecordingCanvasFrameImpl(InstrumentingAgents&, CanvasRenderingContext&, bool forceDispatch = false); > #if ENABLE(WEBGL) > static void didEnableExtensionImpl(InstrumentingAgents&, WebGLRenderingContextBase&, const String&); >@@ -1311,7 +1312,7 @@ inline void InspectorInstrumentation::didChangeCanvasMemory(CanvasRenderingConte > didChangeCanvasMemoryImpl(*instrumentingAgents, context); > } > >-inline void InspectorInstrumentation::recordCanvasAction(CanvasRenderingContext& context, const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+inline void InspectorInstrumentation::recordCanvasAction(CanvasRenderingContext& context, const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > FAST_RETURN_IF_NO_FRONTENDS(void()); > if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context.canvasBase().scriptExecutionContext())) >diff --git a/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp b/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp >index a33b6032b7fb92de79f0d2b3155ce43e6f4c0103..9be06119fb3219700729722d836a816b25f1c015 100644 >--- a/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp >+++ b/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp >@@ -420,7 +420,7 @@ void InspectorCanvasAgent::didChangeCanvasMemory(CanvasRenderingContext& context > m_frontendDispatcher->canvasMemoryChanged(inspectorCanvas->identifier(), node->memoryCost()); > } > >-void InspectorCanvasAgent::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters) >+void InspectorCanvasAgent::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, std::initializer_list<RecordCanvasActionVariant>&& parameters) > { > auto inspectorCanvas = findInspectorCanvas(canvasRenderingContext); > ASSERT(inspectorCanvas); >diff --git a/Source/WebCore/inspector/agents/InspectorCanvasAgent.h b/Source/WebCore/inspector/agents/InspectorCanvasAgent.h >index 59a2250d7348317118f3d9dd4712417adff80681..fa0f6cc23b0e4519ae19035227bf9881be1f1227 100644 >--- a/Source/WebCore/inspector/agents/InspectorCanvasAgent.h >+++ b/Source/WebCore/inspector/agents/InspectorCanvasAgent.h >@@ -32,6 +32,7 @@ > #include "Timer.h" > #include <JavaScriptCore/InspectorBackendDispatchers.h> > #include <JavaScriptCore/InspectorFrontendDispatchers.h> >+#include <initializer_list> > #include <wtf/HashMap.h> > #include <wtf/RefPtr.h> > #include <wtf/Vector.h> >@@ -87,7 +88,7 @@ public: > void didCreateCanvasRenderingContext(CanvasRenderingContext&); > void willDestroyCanvasRenderingContext(CanvasRenderingContext&); > void didChangeCanvasMemory(CanvasRenderingContext&); >- void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { }); >+ void recordCanvasAction(CanvasRenderingContext&, const String&, std::initializer_list<RecordCanvasActionVariant>&& = { }); > void didFinishRecordingCanvasFrame(CanvasRenderingContext&, bool forceDispatch = false); > void consoleStartRecordingCanvas(CanvasRenderingContext&, JSC::ExecState&, JSC::JSObject* options); > #if ENABLE(WEBGL) >diff --git a/Source/WebInspectorUI/UserInterface/Models/Recording.js b/Source/WebInspectorUI/UserInterface/Models/Recording.js >index c9b743459c886920bfb404d760013f7010d38fcb..3847ce69fe593c20dc55474e03832ac23f30d04f 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/Recording.js >+++ b/Source/WebInspectorUI/UserInterface/Models/Recording.js >@@ -352,7 +352,10 @@ WI.Recording = class Recording extends WI.Object > break; > > case WI.Recording.Swizzle.String: >- this._swizzle[index][type] = String(data); >+ if (Array.isArray(data)) >+ this._swizzle[index][type] = await Promise.all(data.map((item) => this.swizzle(item, WI.Recording.Swizzle.String))); >+ else >+ this._swizzle[index][type] = String(data); > break; > > case WI.Recording.Swizzle.Image:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199611
:
373702
| 373720