| Index: tools/dom/scripts/css_code_generator.py
|
| diff --git a/tools/dom/scripts/css_code_generator.py b/tools/dom/scripts/css_code_generator.py
|
| index 11bf7bcbf63ab04d2a66e2c3307fbbbe35bcd465..18351ae6aad32ddbaa0fd5c0bd9ca7417b085b3d 100644
|
| --- a/tools/dom/scripts/css_code_generator.py
|
| +++ b/tools/dom/scripts/css_code_generator.py
|
| @@ -1,28 +1,28 @@
|
| -#!/usr/bin/python2.6
|
| +#!/usr/bin/python
|
| #
|
| -# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
| +# 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 from css property definitions defined in WebKit."""
|
| +"""Generates CSSStyleDeclaration template file from css property definitions
|
| +defined in WebKit."""
|
|
|
| import tempfile, os
|
|
|
| COMMENT_LINE_PREFIX = ' * '
|
| -SOURCE_PATH = 'Source/WebCore/css/CSSPropertyNames.in'
|
| -INPUT_URL = 'http://trac.webkit.org/export/latest/trunk/%s' % SOURCE_PATH
|
| -INTERFACE_FILE = '../../html/src/CSSStyleDeclaration.dart'
|
| -CLASS_FILE = '../../html/src/CSSStyleDeclarationWrappingImplementation.dart'
|
| -
|
| -def main():
|
| - _, css_names_file = tempfile.mkstemp('.CSSPropertyNames.in')
|
| - try:
|
| - if os.system('wget %s -O %s' % (INPUT_URL, css_names_file)):
|
| - return 1
|
| - generate_code(css_names_file)
|
| - print 'Successfully generated %s and %s' % (INTERFACE_FILE, CLASS_FILE)
|
| - finally:
|
| - os.remove(css_names_file)
|
| +# 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."""
|
| @@ -35,165 +35,196 @@ def camelCaseName(name):
|
| words.append(word)
|
| return ''.join(words)
|
|
|
| -def generate_code(input_path):
|
| - data = open(input_path).readlines()
|
| +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]
|
|
|
| - interface_file = open(INTERFACE_FILE, 'w')
|
| - class_file = open(CLASS_FILE, 'w')
|
| -
|
| - interface_file.write("""
|
| -// Copyright (c) 2011, 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 file was generated by html/scripts/css_code_generator.py
|
| -
|
| -// Source of CSS properties:
|
| -// %s
|
| -
|
| -// TODO(jacobr): add versions that take numeric values in px, miliseconds, etc.
|
| -
|
| -interface CSSStyleDeclaration {
|
| -
|
| - String get cssText;
|
| -
|
| - void set cssText(String value);
|
| -
|
| - int get length;
|
| -
|
| - CSSRule get parentRule;
|
| -
|
| - CSSValue getPropertyCSSValue(String propertyName);
|
| -
|
| - String getPropertyPriority(String propertyName);
|
| -
|
| - String getPropertyShorthand(String propertyName);
|
| -
|
| - String getPropertyValue(String propertyName);
|
| -
|
| - bool isPropertyImplicit(String propertyName);
|
| -
|
| - String item(int index);
|
| -
|
| - String removeProperty(String propertyName);
|
| -
|
| - void setProperty(String propertyName, String value, [String priority]);
|
| -
|
| -""".lstrip() % SOURCE_PATH)
|
| -
|
| + class_file = open(TEMPLATE_FILE, 'w')
|
|
|
| class_file.write("""
|
| -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
| +// 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 file was generated by html/scripts/css_code_generator.py
|
| +// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
|
| +// The template file was generated by scripts/css_code_generator.py
|
|
|
| // Source of CSS properties:
|
| // %s
|
|
|
| -// TODO(jacobr): add versions that take numeric values in px, miliseconds, etc.
|
| -
|
| -class CSSStyleDeclarationWrappingImplementation extends DOMWrapperBase implements CSSStyleDeclaration {
|
| - static String _cachedBrowserPrefix;
|
| +part of $LIBRARYNAME;
|
|
|
| - CSSStyleDeclarationWrappingImplementation._wrap(ptr) : super._wrap(ptr) {}
|
| +$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS) class $CLASSNAME $EXTENDS with
|
| + $(CLASSNAME)Base $IMPLEMENTS {
|
| + factory $CLASSNAME() => new CssStyleDeclaration.css('');
|
|
|
| - static String get _browserPrefix {
|
| - if (_cachedBrowserPrefix == null) {
|
| - if (_Device.isFirefox) {
|
| - _cachedBrowserPrefix = '-moz-';
|
| - } else {
|
| - _cachedBrowserPrefix = '-webkit-';
|
| - }
|
| - // TODO(jacobr): support IE 9.0 and Opera as well.
|
| - }
|
| - return _cachedBrowserPrefix;
|
| + factory $CLASSNAME.css(String css) {
|
| + final style = new Element.tag('div').style;
|
| + style.cssText = css;
|
| + return style;
|
| }
|
|
|
| - String get cssText { return _ptr.cssText; }
|
| -
|
| - void set cssText(String value) { _ptr.cssText = value; }
|
| -
|
| - int get length { return _ptr.length; }
|
| -
|
| - CSSRule get parentRule { return LevelDom.wrapCSSRule(_ptr.parentRule); }
|
| -
|
| - CSSValue getPropertyCSSValue(String propertyName) {
|
| - return LevelDom.wrapCSSValue(_ptr.getPropertyCSSValue(propertyName));
|
| + String getPropertyValue(String propertyName) {
|
| + var propValue = _getPropertyValueHelper(propertyName);
|
| + return propValue != null ? propValue : '';
|
| }
|
|
|
| - String getPropertyPriority(String propertyName) {
|
| - return _ptr.getPropertyPriority(propertyName);
|
| + String _getPropertyValueHelper(String propertyName) {
|
| + if (_supportsProperty(_camelCase(propertyName))) {
|
| + return _getPropertyValue(propertyName);
|
| + } else {
|
| + return _getPropertyValue(Device.cssPrefix + propertyName);
|
| + }
|
| }
|
|
|
| - String getPropertyShorthand(String propertyName) {
|
| - return _ptr.getPropertyShorthand(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));
|
| }
|
|
|
| - String getPropertyValue(String propertyName) {
|
| - return _ptr.getPropertyValue(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(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);
|
| + }
|
| }
|
|
|
| - bool isPropertyImplicit(String propertyName) {
|
| - return _ptr.isPropertyImplicit(propertyName);
|
| + String _camelCase(String hyphenated) {
|
| + bool firstWord = true;
|
| + return hyphenated.splitMapJoin('-', onMatch : (_) => '',
|
| + onNonMatch : (String word) {
|
| + if (word.length > 0) {
|
| + if (firstWord) {
|
| + firstWord = false;
|
| + return word;
|
| + }
|
| + return word[0].toUpperCase() + word.substring(1);
|
| + }
|
| + return '';
|
| + });
|
| }
|
|
|
| - String item(int index) {
|
| - return _ptr.item(index);
|
| +$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) {}
|
| }
|
|
|
| - String removeProperty(String propertyName) {
|
| - return _ptr.removeProperty(propertyName);
|
| + /**
|
| + * Checks to see if CSS Transitions are supported.
|
| + */
|
| + static bool get supportsTransitions {
|
| + return supportsProperty('transition');
|
| + }
|
| +$else
|
| + void _setPropertyHelper(String propertyName, String value, [String priority]) {
|
| + if (priority == null) {
|
| + priority = '';
|
| + }
|
| + _setProperty(propertyName, value, priority);
|
| }
|
|
|
| - void setProperty(String propertyName, String value, [String priority = '']) {
|
| - _ptr.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 get typeName { return "CSSStyleDeclaration"; }
|
| + String getPropertyValue(String propertyName) =>
|
| + _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
|
| + propertyName);
|
|
|
| -""".lstrip() % SOURCE_PATH)
|
| + 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)
|
|
|
| - interface_lines = [];
|
| 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-', '${_browserPrefix}')
|
| + css_name = prop.replace('-webkit-', '')
|
| base_css_name = prop.replace('-webkit-', '')
|
|
|
| - if base_css_name in seen:
|
| + 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 + '" */'
|
| -
|
| - interface_lines.append(comment % 'Gets')
|
| - interface_lines.append("""
|
| - String get %s;
|
| -
|
| -""" % camel_case_name)
|
| -
|
| - interface_lines.append(comment % 'Sets')
|
| - interface_lines.append("""
|
| - void set %s(String value);
|
| -
|
| -""" % camel_case_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');
|
| @@ -201,19 +232,14 @@ class CSSStyleDeclarationWrappingImplementation extends DOMWrapperBase implement
|
| """ % (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))
|
|
|
| - interface_file.write(''.join(interface_lines));
|
| - interface_file.write('}\n')
|
| - interface_file.close()
|
| -
|
| class_file.write(''.join(class_lines));
|
| class_file.write('}\n')
|
| class_file.close()
|
| -
|
| -if __name__ == '__main__':
|
| - main()
|
|
|