Files
sdk/tools/dom/scripts/css_code_generator.py
T
leafp@google.com 8e3aaa4e75 Blink uses types in entry points
This CL changes the way that blink entry points are named to
use the type signature uniformly.  This makes us somewhat
more robust against changes in the idl.

BUG=
R=vsm@google.com

Review URL: https://codereview.chromium.org//552533004

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@40006 260f80e4-7a28-3924-810f-c04153c831b5
2014-09-09 00:17:15 +00:00

246 lines
8.0 KiB
Python

#!/usr/bin/python
#
# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""Generates CSSStyleDeclaration template file from css property definitions
defined in WebKit."""
import tempfile, os
COMMENT_LINE_PREFIX = ' * '
# TODO(efortuna): Pull from DEPS so that we have latest css *in sync* with our
# Dartium. Then remove the checked in CSSPropertyNames.in.
SOURCE_PATH = 'CSSPropertyNames.in'
#SOURCE_PATH = 'Source/WebCore/css/CSSPropertyNames.in'
TEMPLATE_FILE = '../templates/html/impl/impl_CSSStyleDeclaration.darttemplate'
# Supported annotations for any specific CSS properties.
annotated = {
'transition': '''@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)'''
}
def camelCaseName(name):
"""Convert a CSS property name to a lowerCamelCase name."""
name = name.replace('-webkit-', '')
words = []
for word in name.split('-'):
if words:
words.append(word.title())
else:
words.append(word)
return ''.join(words)
def GenerateCssTemplateFile():
data = open(SOURCE_PATH).readlines()
# filter CSSPropertyNames.in to only the properties
# TODO(efortuna): do we also want CSSPropertyNames.in?
data = [d[:-1] for d in data
if len(d) > 1
and not d.startswith('#')
and not d.startswith('//')
and not '=' in d]
class_file = open(TEMPLATE_FILE, 'w')
class_file.write("""
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py
// Source of CSS properties:
// %s
part of $LIBRARYNAME;
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS) class $CLASSNAME $EXTENDS with
$(CLASSNAME)Base $IMPLEMENTS {
factory $CLASSNAME() => new CssStyleDeclaration.css('');
factory $CLASSNAME.css(String css) {
final style = new Element.tag('div').style;
style.cssText = css;
return style;
}
String getPropertyValue(String propertyName) {
var propValue = _getPropertyValueHelper(propertyName);
return propValue != null ? propValue : '';
}
String _getPropertyValueHelper(String propertyName) {
if (_supportsProperty(_camelCase(propertyName))) {
return _getPropertyValue(propertyName);
} else {
return _getPropertyValue(Device.cssPrefix + propertyName);
}
}
/**
* Returns true if the provided *CSS* property name is supported on this
* element.
*
* Please note the property name camelCase, not-hyphens. This
* method returns true if the property is accessible via an unprefixed _or_
* prefixed property.
*/
bool supportsProperty(String propertyName) {
return _supportsProperty(propertyName) ||
_supportsProperty(_camelCase(Device.cssPrefix + propertyName));
}
bool _supportsProperty(String propertyName) {
$if DART2JS
return JS('bool', '# in #', propertyName, this);
$else
// You can't just check the value of a property, because there is no way
// to distinguish between property not being present in the browser and
// not having a value at all. (Ultimately we'll want the native method to
// return null if the property doesn't exist and empty string if it's
// defined but just doesn't have a value.
return _hasProperty(propertyName);
$endif
}
$if DARTIUM
bool _hasProperty(String propertyName) =>
_blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_DOMString(this, propertyName);
$endif
@DomName('CSSStyleDeclaration.setProperty')
void setProperty(String propertyName, String value, [String priority]) {
if (_supportsProperty(_camelCase(propertyName))) {
return _setPropertyHelper(propertyName, value, priority);
} else {
return _setPropertyHelper(Device.cssPrefix + propertyName, value,
priority);
}
}
static String _camelCase(String hyphenated) {
$if DART2JS
var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
var fToUpper = const JS_CONST(
r'function(_, letter) { return letter.toUpperCase(); }');
return JS('String', r'#.replace(/-([\da-z])/ig, #)', replacedMs, fToUpper);
$else
// The "ms" prefix is always lowercased.
return hyphenated.replaceFirst(new RegExp('^-ms-'), 'ms-').replaceAllMapped(
new RegExp('-([a-z]+)', caseSensitive: false),
(match) => match[0][1].toUpperCase() + match[0].substring(2));
$endif
}
$if DART2JS
void _setPropertyHelper(String propertyName, String value, [String priority]) {
// try/catch for IE9 which throws on unsupported values.
try {
if (value == null) value = '';
if (priority == null) {
priority = '';
}
JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
// Bug #2772, IE9 requires a poke to actually apply the value.
if (JS('bool', '!!#.setAttribute', this)) {
JS('void', '#.setAttribute(#, #)', this, propertyName, value);
}
} catch (e) {}
}
/**
* Checks to see if CSS Transitions are supported.
*/
static bool get supportsTransitions {
return document.body.style.supportsProperty('transition');
}
$else
void _setPropertyHelper(String propertyName, String value, [String priority]) {
if (priority == null) {
priority = '';
}
_setProperty(propertyName, value, priority);
}
/**
* Checks to see if CSS Transitions are supported.
*/
static bool get supportsTransitions => true;
$endif
$!MEMBERS
}
class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
final Iterable<Element> _elementIterable;
Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;
_CssStyleDeclarationSet(this._elementIterable) {
_elementCssStyleDeclarationSetIterable = new List.from(
_elementIterable).map((e) => e.style);
}
String getPropertyValue(String propertyName) =>
_elementCssStyleDeclarationSetIterable.first.getPropertyValue(
propertyName);
void setProperty(String propertyName, String value, [String priority]) {
_elementCssStyleDeclarationSetIterable.forEach((e) =>
e.setProperty(propertyName, value, priority));
}
// Important note: CssStyleDeclarationSet does NOT implement every method
// available in CssStyleDeclaration. Some of the methods don't make so much
// sense in terms of having a resonable value to return when you're
// considering a list of Elements. You will need to manually add any of the
// items in the MEMBERS set if you want that functionality.
}
abstract class CssStyleDeclarationBase {
String getPropertyValue(String propertyName);
void setProperty(String propertyName, String value, [String priority]);
""" % SOURCE_PATH)
class_lines = [];
seen = set()
for prop in sorted(data, key=lambda p: camelCaseName(p)):
camel_case_name = camelCaseName(prop)
upper_camel_case_name = camel_case_name[0].upper() + camel_case_name[1:];
css_name = prop.replace('-webkit-', '')
base_css_name = prop.replace('-webkit-', '')
if base_css_name in seen or base_css_name.startswith('-internal'):
continue
seen.add(base_css_name)
comment = ' /** %s the value of "' + base_css_name + '" */'
class_lines.append('\n');
class_lines.append(comment % 'Gets')
if base_css_name in annotated:
class_lines.append(annotated[base_css_name])
class_lines.append("""
String get %s =>
getPropertyValue('%s');
""" % (camel_case_name, css_name))
class_lines.append(comment % 'Sets')
if base_css_name in annotated:
class_lines.append(annotated[base_css_name])
class_lines.append("""
void set %s(String value) {
setProperty('%s', value, '');
}
""" % (camel_case_name, css_name))
class_file.write(''.join(class_lines));
class_file.write('}\n')
class_file.close()