/******************************************************************************* * Copyright (c) 2008 Innoopract Informationssysteme GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Innoopract Informationssysteme GmbH - initial API and implementation ******************************************************************************/ package org.eclipse.rwt.internal.theme.css; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.eclipse.rwt.internal.theme.QxBorder; import org.eclipse.rwt.internal.theme.QxBoxDimensions; import org.eclipse.rwt.internal.theme.QxColor; import org.eclipse.rwt.internal.theme.QxDimension; import org.eclipse.rwt.internal.theme.QxFont; import org.eclipse.rwt.internal.theme.QxImage; import org.eclipse.rwt.internal.theme.QxType; import org.eclipse.rwt.internal.theme.ResourceLoader; import org.w3c.css.sac.LexicalUnit; import org.w3c.css.sac.Selector; import org.w3c.css.sac.SelectorList; public class StyleSheet { private static final MatchedStyleRuleComparator COMPARATOR = new MatchedStyleRuleComparator(); private final StyleRule[] styleRules; private String[] variants; private String headerComment; public StyleSheet( final StyleRule[] styleRules ) { this.styleRules = styleRules; findClasses(); } public StyleRule[] getStyleRules() { return styleRules; } public StyleRule[] getMatchingStyleRules( final Element element ) { List buffer = new ArrayList(); for( int i = 0; i < styleRules.length; i++ ) { StyleRule rule = styleRules[ i ]; Selector selector = rule.getMatchingSelector( element ); if( selector != null ) { int specificity = ( ( Specific )selector ).getSpecificity(); buffer.add( new MatchedStyleRule( rule, specificity, i ) ); } } Collections.sort( buffer, COMPARATOR ); StyleRule[] result = new StyleRule[ buffer.size() ]; for( int i = 0; i < result.length; i++ ) { result[ i ] = ( ( MatchedStyleRule )buffer.get( i ) ).rule; } return result; } public QxType getValue( final String cssProperty, final StylableElement element, final ResourceLoader loader ) { QxType result = null; StyleRule[] rules = getMatchingStyleRules( element ); for( int i = 0; i < rules.length; i++ ) { StyleRule rule = rules[ i ]; StylePropertyMap properties = rule.getProperties(); LexicalUnit property = properties.getProperty( cssProperty ); if( property != null ) { if( "color".equals( cssProperty ) ) { result = readColor( properties ); } else if( "background-color".equals( cssProperty ) ) { result = readBackgroundColor( properties ); } else if( "background-image".equals( cssProperty ) ) { result = readBackgroundImage( properties, loader ); } else if( "border".equals( cssProperty ) ) { result = readBorder( properties ); } else if( "padding".equals( cssProperty ) ) { result = readPadding( properties ); } else if( "margin".equals( cssProperty ) ) { result = readMargin( properties ); } else if( "spacing".equals( cssProperty ) ) { result = readSpacing( properties ); } else if( "height".equals( cssProperty ) ) { result = readHeight( properties ); } else if( "width".equals( cssProperty ) ) { result = readWidth( properties ); } else if( "font".equals( cssProperty ) ) { result = readFont( properties ); } else if( cssProperty.startsWith( "rwt" ) && cssProperty.endsWith( "color" ) ) { result = readColor( properties, cssProperty ); } else if( "background-gradient-color".equals( cssProperty ) ) { result = readBackgroundColor( properties, cssProperty ); } else { // TODO [rst] Logging instead of sysout System.err.println( "unsupported css property: " + cssProperty ); } } } return result; } public String[] getVariants( final String elementName ) { return variants; } private void findClasses() { List list = new ArrayList(); for( int i = 0; i < styleRules.length; i++ ) { StyleRule rule = styleRules[ i ]; SelectorList selectors = rule.getSelectors(); int length = selectors.getLength(); for( int j = 0; j < length; j++ ) { SelectorExt selector = ( SelectorExt )selectors.item( j ); String[] classes = selector.getClasses(); if( classes != null ) { for( int k = 0; k < classes.length; k++ ) { String variant = classes[ k ]; if( !list.contains( variant ) ) { list.add( variant ); // System.out.println( "found variant: " + variant ); } } } } } variants = new String[ list.size() ]; list.toArray( variants ); } private static QxColor readColor( final StylePropertyMap properties ) { return readColor( properties, "color" ); } private static QxColor readColor( final StylePropertyMap properties, final String property ) { LexicalUnit unit = properties.getProperty( property ); QxColor result = PropertyResolver.readColor( unit ); return result != QxColor.TRANSPARENT ? result : null; } private static QxColor readBackgroundColor( final StylePropertyMap properties ) { return readBackgroundColor( properties, "background-color" ); } private static QxColor readBackgroundColor( final StylePropertyMap properties, final String property ) { LexicalUnit unit = properties.getProperty( property ); return PropertyResolver.readColor( unit ); } private QxFont readFont( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "font" ); return PropertyResolver.readFont( property ); } private QxImage readBackgroundImage( final StylePropertyMap properties, final ResourceLoader loader ) { LexicalUnit property = properties.getProperty( "background-image" ); return PropertyResolver.readBackgroundImage( property, loader ); } private QxBorder readBorder( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "border" ); return PropertyResolver.readBorder( property ); } private QxBoxDimensions readPadding( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "padding" ); return PropertyResolver.readBoxDimensions( property ); } private QxBoxDimensions readMargin( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "margin" ); return PropertyResolver.readBoxDimensions( property ); } private QxDimension readSpacing( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "spacing" ); return PropertyResolver.readDimension( property ); } private QxDimension readHeight( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "height" ); return PropertyResolver.readDimension( property ); } private QxDimension readWidth( final StylePropertyMap properties ) { LexicalUnit property = properties.getProperty( "width" ); return PropertyResolver.readDimension( property ); } static class MatchedStyleRuleComparator implements Comparator { public int compare( final Object object1, final Object object2 ) { MatchedStyleRule rule1 = ( MatchedStyleRule )object1; MatchedStyleRule rule2 = ( MatchedStyleRule )object2; int result = 0; if( rule1.specificity > rule2.specificity ) { result = 1; } else if( rule1.specificity < rule2.specificity ) { result = -1; } else if( rule1.position > rule2.position ) { result = 1; } else if( rule1.position < rule2.position ) { result = -1; } return result; } } static class MatchedStyleRule { public final StyleRule rule; public final int specificity; public final int position; public MatchedStyleRule( final StyleRule rule, final int specificity, final int position ) { this.rule = rule; this.specificity = specificity; this.position = position; } } /* * BEGIN Modification for Theme Editor */ public void setHeaderComment( final String headerComment ) { this.headerComment = headerComment; } public String getHeaderComment() { return headerComment; } public int getStyleRulePoition( StyleRule rule ) { int result = -1; for( int i = 0; i < styleRules.length; i++ ) { if( styleRules[ i ] == rule ) { result = i; } } return result; } // public IPropertyWrapper getValueWrapper( final String cssProperty, // final StylableElement element ) // { // IPropertyWrapper result = null; // StyleRule[] rules = getMatchingStyleRules( element ); // for( int i = 0; i < rules.length; i++ ) { // StyleRule rule = rules[ i ]; // StylePropertyMap properties = rule.getProperties(); // LexicalUnit property = properties.getProperty( cssProperty ); // if( property != null ) { // result = PropertyWrapperFactory.createPropertyWrapper( cssProperty, // property, // rule ); // } // } // if ( result == null ) { // result = PropertyWrapperFactory.createPropertyWrapper( cssProperty ); // } // return result; // } public String[] getVariants() { return variants; } /* * END Modification for Theme Editor */ }