You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by aw...@apache.org on 2006/06/30 22:53:13 UTC

svn commit: r418407 - in /incubator/adffaces/trunk/adf-faces: adf-faces-demo/src/main/webapp/skins/purple/ adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/ adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/ adf-fac...

Author: awiner
Date: Fri Jun 30 15:53:12 2006
New Revision: 418407

URL: http://svn.apache.org/viewvc?rev=418407&view=rev
Log:
ADFFACES-27: Add agent and platform support to skinning's css file.  Thanks to Jeanne Waldman for the patch.

Modified:
    incubator/adffaces/trunk/adf-faces/adf-faces-demo/src/main/webapp/skins/purple/purpleSkin.css
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSDocumentHandler.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSParser.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetNode.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetParserUtils.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/CSSGenerationUtils.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetDocument.java
    incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetNode.java

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-demo/src/main/webapp/skins/purple/purpleSkin.css
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-demo/src/main/webapp/skins/purple/purpleSkin.css?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-demo/src/main/webapp/skins/purple/purpleSkin.css (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-demo/src/main/webapp/skins/purple/purpleSkin.css Fri Jun 30 15:53:12 2006
@@ -14,6 +14,8 @@
 * limitations under the License.
 */
 
+
+
 /** Change the colors to purple **/
 
 /** All these styles/icons/properties are overrides of the simple skin */
@@ -99,7 +101,7 @@
 }
 
 af|showOneTab::separator {
-  margin-width:4px;
+  margin:4px;
   border-top: #BB95BB; solid 4pt ;
   border-bottom: #BB95BB; solid 4pt ;
   BACKGROUND-COLOR: white;
@@ -350,19 +352,6 @@
    font-size:larger;
 }
 
-/** selectInputDate launch icon **/
-af|selectInputDate::launch-icon
-{
-  content:url(/skins/purple/images/dateButtonPurple.gif); 
-  width:19px; 
-  height:24px
-}
-af|selectInputDate::launch-icon:rtl
-{
-  content:url(/skins/purple/images/dateButtonPurpleRTL.gif); 
-  width:19px; 
-  height:24px
-}
 
 /** processTrain **/
 /** ------------ **/
@@ -400,6 +389,20 @@
   content:url(/skins/purple/images/checkdc.gif);
 }
 
+/** selectInputDate launch icon **/
+af|selectInputDate::launch-icon
+{
+  content:url(/skins/purple/images/dateButtonPurple.gif); 
+  width:19px; 
+  height:24px
+}
+af|selectInputDate::launch-icon:rtl
+{
+  content:url(/skins/purple/images/dateButtonPurpleRTL.gif); 
+  width:19px; 
+  height:24px
+}
+
 /* use special properties to change the ui **/
 /* don't show the last item in navigationPath (the default is to show it)*/
 
@@ -525,4 +528,41 @@
 af|inputText::label:rtl
 {
   font-weight:bold;
+}
+
+/* test @agent and @platform styles */
+/* right now @agent/@platform work with style selectors, but they have no
+   effect on icon selectors. */
+/* possible values for @agent are: 
+netscape, ie, mozilla, gecko, webkit, ice */
+/* possible values for @platform are: 
+windows, macos, linux, solaris, ppc */
+
+@agent ie
+{
+  af|panelBox::header
+  {
+    text-overflow: ellipsis;
+  }
+
+  .DropShadowStyle
+  {
+    width: 357; 
+    height: 50; 
+    font-size: 36pt; 
+    font-family: Arial Black; 
+    color: blue; 
+    Filter: DropShadow(Color=#FF0000, OffX=2, OffY=2, Positive=1); 
+    
+  }
+}
+
+
+@platform windows, linux, solaris
+{
+  /** for ie and gecko on windows, linux and solaris, make the color pink **/
+  @agent ie, gecko
+  {
+    af|inputText::content {background-color:pink}
+  }
 }

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSDocumentHandler.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSDocumentHandler.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSDocumentHandler.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSDocumentHandler.java Fri Jun 30 15:53:12 2006
@@ -15,131 +15,141 @@
 */
 package org.apache.myfaces.adfinternal.skin;
 
+import java.io.StringReader;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.myfaces.adfinternal.agent.AdfFacesAgent;
+import org.apache.myfaces.adfinternal.style.util.NameUtils;
 import org.apache.myfaces.adfinternal.style.util.StyleUtils;
 import org.apache.myfaces.adfinternal.style.xml.parse.PropertyNode;
+import org.apache.myfaces.adfinternal.util.IntegerUtils;
 import org.apache.myfaces.adfinternal.util.nls.LocaleUtils;
 
-/** As the Skin css file is parsed, methods in this class are called to
- * build up a SkinStyleSheetNode.
- */
+ /** As the Skin css file is parsed, methods in this class are called to
+  * build up a SkinStyleSheetNode.
+  */
 public class SkinCSSDocumentHandler
 {
- 
+
+  
   /**
    * Return the List of SkinStyleSheetNodes that was created
    *  at the end of parsing the skin css file (endDocument).
    */
   public List <SkinStyleSheetNode> getSkinStyleSheetNodes()
   {
-    return _skinStyleSheetNodes;  
+    // We now have a list of CompleteSelectorNodes.
+    // We need to group this list into stylesheet nodes by matching 
+    // the additional information, like direction.
+    // Then we create a list of SkinStyleSheetNodes.
+    return 
+      _createSkinStyleSheetNodes(_completeSelectorNodeList, _namespaceMap);
   }
-  
+   
   /**
-   * Call this at the start of parsing the skin css file.
-   */
+  * Call this at the start of parsing the skin css file.
+  */
   public void startDocument()
   {
-    _namespaceMap = new HashMap();
-    _completeSelectorNodeList = new ArrayList();
+    // do nothing
   }
-  
+   
   /**
-   * Call this at the end of parsing the skin css file.
-   */
+  * Call this at the end of parsing the skin css file.
+  */
   public void endDocument()
   {
-    // We now have a list of CompleteSelectorNodes.
-    // We need to group this list into stylesheet nodes by matching 
-    // the additional information, like direction.
-    // Then we create a list of SkinStyleSheetNodes.
-    _skinStyleSheetNodes = 
-      _createSkinStyleSheetNodes(_completeSelectorNodeList, _namespaceMap);
+    // do nothing
   }
 
   public void comment(String text)
   {
-    // ignore comments
+     // ignore comments
   }
-  
+   
   /**
-   * Call this at the beginning of parsing one set of selectors/properties.
-   * e.g., .AFDefaultFont, af|navigationPath::font 
-   * {font-family:Arial,Helvetica; font-size:small}
-   */
+  * Call this at the beginning of parsing one set of selectors/properties.
+  * e.g., .AFDefaultFont, af|navigationPath::font 
+  * {font-family:Arial,Helvetica; font-size:small}
+  */
   public void startSelector()
   {
     _inStyleRule = true;
     _propertyNodeList = new ArrayList();
   }
-  
+   
   /**
    * Call this at the end of parsing one set of selectors/properties.
    * @param selectors A List of Strings, each String is a selector.
    * e.g., given the selectors/properties:
    * .AFDefaultFont, af|navigationPath::font 
    * {font-family:Arial,Helvetica; font-size:small}
-   * The selectors are ".AFDefaultFont" and "af|navigationPath::font"
-   */
+   * The selectors in the List are 
+   * ".AFDefaultFont" and "af|navigationPath::font"
+  */
   public void endSelector(List selectors)
   {
     if (selectors == null)
       return;
+      
     int selectorNum = selectors.size();
+    
     for (int i = 0; i < selectorNum; i++)
     {
-      String selector = (String)selectors.get(i);
-      CompleteSelectorNode node =
-        _createCompleteSelectorNode(selector, _propertyNodeList);
-      _completeSelectorNodeList.add(node);
+       String selector = (String)selectors.get(i);
+       CompleteSelectorNode node =
+         _createCompleteSelectorNode(selector, 
+                                     _propertyNodeList,
+                                     _selectorAgents,
+                                     _selectorPlatforms);
+       _completeSelectorNodeList.add(node);
     }
+    // reset flags
     _inStyleRule = false;
     _propertyNodeList = null;
   }
 
-  /**
-   * Call this when a property name/value is found.
-   * e.g., given the selectors/properties:
-   * .AFDefaultFont, af|navigationPath::font 
-   * {font-family:Arial,Helvetica; font-size:small}
-   * One property name/value pair is "font-family"/"Arial,Helvetica"
-   * @param name 
-   * @param value 
-   */
+   /**
+    * Call this when a property name/value is found.
+    * e.g., given the selectors/properties:
+    * .AFDefaultFont, af|navigationPath::font 
+    * {font-family:Arial,Helvetica; font-size:small}
+    * One property name/value pair is "font-family"/"Arial,Helvetica"
+    * @param name 
+    * @param value 
+    */
   public void property(String name, String value)
   {
+
     if (_inStyleRule && (_propertyNodeList != null))
     {
       _propertyNodeList.add(new PropertyNode(name, value));
     }
   }
 
-  /**
-   * Call when you have an @ rule. This adds the @ rule to the object's
-   * namespaceMap.
-   * @param name The @rule string, which contains the entire line with the
-   * @ rule, which ends with a semicolon.
-   * e.g., @namespace af url(http:\\www.xxx.com)
-   */
-  public void atRule(String name)
+ /**
+  * Call when you have an atRule. This will do further processing.
+  * @param atRule The @rule string
+  * e.g., @namespace af url(http:\\www.xxx.com);
+  * e.g., @agent gecko { .foo {color:red}}
+  */
+  public void atRule(String atRule)
   {
     // parse the atRule further here.
-    // name will be something like:
-    // "namespace af url(asdfadfadf)"
-    if (name != null)
+    if (atRule != null)
     {
-      if (name.startsWith("@namespace"))
+      if (atRule.startsWith("@namespace"))
       {
-        // @todo deal with default namespaces that don't have prefixes??
-        String[] namespaceParts = name.split("\\s+");
+        // TODO deal with default namespaces that don't have prefixes??
+        String[] namespaceParts = atRule.split("\\s+");
         if (namespaceParts.length > 2)
         {
           String url = namespaceParts[2];
-          
+           
           // first, strip off the url( and );
           if (url.startsWith("url("))
             url = url.substring(4);
@@ -147,20 +157,76 @@
             url = url.substring(0, url.length() - 2);
           else if (url.endsWith(";"))
             url = url.substring(0, url.length() - 1);
-            
+             
           // second, strip off the starting/ending quotes if there are any                    
           url = SkinStyleSheetParserUtils.trimQuotes(url);
           _namespaceMap.put(namespaceParts[1], url);
         }
       }
+      else if (atRule.startsWith(_AT_AGENT))
+      {
+        _parseCustomAtRule(_AT_AGENT, atRule);
+      }
+      else if (atRule.startsWith(_AT_PLATFORM))
+      {
+        _parseCustomAtRule(_AT_PLATFORM, atRule);        
+      }
+      // for now, ignore other atRules in a skinning css file
+      
     }
   }
 
-  // create a CompleteSelectorNode (this is the selector, properties, and
-  // additional info, like 'rtl' direction
+  /** Get the atRule, and send its contents through the SkinCSSParser
+   * again, using the current DocumentHandler object. The start/end
+   * callbacks will be called again, but in the context of the atRule.
+   */
+  private void _parseCustomAtRule(String type, String atRule)
+  {
+    // get the @agent agents, they are deliminated by commas
+    // parse out the content
+    // save the atRule type, so the document handler code can get to it.
+    // run this through parser again
+    String content = _getAtRuleContent(atRule);
+    int[] targetTypes = _getAtRuleTargetTypes(type, atRule);
+    _setAtRuleTargetTypes(type, targetTypes);
+    
+    // use this current DocumentHandler. This way we can add to the 
+    // CompleteSelectorNode list with agent information.
+    SkinCSSParser parser = new SkinCSSParser();
+    parser.parseCSSDocument(new StringReader(content), this);
+    
+    // reset
+    _resetAtRuleTargetTypes(type);
+
+  }
+  
+  private void _setAtRuleTargetTypes(
+    String type,
+    int[]  targetTypes)
+  {
+    
+    if (type == _AT_AGENT)
+      _selectorAgents = targetTypes;
+    else if (type == _AT_PLATFORM)
+      _selectorPlatforms = targetTypes;
+  }
+  
+  private void _resetAtRuleTargetTypes(
+    String type)
+  {
+    if (type == _AT_AGENT)
+      _selectorAgents = null;
+    else if (type == _AT_PLATFORM)
+      _selectorPlatforms = null;
+  }
+  
+   // create a CompleteSelectorNode (this is the selector, properties, and
+   // additional info, like 'rtl' direction
   private CompleteSelectorNode _createCompleteSelectorNode(
     String selector, 
-    List  propertyNodeList)
+    List  propertyNodeList,
+    int[] selectorAgents,
+    int[] selectorPlatforms)
   {
     // parse the selector to see if there is a :rtl or :ltr ending.
     // if so, then set the reading direction.
@@ -174,84 +240,173 @@
     }
     else if (selector.endsWith(StyleUtils.LTR_CSS_SUFFIX))
     {
-      int length = StyleUtils.LTR_CSS_SUFFIX.length();
-      // strip off the SUFFIX  
-      selector = selector.substring(0, selector.length()-length);
-      direction = LocaleUtils.DIRECTION_LEFTTORIGHT;
+       int length = StyleUtils.LTR_CSS_SUFFIX.length();
+       // strip off the SUFFIX  
+       selector = selector.substring(0, selector.length()-length);
+       direction = LocaleUtils.DIRECTION_LEFTTORIGHT;
     }
 
     return 
-      new CompleteSelectorNode(selector, propertyNodeList, direction);
+      new CompleteSelectorNode(
+        selector, 
+        propertyNodeList, 
+        direction, 
+        selectorAgents, 
+        selectorPlatforms);
   }
 
   /**
-   * Given a List of CompleteSelectorNodes, we create a List of 
-   * SkinStyleSheetNodes. We do this by looping through each
-   * CompleteSeletcorNode and finding the SkinStyleSheetNode with matching
-   * direction attribute (someday we'll add locale, browser, etc), or 
-   * creaing a new SkinStyleSheetNode if a matching one doesn't exist.
-   * @param selectorList a list of CompleteSelectorNodes.
-   * @param namespaceMap the namespace map
-   * @return a List of SkinStyleSheetNodes
-   */
+    * Given a List of CompleteSelectorNodes (selector nodes with
+    * infor about selectors, properties, direction, agent), we create a List of 
+    * SkinStyleSheetNodes.
+    * @param selectorList a list of CompleteSelectorNodes.
+    * @param namespaceMap the namespace map
+    * @return a List of SkinStyleSheetNodes
+    */
   private List <SkinStyleSheetNode> _createSkinStyleSheetNodes(
     List <CompleteSelectorNode> selectorList, 
     Map namespaceMap)
   {  
-    List <SkinStyleSheetNode> ssNodeList = new ArrayList();
-    // to start with ssNodeList is empty
-    // for each selector node, look to see if we can find a SkinStyleSheetNode
-    // that it belongs to (by matching direction).
-    // if not, create a new ssNode, and add it to the ssNodeList, and
-    // add the selector node to the ssNode.
-    
+    List <SkinStyleSheetNode> skinStyleSheetNodes = new ArrayList();
+     
     for (CompleteSelectorNode completeSelectorNode : selectorList) 
     {
-       // we add to the ssNodeList in this method.
-        int direction = completeSelectorNode.getDirection();
-        // loop through the skinStyleSheetNodeList to find a match
-        boolean match = false;
-        for (SkinStyleSheetNode ssNode : ssNodeList) 
-        {
-            int ssNodeDirection = ssNode.getDirection();
-            if (ssNodeDirection == direction)
-            {
-              // got a match! use this one to add the selector node to.
-              ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
-              match = true;
-              break;
-            }        
-        }
-        if (!match)
-        {
-          // no matching stylesheet node found, so create a new one
-           SkinStyleSheetNode ssNode = 
-            new SkinStyleSheetNode(namespaceMap, direction);
-           ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
-           // add the ssNode to the ssNodeList
-           ssNodeList.add(ssNode);
-        }
-           
+      // we add to the ssNodeList in this method.
+      int direction = completeSelectorNode.getDirection();
+      int[] agents = completeSelectorNode.getAgents();
+      int[] platforms = completeSelectorNode.getPlatforms();
+         
+      // loop through the skinStyleSheetNodeList to find a match
+      // of direction, agents, platforms, etc.
+      boolean match = false;
+         
+      // iterate backwards, because the last node is most likely the
+      // matching stylesheetnode.
+      for (int i=skinStyleSheetNodes.size()-1; i >=0 && !match; i--)
+      {
+        SkinStyleSheetNode ssNode = skinStyleSheetNodes.get(i);
+        match = ssNode.matches(direction, agents, platforms);
+        if (match)
+          ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
+      }
+
+      if (!match)
+      {
+       // no matching stylesheet node found, so create a new one
+        SkinStyleSheetNode ssNode = 
+         new SkinStyleSheetNode(namespaceMap, direction, agents, platforms);
+        ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
+        skinStyleSheetNodes.add(ssNode);
+      }       
     }
-     
-    return ssNodeList;
-     
+    return skinStyleSheetNodes;
   }
 
   /**
-   * This Class contains a SkinSelectorPropertiesNode and a rtl direction.
-   * We will use this information when creating a SkinStyleSheetNode.
+   * 
+   * @param type type of the at rule. _AT_AGENT or _AT_PLATFORM
+   * @param atRule - the atRule string
+   * @return int[] the target types using AdfFacesAgent constants like
+   * AdfFacesAgent.APPLICATION_IEXPLORER
    */
+  private int[] _getAtRuleTargetTypes(
+    String type, 
+    String atRule)
+  {
+    // given the atRule string, get the target types --
+    // @agent ie, gecko {...} => target types are the 
+    // AdfFacesAgent constants for ie and gecko.
+    int firstSpace = atRule.indexOf(' ');
+    int openBrace = atRule.indexOf('{');
+    if (firstSpace != -1 && openBrace != -1)
+    {
+      String types = atRule.substring(firstSpace, openBrace);
+      String[] typeArray = types.split(",");
+      List <Integer> list = new ArrayList();
+      
+      if (type == _AT_AGENT)
+      {
+        for (int i=0; i < typeArray.length; i++)
+        {
+          int agentInt = NameUtils.getBrowser(typeArray[i].trim());
+          
+          if (agentInt != AdfFacesAgent.APPLICATION_UNKNOWN)
+            list.add(IntegerUtils.getInteger(agentInt));
+        }
+      }
+      else if (type == _AT_PLATFORM)
+      {
+        for (int i=0; i < typeArray.length; i++)
+        {
+          int platformInt = NameUtils.getPlatform(typeArray[i].trim());           
+
+          if (platformInt != AdfFacesAgent.OS_UNKNOWN)
+            list.add(IntegerUtils.getInteger(platformInt));
+        }          
+      }
+      return _getIntArray(list);
+   }
+   else return null;
+  }
+
+  // Copies Integers from a List of Integers into an int array
+  private int[] _getIntArray(List <Integer> integerList)
+  {
+    int count = integerList.size();
+  
+    if (count == 0)
+      return null;
+  
+    int[] array = new int[count];
+  
+    for (int i = 0; i < count; i++)
+      array[i] = integerList.get(i).intValue();
+  
+    return array;
+  }
+   
+   /**
+    * 
+    * @param atRule - the entire @rule's definition, including content.
+    * e.g., @agent ie, gecko { af|inputText::content {color:red}}
+    * @return the content as a String
+    * e.g., "af|inputText::content {color:red}"
+    */
+  private String _getAtRuleContent(String atRule)
+  {
+    int openBraceIndex = atRule.indexOf('{');
+    int endBraceIndex = atRule.lastIndexOf('}');
+    if (endBraceIndex == -1) 
+      endBraceIndex = atRule.length();
+      
+    if (openBraceIndex == -1)
+      return null;
+    else
+     return atRule.substring(openBraceIndex+1, endBraceIndex);
+   
+  }
+   
+
+   /**
+    * This Class contains a SkinSelectorPropertiesNode and a rtl direction.
+    * We will use this information when creating a SkinStyleSheetNode.
+    */
   private static class CompleteSelectorNode
   {
     public CompleteSelectorNode(
       String selectorName,
       List   propertyNodes,
-      int    direction
+      int    direction,
+      int[]  agents,
+      int[]  platforms
       )
     {
       _node = new SkinSelectorPropertiesNode(selectorName, propertyNodes);
       _direction = direction;
+      // copy the agents and platforms because these get nulled out 
+      // at the end of the @rule parsing.
+      _agents = _copyIntArray(agents);
+      _platforms = _copyIntArray(platforms);
     }
     
     public SkinSelectorPropertiesNode getSkinSelectorPropertiesNode()
@@ -264,23 +419,52 @@
       return _direction;
     }
     
+    public int[] getAgents()
+    {
+      return _agents;
+    }
+    
+    public int[] getPlatforms()
+    {
+      return _platforms;
+    }
+    
+    // Returns a copy of the int array
+    private static int[] _copyIntArray(int[] array)
+    {
+      if (array == null)
+        return null;
+    
+      int[] copy = new int[array.length];
+      System.arraycopy(array, 0, copy, 0, array.length);
+    
+      return copy;
+    }
+     
     private SkinSelectorPropertiesNode _node;
     private int _direction;  // the reading direction
-  }
-  
-  private boolean _inStyleRule = false;
- 
-  private List <SkinStyleSheetNode> _skinStyleSheetNodes = null;
-
-  private List _propertyNodeList = null;
+    private int[] _agents;
+    private int[] _platforms;
 
-  // we build this list in this document handler. We use this 
-  // list to create a list of 
-  // SkinStyleSheetNodes and SkinSelectorPropertiesNodes
-  private List <CompleteSelectorNode> _completeSelectorNodeList;
+  }
 
-  private Map _namespaceMap;
+  private static String _AT_AGENT = "@agent";
+  private static String _AT_PLATFORM = "@platform";
 
-}  
-  
+  // below are properties that we set and reset 
+  // as the methods of this documentHandler get called.
+  private boolean _inStyleRule = false;
+  private List _propertyNodeList = null;
+  // we build this list as we parse the skinning css file. We use this 
+  // list to create a list of SkinStyleSheetNodes
+  private List <CompleteSelectorNode> _completeSelectorNodeList = 
+    new ArrayList<CompleteSelectorNode>();
+  // these are the selector platform and agents of the selectors we
+  // are currently parsing in this document.
+  private int[] _selectorPlatforms = null;
+  private int[] _selectorAgents = null;
+  private Map _namespaceMap = new HashMap();
   
+}  
+   
+   

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSParser.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSParser.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSParser.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinCSSParser.java Fri Jun 30 15:53:12 2006
@@ -292,12 +292,56 @@
           case '@':
             if (_type != CSSLexicalUnits.LEFT_CURLY_BRACE)
             {
+              // found @.
+              // @namespace is treated differently than other @rules.
+              // These are the formats:
+              // @namespace foo url(http://www.foo.com);
+              // @agent {
+              //    af|inputText::content{color:red; background-color:blue;}
+              // }
+              // @platform {...}
+              // If @namespace, go 'til the semi-colon
+              // Else, go until the start/end brace match.
+
               // found @. keep getting characters until we get a ; or end of file.
+              /*
               _nextChar();
+
               while ((_currentChar != -1) && (_currentChar != ';'))
               {
                 _nextChar();
               }
+              */
+              _nextChar();
+              boolean foundEnd = false;
+              // go until ; or until {} match
+              int openBraceCount = 0;
+              boolean openBraceCountStarted = false;
+              while ((_currentChar != -1))
+              {
+
+                if (_currentChar == '{')
+                  openBraceCount++;
+                if (openBraceCount == 1)
+                  openBraceCountStarted = true;
+                if (_currentChar == '}' && openBraceCountStarted)
+                {
+                  openBraceCount--;
+                  if (openBraceCountStarted && openBraceCount == 0)
+                  {
+                    foundEnd = true;
+                    break;
+                  }
+                }
+                if (_currentChar == ';' && openBraceCount==0)
+                {
+                  foundEnd = true;
+                  break;
+                }
+                _nextChar();
+
+              }
+             
   
               _type = CSSLexicalUnits.AT_KEYWORD;
               return;

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetNode.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetNode.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetNode.java Fri Jun 30 15:53:12 2006
@@ -17,6 +17,7 @@
 package org.apache.myfaces.adfinternal.skin;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -38,22 +39,28 @@
     SkinStyleSheetNode(
       List <SkinSelectorPropertiesNode> skinSelectorNodeList,
       Map  namespaceMap,
-      int  direction
+      int  direction,
+      int[] agents
       )
     {
       _skinSelectorNodeList = skinSelectorNodeList;
       _namespaceMap     = namespaceMap;
       _direction        = direction;
+      _agents           = agents;
     } 
     
   
   SkinStyleSheetNode(
     Map  namespaceMap,
-    int  direction
+    int  direction,
+    int[] agents,
+    int[] platforms
     )
   {
     _namespaceMap     = namespaceMap;
     _direction        = direction;
+    _agents           = agents;
+    _platforms        = platforms;
   }     
     
   public void add(SkinSelectorPropertiesNode node)
@@ -82,20 +89,55 @@
       return _skinSelectorNodeList;
     }
     
-    /**
-    *
-    * @return int indicating the direction
-    * LocaleUtils.DIRECTION_DEFAULT 
-    * LocaleUtils.DIRECTION_LEFTTORIGHT 
-    * LocaleUtils.DIRECTION_RIGHTTOLEFT
-    */
     public int getDirection()
     {
       return _direction;
-    }    
-
+    }
+    
+    public int[] getAgents()
+    {
+      return _agents;
+    }
+    
+    public int[] getPlatforms()
+    {
+      return _platforms;
+    }
+    
+    public boolean matches(
+      int direction, 
+      int[] agents, 
+      int[] platforms)
+    {
+      if (direction == _direction)
+      {
+        boolean agentsMatch = _intArraysEqual(agents, _agents);
+        
+        if (agentsMatch)
+        {
+          boolean platformsMatch = _intArraysEqual(platforms, _platforms);
+          if (platformsMatch)
+            return true;
+        }
+      }
+      return false;
+    }
+  
+    private boolean _intArraysEqual(
+      int[] a1, 
+      int[] a2)
+    {
+      if (a1 != null)
+        Arrays.sort(a1);
+      if (a2 != null)
+        Arrays.sort(a2);
+      return Arrays.equals(a1, a2); 
+    }
+    
     private Map  _namespaceMap;
     private List <SkinSelectorPropertiesNode> _skinSelectorNodeList;
-    private int _direction;  // reading direction
+    private int  _direction;  // reading direction
+    private int[] _agents;
+    private int[] _platforms;
 
 }

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetParserUtils.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetParserUtils.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetParserUtils.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/skin/SkinStyleSheetParserUtils.java Fri Jun 30 15:53:12 2006
@@ -236,6 +236,23 @@
           _addIconNode(selectorName,
                        noOraPropertyList,
                        iconNodeList);
+          // log warning if the icon is defined within an @agent or @platform
+          // block that tells the user that this icon will be used 
+          // for all agents and platforms.
+          // TODO add agent and platform support for icons.
+          // This means that if an icon is defined within the @agent and/or
+          // the @platform keys, then that icon should be rendered when
+          // the rendering context matches the agent/platform.
+          if (skinSSNode.getAgents() != null ||
+              skinSSNode.getPlatforms() != null)
+          {
+            _LOG.warning("Icon '" +
+                         selectorName +
+                         "' is defined for agents and/or platforms in the skinning file." +
+                         " However that feature is not implemented yet for icons, only styles. "+ " " +
+                         "Therefore, this icon will be used " +
+                         "regardless of the request's agent or platform.");
+          }
         }
         else
         {
@@ -257,11 +274,11 @@
         StyleNode[] styleNodeArray = styleNodeList.toArray(new StyleNode[0]);
         StyleSheetNode ssNode = 
           new StyleSheetNode(styleNodeArray,
-                             null,
+                             null,/*locales, not yet supported*/
                              skinSSNode.getDirection(),
-                             null,
-                             null,
-                             null,
+                             skinSSNode.getAgents(),
+                             null,/*versions, not supported*/
+                             skinSSNode.getPlatforms(),
                              0);
         ssNodeList.add(ssNode);
       }
@@ -412,7 +429,9 @@
 
 
     Integer width = null;
+    String  widthValue = null;
     Integer height = null;
+    String  heightValue = null;
     //String  styleClass = null;
     String  uri = null;
     String  text = null;
@@ -429,17 +448,17 @@
       String propertyValue = propertyNode.getValue();
       if (propertyName.equals("width"))
       {
-        int pxPosition = propertyValue.indexOf("px");
-        if (pxPosition > -1)
-          propertyValue = propertyValue.substring(0, pxPosition);
-        width = Integer.valueOf(propertyValue);
+        // save original width value
+        // strip off px from the string and return an Integer
+        widthValue = propertyValue;
+        width = _convertPxDimensionStringToInteger(widthValue);
       }
       else if (propertyName.equals("height"))
       {
-        int pxPosition = propertyValue.indexOf("px");
-        if (pxPosition > -1)
-          propertyValue = propertyValue.substring(0, pxPosition);
-        height = Integer.valueOf(propertyValue);
+        // save original height value
+        // strip off px from the string and return an Integer
+        heightValue = propertyValue;
+        height = _convertPxDimensionStringToInteger(heightValue);
       }
       else if (propertyName.equals("content"))
       {
@@ -475,6 +494,11 @@
       {
         // don't allow styleClass from the css parsing file. We can handle
         // this when we have style includes
+        // put back the width/height properties if there were some
+        if (heightValue != null)
+         inlineStyle.setProperty("height", heightValue);
+        if (widthValue != null)
+          inlineStyle.setProperty("width", widthValue);
         icon = new TextIcon(text, text, null, inlineStyle);
       }
       else if (uri != null)
@@ -851,6 +875,23 @@
     return buffer.toString();
   }
 
+  /**
+   * Given a String that denotes a width or height css style
+   * property, return an Integer. This will strip off 'px' from
+   * the string if there is one.
+   * e.g., if propertyValue is '7px', the Integer 7 will be returned.
+   * @param propertyValue - this is a string that indicates width
+   * or height.
+   * @return Integer
+   */
+  private static Integer _convertPxDimensionStringToInteger(
+    String propertyValue)
+  {
+    int pxPosition = propertyValue.indexOf("px");
+    if (pxPosition > -1)
+      propertyValue = propertyValue.substring(0, pxPosition);
+    return Integer.valueOf(propertyValue);    
+  }
   private static class ResolvedSkinProperties
   {
 

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/CSSGenerationUtils.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/CSSGenerationUtils.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/CSSGenerationUtils.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/util/CSSGenerationUtils.java Fri Jun 30 15:53:12 2006
@@ -217,14 +217,16 @@
 
           // if the transformed full name is different than the shortSelector
           // then write out the shortSelector, too.
-          if ( (shortSelector != null) &&
-               (!validFullNameSelector.equals(shortSelector)) )
+          if (shortSelector != null)
           {
-            out.print(",");
             String validShortSelector =
               _getValidFullNameSelector(shortSelector);
-            if (validShortSelector != null)
+            if (!validFullNameSelector.equals(validShortSelector))
+            {
+              out.print(",");
               out.print(validShortSelector);
+  
+            }
           }
 
           // Write out a separator between matching selectors

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetDocument.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetDocument.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetDocument.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetDocument.java Fri Jun 30 15:53:12 2006
@@ -305,7 +305,7 @@
     {
       StyleSheetNode styleSheet = (StyleSheetNode)e.next();
 
-      if (styleSheet.compareVariants(locale, direction, agent,mode) > 0)
+      if (styleSheet.compareVariants(locale, direction, agent, mode) > 0)
         v.addElement(styleSheet);
     }
 
@@ -319,7 +319,8 @@
     Comparator comparator = new StyleSheetComparator(locale,
                                                      direction,
                                                      agent,
-                                                     _styleSheets,mode);
+                                                     mode,
+                                                     _styleSheets);
 
     Arrays.sort(styleSheets, comparator);
 
@@ -895,8 +896,9 @@
       Locale locale,
       int direction,
       AdfFacesAgent agent,
-      StyleSheetNode[] styleSheets,
-      int mode)
+      int mode,
+      StyleSheetNode[] styleSheets
+      )
     {
       _direction = direction;
       _locale = locale;

Modified: incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetNode.java?rev=418407&r1=418406&r2=418407&view=diff
==============================================================================
--- incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetNode.java (original)
+++ incubator/adffaces/trunk/adf-faces/adf-faces-impl/src/main/java/org/apache/myfaces/adfinternal/style/xml/parse/StyleSheetNode.java Fri Jun 30 15:53:12 2006
@@ -155,7 +155,11 @@
    * sort style sheets according to precedence.
    * @param mode 
    */
-  public int compareVariants(Locale locale, int direction, AdfFacesAgent agent, int mode)
+  public int compareVariants(
+    Locale locale, 
+    int direction, 
+    AdfFacesAgent agent, 
+    int mode)
   {
     int localeMatch = _compareLocale(locale);
     if (localeMatch == 0)