| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 """This module provides shared functionality for the systems to generate | 6 """This module provides shared functionality for the systems to generate |
| 7 native binding from the IDL database.""" | 7 native binding from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 import os | 10 import os |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 emitter = \ | 238 emitter = \ |
| 239 library_emitter.Emit(template, | 239 library_emitter.Emit(template, |
| 240 AUXILIARY_DIR=massage_path(auxiliary_dir)) | 240 AUXILIARY_DIR=massage_path(auxiliary_dir)) |
| 241 return emitter | 241 return emitter |
| 242 | 242 |
| 243 class DartiumBackend(HtmlDartGenerator): | 243 class DartiumBackend(HtmlDartGenerator): |
| 244 """Generates Dart implementation for one DOM IDL interface.""" | 244 """Generates Dart implementation for one DOM IDL interface.""" |
| 245 | 245 |
| 246 def __init__(self, interface, native_library_emitter, | 246 def __init__(self, interface, native_library_emitter, |
| 247 cpp_library_emitter, options, dart_use_blink): | 247 cpp_library_emitter, options, dart_use_blink): |
| 248 super(DartiumBackend, self).__init__(interface, options) | 248 super(DartiumBackend, self).__init__(interface, options, dart_use_blink) |
| 249 | 249 |
| 250 self._interface = interface | 250 self._interface = interface |
| 251 self._cpp_library_emitter = cpp_library_emitter | 251 self._cpp_library_emitter = cpp_library_emitter |
| 252 self._native_library_emitter = native_library_emitter | 252 self._native_library_emitter = native_library_emitter |
| 253 self._database = options.database | 253 self._database = options.database |
| 254 self._template_loader = options.templates | 254 self._template_loader = options.templates |
| 255 self._type_registry = options.type_registry | 255 self._type_registry = options.type_registry |
| 256 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) | 256 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) |
| 257 self._metadata = options.metadata | 257 self._metadata = options.metadata |
| 258 self._native_library_name = "_blink" | 258 self._native_library_name = "_blink" |
| 259 # This goes away after the Chrome 35 roll (or whenever we commit to the | |
| 260 # dart:blink refactor) | |
| 261 self._dart_use_blink = dart_use_blink | |
| 262 # These get initialized by StartInterface | 259 # These get initialized by StartInterface |
| 263 self._cpp_header_emitter = None | 260 self._cpp_header_emitter = None |
| 264 self._cpp_impl_emitter = None | 261 self._cpp_impl_emitter = None |
| 265 self._members_emitter = None | 262 self._members_emitter = None |
| 266 self._cpp_declarations_emitter = None | 263 self._cpp_declarations_emitter = None |
| 267 self._cpp_impl_includes = None | 264 self._cpp_impl_includes = None |
| 268 self._cpp_definitions_emitter = None | 265 self._cpp_definitions_emitter = None |
| 269 self._cpp_resolver_emitter = None | 266 self._cpp_resolver_emitter = None |
| 270 | 267 |
| 271 def ImplementsMergedMembers(self): | 268 def ImplementsMergedMembers(self): |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 self._cpp_definitions_emitter.Emit( | 440 self._cpp_definitions_emitter.Emit( |
| 444 '\n' | 441 '\n' |
| 445 'static void constructorCallback(Dart_NativeArguments args)\n' | 442 'static void constructorCallback(Dart_NativeArguments args)\n' |
| 446 '{\n' | 443 '{\n' |
| 447 ' WebCore::DartArrayBufferViewInternal::constructWebGLArray<Dart$(INT
ERFACE_NAME)>(args);\n' | 444 ' WebCore::DartArrayBufferViewInternal::constructWebGLArray<Dart$(INT
ERFACE_NAME)>(args);\n' |
| 448 '}\n', | 445 '}\n', |
| 449 INTERFACE_NAME=self._interface.id); | 446 INTERFACE_NAME=self._interface.id); |
| 450 | 447 |
| 451 def _EmitConstructorInfrastructure(self, | 448 def _EmitConstructorInfrastructure(self, |
| 452 constructor_info, constructor_callback_cpp_name, factory_method_name, | 449 constructor_info, constructor_callback_cpp_name, factory_method_name, |
| 453 argument_count=None): | 450 argument_count=None, emit_to_native=False): |
| 454 constructor_callback_id = self._interface.id + '_' + constructor_callback_cp
p_name | 451 constructor_callback_id = self._interface.id + '_' + constructor_callback_cp
p_name |
| 455 if argument_count is None: | 452 if argument_count is None: |
| 456 argument_count = len(constructor_info.param_infos) | 453 argument_count = len(constructor_info.param_infos) |
| 457 | 454 |
| 458 typed_formals = constructor_info.ParametersAsArgumentList(argument_count) | 455 typed_formals = constructor_info.ParametersAsArgumentList(argument_count) |
| 459 parameters = constructor_info.ParametersAsStringOfVariables(argument_count) | 456 parameters = constructor_info.ParametersAsStringOfVariables(argument_count) |
| 460 interface_name = self._interface_type_info.interface_name() | 457 interface_name = self._interface_type_info.interface_name() |
| 461 | 458 |
| 462 if self._dart_use_blink: | 459 if self._dart_use_blink: |
| 463 # First we emit the toplevel function | 460 # First we emit the toplevel function |
| 464 dart_native_name = \ | 461 dart_native_name = \ |
| 465 DeriveNativeName(self._interface.id, constructor_callback_cpp_name,
"") | 462 DeriveNativeName(self._interface.id, constructor_callback_cpp_name,
"") |
| 466 self._native_library_emitter.Emit( | 463 self._native_library_emitter.Emit( |
| 467 '\n' | 464 '\n' |
| 468 '$FACTORY_METHOD_NAME($PARAMETERS) native "$ID";\n', | 465 '$FACTORY_METHOD_NAME($PARAMETERS) native "$ID";\n', |
| 469 FACTORY_METHOD_NAME=dart_native_name, | 466 FACTORY_METHOD_NAME=dart_native_name, |
| 470 PARAMETERS=parameters, | 467 PARAMETERS=parameters, |
| 471 ID=constructor_callback_id) | 468 ID=constructor_callback_id) |
| 472 | 469 |
| 473 # Then we emit the impedance matching wrapper to call out to the | 470 # Then we emit the impedance matching wrapper to call out to the |
| 474 # toplevel wrapper | 471 # toplevel wrapper |
| 475 self._members_emitter.Emit( | 472 if not emit_to_native: |
| 476 '\n @DocsEditable()\n' | 473 self._members_emitter.Emit( |
| 477 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => ' | 474 '\n @DocsEditable()\n' |
| 478 '$TOPLEVEL_NAME($OUTPARAMETERS);\n', | 475 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => ' |
| 479 INTERFACE_NAME=self._interface_type_info.interface_name(), | 476 '$TOPLEVEL_NAME($OUTPARAMETERS);\n', |
| 480 FACTORY_METHOD_NAME=factory_method_name, | 477 INTERFACE_NAME=self._interface_type_info.interface_name(), |
| 481 PARAMETERS=typed_formals, | 478 FACTORY_METHOD_NAME=factory_method_name, |
| 482 TOPLEVEL_NAME=DeriveQualifiedName(self._native_library_name, | 479 PARAMETERS=typed_formals, |
| 483 dart_native_name), | 480 TOPLEVEL_NAME=DeriveQualifiedName(self._native_library_name, |
| 484 OUTPARAMETERS=parameters) | 481 dart_native_name), |
| 482 OUTPARAMETERS=parameters) |
| 485 else: | 483 else: |
| 486 self._members_emitter.Emit( | 484 self._members_emitter.Emit( |
| 487 '\n @DocsEditable()\n' | 485 '\n @DocsEditable()\n' |
| 488 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) ' | 486 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) ' |
| 489 'native "$ID";\n', | 487 'native "$ID";\n', |
| 490 INTERFACE_NAME=self._interface_type_info.interface_name(), | 488 INTERFACE_NAME=self._interface_type_info.interface_name(), |
| 491 FACTORY_METHOD_NAME=factory_method_name, | 489 FACTORY_METHOD_NAME=factory_method_name, |
| 492 PARAMETERS=typed_formals, | 490 PARAMETERS=typed_formals, |
| 493 ID=constructor_callback_id) | 491 ID=constructor_callback_id) |
| 494 | 492 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 524 CPP_CALLBACK=constructor_callback_cpp_name) | 522 CPP_CALLBACK=constructor_callback_cpp_name) |
| 525 | 523 |
| 526 return True | 524 return True |
| 527 | 525 |
| 528 def IsConstructorArgumentOptional(self, argument): | 526 def IsConstructorArgumentOptional(self, argument): |
| 529 return False | 527 return False |
| 530 | 528 |
| 531 def EmitStaticFactoryOverload(self, constructor_info, name, arguments): | 529 def EmitStaticFactoryOverload(self, constructor_info, name, arguments): |
| 532 constructor_callback_cpp_name = name + 'constructorCallback' | 530 constructor_callback_cpp_name = name + 'constructorCallback' |
| 533 self._EmitConstructorInfrastructure( | 531 self._EmitConstructorInfrastructure( |
| 534 constructor_info, constructor_callback_cpp_name, name, len(arguments)) | 532 constructor_info, constructor_callback_cpp_name, name, len(arguments), |
| 533 emit_to_native=self._dart_use_blink) |
| 535 | 534 |
| 536 ext_attrs = self._interface.ext_attrs | 535 ext_attrs = self._interface.ext_attrs |
| 537 | 536 |
| 538 create_function = 'create' | 537 create_function = 'create' |
| 539 if 'NamedConstructor' in ext_attrs: | 538 if 'NamedConstructor' in ext_attrs: |
| 540 create_function = 'createForJSConstructor' | 539 create_function = 'createForJSConstructor' |
| 541 function_expression = '%s::%s' % (self._interface_type_info.native_type(), c
reate_function) | 540 function_expression = '%s::%s' % (self._interface_type_info.native_type(), c
reate_function) |
| 542 self._GenerateNativeCallback( | 541 self._GenerateNativeCallback( |
| 543 constructor_callback_cpp_name, | 542 constructor_callback_cpp_name, |
| 544 False, | 543 False, |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos) | 1006 argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos) |
| 1008 native_suffix = 'Callback' | 1007 native_suffix = 'Callback' |
| 1009 auto_scope_setup = self._GenerateAutoSetupScope(info.name, native_suffix) | 1008 auto_scope_setup = self._GenerateAutoSetupScope(info.name, native_suffix) |
| 1010 cpp_callback_name = self._GenerateNativeBinding( | 1009 cpp_callback_name = self._GenerateNativeBinding( |
| 1011 info.name, argument_count, dart_declaration, | 1010 info.name, argument_count, dart_declaration, |
| 1012 info.IsStatic(), return_type, parameters, | 1011 info.IsStatic(), return_type, parameters, |
| 1013 native_suffix, is_custom, auto_scope_setup) | 1012 native_suffix, is_custom, auto_scope_setup) |
| 1014 if not is_custom: | 1013 if not is_custom: |
| 1015 self._GenerateOperationNativeCallback(operation, operation.arguments, cp
p_callback_name, auto_scope_setup) | 1014 self._GenerateOperationNativeCallback(operation, operation.arguments, cp
p_callback_name, auto_scope_setup) |
| 1016 else: | 1015 else: |
| 1017 self._GenerateDispatcher(info, info.operations, dart_declaration) | 1016 self._GenerateDispatcher(info, info.operations, dart_declaration, html_nam
e) |
| 1018 | 1017 |
| 1019 def _GenerateDispatcher(self, info, operations, dart_declaration): | 1018 def _GenerateDispatcher(self, info, operations, dart_declaration, html_name): |
| 1020 | 1019 |
| 1021 def GenerateCall( | 1020 def GenerateCall( |
| 1022 stmts_emitter, call_emitter, version, operation, argument_count): | 1021 stmts_emitter, call_emitter, version, operation, argument_count): |
| 1023 overload_name = '_%s_%s' % (operation.id, version) | 1022 native_suffix = 'Callback' |
| 1023 actuals = info.ParametersAsListOfVariables(argument_count) |
| 1024 return_type = self.SecureOutputType(operation.type.id) | 1024 return_type = self.SecureOutputType(operation.type.id) |
| 1025 actuals = info.ParametersAsListOfVariables(argument_count) | 1025 if self._dart_use_blink: |
| 1026 actuals_s = ", ".join(actuals) | 1026 base_name = '_%s_%s' % (operation.id, version) |
| 1027 overload_name = \ |
| 1028 DeriveNativeName(self._interface.id, base_name, native_suffix) |
| 1029 static = True |
| 1030 if not operation.is_static: |
| 1031 actuals = ['mthis'] + actuals |
| 1032 actuals_s = ", ".join(actuals) |
| 1033 dart_declaration = '%s(%s)' % ( |
| 1034 base_name, actuals_s) |
| 1035 else: |
| 1036 base_name = '_%s_%s' % (operation.id, version) |
| 1037 overload_name = base_name |
| 1038 static = operation.is_static |
| 1039 actuals_s = ", ".join(actuals) |
| 1040 dart_declaration = '%s%s %s(%s)' % ( |
| 1041 'static ' if static else '', |
| 1042 return_type, |
| 1043 overload_name, actuals_s) |
| 1044 |
| 1027 call_emitter.Emit('$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s) | 1045 call_emitter.Emit('$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s) |
| 1028 dart_declaration = '%s%s %s(%s)' % ( | |
| 1029 'static ' if operation.is_static else '', | |
| 1030 return_type, | |
| 1031 overload_name, actuals_s) | |
| 1032 is_custom = 'Custom' in operation.ext_attrs | 1046 is_custom = 'Custom' in operation.ext_attrs |
| 1033 native_suffix = 'Callback' | 1047 native_suffix = 'Callback' |
| 1034 auto_scope_setup = \ | 1048 auto_scope_setup = \ |
| 1035 self._GenerateAutoSetupScope(overload_name, native_suffix) | 1049 self._GenerateAutoSetupScope(base_name, native_suffix) |
| 1036 cpp_callback_name = self._GenerateNativeBinding( | 1050 cpp_callback_name = self._GenerateNativeBinding( |
| 1037 overload_name, (0 if operation.is_static else 1) + argument_count, | 1051 base_name, (0 if static else 1) + argument_count, |
| 1038 dart_declaration, operation.is_static, return_type, actuals, | 1052 dart_declaration, static, return_type, actuals, |
| 1039 'Callback', is_custom, auto_scope_setup, emit_metadata=False) | 1053 native_suffix, is_custom, auto_scope_setup, emit_metadata=False, |
| 1054 emit_to_native=self._dart_use_blink) |
| 1040 if not is_custom: | 1055 if not is_custom: |
| 1041 self._GenerateOperationNativeCallback(operation, | 1056 self._GenerateOperationNativeCallback(operation, |
| 1042 operation.arguments[:argument_count], cpp_callback_name, | 1057 operation.arguments[:argument_count], cpp_callback_name, |
| 1043 auto_scope_setup) | 1058 auto_scope_setup) |
| 1044 | 1059 |
| 1060 |
| 1061 if self._dart_use_blink: |
| 1062 name = DeriveNativeName(self._interface.id, html_name, "") |
| 1063 qual_name = DeriveQualifiedName(self._native_library_name, |
| 1064 name) |
| 1065 actuals = info.ParametersAsListOfVariables() |
| 1066 formals = info.ParametersAsListOfVariables() |
| 1067 if not info.IsStatic(): |
| 1068 formals = ['mthis'] + formals |
| 1069 actuals = ['this'] + actuals |
| 1070 actuals_s = ', '.join(actuals) |
| 1071 formals_s = ', '.join(formals) |
| 1072 self._members_emitter.Emit( |
| 1073 '\n' |
| 1074 ' $DECLARATION => $NATIVE_NAME($ACTUALS);\n', |
| 1075 DECLARATION=dart_declaration, |
| 1076 NATIVE_NAME=qual_name, |
| 1077 ACTUALS=actuals_s) |
| 1078 |
| 1079 dart_declaration = \ |
| 1080 '// Generated overload resolver\n' \ |
| 1081 '%s(%s)' % (name, formals_s) |
| 1082 |
| 1045 self._GenerateDispatcherBody( | 1083 self._GenerateDispatcherBody( |
| 1046 info, | 1084 info, |
| 1047 operations, | 1085 operations, |
| 1048 dart_declaration, | 1086 dart_declaration, |
| 1049 GenerateCall, | 1087 GenerateCall, |
| 1050 self._IsArgumentOptionalInWebCore) | 1088 self._IsArgumentOptionalInWebCore) |
| 1051 | 1089 |
| 1052 def SecondaryContext(self, interface): | 1090 def SecondaryContext(self, interface): |
| 1053 pass | 1091 pass |
| 1054 | 1092 |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1434 auto_scope_setup, | 1472 auto_scope_setup, |
| 1435 self._interface.id, | 1473 self._interface.id, |
| 1436 ext_attrs) | 1474 ext_attrs) |
| 1437 set_return_value = '%s' % (return_to_dart_conversion) | 1475 set_return_value = '%s' % (return_to_dart_conversion) |
| 1438 invocation_emitter.Emit( | 1476 invocation_emitter.Emit( |
| 1439 ' $RETURN_VALUE;\n', | 1477 ' $RETURN_VALUE;\n', |
| 1440 RETURN_VALUE=set_return_value) | 1478 RETURN_VALUE=set_return_value) |
| 1441 | 1479 |
| 1442 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, | 1480 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, |
| 1443 static, return_type, parameters, native_suffix, is_custom, | 1481 static, return_type, parameters, native_suffix, is_custom, |
| 1444 auto_scope_setup=True, emit_metadata=True): | 1482 auto_scope_setup=True, emit_metadata=True, emit_to_native=False): |
| 1445 metadata = [] | 1483 metadata = [] |
| 1446 if emit_metadata: | 1484 if emit_metadata: |
| 1447 metadata = self._metadata.GetFormattedMetadata( | 1485 metadata = self._metadata.GetFormattedMetadata( |
| 1448 self._renamer.GetLibraryName(self._interface), | 1486 self._renamer.GetLibraryName(self._interface), |
| 1449 self._interface, idl_name, ' ') | 1487 self._interface, idl_name, ' ') |
| 1450 dart_native_name = \ | 1488 dart_native_name = \ |
| 1451 DeriveNativeName(self._interface.id, idl_name, native_suffix) | 1489 DeriveNativeName(self._interface.id, idl_name, native_suffix) |
| 1452 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) | 1490 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) |
| 1453 if self._dart_use_blink: | 1491 if self._dart_use_blink: |
| 1454 if not static: | 1492 if not static: |
| 1455 formals = ", ".join(['mthis'] + parameters) | 1493 formals = ", ".join(['mthis'] + parameters) |
| 1456 actuals = ", ".join(['this'] + parameters) | 1494 actuals = ", ".join(['this'] + parameters) |
| 1457 else: | 1495 else: |
| 1458 formals = ", ".join(parameters) | 1496 formals = ", ".join(parameters) |
| 1459 actuals = ", ".join(parameters) | 1497 actuals = ", ".join(parameters) |
| 1460 | 1498 |
| 1461 self._native_library_emitter.Emit( | 1499 self._native_library_emitter.Emit( |
| 1462 '\n' | 1500 '\n' |
| 1463 '$DART_NAME($FORMALS) native "$NATIVE_BINDING";\n', | 1501 '$DART_NAME($FORMALS) native "$NATIVE_BINDING";\n', |
| 1464 DART_NAME=dart_native_name, | 1502 DART_NAME=dart_native_name, |
| 1465 FORMALS=formals, | 1503 FORMALS=formals, |
| 1466 NATIVE_BINDING=native_binding) | 1504 NATIVE_BINDING=native_binding) |
| 1467 | 1505 |
| 1468 # We then emit a class method which calls out to the mangled toplevel | 1506 if not emit_to_native: |
| 1469 # function. Eventually this will be replaced with a call to an | 1507 caller_emitter = self._members_emitter |
| 1470 # interceptor | 1508 full_dart_name = DeriveQualifiedName(self._native_library_name, |
| 1471 self._members_emitter.Emit( | 1509 dart_native_name) |
| 1472 '\n' | 1510 caller_emitter.Emit( |
| 1473 ' $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);\n', | 1511 '\n' |
| 1474 METADATA=metadata, | 1512 ' $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);\n', |
| 1475 DART_DECLARATION=dart_declaration, | 1513 METADATA=metadata, |
| 1476 DART_NAME=DeriveQualifiedName(self._native_library_name, | 1514 DART_DECLARATION=dart_declaration, |
| 1477 dart_native_name), | 1515 DART_NAME=full_dart_name, |
| 1478 ACTUALS=actuals) | 1516 ACTUALS=actuals) |
| 1479 else: | 1517 else: |
| 1480 self._members_emitter.Emit( | 1518 self._members_emitter.Emit( |
| 1481 '\n' | 1519 '\n' |
| 1482 ' $METADATA$DART_DECLARATION native "$NATIVE_BINDING";\n', | 1520 ' $METADATA$DART_DECLARATION native "$NATIVE_BINDING";\n', |
| 1483 METADATA=metadata, | 1521 METADATA=metadata, |
| 1484 DART_DECLARATION=dart_declaration, | 1522 DART_DECLARATION=dart_declaration, |
| 1485 NATIVE_BINDING=native_binding) | 1523 NATIVE_BINDING=native_binding) |
| 1486 cpp_callback_name = '%s%s' % (idl_name, native_suffix) | 1524 cpp_callback_name = '%s%s' % (idl_name, native_suffix) |
| 1487 | 1525 |
| 1488 self._cpp_resolver_emitter.Emit( | 1526 self._cpp_resolver_emitter.Emit( |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 e.Emit("};\n"); | 1782 e.Emit("};\n"); |
| 1745 e.Emit('\n'); | 1783 e.Emit('\n'); |
| 1746 e.Emit('} // namespace WebCore\n'); | 1784 e.Emit('} // namespace WebCore\n'); |
| 1747 | 1785 |
| 1748 def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument): | 1786 def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument): |
| 1749 return ( | 1787 return ( |
| 1750 interface.id.endswith('Event') and | 1788 interface.id.endswith('Event') and |
| 1751 operation.id.startswith('init') and | 1789 operation.id.startswith('init') and |
| 1752 argument.ext_attrs.get('Default') == 'Undefined' and | 1790 argument.ext_attrs.get('Default') == 'Undefined' and |
| 1753 argument.type.id == 'DOMString') | 1791 argument.type.id == 'DOMString') |
| OLD | NEW |