| /* |
| * 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. |
| * 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 V8DOMConfiguration_h |
| #define V8DOMConfiguration_h |
| |
| #include "bindings/core/v8/V8Binding.h" |
| #include "bindings/core/v8/V8DOMWrapper.h" |
| #include <v8.h> |
| |
| namespace blink { |
| |
| class V8DOMConfiguration { |
| public: |
| // The following Configuration structs and install methods are used for |
| // setting multiple properties on an ObjectTemplate, used from the |
| // generated bindings initialization (ConfigureXXXTemplate). This greatly |
| // reduces the binary size by moving from code driven setup to data table |
| // driven setup. |
| |
| enum ExposeConfiguration { |
| ExposedToAllScripts, |
| OnlyExposedToPrivateScript, |
| }; |
| |
| enum InstanceOrPrototypeConfiguration { |
| OnInstance, |
| OnPrototype, |
| }; |
| |
| // AttributeConfiguration translates into calls to SetAccessor() on either |
| // the instance or the prototype ObjectTemplate, based on |instanceOrPrototypeConfiguration|. |
| struct AttributeConfiguration { |
| const char* const name; |
| v8::AccessorGetterCallback getter; |
| v8::AccessorSetterCallback setter; |
| v8::AccessorGetterCallback getterForMainWorld; |
| v8::AccessorSetterCallback setterForMainWorld; |
| const WrapperTypeInfo* data; |
| v8::AccessControl settings; |
| v8::PropertyAttribute attribute; |
| ExposeConfiguration exposeConfiguration; |
| InstanceOrPrototypeConfiguration instanceOrPrototypeConfiguration; |
| }; |
| |
| // AccessorConfiguration translates into calls to SetAccessorProperty() |
| // on prototype ObjectTemplate. |
| struct AccessorConfiguration { |
| const char* const name; |
| v8::FunctionCallback getter; |
| v8::FunctionCallback setter; |
| v8::FunctionCallback getterForMainWorld; |
| v8::FunctionCallback setterForMainWorld; |
| const WrapperTypeInfo* data; |
| v8::AccessControl settings; |
| v8::PropertyAttribute attribute; |
| ExposeConfiguration exposeConfiguration; |
| }; |
| |
| static void installAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const AttributeConfiguration*, size_t attributeCount, v8::Isolate*); |
| |
| template<class ObjectOrTemplate> |
| static inline void installAttribute(v8::Handle<ObjectOrTemplate> instanceTemplate, v8::Handle<ObjectOrTemplate> prototype, const AttributeConfiguration& attribute, v8::Isolate* isolate) |
| { |
| DOMWrapperWorld& world = DOMWrapperWorld::current(isolate); |
| if (attribute.exposeConfiguration == OnlyExposedToPrivateScript && !world.isPrivateScriptIsolatedWorld()) |
| return; |
| |
| v8::AccessorGetterCallback getter = attribute.getter; |
| v8::AccessorSetterCallback setter = attribute.setter; |
| if (world.isMainWorld()) { |
| if (attribute.getterForMainWorld) |
| getter = attribute.getterForMainWorld; |
| if (attribute.setterForMainWorld) |
| setter = attribute.setterForMainWorld; |
| } |
| (attribute.instanceOrPrototypeConfiguration == OnPrototype ? prototype : instanceTemplate)->SetAccessor(v8AtomicString(isolate, attribute.name), |
| getter, |
| setter, |
| v8::External::New(isolate, const_cast<WrapperTypeInfo*>(attribute.data)), |
| attribute.settings, |
| attribute.attribute); |
| } |
| |
| enum ConstantType { |
| ConstantTypeShort, |
| ConstantTypeLong, |
| ConstantTypeUnsignedShort, |
| ConstantTypeUnsignedLong, |
| ConstantTypeFloat, |
| ConstantTypeDouble, |
| ConstantTypeString |
| }; |
| |
| // ConstantConfiguration translates into calls to Set() for setting up an |
| // object's constants. It sets the constant on both the FunctionTemplate and |
| // the ObjectTemplate. PropertyAttributes is always ReadOnly. |
| struct ConstantConfiguration { |
| const char* const name; |
| int ivalue; |
| double dvalue; |
| const char* const svalue; |
| ConstantType type; |
| }; |
| |
| static void installConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const ConstantConfiguration*, size_t constantCount, v8::Isolate*); |
| static void installConstant(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const char* name, v8::AccessorGetterCallback, v8::Isolate*); |
| |
| // MethodConfiguration translates into calls to Set() for setting up an |
| // object's callbacks. It sets the method on both the FunctionTemplate or |
| // the ObjectTemplate. |
| struct MethodConfiguration { |
| v8::Local<v8::Name> methodName(v8::Isolate* isolate) const { return v8AtomicString(isolate, name); } |
| v8::FunctionCallback callbackForWorld(const DOMWrapperWorld& world) const |
| { |
| return world.isMainWorld() && callbackForMainWorld ? callbackForMainWorld : callback; |
| } |
| |
| const char* const name; |
| v8::FunctionCallback callback; |
| v8::FunctionCallback callbackForMainWorld; |
| int length; |
| ExposeConfiguration exposeConfiguration; |
| }; |
| |
| struct SymbolKeyedMethodConfiguration { |
| v8::Local<v8::Name> methodName(v8::Isolate* isolate) const { return getSymbol(isolate); } |
| v8::FunctionCallback callbackForWorld(const DOMWrapperWorld&) const |
| { |
| return callback; |
| } |
| |
| v8::Local<v8::Symbol> (*getSymbol)(v8::Isolate*); |
| v8::FunctionCallback callback; |
| // SymbolKeyedMethodConfiguration doesn't support per-world bindings. |
| int length; |
| ExposeConfiguration exposeConfiguration; |
| }; |
| |
| static void installMethods(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, v8::PropertyAttribute, const MethodConfiguration*, size_t callbackCount, v8::Isolate*); |
| |
| template <class ObjectOrTemplate, class Configuration> |
| static void installMethod(v8::Handle<ObjectOrTemplate> objectOrTemplate, v8::Handle<v8::Signature> signature, v8::PropertyAttribute attribute, const Configuration& callback, v8::Isolate* isolate) |
| { |
| DOMWrapperWorld& world = DOMWrapperWorld::current(isolate); |
| if (callback.exposeConfiguration == OnlyExposedToPrivateScript && !world.isPrivateScriptIsolatedWorld()) |
| return; |
| |
| v8::Local<v8::FunctionTemplate> functionTemplate = functionTemplateForCallback(isolate, signature, callback.callbackForWorld(world), callback.length); |
| setMethod(objectOrTemplate, callback.methodName(isolate), functionTemplate, attribute); |
| } |
| |
| static void installAccessors(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, const AccessorConfiguration*, size_t accessorCount, v8::Isolate*); |
| |
| static v8::Local<v8::Signature> installDOMClassTemplate(v8::Handle<v8::FunctionTemplate>, const char* interfaceName, v8::Handle<v8::FunctionTemplate> parentClass, size_t fieldCount, |
| const AttributeConfiguration*, size_t attributeCount, |
| const AccessorConfiguration*, size_t accessorCount, |
| const MethodConfiguration*, size_t callbackCount, |
| v8::Isolate*); |
| |
| static v8::Handle<v8::FunctionTemplate> domClassTemplate(v8::Isolate*, WrapperTypeInfo*, void (*)(v8::Handle<v8::FunctionTemplate>, v8::Isolate*)); |
| |
| private: |
| static void setMethod(v8::Handle<v8::Object> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) |
| { |
| target->Set(name, functionTemplate->GetFunction()); |
| } |
| static void setMethod(v8::Handle<v8::FunctionTemplate> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) |
| { |
| target->Set(name, functionTemplate, attribute); |
| } |
| static void setMethod(v8::Handle<v8::ObjectTemplate> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) |
| { |
| target->Set(name, functionTemplate, attribute); |
| } |
| |
| static v8::Handle<v8::FunctionTemplate> functionTemplateForCallback(v8::Isolate*, v8::Handle<v8::Signature>, v8::FunctionCallback, int length); |
| }; |
| |
| } // namespace blink |
| |
| #endif // V8DOMConfiguration_h |