| 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 functionality to generate dart:html event classes.""" | 6 """This module provides functionality to generate dart:html event classes.""" |
| 7 | 7 |
| 8 import logging | 8 import logging |
| 9 | 9 |
| 10 _logger = logging.getLogger('dartgenerator') | 10 _logger = logging.getLogger('dartgenerator') |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 _html_explicit_event_classes = set(['DocumentFragment']) | 373 _html_explicit_event_classes = set(['DocumentFragment']) |
| 374 | 374 |
| 375 class HtmlEventGenerator(object): | 375 class HtmlEventGenerator(object): |
| 376 | 376 |
| 377 def __init__(self, database, renamer, template_loader): | 377 def __init__(self, database, renamer, template_loader): |
| 378 self._event_classes = set() | 378 self._event_classes = set() |
| 379 self._database = database | 379 self._database = database |
| 380 self._renamer = renamer | 380 self._renamer = renamer |
| 381 self._template_loader = template_loader | 381 self._template_loader = template_loader |
| 382 | 382 |
| 383 def EmitStreamProviders(self, interface, html_interface_name, custom_events, | 383 def EmitStreamProviders(self, interface, custom_events, |
| 384 members_emitter): | 384 members_emitter): |
| 385 events = self._GetEvents(interface, html_interface_name, custom_events) | 385 events = self._GetEvents(interface, custom_events) |
| 386 if not events: | 386 if not events: |
| 387 return | 387 return |
| 388 | 388 |
| 389 for event_info in events: | 389 for event_info in events: |
| 390 (dom_name, html_name, event_type) = event_info | 390 (dom_name, html_name, event_type) = event_info |
| 391 |
| 392 # If we're using a different provider, then don't declare one. |
| 393 if self._GetEventRedirection(interface, html_name, event_type): |
| 394 continue |
| 395 |
| 391 members_emitter.Emit( | 396 members_emitter.Emit( |
| 392 "\n" | 397 "\n" |
| 393 " static const EventStreamProvider<$TYPE> $(NAME)Event = " | 398 " static const EventStreamProvider<$TYPE> $(NAME)Event = " |
| 394 "const EventStreamProvider<$TYPE>('$DOM_NAME');\n", | 399 "const EventStreamProvider<$TYPE>('$DOM_NAME');\n", |
| 395 NAME=html_name, | 400 NAME=html_name, |
| 396 DOM_NAME=dom_name, | 401 DOM_NAME=dom_name, |
| 397 TYPE=event_type) | 402 TYPE=event_type) |
| 398 | 403 |
| 399 def EmitStreamGetters(self, interface, html_interface_name, custom_events, | 404 def EmitStreamGetters(self, interface, custom_events, |
| 400 members_emitter): | 405 members_emitter): |
| 401 events = self._GetEvents(interface, html_interface_name, custom_events) | 406 events = self._GetEvents(interface, custom_events) |
| 402 if not events: | 407 if not events: |
| 403 return | 408 return |
| 404 | 409 |
| 405 for event_info in events: | 410 for event_info in events: |
| 406 (dom_name, html_name, event_type) = event_info | 411 (dom_name, html_name, event_type) = event_info |
| 407 getter_name = 'on%s%s' % (html_name[:1].upper(), html_name[1:]) | 412 getter_name = 'on%s%s' % (html_name[:1].upper(), html_name[1:]) |
| 408 | 413 |
| 414 # If the provider is declared elsewhere, point to that. |
| 415 redirection = self._GetEventRedirection(interface, html_name, event_type) |
| 416 if redirection: |
| 417 provider = '%s.%sEvent' % (redirection, html_name) |
| 418 else: |
| 419 provider = html_name + 'Event' |
| 420 |
| 409 members_emitter.Emit( | 421 members_emitter.Emit( |
| 410 "\n" | 422 "\n" |
| 411 " Stream<$TYPE> get $(NAME) => $PROVIDER.forTarget(this);\n", | 423 " Stream<$TYPE> get $(NAME) => $PROVIDER.forTarget(this);\n", |
| 412 NAME=getter_name, | 424 NAME=getter_name, |
| 413 PROVIDER=html_name + 'Event', | 425 PROVIDER=provider, |
| 414 TYPE=event_type) | 426 TYPE=event_type) |
| 415 | 427 |
| 416 def _GetEvents(self, interface, html_interface_name, custom_events): | 428 def _GetEvents(self, interface, custom_events): |
| 429 """ Gets a list of all of the events for the specified interface. |
| 430 """ |
| 417 events = set([attr for attr in interface.attributes | 431 events = set([attr for attr in interface.attributes |
| 418 if attr.type.id == 'EventListener']) | 432 if attr.type.id == 'EventListener']) |
| 419 if not events and interface.id not in _html_explicit_event_classes: | 433 if not events and interface.id not in _html_explicit_event_classes: |
| 420 return None | 434 return None |
| 421 | 435 |
| 436 html_interface_name = interface.doc_js_name |
| 437 |
| 422 dom_event_names = set() | 438 dom_event_names = set() |
| 423 for event in events: | 439 for event in events: |
| 424 dom_name = event.id[2:] | 440 dom_name = event.id[2:] |
| 425 dom_name = _on_attribute_to_event_name_mapping.get(dom_name, dom_name) | 441 dom_name = _on_attribute_to_event_name_mapping.get(dom_name, dom_name) |
| 426 dom_event_names.add(dom_name) | 442 dom_event_names.add(dom_name) |
| 427 if html_interface_name in _html_manual_events: | 443 if html_interface_name in _html_manual_events: |
| 428 dom_event_names.update(_html_manual_events[html_interface_name]) | 444 dom_event_names.update(_html_manual_events[html_interface_name]) |
| 429 | 445 |
| 430 events = [] | 446 events = [] |
| 431 for dom_name in sorted(dom_event_names): | 447 for dom_name in sorted(dom_event_names): |
| 432 event_info = self._FindEventInfo(html_interface_name, dom_name) | 448 event_info = self._FindEventInfo(html_interface_name, dom_name) |
| 433 if not event_info: | 449 if not event_info: |
| 434 continue | 450 continue |
| 435 | 451 |
| 436 (html_name, event_type) = event_info | 452 (html_name, event_type) = event_info |
| 453 if self._IsEventSuppressed(interface, html_name, event_type): |
| 454 continue |
| 455 |
| 437 full_event_name = '%sEvents.%s' % (html_interface_name, html_name) | 456 full_event_name = '%sEvents.%s' % (html_interface_name, html_name) |
| 438 if not full_event_name in custom_events: | 457 if not full_event_name in custom_events: |
| 439 events.append((dom_name, html_name, event_type)) | 458 events.append((dom_name, html_name, event_type)) |
| 440 return events | 459 return events |
| 441 | 460 |
| 461 def _HasEvent(self, events, event_name, event_type): |
| 462 """ Checks if the event is declared in the list of events (from _GetEvents), |
| 463 with the same event type. |
| 464 """ |
| 465 for (dom_name, html_name, found_type) in events: |
| 466 if html_name == event_name and event_type == found_type: |
| 467 return True |
| 468 return False |
| 469 |
| 470 def _IsEventSuppressed(self, interface, event_name, event_type): |
| 471 """ Checks if the event should not be emitted. |
| 472 """ |
| 473 if self._renamer.ShouldSuppressMember(interface, event_name, 'on:'): |
| 474 return True |
| 475 |
| 476 if interface.doc_js_name == 'Window': |
| 477 media_interface = self._database.GetInterface('HTMLMediaElement') |
| 478 media_events = self._GetEvents(media_interface, []) |
| 479 if self._HasEvent(media_events, event_name, event_type): |
| 480 return True |
| 481 |
| 482 def _GetEventRedirection(self, interface, event_name, event_type): |
| 483 """ For events which are declared in one place, but exposed elsewhere, |
| 484 this gets the source of the event (where the provider is declared) |
| 485 """ |
| 486 if interface.doc_js_name == 'Window' or interface.doc_js_name == 'Document': |
| 487 element_interface = self._database.GetInterface('Element') |
| 488 element_events = self._GetEvents(element_interface, []) |
| 489 if self._HasEvent(element_events, event_name, event_type): |
| 490 return 'Element' |
| 491 return None |
| 492 |
| 442 def _FindEventInfo(self, html_interface_name, dom_event_name): | 493 def _FindEventInfo(self, html_interface_name, dom_event_name): |
| 494 """ Finds the event info (event name and type). |
| 495 """ |
| 443 key = '%s.%s' % (html_interface_name, dom_event_name) | 496 key = '%s.%s' % (html_interface_name, dom_event_name) |
| 444 if key in _html_event_types: | 497 if key in _html_event_types: |
| 445 return _html_event_types[key] | 498 return _html_event_types[key] |
| 446 key = '*.%s' % dom_event_name | 499 key = '*.%s' % dom_event_name |
| 447 if key in _html_event_types: | 500 if key in _html_event_types: |
| 448 return _html_event_types[key] | 501 return _html_event_types[key] |
| 449 _logger.warn('Cannot resolve event type for %s.%s' % | 502 _logger.warn('Cannot resolve event type for %s.%s' % |
| 450 (html_interface_name, dom_event_name)) | 503 (html_interface_name, dom_event_name)) |
| 451 return None | 504 return None |
| 452 | 505 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 parent_events_class_name = 'Events' | 575 parent_events_class_name = 'Events' |
| 523 interfaces_with_events = set() | 576 interfaces_with_events = set() |
| 524 for parent in self._database.Hierarchy(interface): | 577 for parent in self._database.Hierarchy(interface): |
| 525 if parent != interface and parent.id in self._event_classes: | 578 if parent != interface and parent.id in self._event_classes: |
| 526 parent_name = self._renamer.RenameInterface(parent) | 579 parent_name = self._renamer.RenameInterface(parent) |
| 527 parent_events_class_name = parent_name + 'Events' | 580 parent_events_class_name = parent_name + 'Events' |
| 528 interfaces_with_events.add(parent) | 581 interfaces_with_events.add(parent) |
| 529 if len(interfaces_with_events) > 1: | 582 if len(interfaces_with_events) > 1: |
| 530 raise Exception('Only one parent event class allowed ' + interface.id) | 583 raise Exception('Only one parent event class allowed ' + interface.id) |
| 531 return parent_events_class_name | 584 return parent_events_class_name |
| OLD | NEW |