Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: sdk/lib/html/scripts/htmleventgenerator.py

Issue 11691009: Moved most of html lib generating scripts into tools. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/html/scripts/htmldartgenerator.py ('k') | sdk/lib/html/scripts/htmlrenamer.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
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
4 # BSD-style license that can be found in the LICENSE file.
5
6 """This module provides functionality to generate dart:html event classes."""
7
8 import logging
9
10 _logger = logging.getLogger('dartgenerator')
11
12 # Events without onEventName attributes in the IDL we want to support.
13 # We can automatically extract most event names by checking for
14 # onEventName methods in the IDL but some events aren't listed so we need
15 # to manually add them here so that they are easy for users to find.
16 _html_manual_events = {
17 'Element': ['touchleave', 'touchenter', 'webkitTransitionEnd'],
18 'Window': ['DOMContentLoaded']
19 }
20
21 # These event names must be camel case when attaching event listeners
22 # using addEventListener even though the onEventName properties in the DOM for
23 # them are not camel case.
24 _on_attribute_to_event_name_mapping = {
25 'webkitanimationend': 'webkitAnimationEnd',
26 'webkitanimationiteration': 'webkitAnimationIteration',
27 'webkitanimationstart': 'webkitAnimationStart',
28 'webkitspeechchange': 'webkitSpeechChange',
29 'webkittransitionend': 'webkitTransitionEnd',
30 }
31
32 # Mapping from raw event names to the pretty camelCase event names exposed as
33 # properties in dart:html. If the DOM exposes a new event name, you will need
34 # to add the lower case to camel case conversion for that event name here.
35 _html_event_names = {
36 'DOMContentLoaded': 'contentLoaded',
37 'abort': 'abort',
38 'addstream': 'addStream',
39 'addtrack': 'addTrack',
40 'audioend': 'audioEnd',
41 'audioprocess': 'audioProcess',
42 'audiostart': 'audioStart',
43 'beforecopy': 'beforeCopy',
44 'beforecut': 'beforeCut',
45 'beforepaste': 'beforePaste',
46 'beforeunload': 'beforeUnload',
47 'blocked': 'blocked',
48 'blur': 'blur',
49 'cached': 'cached',
50 'canplay': 'canPlay',
51 'canplaythrough': 'canPlayThrough',
52 'change': 'change',
53 'chargingchange': 'chargingChange',
54 'chargingtimechange': 'chargingTimeChange',
55 'checking': 'checking',
56 'click': 'click',
57 'close': 'close',
58 'complete': 'complete',
59 'connect': 'connect',
60 'connecting': 'connecting',
61 'contextmenu': 'contextMenu',
62 'copy': 'copy',
63 'cuechange': 'cueChange',
64 'cut': 'cut',
65 'dblclick': 'doubleClick',
66 'devicemotion': 'deviceMotion',
67 'deviceorientation': 'deviceOrientation',
68 'dischargingtimechange': 'dischargingTimeChange',
69 'display': 'display',
70 'downloading': 'downloading',
71 'drag': 'drag',
72 'dragend': 'dragEnd',
73 'dragenter': 'dragEnter',
74 'dragleave': 'dragLeave',
75 'dragover': 'dragOver',
76 'dragstart': 'dragStart',
77 'drop': 'drop',
78 'durationchange': 'durationChange',
79 'emptied': 'emptied',
80 'end': 'end',
81 'ended': 'ended',
82 'enter': 'enter',
83 'error': 'error',
84 'exit': 'exit',
85 'focus': 'focus',
86 'hashchange': 'hashChange',
87 'icecandidate': 'iceCandidate',
88 'icechange': 'iceChange',
89 'input': 'input',
90 'invalid': 'invalid',
91 'keydown': 'keyDown',
92 'keypress': 'keyPress',
93 'keyup': 'keyUp',
94 'levelchange': 'levelChange',
95 'load': 'load',
96 'loadeddata': 'loadedData',
97 'loadedmetadata': 'loadedMetadata',
98 'loadend': 'loadEnd',
99 'loadstart': 'loadStart',
100 'message': 'message',
101 'mousedown': 'mouseDown',
102 'mousemove': 'mouseMove',
103 'mouseout': 'mouseOut',
104 'mouseover': 'mouseOver',
105 'mouseup': 'mouseUp',
106 'mousewheel': 'mouseWheel',
107 'mute': 'mute',
108 'negotiationneeded': 'negotiationNeeded',
109 'nomatch': 'noMatch',
110 'noupdate': 'noUpdate',
111 'obsolete': 'obsolete',
112 'offline': 'offline',
113 'online': 'online',
114 'open': 'open',
115 'pagehide': 'pageHide',
116 'pageshow': 'pageShow',
117 'paste': 'paste',
118 'pause': 'pause',
119 'play': 'play',
120 'playing': 'playing',
121 'popstate': 'popState',
122 'progress': 'progress',
123 'ratechange': 'rateChange',
124 'readystatechange': 'readyStateChange',
125 'removestream': 'removeStream',
126 'removetrack': 'removeTrack',
127 'reset': 'reset',
128 'resize': 'resize',
129 'result': 'result',
130 'resultdeleted': 'resultDeleted',
131 'scroll': 'scroll',
132 'search': 'search',
133 'seeked': 'seeked',
134 'seeking': 'seeking',
135 'select': 'select',
136 'selectionchange': 'selectionChange',
137 'selectstart': 'selectStart',
138 'show': 'show',
139 'soundend': 'soundEnd',
140 'soundstart': 'soundStart',
141 'speechend': 'speechEnd',
142 'speechstart': 'speechStart',
143 'stalled': 'stalled',
144 'start': 'start',
145 'statechange': 'stateChange',
146 'storage': 'storage',
147 'submit': 'submit',
148 'success': 'success',
149 'suspend': 'suspend',
150 'timeupdate': 'timeUpdate',
151 'touchcancel': 'touchCancel',
152 'touchend': 'touchEnd',
153 'touchenter': 'touchEnter',
154 'touchleave': 'touchLeave',
155 'touchmove': 'touchMove',
156 'touchstart': 'touchStart',
157 'unload': 'unload',
158 'upgradeneeded': 'upgradeNeeded',
159 'unmute': 'unmute',
160 'updateready': 'updateReady',
161 'versionchange': 'versionChange',
162 'volumechange': 'volumeChange',
163 'waiting': 'waiting',
164 'webkitAnimationEnd': 'animationEnd',
165 'webkitAnimationIteration': 'animationIteration',
166 'webkitAnimationStart': 'animationStart',
167 'webkitfullscreenchange': 'fullscreenChange',
168 'webkitfullscreenerror': 'fullscreenError',
169 'webkitkeyadded': 'keyAdded',
170 'webkitkeyerror': 'keyError',
171 'webkitkeymessage': 'keyMessage',
172 'webkitneedkey': 'needKey',
173 'webkitpointerlockchange': 'pointerLockChange',
174 'webkitpointerlockerror': 'pointerLockError',
175 'webkitSpeechChange': 'speechChange',
176 'webkitsourceclose': 'sourceClose',
177 'webkitsourceended': 'sourceEnded',
178 'webkitsourceopen': 'sourceOpen',
179 'webkitTransitionEnd': 'transitionEnd',
180 'write': 'write',
181 'writeend': 'writeEnd',
182 'writestart': 'writeStart'
183 }
184
185 # These classes require an explicit declaration for the "on" method even though
186 # they don't declare any unique events, because the concrete class hierarchy
187 # doesn't match the interface hierarchy.
188 _html_explicit_event_classes = set(['DocumentFragment'])
189
190 class HtmlEventGenerator(object):
191
192 def __init__(self, database, renamer, template_loader):
193 self._event_classes = set()
194 self._database = database
195 self._renamer = renamer
196 self._template_loader = template_loader
197
198 def ProcessInterface(self, interface, html_interface_name, custom_events,
199 events_implementation_emitter):
200 event_names = set([attr.id[2:] for attr in interface.attributes
201 if attr.type.id == 'EventListener'])
202
203 # Document and DocumentFragment actually derive from Element, so omit
204 # any events which are duplicated with that.
205 if interface.id == 'Document' or interface.id == 'DocumentFragment':
206 element_interface = self._database.GetInterface('Element')
207 for attr in element_interface.attributes:
208 if attr.type.id == 'EventListener' and attr.id[2:] in event_names:
209 event_names.remove(attr.id[2:])
210
211 if not event_names and interface.id not in _html_explicit_event_classes:
212 return None
213
214 self._event_classes.add(interface.id)
215 events_class_name = html_interface_name + 'Events'
216 parent_events_class_name = self._GetParentEventsClassName(interface)
217
218 if not event_names:
219 return parent_events_class_name
220
221 template_file = 'impl_%s.darttemplate' % events_class_name
222 template = (self._template_loader.TryLoad(template_file) or
223 '\n'
224 '/// @docsEditable true\n'
225 'class $CLASSNAME extends $SUPER {\n'
226 ' /// @docsEditable true\n'
227 ' $CLASSNAME(EventTarget _ptr) : super(_ptr);\n'
228 '$!MEMBERS}\n')
229
230 # TODO(jacobr): specify the type of _ptr as EventTarget
231 implementation_events_members = events_implementation_emitter.Emit(
232 template,
233 CLASSNAME=events_class_name,
234 SUPER='%s' % parent_events_class_name)
235
236 dom_event_names = set()
237 for event in event_names:
238 dom_name = event
239 dom_name = _on_attribute_to_event_name_mapping.get(dom_name, dom_name)
240 dom_event_names.add(dom_name)
241 if html_interface_name in _html_manual_events:
242 dom_event_names.update(_html_manual_events[html_interface_name])
243 for dom_name in sorted(dom_event_names):
244 if dom_name not in _html_event_names:
245 _logger.warn('omitting %s event as there is no HTML name for it' % dom_n ame)
246 continue
247
248 html_name = _html_event_names[dom_name]
249 full_event_name = '%sEvents.%s' % (html_interface_name, html_name)
250 if not full_event_name in custom_events:
251 implementation_events_members.Emit(
252 "\n"
253 " /// @docsEditable true\n"
254 " EventListenerList get $NAME => this['$DOM_NAME'];\n",
255 NAME=html_name,
256 DOM_NAME=dom_name)
257
258 return events_class_name
259
260 # TODO(jacobr): this isn't quite right....
261 def _GetParentEventsClassName(self, interface):
262 # Ugly hack as we don't specify that Document and DocumentFragment inherit
263 # from Element in our IDL.
264 if interface.id == 'Document' or interface.id == 'DocumentFragment':
265 return 'ElementEvents'
266
267 parent_events_class_name = 'Events'
268 interfaces_with_events = set()
269 for parent in self._database.Hierarchy(interface):
270 if parent != interface and parent.id in self._event_classes:
271 parent_name = self._renamer.RenameInterface(parent)
272 parent_events_class_name = parent_name + 'Events'
273 interfaces_with_events.add(parent)
274 if len(interfaces_with_events) > 1:
275 raise Exception('Only one parent event class allowed ' + interface.id)
276 return parent_events_class_name
OLDNEW
« no previous file with comments | « sdk/lib/html/scripts/htmldartgenerator.py ('k') | sdk/lib/html/scripts/htmlrenamer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698