| 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 system to generate | 6 """This module provides shared functionality for the system to generate |
| 7 Dart:html APIs from the IDL database.""" | 7 Dart:html APIs from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 # children of merged interface are not affected by the merge. | 42 # children of merged interface are not affected by the merge. |
| 43 # As a consequence, target interface implementation and its direct children | 43 # As a consequence, target interface implementation and its direct children |
| 44 # interface implementations should implement merged attribute accessors and | 44 # interface implementations should implement merged attribute accessors and |
| 45 # operations. For example, SVGElement and Element implementation classes should | 45 # operations. For example, SVGElement and Element implementation classes should |
| 46 # implement HTMLElement.insertAdjacentElement(), HTMLElement.innerHTML, etc. | 46 # implement HTMLElement.insertAdjacentElement(), HTMLElement.innerHTML, etc. |
| 47 _merged_html_interfaces = { | 47 _merged_html_interfaces = { |
| 48 'HTMLDocument': 'Document', | 48 'HTMLDocument': 'Document', |
| 49 'HTMLElement': 'Element' | 49 'HTMLElement': 'Element' |
| 50 } | 50 } |
| 51 | 51 |
| 52 # Events without onEventName attributes in the IDL we want to support. | |
| 53 # We can automatically extract most event event names by checking for | |
| 54 # onEventName methods in the IDL but some events aren't listed so we need | |
| 55 # to manually add them here so that they are easy for users to find. | |
| 56 _html_manual_events = { | |
| 57 'Element': ['touchleave', 'touchenter', 'webkitTransitionEnd'], | |
| 58 'Window': ['DOMContentLoaded'] | |
| 59 } | |
| 60 | |
| 61 # These event names must be camel case when attaching event listeners | |
| 62 # using addEventListener even though the onEventName properties in the DOM for | |
| 63 # them are not camel case. | |
| 64 _on_attribute_to_event_name_mapping = { | |
| 65 'webkitanimationend': 'webkitAnimationEnd', | |
| 66 'webkitanimationiteration': 'webkitAnimationIteration', | |
| 67 'webkitanimationstart': 'webkitAnimationStart', | |
| 68 'webkitspeechchange': 'webkitSpeechChange', | |
| 69 'webkittransitionend': 'webkitTransitionEnd', | |
| 70 } | |
| 71 | |
| 72 # Mapping from raw event names to the pretty camelCase event names exposed as | |
| 73 # properties in dart:html. If the DOM exposes a new event name, you will need | |
| 74 # to add the lower case to camel case conversion for that event name here. | |
| 75 _html_event_names = { | |
| 76 'DOMContentLoaded': 'contentLoaded', | |
| 77 'abort': 'abort', | |
| 78 'addstream': 'addStream', | |
| 79 'addtrack': 'addTrack', | |
| 80 'audioend': 'audioEnd', | |
| 81 'audioprocess': 'audioProcess', | |
| 82 'audiostart': 'audioStart', | |
| 83 'beforecopy': 'beforeCopy', | |
| 84 'beforecut': 'beforeCut', | |
| 85 'beforepaste': 'beforePaste', | |
| 86 'beforeunload': 'beforeUnload', | |
| 87 'blocked': 'blocked', | |
| 88 'blur': 'blur', | |
| 89 'cached': 'cached', | |
| 90 'canplay': 'canPlay', | |
| 91 'canplaythrough': 'canPlayThrough', | |
| 92 'change': 'change', | |
| 93 'chargingchange': 'chargingChange', | |
| 94 'chargingtimechange': 'chargingTimeChange', | |
| 95 'checking': 'checking', | |
| 96 'click': 'click', | |
| 97 'close': 'close', | |
| 98 'complete': 'complete', | |
| 99 'connect': 'connect', | |
| 100 'connecting': 'connecting', | |
| 101 'contextmenu': 'contextMenu', | |
| 102 'copy': 'copy', | |
| 103 'cuechange': 'cueChange', | |
| 104 'cut': 'cut', | |
| 105 'dblclick': 'doubleClick', | |
| 106 'devicemotion': 'deviceMotion', | |
| 107 'deviceorientation': 'deviceOrientation', | |
| 108 'dischargingtimechange': 'dischargingTimeChange', | |
| 109 'display': 'display', | |
| 110 'downloading': 'downloading', | |
| 111 'drag': 'drag', | |
| 112 'dragend': 'dragEnd', | |
| 113 'dragenter': 'dragEnter', | |
| 114 'dragleave': 'dragLeave', | |
| 115 'dragover': 'dragOver', | |
| 116 'dragstart': 'dragStart', | |
| 117 'drop': 'drop', | |
| 118 'durationchange': 'durationChange', | |
| 119 'emptied': 'emptied', | |
| 120 'end': 'end', | |
| 121 'ended': 'ended', | |
| 122 'enter': 'enter', | |
| 123 'error': 'error', | |
| 124 'exit': 'exit', | |
| 125 'focus': 'focus', | |
| 126 'hashchange': 'hashChange', | |
| 127 'icecandidate': 'iceCandidate', | |
| 128 'icechange': 'iceChange', | |
| 129 'input': 'input', | |
| 130 'invalid': 'invalid', | |
| 131 'keydown': 'keyDown', | |
| 132 'keypress': 'keyPress', | |
| 133 'keyup': 'keyUp', | |
| 134 'levelchange': 'levelChange', | |
| 135 'load': 'load', | |
| 136 'loadeddata': 'loadedData', | |
| 137 'loadedmetadata': 'loadedMetadata', | |
| 138 'loadend': 'loadEnd', | |
| 139 'loadstart': 'loadStart', | |
| 140 'message': 'message', | |
| 141 'mousedown': 'mouseDown', | |
| 142 'mousemove': 'mouseMove', | |
| 143 'mouseout': 'mouseOut', | |
| 144 'mouseover': 'mouseOver', | |
| 145 'mouseup': 'mouseUp', | |
| 146 'mousewheel': 'mouseWheel', | |
| 147 'mute': 'mute', | |
| 148 'negotiationneeded': 'negotiationNeeded', | |
| 149 'nomatch': 'noMatch', | |
| 150 'noupdate': 'noUpdate', | |
| 151 'obsolete': 'obsolete', | |
| 152 'offline': 'offline', | |
| 153 'online': 'online', | |
| 154 'open': 'open', | |
| 155 'pagehide': 'pageHide', | |
| 156 'pageshow': 'pageShow', | |
| 157 'paste': 'paste', | |
| 158 'pause': 'pause', | |
| 159 'play': 'play', | |
| 160 'playing': 'playing', | |
| 161 'popstate': 'popState', | |
| 162 'progress': 'progress', | |
| 163 'ratechange': 'rateChange', | |
| 164 'readystatechange': 'readyStateChange', | |
| 165 'removestream': 'removeStream', | |
| 166 'removetrack': 'removeTrack', | |
| 167 'reset': 'reset', | |
| 168 'resize': 'resize', | |
| 169 'result': 'result', | |
| 170 'resultdeleted': 'resultDeleted', | |
| 171 'scroll': 'scroll', | |
| 172 'search': 'search', | |
| 173 'seeked': 'seeked', | |
| 174 'seeking': 'seeking', | |
| 175 'select': 'select', | |
| 176 'selectionchange': 'selectionChange', | |
| 177 'selectstart': 'selectStart', | |
| 178 'show': 'show', | |
| 179 'soundend': 'soundEnd', | |
| 180 'soundstart': 'soundStart', | |
| 181 'speechend': 'speechEnd', | |
| 182 'speechstart': 'speechStart', | |
| 183 'stalled': 'stalled', | |
| 184 'start': 'start', | |
| 185 'statechange': 'stateChange', | |
| 186 'storage': 'storage', | |
| 187 'submit': 'submit', | |
| 188 'success': 'success', | |
| 189 'suspend': 'suspend', | |
| 190 'timeupdate': 'timeUpdate', | |
| 191 'touchcancel': 'touchCancel', | |
| 192 'touchend': 'touchEnd', | |
| 193 'touchenter': 'touchEnter', | |
| 194 'touchleave': 'touchLeave', | |
| 195 'touchmove': 'touchMove', | |
| 196 'touchstart': 'touchStart', | |
| 197 'unload': 'unload', | |
| 198 'upgradeneeded': 'upgradeNeeded', | |
| 199 'unmute': 'unmute', | |
| 200 'updateready': 'updateReady', | |
| 201 'versionchange': 'versionChange', | |
| 202 'volumechange': 'volumeChange', | |
| 203 'waiting': 'waiting', | |
| 204 'webkitAnimationEnd': 'animationEnd', | |
| 205 'webkitAnimationIteration': 'animationIteration', | |
| 206 'webkitAnimationStart': 'animationStart', | |
| 207 'webkitfullscreenchange': 'fullscreenChange', | |
| 208 'webkitfullscreenerror': 'fullscreenError', | |
| 209 'webkitkeyadded': 'keyAdded', | |
| 210 'webkitkeyerror': 'keyError', | |
| 211 'webkitkeymessage': 'keyMessage', | |
| 212 'webkitneedkey': 'needKey', | |
| 213 'webkitpointerlockchange': 'pointerLockChange', | |
| 214 'webkitpointerlockerror': 'pointerLockError', | |
| 215 'webkitSpeechChange': 'speechChange', | |
| 216 'webkitsourceclose': 'sourceClose', | |
| 217 'webkitsourceended': 'sourceEnded', | |
| 218 'webkitsourceopen': 'sourceOpen', | |
| 219 'webkitTransitionEnd': 'transitionEnd', | |
| 220 'write': 'write', | |
| 221 'writeend': 'writeEnd', | |
| 222 'writestart': 'writeStart' | |
| 223 } | |
| 224 | |
| 225 # Information for generating element constructors. | 52 # Information for generating element constructors. |
| 226 # | 53 # |
| 227 # TODO(sra): maybe remove all the argument complexity and use cascades. | 54 # TODO(sra): maybe remove all the argument complexity and use cascades. |
| 228 # | 55 # |
| 229 # var c = new CanvasElement(width: 100, height: 70); | 56 # var c = new CanvasElement(width: 100, height: 70); |
| 230 # var c = new CanvasElement()..width = 100..height = 70; | 57 # var c = new CanvasElement()..width = 100..height = 70; |
| 231 # | 58 # |
| 232 class ElementConstructorInfo(object): | 59 class ElementConstructorInfo(object): |
| 233 def __init__(self, name=None, tag=None, | 60 def __init__(self, name=None, tag=None, |
| 234 params=[], opt_params=[], | 61 params=[], opt_params=[], |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 ' return _e;\n' | 173 ' return _e;\n' |
| 347 ' }\n', | 174 ' }\n', |
| 348 RETURN_TYPE=constructor_info.type_name, | 175 RETURN_TYPE=constructor_info.type_name, |
| 349 CONSTRUCTOR=constructor_info.ConstructorFactoryName(DartType), | 176 CONSTRUCTOR=constructor_info.ConstructorFactoryName(DartType), |
| 350 CLASS=class_name, | 177 CLASS=class_name, |
| 351 TAG=info.tag, | 178 TAG=info.tag, |
| 352 PARAMS=constructor_info.ParametersInterfaceDeclaration(DartType)) | 179 PARAMS=constructor_info.ParametersInterfaceDeclaration(DartType)) |
| 353 for param in constructor_info.param_infos: | 180 for param in constructor_info.param_infos: |
| 354 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) | 181 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) |
| 355 | 182 |
| 356 | |
| 357 # These classes require an explicit declaration for the "on" method even though | |
| 358 # they don't declare any unique events, because the concrete class hierarchy | |
| 359 # doesn't match the interface hierarchy. | |
| 360 _html_explicit_event_classes = set(['DocumentFragment']) | |
| 361 | |
| 362 def _OnAttributeToEventName(on_method): | |
| 363 event_name = on_method.id[2:] | |
| 364 if event_name in _on_attribute_to_event_name_mapping: | |
| 365 return _on_attribute_to_event_name_mapping[event_name] | |
| 366 else: | |
| 367 return event_name | |
| 368 | |
| 369 def DomToHtmlEvents(interface_id, events): | |
| 370 event_names = set(map(_OnAttributeToEventName, events)) | |
| 371 if interface_id in _html_manual_events: | |
| 372 for manual_event_name in _html_manual_events[interface_id]: | |
| 373 event_names.add(manual_event_name) | |
| 374 | |
| 375 return sorted(event_names, key=lambda name: _html_event_names[name]) | |
| 376 | |
| 377 def DomToHtmlEvent(event_name): | |
| 378 assert event_name in _html_event_names, \ | |
| 379 'No known html event name for event: ' + event_name | |
| 380 return _html_event_names[event_name] | |
| 381 | |
| 382 # ------------------------------------------------------------------------------ | |
| 383 class HtmlSystemShared(object): | |
| 384 | |
| 385 def __init__(self, database): | |
| 386 self._event_classes = set() | |
| 387 self._database = database | |
| 388 | |
| 389 # TODO(jacobr): this isn't quite right.... | |
| 390 def GetParentsEventsClasses(self, interface): | |
| 391 # Ugly hack as we don't specify that Document and DocumentFragment inherit | |
| 392 # from Element in our IDL. | |
| 393 if interface.id == 'Document' or interface.id == 'DocumentFragment': | |
| 394 return ['ElementEvents'] | |
| 395 | |
| 396 interfaces_with_events = set() | |
| 397 for parent in self._database.Hierarchy(interface): | |
| 398 if parent != interface and parent.id in self._event_classes: | |
| 399 interfaces_with_events.add(parent) | |
| 400 | |
| 401 if len(interfaces_with_events) == 0: | |
| 402 return ['Events'] | |
| 403 else: | |
| 404 names = [] | |
| 405 for interface in interfaces_with_events: | |
| 406 names.append(interface.id + 'Events') | |
| 407 return names | |
| 408 | |
| 409 def GetParentEventsClass(self, interface): | |
| 410 parent_event_classes = self.GetParentsEventsClasses(interface) | |
| 411 if len(parent_event_classes) != 1: | |
| 412 raise Exception('Only one parent event class allowed ' + interface.id) | |
| 413 return parent_event_classes[0] | |
| 414 | |
| 415 # This returns two values: the first is whether or not an "on" property should | |
| 416 # be generated for the interface, and the second is the event attributes to | |
| 417 # generate if it should. | |
| 418 def GetEventAttributes(self, interface): | |
| 419 events = set([attr for attr in interface.attributes | |
| 420 if attr.type.id == 'EventListener']) | |
| 421 | |
| 422 if events or interface.id in _html_explicit_event_classes: | |
| 423 return True, events | |
| 424 else: | |
| 425 return False, None | |
| 426 | |
| 427 def IsPrivate(self, name): | |
| 428 return name.startswith('_') | |
| 429 | |
| 430 # ------------------------------------------------------------------------------ | 183 # ------------------------------------------------------------------------------ |
| 431 | 184 |
| 432 class HtmlDartInterfaceGenerator(BaseGenerator): | 185 class HtmlDartInterfaceGenerator(BaseGenerator): |
| 433 """Generates dart interface and implementation for the DOM IDL interface.""" | 186 """Generates dart interface and implementation for the DOM IDL interface.""" |
| 434 | 187 |
| 435 def __init__(self, shared, options, library_emitter, interface, backend): | 188 def __init__(self, options, library_emitter, event_generator, interface, |
| 189 backend): |
| 436 super(HtmlDartInterfaceGenerator, self).__init__(None, None, interface) | 190 super(HtmlDartInterfaceGenerator, self).__init__(None, None, interface) |
| 437 self._renamer = options.renamer | 191 self._renamer = options.renamer |
| 438 self._database = options.database | 192 self._database = options.database |
| 439 self._template_loader = options.templates | 193 self._template_loader = options.templates |
| 440 self._type_registry = options.type_registry | 194 self._type_registry = options.type_registry |
| 441 self._library_emitter = library_emitter | 195 self._library_emitter = library_emitter |
| 196 self._event_generator = event_generator |
| 442 self._backend = backend | 197 self._backend = backend |
| 443 self._shared = shared | |
| 444 self._html_interface_name = options.renamer.RenameInterface(self._interface) | 198 self._html_interface_name = options.renamer.RenameInterface(self._interface) |
| 445 | 199 |
| 446 def GenerateCallback(self, info): | 200 def GenerateCallback(self, info): |
| 447 """Generates a typedef for the callback interface.""" | 201 """Generates a typedef for the callback interface.""" |
| 448 code = self._library_emitter.FileEmitter(self._interface.id) | 202 code = self._library_emitter.FileEmitter(self._interface.id) |
| 449 code.Emit(self._template_loader.Load('callback.darttemplate')) | 203 code.Emit(self._template_loader.Load('callback.darttemplate')) |
| 450 code.Emit('typedef $TYPE $NAME($PARAMS);\n', | 204 code.Emit('typedef $TYPE $NAME($PARAMS);\n', |
| 451 NAME=self._interface.id, | 205 NAME=self._interface.id, |
| 452 TYPE=DartType(info.type_name), | 206 TYPE=DartType(info.type_name), |
| 453 PARAMS=info.ParametersImplementationDeclaration(DartType)) | 207 PARAMS=info.ParametersImplementationDeclaration(DartType)) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 '\n' | 317 '\n' |
| 564 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' | 318 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' |
| 565 ' $FACTORY.create$(CTOR)_fromList(list);\n' | 319 ' $FACTORY.create$(CTOR)_fromList(list);\n' |
| 566 '\n' | 320 '\n' |
| 567 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l
ength]) => \n' | 321 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l
ength]) => \n' |
| 568 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n'
, | 322 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n'
, |
| 569 CTOR=self._interface.id, | 323 CTOR=self._interface.id, |
| 570 TYPE=self._DartType(element_type), | 324 TYPE=self._DartType(element_type), |
| 571 FACTORY=factory_provider) | 325 FACTORY=factory_provider) |
| 572 | 326 |
| 573 self._GenerateEvents() | 327 events_interface = self._event_generator.ProcessInterface( |
| 328 self._interface, self._html_interface_name, |
| 329 self._backend.CustomJSMembers(), |
| 330 self._interface_emitter, self._implementation_emitter) |
| 331 if events_interface: |
| 332 self._EmitEventGetter(events_interface, '_%sImpl' % events_interface) |
| 574 | 333 |
| 575 old_backend = self._backend | 334 old_backend = self._backend |
| 576 if not self._backend.ImplementsMergedMembers(): | 335 if not self._backend.ImplementsMergedMembers(): |
| 577 self._backend = HtmlGeneratorDummyBackend() | 336 self._backend = HtmlGeneratorDummyBackend() |
| 578 for merged_interface in _merged_html_interfaces: | 337 for merged_interface in _merged_html_interfaces: |
| 579 if _merged_html_interfaces[merged_interface] == self._interface.id: | 338 if _merged_html_interfaces[merged_interface] == self._interface.id: |
| 580 merged_interface = self._database.GetInterface(merged_interface) | 339 merged_interface = self._database.GetInterface(merged_interface) |
| 581 self.AddMembers(merged_interface) | 340 self.AddMembers(merged_interface) |
| 582 self._backend = old_backend | 341 self._backend = old_backend |
| 583 | 342 |
| 584 def AddIndexer(self, element_type): | 343 def AddIndexer(self, element_type): |
| 585 self._backend.AddIndexer(element_type) | 344 self._backend.AddIndexer(element_type) |
| 586 | 345 |
| 587 def AmendIndexer(self, element_type): | 346 def AmendIndexer(self, element_type): |
| 588 self._backend.AmendIndexer(element_type) | 347 self._backend.AmendIndexer(element_type) |
| 589 | 348 |
| 590 def AddAttribute(self, attribute, is_secondary=False): | 349 def AddAttribute(self, attribute, is_secondary=False): |
| 591 dom_name = DartDomNameOfAttribute(attribute) | 350 dom_name = DartDomNameOfAttribute(attribute) |
| 592 html_name = self._renamer.RenameMember( | 351 html_name = self._renamer.RenameMember( |
| 593 self._interface.id, dom_name, 'get:') | 352 self._interface.id, dom_name, 'get:') |
| 594 if not html_name or self._shared.IsPrivate(html_name): | 353 if not html_name or self._IsPrivate(html_name): |
| 595 return | 354 return |
| 596 | 355 |
| 597 | 356 |
| 598 html_setter_name = self._renamer.RenameMember( | 357 html_setter_name = self._renamer.RenameMember( |
| 599 self._interface.id, dom_name, 'set:') | 358 self._interface.id, dom_name, 'set:') |
| 600 read_only = IsReadOnly(attribute) or not html_setter_name | 359 read_only = IsReadOnly(attribute) or not html_setter_name |
| 601 | 360 |
| 602 # We don't yet handle inconsistent renames of the getter and setter yet. | 361 # We don't yet handle inconsistent renames of the getter and setter yet. |
| 603 assert(not html_setter_name or html_name == html_setter_name) | 362 assert(not html_setter_name or html_name == html_setter_name) |
| 604 | 363 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 627 operations - contains the overloads, one or more operations with the same | 386 operations - contains the overloads, one or more operations with the same |
| 628 name. | 387 name. |
| 629 """ | 388 """ |
| 630 html_name = self._renamer.RenameMember(self._interface.id, info.name) | 389 html_name = self._renamer.RenameMember(self._interface.id, info.name) |
| 631 if not html_name: | 390 if not html_name: |
| 632 if info.name == 'item': | 391 if info.name == 'item': |
| 633 # FIXME: item should be renamed to operator[], not removed. | 392 # FIXME: item should be renamed to operator[], not removed. |
| 634 self._backend.AddOperation(info, '_item') | 393 self._backend.AddOperation(info, '_item') |
| 635 return | 394 return |
| 636 | 395 |
| 637 if not self._shared.IsPrivate(html_name) and not skip_declaration: | 396 if not self._IsPrivate(html_name) and not skip_declaration: |
| 638 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 397 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 639 DOMINTERFACE=info.overloads[0].doc_js_interface_name, | 398 DOMINTERFACE=info.overloads[0].doc_js_interface_name, |
| 640 DOMNAME=info.name) | 399 DOMNAME=info.name) |
| 641 | 400 |
| 642 if info.IsStatic(): | 401 if info.IsStatic(): |
| 643 # FIXME: provide a type. | 402 # FIXME: provide a type. |
| 644 self._members_emitter.Emit('\n' | 403 self._members_emitter.Emit('\n' |
| 645 ' static final $NAME = $IMPL_CLASS_NAME.$NAME
;\n', | 404 ' static final $NAME = $IMPL_CLASS_NAME.$NAME
;\n', |
| 646 IMPL_CLASS_NAME=self._backend.ImplementationCl
assName(), | 405 IMPL_CLASS_NAME=self._backend.ImplementationCl
assName(), |
| 647 NAME=html_name) | 406 NAME=html_name) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 661 self._backend.FinishInterface() | 420 self._backend.FinishInterface() |
| 662 | 421 |
| 663 def AddConstant(self, constant): | 422 def AddConstant(self, constant): |
| 664 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) | 423 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) |
| 665 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', | 424 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', |
| 666 NAME=constant.id, | 425 NAME=constant.id, |
| 667 TYPE=type, | 426 TYPE=type, |
| 668 VALUE=constant.value) | 427 VALUE=constant.value) |
| 669 self._backend.AddConstant(constant) | 428 self._backend.AddConstant(constant) |
| 670 | 429 |
| 671 def _GenerateEvents(self): | |
| 672 emit_events, event_attrs = self._shared.GetEventAttributes(self._interface) | |
| 673 if not emit_events: | |
| 674 return | |
| 675 | |
| 676 self._shared._event_classes.add(self._interface.id) | |
| 677 events_interface = self._html_interface_name + 'Events' | |
| 678 events_class = '_%sImpl' % events_interface | |
| 679 parent_events_interface = self._shared.GetParentEventsClass(self._interface) | |
| 680 parent_events_class = '_%sImpl' % parent_events_interface | |
| 681 | |
| 682 if not event_attrs: | |
| 683 self._EmitEventGetter(parent_events_interface, parent_events_class) | |
| 684 return | |
| 685 | |
| 686 self._EmitEventGetter(events_interface, events_class) | |
| 687 | |
| 688 events_members = self._interface_emitter.Emit( | |
| 689 '\nabstract class $INTERFACE implements $PARENTS {\n$!MEMBERS}\n', | |
| 690 INTERFACE=events_interface, | |
| 691 PARENTS=', '.join( | |
| 692 self._shared.GetParentsEventsClasses(self._interface))) | |
| 693 | |
| 694 template_file = 'impl_%s.darttemplate' % events_interface | |
| 695 template = (self._template_loader.TryLoad(template_file) or | |
| 696 '\n' | |
| 697 'class $CLASSNAME extends $SUPER implements $INTERFACE {\n' | |
| 698 ' $CLASSNAME(_ptr) : super(_ptr);\n' | |
| 699 '$!MEMBERS}\n') | |
| 700 | |
| 701 # TODO(jacobr): specify the type of _ptr as EventTarget | |
| 702 implementation_events_members = self._implementation_emitter.Emit( | |
| 703 template, | |
| 704 CLASSNAME=events_class, | |
| 705 INTERFACE=events_interface, | |
| 706 SUPER=parent_events_class) | |
| 707 | |
| 708 event_attrs = DomToHtmlEvents(self._html_interface_name, event_attrs) | |
| 709 for event_name in event_attrs: | |
| 710 if event_name in _html_event_names: | |
| 711 dart_event_name = _html_event_names[event_name] | |
| 712 events_members.Emit('\n EventListenerList get $NAME;\n', | |
| 713 NAME=dart_event_name) | |
| 714 if not self._backend.HasCustomEventImplementation(dart_event_name): | |
| 715 implementation_events_members.Emit( | |
| 716 "\n" | |
| 717 " EventListenerList get $NAME => this['$DOM_NAME'];\n", | |
| 718 NAME=dart_event_name, | |
| 719 DOM_NAME=event_name) | |
| 720 else: | |
| 721 raise Exception('No known html even name for event: ' + event_name) | |
| 722 | |
| 723 def _EmitEventGetter(self, events_interface, events_class): | 430 def _EmitEventGetter(self, events_interface, events_class): |
| 724 self._members_emitter.Emit( | 431 self._members_emitter.Emit( |
| 725 '\n /**' | 432 '\n /**' |
| 726 '\n * @domName EventTarget.addEventListener, ' | 433 '\n * @domName EventTarget.addEventListener, ' |
| 727 'EventTarget.removeEventListener, EventTarget.dispatchEvent' | 434 'EventTarget.removeEventListener, EventTarget.dispatchEvent' |
| 728 '\n */' | 435 '\n */' |
| 729 '\n $TYPE get on;\n', | 436 '\n $TYPE get on;\n', |
| 730 TYPE=events_interface) | 437 TYPE=events_interface) |
| 731 | 438 |
| 732 self._implementation_members_emitter.Emit( | 439 self._implementation_members_emitter.Emit( |
| 733 '\n $TYPE get on =>\n new $TYPE(this);\n', | 440 '\n $TYPE get on =>\n new $TYPE(this);\n', |
| 734 TYPE=events_class) | 441 TYPE=events_class) |
| 735 | 442 |
| 443 def _IsPrivate(self, name): |
| 444 return name.startswith('_') |
| 445 |
| 736 | 446 |
| 737 class HtmlGeneratorDummyBackend(object): | 447 class HtmlGeneratorDummyBackend(object): |
| 738 def AddAttribute(self, attribute, html_name, read_only): | 448 def AddAttribute(self, attribute, html_name, read_only): |
| 739 pass | 449 pass |
| 740 | 450 |
| 741 def AddOperation(self, info, html_name): | 451 def AddOperation(self, info, html_name): |
| 742 pass | 452 pass |
| 743 | 453 |
| 744 | 454 |
| 745 # ------------------------------------------------------------------------------ | 455 # ------------------------------------------------------------------------------ |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 def _OutputConversion(self, idl_type, member): | 920 def _OutputConversion(self, idl_type, member): |
| 1211 return FindConversion(idl_type, 'get', self._interface.id, member) | 921 return FindConversion(idl_type, 'get', self._interface.id, member) |
| 1212 | 922 |
| 1213 def _InputConversion(self, idl_type, member): | 923 def _InputConversion(self, idl_type, member): |
| 1214 return FindConversion(idl_type, 'set', self._interface.id, member) | 924 return FindConversion(idl_type, 'set', self._interface.id, member) |
| 1215 | 925 |
| 1216 def _HasCustomImplementation(self, member_name): | 926 def _HasCustomImplementation(self, member_name): |
| 1217 member_name = '%s.%s' % (self._html_interface_name, member_name) | 927 member_name = '%s.%s' % (self._html_interface_name, member_name) |
| 1218 return member_name in _js_custom_members | 928 return member_name in _js_custom_members |
| 1219 | 929 |
| 1220 def HasCustomEventImplementation(self, member_name): | 930 def CustomJSMembers(self): |
| 1221 member_name = '%sEvents.%s' % (self._html_interface_name, member_name) | 931 return _js_custom_members |
| 1222 return member_name in _js_custom_members | |
| 1223 | 932 |
| 1224 def _HasJavaScriptIndexingBehaviour(self): | 933 def _HasJavaScriptIndexingBehaviour(self): |
| 1225 """Returns True if the native object has an indexer and length property.""" | 934 """Returns True if the native object has an indexer and length property.""" |
| 1226 (element_type, requires_indexer) = ListImplementationInfo( | 935 (element_type, requires_indexer) = ListImplementationInfo( |
| 1227 self._interface, self._database) | 936 self._interface, self._database) |
| 1228 if element_type and requires_indexer: return True | 937 if element_type and requires_indexer: return True |
| 1229 return False | 938 return False |
| 1230 | 939 |
| 1231 def _ShouldNarrowToImplementationType(self, type_name): | 940 def _ShouldNarrowToImplementationType(self, type_name): |
| 1232 # TODO(sra): Move into the 'system' and cache the result. | 941 # TODO(sra): Move into the 'system' and cache the result. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 | 1024 |
| 1316 library_emitter = self._multiemitter.FileEmitter(library_file_path) | 1025 library_emitter = self._multiemitter.FileEmitter(library_file_path) |
| 1317 library_file_dir = os.path.dirname(library_file_path) | 1026 library_file_dir = os.path.dirname(library_file_path) |
| 1318 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) | 1027 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) |
| 1319 imports_emitter = library_emitter.Emit( | 1028 imports_emitter = library_emitter.Emit( |
| 1320 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) | 1029 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) |
| 1321 for path in sorted(self._path_to_emitter.keys()): | 1030 for path in sorted(self._path_to_emitter.keys()): |
| 1322 relpath = os.path.relpath(path, library_file_dir) | 1031 relpath = os.path.relpath(path, library_file_dir) |
| 1323 imports_emitter.Emit( | 1032 imports_emitter.Emit( |
| 1324 "#source('$PATH');\n", PATH=massage_path(relpath)) | 1033 "#source('$PATH');\n", PATH=massage_path(relpath)) |
| OLD | NEW |