1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef V8DOMConfiguration_h 30 #define V8DOMConfiguration_h 31 32 #include "bindings/core/v8/V8Binding.h" 33 #include "bindings/core/v8/V8DOMWrapper.h" 34 #include <v8.h> 35 36 namespace blink { 37 38 class V8DOMConfiguration { 39 public: 40 // The following Configuration structs and install methods are used for 41 // setting multiple properties on an ObjectTemplate, used from the 42 // generated bindings initialization (ConfigureXXXTemplate). This greatly 43 // reduces the binary size by moving from code driven setup to data table 44 // driven setup. 45 46 enum ExposeConfiguration { 47 ExposedToAllScripts, 48 OnlyExposedToPrivateScript, 49 }; 50 51 enum InstanceOrPrototypeConfiguration { 52 OnInstance, 53 OnPrototype, 54 }; 55 56 // AttributeConfiguration translates into calls to SetAccessor() on either 57 // the instance or the prototype ObjectTemplate, based on |instanceOrPrototypeConfiguration|. 58 struct AttributeConfiguration { 59 const char* const name; 60 v8::AccessorGetterCallback getter; 61 v8::AccessorSetterCallback setter; 62 v8::AccessorGetterCallback getterForMainWorld; 63 v8::AccessorSetterCallback setterForMainWorld; 64 const WrapperTypeInfo* data; 65 v8::AccessControl settings; 66 v8::PropertyAttribute attribute; 67 ExposeConfiguration exposeConfiguration; 68 InstanceOrPrototypeConfiguration instanceOrPrototypeConfiguration; 69 }; 70 71 // AccessorConfiguration translates into calls to SetAccessorProperty() 72 // on prototype ObjectTemplate. 73 struct AccessorConfiguration { 74 const char* const name; 75 v8::FunctionCallback getter; 76 v8::FunctionCallback setter; 77 v8::FunctionCallback getterForMainWorld; 78 v8::FunctionCallback setterForMainWorld; 79 const WrapperTypeInfo* data; 80 v8::AccessControl settings; 81 v8::PropertyAttribute attribute; 82 ExposeConfiguration exposeConfiguration; 83 }; 84 85 static void installAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const AttributeConfiguration*, size_t attributeCount, v8::Isolate*); 86 87 template<class ObjectOrTemplate> installAttribute(v8::Handle<ObjectOrTemplate> instanceTemplate,v8::Handle<ObjectOrTemplate> prototype,const AttributeConfiguration & attribute,v8::Isolate * isolate)88 static inline void installAttribute(v8::Handle<ObjectOrTemplate> instanceTemplate, v8::Handle<ObjectOrTemplate> prototype, const AttributeConfiguration& attribute, v8::Isolate* isolate) 89 { 90 DOMWrapperWorld& world = DOMWrapperWorld::current(isolate); 91 if (attribute.exposeConfiguration == OnlyExposedToPrivateScript && !world.isPrivateScriptIsolatedWorld()) 92 return; 93 94 v8::AccessorGetterCallback getter = attribute.getter; 95 v8::AccessorSetterCallback setter = attribute.setter; 96 if (world.isMainWorld()) { 97 if (attribute.getterForMainWorld) 98 getter = attribute.getterForMainWorld; 99 if (attribute.setterForMainWorld) 100 setter = attribute.setterForMainWorld; 101 } 102 (attribute.instanceOrPrototypeConfiguration == OnPrototype ? prototype : instanceTemplate)->SetAccessor(v8AtomicString(isolate, attribute.name), 103 getter, 104 setter, 105 v8::External::New(isolate, const_cast<WrapperTypeInfo*>(attribute.data)), 106 attribute.settings, 107 attribute.attribute); 108 } 109 110 enum ConstantType { 111 ConstantTypeShort, 112 ConstantTypeLong, 113 ConstantTypeUnsignedShort, 114 ConstantTypeUnsignedLong, 115 ConstantTypeFloat, 116 ConstantTypeDouble, 117 ConstantTypeString 118 }; 119 120 // ConstantConfiguration translates into calls to Set() for setting up an 121 // object's constants. It sets the constant on both the FunctionTemplate and 122 // the ObjectTemplate. PropertyAttributes is always ReadOnly. 123 struct ConstantConfiguration { 124 const char* const name; 125 int ivalue; 126 double dvalue; 127 const char* const svalue; 128 ConstantType type; 129 }; 130 131 static void installConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const ConstantConfiguration*, size_t constantCount, v8::Isolate*); 132 static void installConstant(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const char* name, v8::AccessorGetterCallback, v8::Isolate*); 133 134 // MethodConfiguration translates into calls to Set() for setting up an 135 // object's callbacks. It sets the method on both the FunctionTemplate or 136 // the ObjectTemplate. 137 struct MethodConfiguration { methodNameMethodConfiguration138 v8::Local<v8::Name> methodName(v8::Isolate* isolate) const { return v8AtomicString(isolate, name); } callbackForWorldMethodConfiguration139 v8::FunctionCallback callbackForWorld(const DOMWrapperWorld& world) const 140 { 141 return world.isMainWorld() && callbackForMainWorld ? callbackForMainWorld : callback; 142 } 143 144 const char* const name; 145 v8::FunctionCallback callback; 146 v8::FunctionCallback callbackForMainWorld; 147 int length; 148 ExposeConfiguration exposeConfiguration; 149 }; 150 151 struct SymbolKeyedMethodConfiguration { methodNameSymbolKeyedMethodConfiguration152 v8::Local<v8::Name> methodName(v8::Isolate* isolate) const { return getSymbol(isolate); } callbackForWorldSymbolKeyedMethodConfiguration153 v8::FunctionCallback callbackForWorld(const DOMWrapperWorld&) const 154 { 155 return callback; 156 } 157 158 v8::Local<v8::Symbol> (*getSymbol)(v8::Isolate*); 159 v8::FunctionCallback callback; 160 // SymbolKeyedMethodConfiguration doesn't support per-world bindings. 161 int length; 162 ExposeConfiguration exposeConfiguration; 163 }; 164 165 static void installMethods(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, v8::PropertyAttribute, const MethodConfiguration*, size_t callbackCount, v8::Isolate*); 166 167 template <class ObjectOrTemplate, class Configuration> installMethod(v8::Handle<ObjectOrTemplate> objectOrTemplate,v8::Handle<v8::Signature> signature,v8::PropertyAttribute attribute,const Configuration & callback,v8::Isolate * isolate)168 static void installMethod(v8::Handle<ObjectOrTemplate> objectOrTemplate, v8::Handle<v8::Signature> signature, v8::PropertyAttribute attribute, const Configuration& callback, v8::Isolate* isolate) 169 { 170 DOMWrapperWorld& world = DOMWrapperWorld::current(isolate); 171 if (callback.exposeConfiguration == OnlyExposedToPrivateScript && !world.isPrivateScriptIsolatedWorld()) 172 return; 173 174 v8::Local<v8::FunctionTemplate> functionTemplate = functionTemplateForCallback(signature, callback.callbackForWorld(world), callback.length, isolate); 175 setMethod(objectOrTemplate, callback.methodName(isolate), functionTemplate, attribute); 176 } 177 178 static void installAccessors(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Signature>, const AccessorConfiguration*, size_t accessorCount, v8::Isolate*); 179 180 static v8::Local<v8::Signature> installDOMClassTemplate(v8::Handle<v8::FunctionTemplate>, const char* interfaceName, v8::Handle<v8::FunctionTemplate> parentClass, size_t fieldCount, 181 const AttributeConfiguration*, size_t attributeCount, 182 const AccessorConfiguration*, size_t accessorCount, 183 const MethodConfiguration*, size_t callbackCount, 184 v8::Isolate*); 185 186 static v8::Handle<v8::FunctionTemplate> domClassTemplate(v8::Isolate*, WrapperTypeInfo*, void (*)(v8::Handle<v8::FunctionTemplate>, v8::Isolate*)); 187 188 private: setMethod(v8::Handle<v8::Object> target,v8::Handle<v8::Name> name,v8::Handle<v8::FunctionTemplate> functionTemplate,v8::PropertyAttribute attribute)189 static void setMethod(v8::Handle<v8::Object> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) 190 { 191 target->Set(name, functionTemplate->GetFunction()); 192 } setMethod(v8::Handle<v8::FunctionTemplate> target,v8::Handle<v8::Name> name,v8::Handle<v8::FunctionTemplate> functionTemplate,v8::PropertyAttribute attribute)193 static void setMethod(v8::Handle<v8::FunctionTemplate> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) 194 { 195 target->Set(name, functionTemplate, attribute); 196 } setMethod(v8::Handle<v8::ObjectTemplate> target,v8::Handle<v8::Name> name,v8::Handle<v8::FunctionTemplate> functionTemplate,v8::PropertyAttribute attribute)197 static void setMethod(v8::Handle<v8::ObjectTemplate> target, v8::Handle<v8::Name> name, v8::Handle<v8::FunctionTemplate> functionTemplate, v8::PropertyAttribute attribute) 198 { 199 target->Set(name, functionTemplate, attribute); 200 } 201 202 static v8::Handle<v8::FunctionTemplate> functionTemplateForCallback(v8::Handle<v8::Signature>, v8::FunctionCallback, int length, v8::Isolate*); 203 }; 204 205 } // namespace blink 206 207 #endif // V8DOMConfiguration_h 208