Chromium Code Reviews| Index: third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp |
| diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp |
| index ec5f583315f21d4b9b1c2d6de82d3f185336f81b..7683b468f880b879bf6f5fa07880e77b6ff3228c 100644 |
| --- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp |
| +++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScope.cpp |
| @@ -4,8 +4,12 @@ |
| #include "modules/csspaint/PaintWorkletGlobalScope.h" |
| +#include "bindings/core/v8/CSSPaintBinding.h" |
| +#include "bindings/core/v8/ScopedPersistent.h" |
| #include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
| +#include "core/dom/ExceptionCode.h" |
| #include "core/inspector/MainThreadDebugger.h" |
| +#include "modules/csspaint/CSSPaintDefinition.h" |
| namespace blink { |
| @@ -27,4 +31,107 @@ PaintWorkletGlobalScope::~PaintWorkletGlobalScope() |
| { |
| } |
| +void PaintWorkletGlobalScope::registerPaint(const String& name, const ScriptValue& ctorValue, ExceptionState& exceptionState) |
| +{ |
| + if (m_paintDefinitions.contains(name)) { |
| + exceptionState.throwDOMException(NotSupportedError, "A class with name:'" + name + "' is already registered."); |
| + return; |
| + } |
| + |
| + if (name.isEmpty()) { |
| + exceptionState.throwTypeError("The empty string is not a valid name."); |
| + return; |
| + } |
| + |
| + v8::Isolate* isolate = scriptController()->getScriptState()->isolate(); |
| + |
| + v8::TryCatch block(isolate); |
| + v8::Local<v8::Context> context = scriptController()->context(); |
| + |
| + ASSERT(ctorValue.v8Value()->IsFunction()); |
| + v8::Local<v8::Function> constructor = v8::Local<v8::Function>::Cast(ctorValue.v8Value()); |
| + |
| + v8::Local<v8::Value> inputPropertiesValue; |
| + if (!constructor->Get(context, v8String(isolate, "inputProperties")).ToLocal(&inputPropertiesValue)) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return; |
| + } |
| + |
| + if (!isUndefinedOrNull(inputPropertiesValue)) { |
| + toImplArray<Vector<String>>(inputPropertiesValue, 0, isolate, exceptionState); |
| + |
| + if (exceptionState.hadException()) |
| + return; |
| + |
| + // TODO(ikilpatrick): Hook up invalidation based on these inputProperties. |
| + } |
| + |
| + v8::Local<v8::Value> prototypeValue; |
| + if (!constructor->Get(context, v8String(isolate, "prototype")).ToLocal(&prototypeValue)) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return; |
| + } |
| + |
| + if (isUndefinedOrNull(prototypeValue)) { |
| + exceptionState.throwTypeError("The 'prototype' object on the class does not exist."); |
| + return; |
| + } |
| + |
| + if (!prototypeValue->IsObject()) { |
| + exceptionState.throwTypeError("The 'prototype' property on the class is not an object."); |
| + return; |
| + } |
| + |
| + v8::Local<v8::Object> prototype = v8::Local<v8::Object>::Cast(prototypeValue); |
| + |
| + v8::Local<v8::Value> paintValue; |
| + if (!prototype->Get(context, v8String(isolate, "paint")).ToLocal(&paintValue)) { |
| + exceptionState.rethrowV8Exception(block.Exception()); |
| + return; |
| + } |
| + |
| + if (isUndefinedOrNull(paintValue)) { |
| + exceptionState.throwTypeError("The 'paint' function on the prototype does not exist."); |
| + return; |
| + } |
| + |
| + if (!paintValue->IsFunction()) { |
| + exceptionState.throwTypeError("The 'paint' property on the prototype is not a function."); |
| + return; |
| + } |
| + |
| + v8::Local<v8::Function> paint = v8::Local<v8::Function>::Cast(paintValue); |
| + |
| + RefPtrWillBeRawPtr<CSSPaintDefinition> definition = CSSPaintDefinition::create(scriptController()->getScriptState(), constructor, paint); |
|
haraken
2016/03/31 02:01:59
Just to confirm: Once registerPaint is called, you
ikilpatrick
2016/03/31 21:59:05
Yes that's correct. Sounds good. Done.
|
| + m_paintDefinitions.set(name, definition); |
| + |
| + setBindingOnPerContextData(CSSPaintBinding::create(isolate, constructor, paint)); |
| +} |
| + |
| +CSSPaintDefinition* PaintWorkletGlobalScope::findDefinition(const String& name) |
| +{ |
| + return m_paintDefinitions.get(name); |
| +} |
| + |
| +void PaintWorkletGlobalScope::setBindingOnPerContextData(PassOwnPtr<CSSPaintBinding> binding) |
| +{ |
| + v8::Local<v8::Context> context = scriptController()->getScriptState()->context(); |
| + ASSERT(!context.IsEmpty()); |
| + |
| + V8PerContextData* perContextData = V8PerContextData::from(context); |
| + ASSERT(perContextData); |
| + |
| + // The context is responsible for keeping the constructor and paint |
| + // functions alive. |
| + perContextData->addCSSPaintBinding(std::move(binding)); |
| +} |
| + |
| +DEFINE_TRACE(PaintWorkletGlobalScope) |
| +{ |
| +#if ENABLE(OILPAN) |
| + visitor->trace(m_paintDefinitions); |
| +#endif |
| + WorkletGlobalScope::trace(visitor); |
| +} |
| + |
| } // namespace blink |