blob: b5b9b779c09d4f1c5dd1c7126085ae4fa6eea596 [file] [log] [blame]
/*******************************************************************************
* 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
*/
}