OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
6 | 6 |
7 """Generates CSSStyleDeclaration template file from css property definitions | 7 """Generates CSSStyleDeclaration template file from css property definitions |
8 defined in WebKit.""" | 8 defined in WebKit.""" |
9 | 9 |
10 import tempfile, os, re | 10 import tempfile, os, re |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 * Please note the property name camelCase, not-hyphens. This | 133 * Please note the property name camelCase, not-hyphens. This |
134 * method returns true if the property is accessible via an unprefixed _or_ | 134 * method returns true if the property is accessible via an unprefixed _or_ |
135 * prefixed property. | 135 * prefixed property. |
136 */ | 136 */ |
137 bool supportsProperty(String propertyName) { | 137 bool supportsProperty(String propertyName) { |
138 return _supportsProperty(propertyName) || | 138 return _supportsProperty(propertyName) || |
139 _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName")); | 139 _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName")); |
140 } | 140 } |
141 | 141 |
142 bool _supportsProperty(String propertyName) { | 142 bool _supportsProperty(String propertyName) { |
143 $if DART2JS | |
144 return JS('bool', '# in #', propertyName, this); | 143 return JS('bool', '# in #', propertyName, this); |
145 $else | |
146 // You can't just check the value of a property, because there is no way | |
147 // to distinguish between property not being present in the browser and | |
148 // not having a value at all. (Ultimately we'll want the native method to | |
149 // return null if the property doesn't exist and empty string if it's | |
150 // defined but just doesn't have a value. | |
151 return _hasProperty(propertyName); | |
152 $endif | |
153 } | 144 } |
154 | 145 |
155 $if DARTIUM | |
156 bool _hasProperty(String propertyName) => | |
157 _blink.BlinkCSSStyleDeclaration.instance.$__get___propertyIsEnumerable_Cal
lback_1_(this, propertyName); | |
158 $endif | |
159 | 146 |
160 @DomName('CSSStyleDeclaration.setProperty') | 147 @DomName('CSSStyleDeclaration.setProperty') |
161 void setProperty(String propertyName, String value, [String priority]) { | 148 void setProperty(String propertyName, String value, [String priority]) { |
162 return _setPropertyHelper(_browserPropertyName(propertyName), | 149 return _setPropertyHelper(_browserPropertyName(propertyName), |
163 value, priority); | 150 value, priority); |
164 } | 151 } |
165 | 152 |
166 String _browserPropertyName(String propertyName) { | 153 String _browserPropertyName(String propertyName) { |
167 String name = _readCache(propertyName); | 154 String name = _readCache(propertyName); |
168 if (name is String) return name; | 155 if (name is String) return name; |
169 name = _supportedBrowserPropertyName(propertyName); | 156 name = _supportedBrowserPropertyName(propertyName); |
170 _writeCache(propertyName, name); | 157 _writeCache(propertyName, name); |
171 return name; | 158 return name; |
172 } | 159 } |
173 | 160 |
174 String _supportedBrowserPropertyName(String propertyName) { | 161 String _supportedBrowserPropertyName(String propertyName) { |
175 if (_supportsProperty(_camelCase(propertyName))) { | 162 if (_supportsProperty(_camelCase(propertyName))) { |
176 return propertyName; | 163 return propertyName; |
177 } | 164 } |
178 var prefixed = "${Device.cssPrefix}$propertyName"; | 165 var prefixed = "${Device.cssPrefix}$propertyName"; |
179 if (_supportsProperty(prefixed)) { | 166 if (_supportsProperty(prefixed)) { |
180 return prefixed; | 167 return prefixed; |
181 } | 168 } |
182 // May be a CSS variable, just use it as provided. | 169 // May be a CSS variable, just use it as provided. |
183 return propertyName; | 170 return propertyName; |
184 } | 171 } |
185 | 172 |
186 $if DART2JS | |
187 static final _propertyCache = JS('', '{}'); | 173 static final _propertyCache = JS('', '{}'); |
188 static String _readCache(String key) => | 174 static String _readCache(String key) => |
189 JS('String|Null', '#[#]', _propertyCache, key); | 175 JS('String|Null', '#[#]', _propertyCache, key); |
190 static void _writeCache(String key, String value) { | 176 static void _writeCache(String key, String value) { |
191 JS('void', '#[#] = #', _propertyCache, key, value); | 177 JS('void', '#[#] = #', _propertyCache, key, value); |
192 } | 178 } |
193 $else | |
194 static String _readCache(String key) => null; | |
195 static void _writeCache(String key, value) {} | |
196 $endif | |
197 | 179 |
198 static String _camelCase(String hyphenated) { | 180 static String _camelCase(String hyphenated) { |
199 $if DART2JS | |
200 var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated); | 181 var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated); |
201 return JS( | 182 return JS( |
202 'String', | 183 'String', |
203 r'#.replace(/-([\da-z])/ig,' | 184 r'#.replace(/-([\da-z])/ig,' |
204 r'function(_, letter) { return letter.toUpperCase();})', | 185 r'function(_, letter) { return letter.toUpperCase();})', |
205 replacedMs); | 186 replacedMs); |
206 $else | |
207 // The "ms" prefix is always lowercased. | |
208 return hyphenated.replaceFirst(new RegExp('^-ms-'), 'ms-').replaceAllMapped( | |
209 new RegExp('-([a-z]+)', caseSensitive: false), | |
210 (match) => match[0][1].toUpperCase() + match[0].substring(2)); | |
211 $endif | |
212 } | 187 } |
213 | 188 |
214 $if DART2JS | |
215 void _setPropertyHelper(String propertyName, String value, [String priority])
{ | 189 void _setPropertyHelper(String propertyName, String value, [String priority])
{ |
216 if (value == null) value = ''; | 190 if (value == null) value = ''; |
217 if (priority == null) priority = ''; | 191 if (priority == null) priority = ''; |
218 JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority); | 192 JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority); |
219 } | 193 } |
220 | 194 |
221 /** | 195 /** |
222 * Checks to see if CSS Transitions are supported. | 196 * Checks to see if CSS Transitions are supported. |
223 */ | 197 */ |
224 static bool get supportsTransitions { | 198 static bool get supportsTransitions { |
225 return document.body.style.supportsProperty('transition'); | 199 return document.body.style.supportsProperty('transition'); |
226 } | 200 } |
227 $else | |
228 void _setPropertyHelper(String propertyName, String value, [String priority])
{ | |
229 if (priority == null) { | |
230 priority = ''; | |
231 } | |
232 _setProperty(propertyName, value, priority); | |
233 } | |
234 | |
235 /** | |
236 * Checks to see if CSS Transitions are supported. | |
237 */ | |
238 static bool get supportsTransitions => true; | |
239 $endif | |
240 $!MEMBERS | 201 $!MEMBERS |
241 $if DART2JS | |
242 """) | 202 """) |
243 | 203 |
244 for camelName in sorted(universal_properties): | 204 for camelName in sorted(universal_properties): |
245 property = dashifyName(camelName) | 205 property = dashifyName(camelName) |
246 class_file.write(""" | 206 class_file.write(""" |
247 /** Gets the value of "%s" */ | 207 /** Gets the value of "%s" */ |
248 String get %s => this._%s; | 208 String get %s => this._%s; |
249 | 209 |
250 /** Sets the value of "%s" */ | 210 /** Sets the value of "%s" */ |
251 set %s(String value) { | 211 set %s(String value) { |
252 _%s = value == null ? '' : value; | 212 _%s = value == null ? '' : value; |
253 } | 213 } |
254 @Returns('String') | 214 @Returns('String') |
255 @JSName('%s') | 215 @JSName('%s') |
256 String _%s; | 216 String _%s; |
257 """ % (property, camelName, camelName, | 217 """ % (property, camelName, camelName, |
258 property, camelName, camelName, | 218 property, camelName, camelName, |
259 camelName, camelName)) | 219 camelName, camelName)) |
260 | 220 |
261 class_file.write(""" | 221 class_file.write(""" |
262 $endif | |
263 } | 222 } |
264 | 223 |
265 class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase { | 224 class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase { |
266 final Iterable<Element> _elementIterable; | 225 final Iterable<Element> _elementIterable; |
267 Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable; | 226 Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable; |
268 | 227 |
269 _CssStyleDeclarationSet(this._elementIterable) { | 228 _CssStyleDeclarationSet(this._elementIterable) { |
270 _elementCssStyleDeclarationSetIterable = new List.from( | 229 _elementCssStyleDeclarationSetIterable = new List.from( |
271 _elementIterable).map((e) => e.style); | 230 _elementIterable).map((e) => e.style); |
272 } | 231 } |
273 | 232 |
274 String getPropertyValue(String propertyName) => | 233 String getPropertyValue(String propertyName) => |
275 _elementCssStyleDeclarationSetIterable.first.getPropertyValue( | 234 _elementCssStyleDeclarationSetIterable.first.getPropertyValue( |
276 propertyName); | 235 propertyName); |
277 | 236 |
278 void setProperty(String propertyName, String value, [String priority]) { | 237 void setProperty(String propertyName, String value, [String priority]) { |
279 _elementCssStyleDeclarationSetIterable.forEach((e) => | 238 _elementCssStyleDeclarationSetIterable.forEach((e) => |
280 e.setProperty(propertyName, value, priority)); | 239 e.setProperty(propertyName, value, priority)); |
281 } | 240 } |
282 | 241 |
283 """) | 242 """) |
284 | 243 |
285 class_file.write(""" | 244 class_file.write(""" |
286 $if DART2JS | |
287 void _setAll(String propertyName, String value) { | 245 void _setAll(String propertyName, String value) { |
288 value = value == null ? '' : value; | 246 value = value == null ? '' : value; |
289 for (Element element in _elementIterable) { | 247 for (Element element in _elementIterable) { |
290 JS('void', '#.style[#] = #', element, propertyName, value); | 248 JS('void', '#.style[#] = #', element, propertyName, value); |
291 } | 249 } |
292 } | 250 } |
293 """) | 251 """) |
294 | 252 |
295 | 253 |
296 for camelName in sorted(universal_properties): | 254 for camelName in sorted(universal_properties): |
297 property = dashifyName(camelName) | 255 property = dashifyName(camelName) |
298 class_file.write(""" | 256 class_file.write(""" |
299 /** Sets the value of "%s" */ | 257 /** Sets the value of "%s" */ |
300 set %s(String value) { | 258 set %s(String value) { |
301 _setAll('%s', value); | 259 _setAll('%s', value); |
302 } | 260 } |
303 """ % (property, camelName, camelName)) | 261 """ % (property, camelName, camelName)) |
304 | 262 |
305 class_file.write(""" | 263 class_file.write(""" |
306 $endif | |
307 | 264 |
308 // Important note: CssStyleDeclarationSet does NOT implement every method | 265 // Important note: CssStyleDeclarationSet does NOT implement every method |
309 // available in CssStyleDeclaration. Some of the methods don't make so much | 266 // available in CssStyleDeclaration. Some of the methods don't make so much |
310 // sense in terms of having a resonable value to return when you're | 267 // sense in terms of having a resonable value to return when you're |
311 // considering a list of Elements. You will need to manually add any of the | 268 // considering a list of Elements. You will need to manually add any of the |
312 // items in the MEMBERS set if you want that functionality. | 269 // items in the MEMBERS set if you want that functionality. |
313 } | 270 } |
314 | 271 |
315 $if DART2JS | |
316 abstract class CssStyleDeclarationBase { | 272 abstract class CssStyleDeclarationBase { |
317 String getPropertyValue(String propertyName); | 273 String getPropertyValue(String propertyName); |
318 void setProperty(String propertyName, String value, [String priority]); | 274 void setProperty(String propertyName, String value, [String priority]); |
319 $else | |
320 $if JSINTEROP | |
321 class CssStyleDeclarationBase { | |
322 String getPropertyValue(String propertyName) => | |
323 throw new StateError('getProperty not overridden in dart:html'); | |
324 void setProperty(String propertyName, String value, [String priority]) => | |
325 throw new StateError('setProperty not overridden in dart:html'); | |
326 $else | |
327 abstract class CssStyleDeclarationBase { | |
328 String getPropertyValue(String propertyName); | |
329 void setProperty(String propertyName, String value, [String priority]); | |
330 $endif | |
331 $endif | |
332 """) | 275 """) |
333 | 276 |
334 class_lines = []; | 277 class_lines = []; |
335 | 278 |
336 seen = set() | 279 seen = set() |
337 for prop in sorted(data, key=camelCaseName): | 280 for prop in sorted(data, key=camelCaseName): |
338 camel_case_name = camelCaseName(prop) | 281 camel_case_name = camelCaseName(prop) |
339 upper_camel_case_name = camel_case_name[0].upper() + camel_case_name[1:]; | 282 upper_camel_case_name = camel_case_name[0].upper() + camel_case_name[1:]; |
340 css_name = prop.replace('-webkit-', '') | 283 css_name = prop.replace('-webkit-', '') |
341 base_css_name = prop.replace('-webkit-', '') | 284 base_css_name = prop.replace('-webkit-', '') |
(...skipping 18 matching lines...) Expand all Loading... |
360 class_lines.append(annotated[base_css_name]) | 303 class_lines.append(annotated[base_css_name]) |
361 class_lines.append(""" | 304 class_lines.append(""" |
362 set %s(String value) { | 305 set %s(String value) { |
363 setProperty('%s', value, ''); | 306 setProperty('%s', value, ''); |
364 } | 307 } |
365 """ % (camel_case_name, css_name)) | 308 """ % (camel_case_name, css_name)) |
366 | 309 |
367 class_file.write(''.join(class_lines)); | 310 class_file.write(''.join(class_lines)); |
368 class_file.write('}\n') | 311 class_file.write('}\n') |
369 class_file.close() | 312 class_file.close() |
OLD | NEW |