Changeset 49510 in webkit
- Timestamp:
- Oct 13, 2009 2:44:38 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r49508 r49510 1 2009-10-13 Drew Wilson <atwilson@atwilson-macpro.local> 2 3 Reviewed by Dimitri Glazkov. 4 5 window attributes (like localStorage) that are disabled at runtime are still visible 6 https://bugs.webkit.org/show_bug.cgi?id=30240 7 8 Adding codegen/bindings to support runtime disabling of attributes. 9 10 No new tests (only supported by chrome currently) 11 12 * bindings/scripts/CodeGeneratorV8.pm: 13 Refactored the guts of GenerateBatchedAttributeData into a separate GenerateSingleBatchedAttribute with a passed-in indentation level to allow generating a single BatchedAttribute struct. 14 Added support for the EnabledAtRuntime extended attribute, which generates a call to the appropriate XXXXEnabled() API before adding the attribute to the instance. 15 * bindings/v8/V8Proxy.cpp: 16 (WebCore::batchConfigureAttributes): 17 Refactored attribute setting code into a common inline routine. 18 * bindings/v8/V8Proxy.h: 19 (WebCore::configureAttribute): 20 Inline function which configures a single attribute given a BatchedAttribute struct. 21 * bindings/v8/custom/V8CustomBinding.h: 22 Added (DECLARE_)ACCESSOR_RUNTIME_ENABLER to allow enabling attributes at runtime. 23 * bindings/v8/custom/V8DOMWindowCustom.cpp: 24 Added code to enable window.Audio only if MediaPlayer.isAvailable() == true 25 * page/DOMWindow.idl: 26 Added [EnabledAtRuntime] extended attribute to the Audio attribute. 27 1 28 2009-10-13 Michelangelo De Simone <micdesim@gmail.com> 2 29 -
trunk/WebCore/bindings/scripts/CodeGeneratorV8.pm
r49432 r49510 949 949 950 950 foreach my $attribute (@$attributes) { 951 my $attrName = $attribute->signature->name;952 my $attrExt = $attribute->signature->extendedAttributes;953 954 my $accessControl = "v8::DEFAULT";955 if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {956 $accessControl = "v8::ALL_CAN_READ";957 } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {958 $accessControl = "v8::ALL_CAN_WRITE";959 } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {960 $accessControl = "v8::ALL_CAN_READ";961 if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {962 $accessControl .= "|v8::ALL_CAN_WRITE";963 }964 }965 if ($attrExt->{"V8DisallowShadowing"}) {966 $accessControl .= "|v8::PROHIBITS_OVERWRITING";967 }968 $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";969 970 my $customAccessor =971 $attrExt->{"Custom"} ||972 $attrExt->{"CustomSetter"} ||973 $attrExt->{"CustomGetter"} ||974 $attrExt->{"V8Custom"} ||975 $attrExt->{"V8CustomSetter"} ||976 $attrExt->{"V8CustomGetter"} ||977 "";978 if ($customAccessor eq 1) {979 # use the naming convension, interface + (capitalize) attr name980 $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName);981 }982 983 my $getter;984 my $setter;985 my $propAttr = "v8::None";986 my $hasCustomSetter = 0;987 988 # Check attributes.989 if ($attrExt->{"DontEnum"}) {990 $propAttr .= "|v8::DontEnum";991 }992 if ($attrExt->{"V8DisallowShadowing"}) {993 $propAttr .= "|v8::DontDelete";994 }995 996 my $on_proto = "0 /* on instance */";997 my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";998 999 # Constructor1000 if ($attribute->signature->type =~ /Constructor$/) {1001 my $constructorType = $codeGenerator->StripModule($attribute->signature->type);1002 $constructorType =~ s/Constructor$//;1003 my $constructorIndex = uc($constructorType);1004 if ($customAccessor) {1005 $getter = "V8Custom::v8${customAccessor}AccessorGetter";1006 } else {1007 $data = "V8ClassIndex::${constructorIndex}";1008 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";1009 }1010 $setter = "0";1011 $propAttr = "v8::ReadOnly";1012 1013 } else {1014 # Default Getter and Setter1015 $getter = "${interfaceName}Internal::${attrName}AttrGetter";1016 $setter = "${interfaceName}Internal::${attrName}AttrSetter";1017 1018 # Custom Setter1019 if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {1020 $hasCustomSetter = 1;1021 $setter = "V8Custom::v8${customAccessor}AccessorSetter";1022 }1023 1024 # Custom Getter1025 if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {1026 $getter = "V8Custom::v8${customAccessor}AccessorGetter";1027 }1028 }1029 1030 # Replaceable1031 if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {1032 $setter = "0";1033 # Handle the special case of window.top being marked as Replaceable.1034 # FIXME: Investigate whether we could treat window.top as replaceable1035 # and allow shadowing without it being a security hole.1036 if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {1037 $propAttr .= "|v8::ReadOnly";1038 }1039 }1040 1041 # Read only attributes1042 if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {1043 $setter = "0";1044 }1045 1046 # An accessor can be installed on the proto1047 if ($attrExt->{"v8OnProto"}) {1048 $on_proto = "1 /* on proto */";1049 }1050 1051 my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .1052 "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";1053 1054 951 my $conditionalString = GenerateConditionalString($attribute->signature); 1055 952 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString; 1056 1057 push(@implContent, <<END); 1058 // $commentInfo 1059 { "$attrName", 1060 $getter, 1061 $setter, 1062 $data, 1063 $accessControl, 1064 static_cast<v8::PropertyAttribute>($propAttr), 1065 $on_proto }, 1066 END 953 GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", ""); 1067 954 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString; 1068 955 } 1069 956 } 1070 957 958 sub GenerateSingleBatchedAttribute 959 { 960 my $interfaceName = shift; 961 my $attribute = shift; 962 my $delimiter = shift; 963 my $indent = shift; 964 my $attrName = $attribute->signature->name; 965 my $attrExt = $attribute->signature->extendedAttributes; 966 967 my $accessControl = "v8::DEFAULT"; 968 if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) { 969 $accessControl = "v8::ALL_CAN_READ"; 970 } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) { 971 $accessControl = "v8::ALL_CAN_WRITE"; 972 } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) { 973 $accessControl = "v8::ALL_CAN_READ"; 974 if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) { 975 $accessControl .= "|v8::ALL_CAN_WRITE"; 976 } 977 } 978 if ($attrExt->{"V8DisallowShadowing"}) { 979 $accessControl .= "|v8::PROHIBITS_OVERWRITING"; 980 } 981 $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")"; 982 983 my $customAccessor = 984 $attrExt->{"Custom"} || 985 $attrExt->{"CustomSetter"} || 986 $attrExt->{"CustomGetter"} || 987 $attrExt->{"V8Custom"} || 988 $attrExt->{"V8CustomSetter"} || 989 $attrExt->{"V8CustomGetter"} || 990 ""; 991 if ($customAccessor eq 1) { 992 # use the naming convension, interface + (capitalize) attr name 993 $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName); 994 } 995 996 my $getter; 997 my $setter; 998 my $propAttr = "v8::None"; 999 my $hasCustomSetter = 0; 1000 1001 # Check attributes. 1002 if ($attrExt->{"DontEnum"}) { 1003 $propAttr .= "|v8::DontEnum"; 1004 } 1005 if ($attrExt->{"V8DisallowShadowing"}) { 1006 $propAttr .= "|v8::DontDelete"; 1007 } 1008 1009 my $on_proto = "0 /* on instance */"; 1010 my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */"; 1011 1012 # Constructor 1013 if ($attribute->signature->type =~ /Constructor$/) { 1014 my $constructorType = $codeGenerator->StripModule($attribute->signature->type); 1015 $constructorType =~ s/Constructor$//; 1016 my $constructorIndex = uc($constructorType); 1017 if ($customAccessor) { 1018 $getter = "V8Custom::v8${customAccessor}AccessorGetter"; 1019 } else { 1020 $data = "V8ClassIndex::${constructorIndex}"; 1021 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter"; 1022 } 1023 $setter = "0"; 1024 $propAttr = "v8::ReadOnly"; 1025 1026 } else { 1027 # Default Getter and Setter 1028 $getter = "${interfaceName}Internal::${attrName}AttrGetter"; 1029 $setter = "${interfaceName}Internal::${attrName}AttrSetter"; 1030 1031 # Custom Setter 1032 if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { 1033 $hasCustomSetter = 1; 1034 $setter = "V8Custom::v8${customAccessor}AccessorSetter"; 1035 } 1036 1037 # Custom Getter 1038 if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) { 1039 $getter = "V8Custom::v8${customAccessor}AccessorGetter"; 1040 } 1041 } 1042 1043 # Replaceable 1044 if ($attrExt->{"Replaceable"} && !$hasCustomSetter) { 1045 $setter = "0"; 1046 # Handle the special case of window.top being marked as Replaceable. 1047 # FIXME: Investigate whether we could treat window.top as replaceable 1048 # and allow shadowing without it being a security hole. 1049 if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) { 1050 $propAttr .= "|v8::ReadOnly"; 1051 } 1052 } 1053 1054 # Read only attributes 1055 if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) { 1056 $setter = "0"; 1057 } 1058 1059 # An accessor can be installed on the proto 1060 if ($attrExt->{"v8OnProto"}) { 1061 $on_proto = "1 /* on proto */"; 1062 } 1063 1064 my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type . 1065 "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')"; 1066 1067 push(@implContent, $indent . " {\n"); 1068 push(@implContent, $indent . " \/\/ $commentInfo\n"); 1069 push(@implContent, $indent . " \"$attrName\",\n"); 1070 push(@implContent, $indent . " $getter,\n"); 1071 push(@implContent, $indent . " $setter,\n"); 1072 push(@implContent, $indent . " $data,\n"); 1073 push(@implContent, $indent . " $accessControl,\n"); 1074 push(@implContent, $indent . " static_cast<v8::PropertyAttribute>($propAttr),\n"); 1075 push(@implContent, $indent . " $on_proto\n"); 1076 push(@implContent, $indent . " }" . $delimiter . "\n"); 1077 END 1078 } 1071 1079 1072 1080 sub GenerateImplementation … … 1181 1189 # For the DOMWindow interface we partition the attributes into the 1182 1190 # ones that disallows shadowing and the rest. 1183 my @disallows_shadowing; 1191 my @disallowsShadowing; 1192 # Also separate out attributes that are enabled at runtime so we can process them specially. 1193 my @enabledAtRuntime; 1184 1194 my @normal; 1185 if ($interfaceName eq "DOMWindow") { 1186 foreach my $attribute (@$attributes) { 1187 if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) { 1188 push(@disallows_shadowing, $attribute); 1189 } else { 1190 push(@normal, $attribute); 1191 } 1192 } 1193 # Put the attributes that disallow shadowing on the shadow object. 1194 $attributes = \@normal; 1195 foreach my $attribute (@$attributes) { 1196 if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) { 1197 push(@disallowsShadowing, $attribute); 1198 } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) { 1199 push(@enabledAtRuntime, $attribute); 1200 } else { 1201 push(@normal, $attribute); 1202 } 1203 } 1204 $attributes = \@normal; 1205 # Put the attributes that disallow shadowing on the shadow object. 1206 if (@disallowsShadowing) { 1195 1207 push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n"); 1196 GenerateBatchedAttributeData($dataNode, \@disallows _shadowing);1208 GenerateBatchedAttributeData($dataNode, \@disallowsShadowing); 1197 1209 push(@implContent, "};\n"); 1198 1210 } … … 1274 1286 batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs)); 1275 1287 END 1288 } 1289 1290 # Setup the enable-at-runtime attrs if we have them 1291 foreach my $runtime_attr (@enabledAtRuntime) { 1292 $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($runtime_attr->signature->name); 1293 my $conditionalString = GenerateConditionalString($runtime_attr->signature); 1294 push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString; 1295 push(@implContent, " if (V8Custom::v8${enable_function}Enabled()) {\n"); 1296 push(@implContent, " static const BatchedAttribute attrData =\\\n"); 1297 GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", " "); 1298 push(@implContent, <<END); 1299 configureAttribute(instance, proto, attrData); 1300 } 1301 END 1302 push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString; 1276 1303 } 1277 1304 -
trunk/WebCore/bindings/v8/V8Proxy.cpp
r49278 r49510 73 73 void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount) 74 74 { 75 for (size_t i = 0; i < attributeCount; ++i) { 76 const BatchedAttribute* attribute = &attributes[i]; 77 (attribute->onProto ? proto : instance)->SetAccessor(v8::String::New(attribute->name), 78 attribute->getter, 79 attribute->setter, 80 attribute->data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute->data)), 81 attribute->settings, 82 attribute->attribute); 83 } 75 for (size_t i = 0; i < attributeCount; ++i) 76 configureAttribute(instance, proto, attributes[i]); 84 77 } 85 78 -
trunk/WebCore/bindings/v8/V8Proxy.h
r49278 r49510 83 83 void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount); 84 84 85 inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute) 86 { 87 (attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name), 88 attribute.getter, 89 attribute.setter, 90 attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)), 91 attribute.settings, 92 attribute.attribute); 93 } 94 85 95 // BatchedConstant translates into calls to Set() for setting up an object's 86 96 // constants. It sets the constant on both the FunctionTemplate and the -
trunk/WebCore/bindings/v8/custom/V8CustomBinding.h
r49488 r49510 79 79 uint32_t index, v8::AccessType type, v8::Local<v8::Value> data) 80 80 81 #define ACCESSOR_RUNTIME_ENABLER(NAME) bool V8Custom::v8##NAME##Enabled() 82 81 83 namespace WebCore { 82 84 … … 233 235 uint32_t index, v8::AccessType type, v8::Local<v8::Value> data) 234 236 237 #define DECLARE_ACCESSOR_RUNTIME_ENABLER(NAME) static bool v8##NAME##Enabled() 238 235 239 DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle); 236 240 DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle); … … 242 246 #if ENABLE(VIDEO) 243 247 DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowAudio); 248 DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio); 244 249 #endif 245 250 -
trunk/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
r49248 r49510 46 46 #include "FrameView.h" 47 47 #include "HTMLCollection.h" 48 #include "MediaPlayer.h" 48 49 #include "Page.h" 49 50 #include "PlatformScreen.h" … … 234 235 DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder()); 235 236 return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window); 237 } 238 239 ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio) 240 { 241 return MediaPlayer::isAvailable(); 236 242 } 237 243 -
trunk/WebCore/page/DOMWindow.idl
r49400 r49510 524 524 #endif 525 525 526 attribute [CustomGetter,Conditional=VIDEO ] HTMLAudioElementConstructor Audio; // Usable with the new operator526 attribute [CustomGetter,Conditional=VIDEO,EnabledAtRuntime] HTMLAudioElementConstructor Audio; // Usable with the new operator 527 527 attribute [Conditional=VIDEO] HTMLAudioElementConstructor HTMLAudioElement; 528 528 attribute [Conditional=VIDEO] HTMLMediaElementConstructor HTMLMediaElement;
Note: See TracChangeset
for help on using the changeset viewer.