You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2012/02/06 17:48:10 UTC

svn commit: r1241072 [1/2] - in /myfaces/trinidad/branches/sobryan_ios_changes: trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/ trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/ trinidad-examples/trinidad-demo/src/main/...

Author: sobryan
Date: Mon Feb  6 16:48:10 2012
New Revision: 1241072

URL: http://svn.apache.org/viewvc?rev=1241072&view=rev
Log:
TRINIDAD-2111

Modified:
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/layout.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/beach.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleBigFontSkinTwo.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleSkin.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/suede/suede.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/agent/TrinidadAgent.java
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentAtRuleMatcher.java
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/casablancaSkin.css
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/capabilities.xml
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/htmlBasic.xml
    myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/layout.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/layout.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/layout.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-components-showcase/src/main/webapp/skins/layout.css Mon Feb  6 16:48:10 2012
@@ -550,11 +550,13 @@ code {
 .components_list af|navigationPane::list-inactive-enabled af|navigationPane::list-content a {
     -tr-rule-ref: selector(".CBNavPaneListOption_Custom");
 }
-.components_list af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneListOptionHover_Custom");
-}
-.components_list af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneListOptionSelectedHover_Custom");
+@agent (touchScreen:none) {
+  .components_list af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneListOptionHover_Custom");
+  }
+  .components_list af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneListOptionSelectedHover_Custom");
+  }
 }
 .components_list af|navigationPane::list-active-disabled af|navigationPane::list-content,
     af|navigationPane::list-inactive-disabled af|navigationPane::list-content {
@@ -718,10 +720,29 @@ code {
         float: none;
     }
 }
-#page_bar a:hover {
-	text-decoration: none;
-	color: white;
-	background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom right;
+@agent (touchScreen:none) {
+  #page_bar a:hover {
+    text-decoration: none;
+    color: white;
+    background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom right;
+  }
+  #page_bar a:hover span {
+    border-top: 1px solid #88847F;
+    border-bottom: 1px solid #423F3B;
+  }
+  #page_bar .menu_anchor, #page_bar a:hover .menu_anchor {
+  	display: block;
+	position: relative;
+    z-index: 10000;
+	border: none;
+	padding: 0;
+  }
+  #main_menu li a:hover {
+  }
+  #page_bar .expand:hover .submenu {
+	display: block;
+  }
+
 }
 #page_bar a span {
 	display: block;
@@ -732,10 +753,6 @@ code {
     line-height: 1em;
     font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
 }
-#page_bar a:hover span {
-	border-top: 1px solid #88847F;
-	border-bottom: 1px solid #423F3B;
-}
 #page_bar a.expand span {
 	padding-right: 24px;
 	background: url("/skins/slices/expand_arrow.png") no-repeat center right;
@@ -747,13 +764,6 @@ code {
 	padding-right: 12px;
 	background: none;
 }
-#page_bar .menu_anchor, #page_bar a:hover .menu_anchor {
-	display: block;
-	position: relative;
-    z-index: 10000;
-	border: none;
-	padding: 0;
-}
 /* Main Menu -------------------------------------------------------------------------------------------------------- */
 #main_menu li {
 	float: left;
@@ -762,8 +772,6 @@ code {
 #main_menu li a {
     text-decoration: none;
 }
-#main_menu li a:hover {
-}
 /* Submenu ---------------------------------------------------------------------------------------------------------- */
 #page_bar .submenu_container {
     min-width: 100%;
@@ -787,9 +795,6 @@ code {
 	background: #615D59;     
 	border: 1px solid #56524E;
 }
-#page_bar .expand:hover .submenu {
-	display: block;
-}
 @agent ie and (version: 5), ie and (version: 6), ie and (version: 7), ie and (version: 8) {
     #page_bar .expand:hover .submenu {
         width: 100%;
@@ -798,8 +803,10 @@ code {
 #page_bar .expand .submenu a {
 	background: #78736E;
 }
-#page_bar .expand .submenu a:hover {
-    background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom center;
+@agent (touchScreen:none) {
+  #page_bar .expand .submenu a:hover {
+      background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom center;
+  }
 }
 #page_bar .expand .submenu a span {
 	border-bottom: none;
@@ -822,8 +829,10 @@ code {
 #skin_menu li a {
 	text-decoration: none;
 }
-#skin_menu a:hover {
-	background-position: bottom left;
+@agent (touchScreen:none) {
+  #skin_menu a:hover {
+    background-position: bottom left;
+  }
 }
 
 /* ------------------------------------------------------------------------------------------------------------------ */
@@ -874,10 +883,12 @@ code {
         float: none;
     }
 }
-#page_bar a:hover {
-	text-decoration: none;
-	color: white;
-	background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom right;
+@agent (touchScreen:none) {
+  #page_bar a:hover {
+    text-decoration: none;
+    color: white;
+    background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom right;
+  }
 }
 #page_bar a span {
 	display: block;
@@ -886,9 +897,11 @@ code {
 	padding: 7px 12px;
 	white-space: nowrap;
 }
-#page_bar a:hover span {
-	border-top: 1px solid #88847F;
-	border-bottom: 1px solid #423F3B;
+@agent (touchScreen:none) {
+  #page_bar a:hover span {
+    border-top: 1px solid #88847F;
+    border-bottom: 1px solid #423F3B;
+  }
 }
 #page_bar a.expand span {
 	padding-right: 24px;
@@ -906,18 +919,30 @@ code {
 	padding-right: 12px;
 	background: none;
 }
-#page_bar .menu_anchor, #page_bar a:hover .menu_anchor {
+
+#page_bar .menu_anchor {
 	display: block;
 	position: relative;
     z-index: 10000;
 	border: none;
 	padding: 0;
 }
+@agent (touchScreen:none) {
+  #page_bar a:hover .menu_anchor {
+    display: block;
+    position: relative;
+      z-index: 10000;
+    border: none;
+    padding: 0;
+  }
+}
 /* Main Menu -------------------------------------------------------------------------------------------------------- */
 #main_menu li {
 	float: left;
 }
-#main_menu li a:hover {
+@agent (touchScreen:none) {
+  #main_menu li a:hover {
+  }
 }
 /* Submenu ---------------------------------------------------------------------------------------------------------- */
 #page_bar .submenu_container {
@@ -939,8 +964,10 @@ code {
 	background: #615D59;     
 	border: 1px solid #56524E;
 }
-#page_bar .expand:hover .submenu {
-	display: block;
+@agent (touchScreen:none) {
+  #page_bar .expand:hover .submenu {
+    display: block;
+  }
 }
 @agent ie and (version: 5), ie and (version: 6), ie and (version: 7), ie and (version: 8) {
     #page_bar .expand:hover .submenu {
@@ -950,8 +977,10 @@ code {
 #page_bar .expand .submenu a {
 	background: #78736E;
 }
-#page_bar .expand .submenu a:hover {
-    background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom center;
+@agent (touchScreen:none) {
+  #page_bar .expand .submenu a:hover {
+      background: #7D7873 url("/skins/slices/menu_hover.png") no-repeat bottom center;
+  }
 }
 #page_bar .expand .submenu a span {
 	border-bottom: none;
@@ -971,8 +1000,10 @@ code {
 #skin_menu a {
 	background-position: bottom left;
 }
-#skin_menu a:hover {
-	background-position: bottom left;
+@agent (touchScreen:none) {
+  #skin_menu a:hover {
+    background-position: bottom left;
+  }
 }
 
 /* ------------------------------------------------------------------------------------------------------------------ */
@@ -1002,8 +1033,16 @@ code {
     color: #0C87D1;
     text-decoration: none;
 }
-.gs-result a.gs-title:hover {
-    text-decoration: underline;
+@agent (touchScreen:none) {
+  .gs-result a.gs-title:hover {
+      text-decoration: underline;
+  }
+  .gsc-cursor .gsc-cursor-page:hover {
+      -tr-rule-ref: selector(".CBPaginatorScrollerHover:alias");
+  }
+  .gsc-cursor .gsc-cursor-current-page:hover {
+      -tr-rule-ref: selector(".CBPaginatorScrollerSelectedHover:alias");
+  }
 }
 /* Search-result item body */
 .gs-result .gs-snippet {
@@ -1013,12 +1052,6 @@ code {
     text-decoration: none;
     -tr-rule-ref: selector(".CBPaginatorScroller:alias");
 }
-.gsc-cursor .gsc-cursor-page:hover {
-    -tr-rule-ref: selector(".CBPaginatorScrollerHover:alias");
-}
 .gsc-cursor .gsc-cursor-current-page {
     -tr-rule-ref: selector(".CBPaginatorScrollerSelected:alias");
 }
-.gsc-cursor .gsc-cursor-current-page:hover {
-    -tr-rule-ref: selector(".CBPaginatorScrollerSelectedHover:alias");
-}

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/beach.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/beach.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/beach.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/beach/beach.css Mon Feb  6 16:48:10 2012
@@ -134,9 +134,31 @@ af|panelTabbed::tab-link {
   text-decoration: none;
 }
 
-af|panelTabbed::tab-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+@agent (touchScreen:none) {
+  af|panelTabbed::tab-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuTabs::enabled-link:hover, af|menuTabs::selected-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuBar::enabled-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuButtons::text:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuButtons::text-selected:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuButtons::text-disabled:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
 }
 
 /* put some space in the
@@ -209,10 +231,6 @@ af|menuTabs::selected-link
 {
   COLOR: black;
 }
-af|menuTabs::enabled-link:hover, af|menuTabs::selected-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
 
 
 
@@ -238,10 +256,6 @@ af|menuBar::body 
   background-color:#02B0AE;
 }
 
-af|menuBar::enabled-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
 af|menuBar::separator
 {
     padding: 0px 2px 0px 2px;
@@ -265,18 +279,6 @@ af|menuBar::separator
   text-decoration:none;
 }
 
-af|menuButtons::text:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
-af|menuButtons::text-selected:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
-af|menuButtons::text-disabled:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
 
 
 /** panelBox **/

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleBigFontSkinTwo.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleBigFontSkinTwo.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleBigFontSkinTwo.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleBigFontSkinTwo.css Mon Feb  6 16:48:10 2012
@@ -21,5 +21,6 @@
 .AFPurpleBigFontSkinTwo {color: green; background-color: purple }
 .AFPurpleBigFontSkinTwo {color: green; background-color: purple }
 
-
-af|panelList:hover {color: orange;}
+@agent (touchScreen:none) {
+  af|panelList:hover {color: orange;}
+}

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleSkin.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleSkin.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleSkin.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/purple/purpleSkin.css Mon Feb  6 16:48:10 2012
@@ -144,11 +144,20 @@ af|panelTabbed::tab-link {
   text-decoration: none;
 }
 
-af|panelTabbed::tab-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+@agent (touchScreen:none) {
+  af|panelTabbed::tab-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuTabs::enabled-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
+  af|menuBar::enabled-link:hover
+  {
+    -tr-rule-ref:selector(".MyLinkHoverColor:alias");
+  }
 }
-
 /* put some space in the
 first cell */
 af|panelTabbed::cell-start {
@@ -206,12 +215,6 @@ af|menuTabs::enabled-link
   color: white;
 }
 
-af|menuTabs::enabled-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
-
-
 /** menuTabs that use icons are define like the following */
 af|menuTabs::enabled-start-icon
 {
@@ -299,10 +302,6 @@ af|menuBar::selected-link
 {
   font-weight:bold;
 }
-af|menuBar::enabled-link:hover
-{
-  -tr-rule-ref:selector(".MyLinkHoverColor:alias");
-}
 af|menuBar::separator
 {
     padding: 0px 2px 0px 2px;
@@ -498,14 +497,15 @@ af|inputDate::launch-icon:rtl
   height:24px
 }
 
-
+@agent (touchScreen:none) {
+  af|breadCrumbs::step:hover {color: green}
+  af|breadCrumbs::selected-step:hover {color: green;}
+  af|treeTable::path-step:hover {color: green}
+  af|treeTable::path-selected-step:hover {color: green;}
+}
 af|breadCrumbs::step {color: purple;}
-af|breadCrumbs::step:hover {color: green}
-af|breadCrumbs::selected-step:hover {color: green;}
 
 af|treeTable::path-step {color: purple; text-decoration:none}
-af|treeTable::path-step:hover {color: green}
-af|treeTable::path-selected-step:hover {color: green;}
 
 
 /** if, for some reason, you don't want an icon to show up, you
@@ -726,10 +726,11 @@ is a right-to-left language. */
   font-size: 24em;
 }
 /* test css parsing only */
-.AFPanelNavigationHorizontal ul li.on:hover ul {
-    background: #224d6f;
-} 
-
+@agent (touchScreen:none) {
+  .AFPanelNavigationHorizontal ul li.on:hover ul {
+      background: #224d6f;
+  }
+}
 af|navigationPane::bar {
   background-color: pink;
 }
@@ -742,10 +743,11 @@ af|navigationPane::bar-active-enabled af
   color: blue;
 }
 
-af|navigationPane::bar-active-enabled af|navigationPane::bar-content A:hover {
-  color: purple;
+@agent (touchScreen:none) {
+  af|navigationPane::bar-active-enabled af|navigationPane::bar-content A:hover {
+    color: purple;
+  }
 }
-
 af|navigationPane::bar-content {
   padding-top: 6px;
   padding-bottom: 6px;

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/suede/suede.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/suede/suede.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/suede/suede.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-examples/trinidad-demo/src/main/webapp/skins/suede/suede.css Mon Feb  6 16:48:10 2012
@@ -456,10 +456,11 @@ af|navigationPane::bar-inactive-disabled
 af|navigationPane::bar-active-disabled af|navigationPane::bar-content {
   -tr-rule-ref: selector(".AFMediumForeground:alias");
 }
-
-af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover,
-af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
-  text-decoration:none;  
+@agent (touchScreen:none) {
+  af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover,
+  af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
+    text-decoration:none;
+  }
 }
 
 af|navigationPane::bar-separator {

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/agent/TrinidadAgent.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/agent/TrinidadAgent.java?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/agent/TrinidadAgent.java (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/agent/TrinidadAgent.java Mon Feb  6 16:48:10 2012
@@ -69,6 +69,13 @@ public abstract class TrinidadAgent impl
           CapabilityKey.getCapabilityKey("height", true);
   
   /**
+   * Touch-screen capability, indicating the agent supports TouchEvent and GestureEvent
+   * events.
+   */
+  static public final CapabilityKey CAP_TOUCH_SCREEN =
+          CapabilityKey.getCapabilityKey("touchScreen", true);
+
+  /**
    * Session History Management (HTML5 History) Capability indicating support for 
    * APIs like history.pushState, history.replaceState, etc.
    */
@@ -246,6 +253,24 @@ public abstract class TrinidadAgent impl
   static public final Object SELECTORS_MULTIPLE        =
           CapabilityValue.getCapabilityValue (CAP_CSS_SELECTORS, "multiple");
   
+  // Values for CAP_TOUCH_SCREEN
+  /**
+   * Agent does not have a touch screen
+   */
+  static public final Object TOUCH_SCREEN_NONE =
+          CapabilityValue.getCapabilityValue (CAP_TOUCH_SCREEN, "none");
+
+  /**
+   * Agent only supports single finger touch events
+   */
+  static public final Object TOUCH_SCREEN_SINGLE =
+          CapabilityValue.getCapabilityValue (CAP_TOUCH_SCREEN, "single");
+  /**
+   * Agent supports multiple finger touch events and gestures
+   */
+  static public final Object TOUCH_SCREEN_MULTIPLE =
+          CapabilityValue.getCapabilityValue (CAP_TOUCH_SCREEN, "multiple");
+
   // Values for CAP_HISTORY_MANAGEMENT
   /**
    * Agent fully supports Session History Management (HTML5 History) APIs

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentAtRuleMatcher.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentAtRuleMatcher.java?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentAtRuleMatcher.java (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentAtRuleMatcher.java Mon Feb  6 16:48:10 2012
@@ -19,8 +19,8 @@
 package org.apache.myfaces.trinidadinternal.skin;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -31,6 +31,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.myfaces.trinidad.context.Version;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.util.CollectionUtils;
 import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
 import org.apache.myfaces.trinidadinternal.style.util.NameUtils;
@@ -44,6 +45,7 @@ import org.apache.myfaces.trinidadintern
  */
 public final class AgentAtRuleMatcher
 {
+
   /**
    * Enumeration representing the result of a call to <code>match</code>.
    * @see #match
@@ -53,7 +55,9 @@ public final class AgentAtRuleMatcher
     /** The Match matched the agent applications */
     APPLICATION,
     /** The Match matched the agent version */
-    VERSION
+    VERSION,
+    /** the Match matched capability touchScreen */
+    CAP_TOUCH_SCREEN
   };
     
   /**
@@ -118,9 +122,11 @@ public final class AgentAtRuleMatcher
         browserMap.put(browsers.get(i), versionSet);
       }
     }
-    
+
     _selectorAgents = browserMap;
-    _hashCode = _calculateStableHashCode(browserMap);
+    // Passing null for capTouchMatchers, this is safe as this method is for XSS and is no more in use.
+    _capTouchMatchers = null;
+    _hashCode = _calculateStableHashCode(browserMap, _capTouchMatchers);
   }
 
   /**
@@ -148,7 +154,8 @@ public final class AgentAtRuleMatcher
   public AgentAtRuleMatcher(String[] selectors)
   {
     Map<TrinidadAgent.Application, Set<AgentMatcher>> selectorAgents = Collections.emptyMap();
-    
+    Set<AgentMatcher> capTouchMatchers = new HashSet<AgentMatcher>();
+
     // process each of the selectors to build the Map of the AgentMatchers to run for any
     // particular agent in this array of rules.
     for (int selectorIndex = 0; selectorIndex < selectors.length; selectorIndex++)
@@ -158,30 +165,41 @@ public final class AgentAtRuleMatcher
       // @agent ie and (version:6.*)
       // @agent ie and (version:5.0.*)
       // @agent ie and (min-version:5.*) and (max-version:6)
-      // @agent ie and (version:6), ie and (version:7), gecko and (version:1.1) 
-            
-      String currSelector = selectors[selectorIndex];
-      
+      // @agent ie and (version:6), ie and (version:7), gecko and (version:1.1)
+      // @agent (touchScreen)
+      // @agent (touchScreen:none)
+      // @agent (touchScreen:none), ie and (version:6)
+      // @agent webkit and (version:6), (touchScreen)
+      // @agent webkit and (touchScreen:single)
+      // @agent webkit and (version:9) and (touchScreen:multiple)
+
+      String currSelector = selectors[selectorIndex].trim();
+      if (currSelector.startsWith(TOUCH_SCREEN_RULE_STR))
+      {
+  	    capTouchMatchers.add(_getTouchScreenMatcher(currSelector));
+        continue;
+      }
+
       // split each of the sections between the "and"s.  For example
       // gecko and (min-version:1.5) and (max-version:1.9) would result in
       // {"gecko", "(min-version:1.5)", "(max-version:1.9)"}
       String[] sections = _AND_SPLITTER.split(currSelector);
-   
+
       // the agent is always the first section and is required.
       // We trim because we are often passed strings with trailing whitespace
       String agentName = sections[0].trim();
-      
+
       // convert the name of the agent to its TrinidadAgent.Application enum
       TrinidadAgent.Application browser = NameUtils.getAgentApplication(agentName);
-      
+
       // turn the array of sections into the Set of AgentMatchers
       //
       if (browser != TrinidadAgent.Application.UNKNOWN)
       {
         int sectionCount = sections.length;
-        
+
         Set<AgentMatcher> agentMatchers;
-        
+
         if (sectionCount == 1)
         {
           // we only have the agent identifier, so no matchers
@@ -189,51 +207,53 @@ public final class AgentAtRuleMatcher
         }
         else
         {
-          AgentMatcher newVersionMatcher;
-          
+          AgentMatcher newAgentMatcher;
+
           if (sectionCount > 2)
           {
             // we have multiple ands, so we need to build up the list of sections to pass to
             // to the AndMatcher, which will AND the results of each of the matches together
             List<AgentMatcher> andedMatchers = new ArrayList<AgentMatcher>(sectionCount - 1);
-            
-            // create version matchers for each section
+
+            // create agent matchers for each section
+            // this could be version matcher or touchScreen matcher
             for (int sectionIndex = 1; sectionIndex < sectionCount; sectionIndex++)
             {
-              andedMatchers.add(_getVersionMatcher(sections[sectionIndex]));
+              andedMatchers.add(_getAgentMatcher(sections[sectionIndex]));
             }
-            
-            newVersionMatcher = new AndMatcher(andedMatchers);
+
+            newAgentMatcher = new AndMatcher(andedMatchers);
           }
           else
           {
-            // only a single and with a version match, so return that matcher directly
-            newVersionMatcher = _getVersionMatcher(sections[1]);
+            // only a single and with a agent match, so return that matcher directly
+            // this could be version matcher or touchScreen matcher
+            newAgentMatcher = _getAgentMatcher(sections[1]);
           }
- 
+
           // if you have selectors that repeat the browser, then get the agentMatchers that
-          // you have so far for that browser so you can append to it. 
+          // you have so far for that browser so you can append to it.
           // @agent ie and (version: 6), ie and (version: 7), gecko and (version: 1.9)
           // Th comma ORs the rules together.
           agentMatchers = selectorAgents.get(browser);
-  
+
           // create the Version Set if it doesn't already exist, or add the Version to the
           // current Version Set if it isn't already in there.  Since most Version entries are
           // a single value, we optimize for that case
           if ((agentMatchers == null) || agentMatchers.isEmpty())
-            agentMatchers = Collections.singleton(newVersionMatcher);
-          else if (!agentMatchers.contains(newVersionMatcher))
+            agentMatchers = Collections.singleton(newAgentMatcher);
+          else if (!agentMatchers.contains(newAgentMatcher))
           {
             // we didn't already have an entry for this matcher.  If the old size is 1, then
             // the current set is going to be a Collections.singleton(), which is immutable,
             // so we need to copy the the singleton Set into a HashSet, which IS mutable
             if (agentMatchers.size() == 1)
               agentMatchers = new HashSet<AgentMatcher>(agentMatchers);
-            
-            agentMatchers.add(newVersionMatcher);
+
+            agentMatchers.add(newAgentMatcher);
           }
         }
-               
+
         // optimize the size of the SelectorAgents Map when we add the new Versions
         if (selectorAgents.isEmpty())
           selectorAgents = Collections.singletonMap(browser, agentMatchers);
@@ -247,52 +267,117 @@ public final class AgentAtRuleMatcher
             // a size of 3 seems a good start.
             Map<TrinidadAgent.Application, Set<AgentMatcher>> newSelectorAgents =
                                    new HashMap<TrinidadAgent.Application, Set<AgentMatcher>>(3);
-            
+
             // get the single entry out of here so we can add it into the new mutable map
-            Map.Entry<TrinidadAgent.Application, Set<AgentMatcher>> singleEntry = 
+            Map.Entry<TrinidadAgent.Application, Set<AgentMatcher>> singleEntry =
                                                        selectorAgents.entrySet().iterator().next();
-            
+
             newSelectorAgents.put(singleEntry.getKey(), singleEntry.getValue());
-            
+
             selectorAgents = newSelectorAgents;
           }
-          
+
           // add the new mapping
-          selectorAgents.put(browser, agentMatchers);         
+          selectorAgents.put(browser, agentMatchers);
         }
       }
     }
-    
+
     _selectorAgents = selectorAgents;
-    _hashCode = _calculateStableHashCode(selectorAgents);
+    _capTouchMatchers = capTouchMatchers;
+    _hashCode = _calculateStableHashCode(_selectorAgents, _capTouchMatchers);
+  }
+
+  /**
+   * Parses touchScreen rule and creates appropriate AgentMatcher
+   * @param currSelector
+   */
+  private TouchScreenCapabilityMatcher _getTouchScreenMatcher(String currSelector) {
+    // split out the separate <capability> and <value> parts of the property selector.  The
+    // <capability> will be in the first group, the <value> in the second.
+    Matcher m = _PROPERTY_SPLITTER.matcher(currSelector);
+    String[] capTouchArray = new String[]{};
+
+    if (m.find())
+    {
+      String propName = m.group(1);
+      String propValue = m.group(2);
+
+      // Needless to check if propName is touchScreen or not. It is already done in the caller side.
+      if (propValue != null)
+      {
+        String capValue = propValue.trim();
+        if (_ALL_TOUCH_CAPABILITIES.contains(capValue))
+          capTouchArray = new String[] {capValue};
+        else
+        {
+          _LOG.warning("INVALID_AGENT_PROPERTY", new Object[]{propName, capValue});
+        }
+      }
+    }
+    else
+    {
+      // when (touchScreen) is specified _PROPERTY_SPLITTER fails to match
+      // in this case add single and multiple
+      capTouchArray = _AFFIRMATIVE_TOUCH_CAPABILITIES;
+    }
+
+    if (capTouchArray.length > 0) {
+      Set<String> capTouchValues = Collections.unmodifiableSet(new HashSet<String>(Arrays.<String>asList(capTouchArray)));
+      TouchScreenCapabilityMatcher matcher = new TouchScreenCapabilityMatcher(capTouchValues);
+      return matcher;
+    }
+
+    // If touchScreen syntax was not parsed and no AgentMatcher was created.
+    throw new IllegalArgumentException("Invalid @agent rule specified: " + currSelector);
   }
-  
+
+
+
   /**
    * Because Enums don't have stable hash codes, we can't use their hash code directly.  Instead
    * we want to use the has code of the enum's name, which should be stable.  Here we essentially
    * duplicate the hash code calculation of Map, using the stable hash code instead
    * @return stable hash code
    */
-  private static int _calculateStableHashCode(
-    Map<TrinidadAgent.Application, Set<AgentMatcher>> selectorAgents)
+  private static int _calculateStableHashCode(final Map<TrinidadAgent.Application, Set<AgentMatcher>> selectorAgents,
+                                              final Set<AgentMatcher> capTouchMatchers)
   {
     int hashCode = 0;
-    
+
     // Map hash code is defined as the additive hash code of the entries
     for (Map.Entry<TrinidadAgent.Application, Set<AgentMatcher>> entry : selectorAgents.entrySet())
     {
       // use the enum's name to have a stable hash code
       int stableKeyHashCode = entry.getKey().name().hashCode();
-      
+
       // entry hash code is defined as the XOR of the key and value.
       int entryHashCode = stableKeyHashCode ^ entry.getValue().hashCode();
-      
+
       hashCode += entryHashCode;
     }
-    
+
+    if (capTouchMatchers != null)
+    {
+      hashCode += capTouchMatchers.hashCode();
+    }
+
     return hashCode;
   }
-  
+
+  private AgentMatcher _getAgentMatcher(String propertySelector)
+  {
+    propertySelector = propertySelector.trim();
+    if (propertySelector.startsWith(TOUCH_SCREEN_RULE_STR))
+    {
+      return _getTouchScreenMatcher(propertySelector);
+    } else
+    {
+      return _getVersionMatcher(propertySelector);
+    }
+
+  }
+
   /**
    * Given a property selector of the form
    * (<opt whitespace><identifier><opt whitespace>:<opt whitespace><version><opt whitespace>)
@@ -308,32 +393,32 @@ public final class AgentAtRuleMatcher
     // split out the separate <identifier> and <version> parts of the property selector.  The
     // <identifier> will be in the first group, the <version> in the second.
     Matcher m = _PROPERTY_SPLITTER.matcher(propertySelector);
-    
+
     if (m.find())
     {
       String propName = m.group(1);
       String version = m.group(2);
-      
+
       // turn the property name--either "min-version", "max-version" or "version" into the
       // type of comparison to perform
       Comparison comparison = _COMPARISON_PARSER.get(propName);
-      
+
       if (comparison == null)
       {
         throw new IllegalArgumentException("Invalid @agent property name: " + propName);
       }
-      
+
       // create the new Version, padding the version number out with wildcards
       Version newVersion = new Version(version, "*");
-      
-      return new VersionMatcher(newVersion, comparison);      
+
+      return new VersionMatcher(newVersion, comparison);
     }
     else
     {
       throw new IllegalArgumentException("Invalid @agent property selector: " + propertySelector);
     }
   }
-  
+
   /**
    * <p>
    * Called to actually determine if this AgentAtRuleMatcher applies to the current agent.  The
@@ -357,27 +442,62 @@ public final class AgentAtRuleMatcher
    */
   public Set<Match> match(TrinidadAgent agent)
   {
+    Set<Match> matches = new HashSet<Match>();
     // If we have browser exact match, compare versions
     TrinidadAgent.Application browser = agent.getAgentApplication();
-    
+
     if (_selectorAgents.containsKey(browser))
     {
+      matches.add(Match.APPLICATION);
       Set<AgentMatcher> agentMatchers = _selectorAgents.get(browser);
-      if (agentMatchers.isEmpty())
-        return _APPLICATION_ONLY_MATCH;
-              
-      for (AgentMatcher currMatcher : agentMatchers)
+      if (!agentMatchers.isEmpty())
+      {
+        for (AgentMatcher currMatcher : agentMatchers)
+        {
+          if (currMatcher.match(agent))
+          {
+            if (currMatcher instanceof VersionMatcher)
+              matches.add(Match.VERSION);
+            else if (currMatcher instanceof TouchScreenCapabilityMatcher)
+              matches.add(Match.CAP_TOUCH_SCREEN);
+            else if (currMatcher instanceof AndMatcher)
+            {
+               AndMatcher andMatcher = (AndMatcher) currMatcher;
+                if (andMatcher.hasVersionMatcher())
+                  matches.add(Match.VERSION);
+                if (andMatcher.hasTouchScreenCapabilityMatcher())
+                  matches.add(Match.CAP_TOUCH_SCREEN);
+            }
+          }
+        }
+
+        // Expect at least one match from the matchers
+        if (!matches.contains(Match.CAP_TOUCH_SCREEN) && !matches.contains(Match.VERSION))
+        {
+          // There were one or many matchers but none matched, so remove all matchers.
+          matches.clear();
+        }
+      }
+    }
+
+    // If touchScreen is already matched then no need to check further.
+    if (!matches.contains(Match.CAP_TOUCH_SCREEN) && !_capTouchMatchers.isEmpty())
+    {
+      for (AgentMatcher currMatcher : _capTouchMatchers)
       {
         if (currMatcher.match(agent))
         {
-          return _APPLICATION_AND_VERSION_MATCH;
+          // If there is a capability matching then APPLICATION match should be by default.
+          matches.add(Match.APPLICATION);
+          matches.add(Match.CAP_TOUCH_SCREEN);
+          break;
         }
       }
     }
 
-    return _NO_MATCH;
+    return Collections.unmodifiableSet(matches);
   }
-  
+
   @Override
   public boolean equals(Object other)
   {
@@ -387,7 +507,9 @@ public final class AgentAtRuleMatcher
     {
       if (other instanceof AgentAtRuleMatcher)
       {
-        return _selectorAgents.equals(((AgentAtRuleMatcher)other)._selectorAgents);
+        AgentAtRuleMatcher otherAgentMatcher = (AgentAtRuleMatcher) other;
+        return (_selectorAgents.equals(otherAgentMatcher._selectorAgents))
+                && (_capTouchMatchers.equals(otherAgentMatcher._capTouchMatchers));
       }
       else
       {
@@ -395,17 +517,17 @@ public final class AgentAtRuleMatcher
       }
     }
   }
-  
+
   @Override
   public final int hashCode()
   {
     return _hashCode;
   }
-  
+
   @Override
   public String toString()
   {
-    return super.toString() + "agents=" + _selectorAgents.toString();
+    return super.toString() + "agents=" + _selectorAgents.toString() + "touchScreenCap=" + _capTouchMatchers.toString();
   }
 
   // the type of comparison to perform on the version
@@ -427,7 +549,7 @@ public final class AgentAtRuleMatcher
    * implement <code>equals</code> and <code>hashCode</code>
    * </p>
    * <p>
-   * While used to hide the differences between VersionMatchers and AndMatchers, 
+   * While used to hide the differences between VersionMatchers and AndMatchers,
    * this class should be abstract enough to support any new types of Agent matchers that we might
    * want to add in the future.
    * </p>
@@ -441,14 +563,14 @@ public final class AgentAtRuleMatcher
      * @return <code>true</code> if the match succeeds
      */
     public abstract boolean match(TrinidadAgent agent);
-    
+
     @Override
     public abstract int hashCode();
-    
-    @Override    
+
+    @Override
     public abstract boolean equals(Object o);
   }
-  
+
   /**
    * Immutable and thread-safe AgentMatcher that matches the supplied Version against the
    * version of a TrinidadAgent using the supplied, MAX, MIN, or EQUALS Comparison
@@ -464,12 +586,12 @@ public final class AgentAtRuleMatcher
     {
       _version = version;
       _comparison = comparison;
-      
+
       // cache the hash code.  Because enums don't have stable hash codes,
       // we use the hash code of the name of the enum, which is stable
       _hashCode = _version.hashCode() * 37 + _comparison.name().hashCode();
     }
-    
+
     /**
      * Matches the Version of this VersionMatcher against the Version of the supplied Agent,
      * using the VersionMatcher's comparison
@@ -481,7 +603,7 @@ public final class AgentAtRuleMatcher
     {
       // use the Version's comparator
       int result = _version.compareTo(agent.getVersion());
-      
+
       // since MIN means less than or equal to and MAX means greater than or equal to, a result
       // of equality always means success
       if (result == 0)
@@ -492,26 +614,26 @@ public final class AgentAtRuleMatcher
         {
           case MIN:
             return result < 0; // min version has to be less than current version
-            
+
           case MAX:
             return result > 0; // max version has to be bigger than current version
-          
+
           case EQUALS:
             return false; // if the result were equal, we wouldn't have gotten this far
-          
+
           default:
             assert false : "Unknown comparison type " + _comparison;
             return false; // this should never happen, but the compiler doesn't know that
         }
       }
     }
- 
+
     @Override
     public final int hashCode()
     {
       return _hashCode;
     }
-    
+
     @Override
     public boolean equals(Object other)
     {
@@ -522,7 +644,7 @@ public final class AgentAtRuleMatcher
         if (other instanceof VersionMatcher)
         {
           VersionMatcher otherVersionMatcher = (VersionMatcher)other;
-          
+
           return _version.equals(otherVersionMatcher._version) &&
                  _comparison.equals(otherVersionMatcher._comparison);
         }
@@ -532,18 +654,18 @@ public final class AgentAtRuleMatcher
         }
       }
     }
-    
+
     @Override
     public String toString()
     {
       return super.toString() + ", version=" + _version + ", comparison=" + _comparison;
     }
-   
+
     private final Version _version;
     private final Comparison _comparison;
     private final int _hashCode;
   }
-  
+
   /**
    * AgentMatcher that ANDs the results of all calling match() on its AgentMatchers together,
    * short-circuiting on the first AgentMatcher.match() that returns false.
@@ -559,12 +681,30 @@ public final class AgentAtRuleMatcher
       // =-= btsulliv should we do anything if matchers contains fewer than two items?  The code
       //              will still work, it just suggests a lack of optimization in the caller
       _matchers = matchers;
-      
+
       // cache the hashcode so we don't traverse the list asking all of the other matchers for
       // their hash codes each time our hash code is called
       _hashCode = matchers.hashCode();
+
+      for (AgentMatcher matcher : matchers)
+      {
+        if (matcher instanceof VersionMatcher)
+          hasVersionMatcher = true;
+        if (matcher instanceof TouchScreenCapabilityMatcher)
+          hasTouchScreenCapabilityMatcher = true;
+      }
     }
-    
+
+    protected boolean hasTouchScreenCapabilityMatcher()
+    {
+      return hasTouchScreenCapabilityMatcher;
+    }
+
+    protected boolean hasVersionMatcher()
+    {
+      return hasVersionMatcher;
+    }
+
     /**
      * @param agent Agent to match againt
      * @return <code>true</code> if all of the matchers matched the Agent
@@ -573,7 +713,7 @@ public final class AgentAtRuleMatcher
     public boolean match(TrinidadAgent agent)
     {
       int matcherCount = _matchers.size();
-      
+
       for (int i = 0; i < matcherCount; i++)
       {
         // a matcher failed, so no sense in trying to match any more.  Let's pick up our
@@ -581,17 +721,17 @@ public final class AgentAtRuleMatcher
         if (!_matchers.get(i).match(agent))
           return false;
       }
-      
+
       // all of the matchers matched.  Yay!
       return true;
     }
-  
+
     @Override
     public int hashCode()
     {
       return _hashCode;
     }
-    
+
     @Override
     public boolean equals(Object other)
     {
@@ -600,7 +740,7 @@ public final class AgentAtRuleMatcher
       else
       {
         if (other instanceof AndMatcher)
-        {          
+        {
           return _matchers.equals(((AndMatcher)other)._matchers);
         }
         else
@@ -609,15 +749,92 @@ public final class AgentAtRuleMatcher
         }
       }
     }
-    
+
     @Override
     public String toString()
     {
       return super.toString() + ", matchers=" + _matchers;
     }
-   
+
     private final List<AgentMatcher> _matchers;
     private final int _hashCode;
+    private boolean hasVersionMatcher;
+    private boolean hasTouchScreenCapabilityMatcher;
+
+  }
+
+  /**
+   * Immutable and thread-safe AgentMatcher that matches the supplied touchScreen capability against the
+   * that of the agent's.
+   */
+  private static final class TouchScreenCapabilityMatcher extends AgentMatcher
+  {
+    /**
+     * Creates a TouchScreenCapabilityMatcher
+     * @param touchCapabilities
+     */
+    public TouchScreenCapabilityMatcher(Set<String> touchCapabilities)
+    {
+      if (touchCapabilities == null)
+        throw new NullPointerException("touchCapabilities must be non-null");
+
+      _touchCapabilities = touchCapabilities;
+      _hashCode = _touchCapabilities.hashCode();
+    }
+
+    /**
+     * Matches the  TouchScreenCapabilityMatcher against the touchScreen capability of the supplied Agent
+     * @param agent Agent to check the touchScreen capability of
+     * @return <code>true</code> if the comparison is successful
+     */
+    @Override
+    public boolean match(TrinidadAgent agent)
+    {
+      String capTouchScreen = (String) agent.getCapabilities().get(TrinidadAgent.CAP_TOUCH_SCREEN);
+      for (String touchCap : _touchCapabilities)
+      {
+        if (capTouchScreen.equals(touchCap))
+        {
+          return true;
+        }
+      }
+
+      return false;
+    }
+
+    @Override
+    public final int hashCode()
+    {
+      return _hashCode;
+    }
+
+    @Override
+    public boolean equals(Object other)
+    {
+      if (this == other)
+        return true;
+      else
+      {
+        if (other instanceof TouchScreenCapabilityMatcher)
+        {
+          TouchScreenCapabilityMatcher otherMatcher = (TouchScreenCapabilityMatcher)other;
+          return _touchCapabilities.equals(otherMatcher._touchCapabilities);
+        }
+        else
+        {
+          return false;
+        }
+      }
+    }
+
+    @Override
+    public String toString()
+    {
+      return super.toString() + ", touchCapabilities=" + _touchCapabilities;
+    }
+
+    private final Set<String> _touchCapabilities;
+    private final int _hashCode;
   }
 
   // RegExp Pattern used to breaking apart the property selectors into a separate property name
@@ -645,33 +862,41 @@ public final class AgentAtRuleMatcher
   // is added later, we require the "and" to be surrounded with whitespace.
   private static final Pattern _AND_SPLITTER = Pattern.compile("\\s+and\\s+");
 
-  // constants representing the three types of Match sets match returns
-  private static final Set<Match> _NO_MATCH = Collections.emptySet();
-  private static final Set<Match> _APPLICATION_ONLY_MATCH = Collections.singleton(Match.APPLICATION);
-  
-  private static final Set<Match> _APPLICATION_AND_VERSION_MATCH = 
-                         Collections.unmodifiableSet(EnumSet.of(Match.APPLICATION, Match.VERSION));
+  private static final String[] _AFFIRMATIVE_TOUCH_CAPABILITIES =
+    new String[]
+    { TrinidadAgent.TOUCH_SCREEN_MULTIPLE.toString(),
+      TrinidadAgent.TOUCH_SCREEN_SINGLE.toString()
+    };
+
+  private static final Set<String> _ALL_TOUCH_CAPABILITIES =
+    new HashSet<String>(Arrays.<String>asList(new String[]
+        { TrinidadAgent.TOUCH_SCREEN_MULTIPLE.toString(),
+          TrinidadAgent.TOUCH_SCREEN_SINGLE.toString(),
+          TrinidadAgent.TOUCH_SCREEN_NONE.toString()
+        }));
 
-  
   // map of property names to the types of comparison to use for each name
   private static final Map<String, Comparison> _COMPARISON_PARSER;
-  
+
   static
   {
     // initialize property-name to Comparison type Map.  Thread-safe because the Map is not
     // modified after initialization
     _COMPARISON_PARSER = new HashMap<String, Comparison>(4);
-    
+
     _COMPARISON_PARSER.put("version", Comparison.EQUALS);
     _COMPARISON_PARSER.put("max-version", Comparison.MAX);
     _COMPARISON_PARSER.put("min-version", Comparison.MIN);
   }
 
   // As we need to be able to have multiple version matching rules for the same agent:
-  // @agent ie and (version:5), ie and (version:6), gecko. 
+  // @agent ie and (version:5), ie and (version:6), gecko.
   // We store a map of agents and their version sets
   private final Map<TrinidadAgent.Application, Set<AgentMatcher>> _selectorAgents;
-  
+  private final Set<AgentMatcher> _capTouchMatchers;
+
   // cached hash code
   private final int _hashCode;
+  private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(AgentAtRuleMatcher.class);
+  private static final String TOUCH_SCREEN_RULE_STR = "(" + TrinidadAgent.CAP_TOUCH_SCREEN.getCapabilityName();
 }

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java Mon Feb  6 16:48:10 2012
@@ -374,7 +374,7 @@ public class StyleSheetNode
     // On the other hand, if we do have a browser specified, but
     // the client browser is not known, we don't have a match
     if (application == TrinidadAgent.Application.UNKNOWN)
-      return 0;
+      return _NO_MATCH;
     
     Set<AgentAtRuleMatcher.Match> matches = _agentMatcher.match(agent);
     
@@ -390,6 +390,11 @@ public class StyleSheetNode
                            ? _VERSION_EXACT_MATCH
                            : _VERSION_UNKNOWN_MATCH;
       matchResult |= versionMatch;
+
+      int capTouchMatch = (matches.contains(AgentAtRuleMatcher.Match.CAP_TOUCH_SCREEN))
+                           ? _CAP_TOUCH_SCREEN_EXACT_MATCH
+                           : _CAP_TOUCH_SCREEN_UNKNOWN_MATCH; 
+      matchResult |= capTouchMatch;
     }
 
     return matchResult;
@@ -589,6 +594,10 @@ public class StyleSheetNode
   private static final int _VERSION_EXACT_MATCH     = 0x00000020;
   private static final int _VERSION_UNKNOWN_MATCH   = 0x00000010;
 
+  // Constants for capability touchScreen matches - 0x000000f0 bits
+  private static final int _CAP_TOUCH_SCREEN_EXACT_MATCH     = 0x00000040;
+  private static final int _CAP_TOUCH_SCREEN_UNKNOWN_MATCH   = 0x00000030;
+
   // Constants for os matches - 0x0000000f bits
   private static final int _OS_EXACT_MATCH          = 0x00000004;
   private static final int _OS_PARTIAL_MATCH        = 0x00000002;

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.css Mon Feb  6 16:48:10 2012
@@ -1226,12 +1226,16 @@
   af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a {
     -tr-rule-ref: selector(".AFTextForeground:alias");
   }
-  af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover {
-    text-decoration: underline;
-  }
-  af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
-    text-decoration: underline;
+
+  @agent (touchScreen:none) {
+    af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover {
+      text-decoration: underline;
+    }
+    af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
+      text-decoration: underline;
+    }
   }
+
   af|navigationPane::bar-active-disabled af|navigationPane::bar-content {
     color: gray;
     font-weight: bold;
@@ -1273,12 +1277,16 @@
   af|navigationPane::buttons-inactive-enabled {
     cursor: pointer;
   }
-  af|navigationPane::buttons-active-enabled af|navigationPane::buttons-content a:hover {
-    text-decoration: underline;
-  }
-  af|navigationPane::buttons-inactive-enabled af|navigationPane::buttons-content a:hover {
-    text-decoration: underline;
+
+  @agent (touchScreen:none) {
+    af|navigationPane::buttons-active-enabled af|navigationPane::buttons-content a:hover {
+      text-decoration: underline;
+    }
+    af|navigationPane::buttons-inactive-enabled af|navigationPane::buttons-content a:hover {
+      text-decoration: underline;
+    }
   }
+
   af|navigationPane::buttons-active-disabled af|navigationPane::buttons-content {
     color: gray;
   }
@@ -1331,12 +1339,16 @@
   af|navigationPane::list-inactive-enabled {
     cursor: pointer;
   }
-  af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
-    text-decoration: underline;
-  }
-  af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
-    text-decoration: underline;
+
+  @agent (touchScreen:none) {
+    af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
+      text-decoration: underline;
+    }
+    af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
+      text-decoration: underline;
+    }
   }
+
   af|navigationPane::list-active-disabled af|navigationPane::list-content {
     color: gray;
   }

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/casablancaSkin.css
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/casablancaSkin.css?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/casablancaSkin.css (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/adf/styles/casablancaSkin.css Mon Feb  6 16:48:10 2012
@@ -49,11 +49,11 @@
 /*    CASABLANCA INJECTION LAYER
 /* 
 /* The CASABLANCA SELECTORS STACK has two main layers:
-/* - The first one is the GENERIC LAYER – on that layer we have generic styles
+/* - The first one is the GENERIC LAYER � on that layer we have generic styles
 /*   that we use everywhere. This is the level where we made changes
 /*   (in most of part) when we want to made another color scheme for the skin
 /*   or to build another skin based on it.
-/* - The second layer is the COMPONENTS STYLING LAYER – this layer define styles
+/* - The second layer is the COMPONENTS STYLING LAYER � this layer define styles
 /*   for each component individually based on generic styles. We will make changes 
 /*   at this layer if we intent to fine-tune the components aspect.
 /*
@@ -67,7 +67,7 @@
 /*   look, button look and so on. In that order we have selectors like:
 /*   .CBBorderSolidLook:alias, .CBDefaultFontLook:alias, .CBHeaderLevel1Look:alias,
 /*   .CBLinkLook:alias, .CBButtonLook:alias ans so on. All styles are prefixed
-/*   by “.CB” which means is a Casablanca style and all are postfixed by “:alias”
+/*   by �.CB� which means is a Casablanca style and all are postfixed by �:alias�
 /*   that means is a generic style.
 /* - BASIC CONTROLS LAYER, define the full graphic aspect of the basic controls
 /*   using general look layer styles. We have here controls like: link, button,
@@ -79,7 +79,7 @@
 /*
 /* NOTE: In general is better at a specific layer to use style defined in the
 /*       layer immediately below it. There are also situations when we need to use
-/*       directly a more generic style when we don’t have alternative, but in general
+/*       directly a more generic style when we don�t have alternative, but in general
 /*       is better to use the layer immediately below.
 /*
 /* The second layer introduces another level of abstraction, for decoupling reasons.
@@ -92,9 +92,9 @@
 /*   the connection between the Casablanca generic controls and true Trinidad components
 /*   and here is the place for adding a custom look for a specific component.
 /* - Second layer is the CASABLANCA INJECTION LAYER where we actually made the
-/*   “conversion” between Casablanca and standard Trinidad skinning selectors.
-/*   In almost all cases we don’t need to make any change at this level. The scope
-/*   of this layer is only to “translate” between two type of skinning selectors in
+/*   �conversion� between Casablanca and standard Trinidad skinning selectors.
+/*   In almost all cases we don�t need to make any change at this level. The scope
+/*   of this layer is only to �translate� between two type of skinning selectors in
 /*   order to hide the naming inconsistency in Trinidad skinning selectors and where
 /*   is possible the lack of uniformity in the output markup.
 /*
@@ -104,38 +104,38 @@
 /* So each style selector is addressed to a specific styled-entity.
 /* Each style selector name must be conforming to the Casablanca styles naming rule:
 /*
-/* .CBName1Name2…NameXType1Type2…TypeXPurposeState1State2…StateX:alias
+/* .CBName1Name2�NameXType1Type2�TypeXPurposeState1State2�StateX:alias
 /*
-/* .CB – from Casablanca prefixes any style selector, so it’s a required field.
-/* Name1    – the name of the styled-entity, required field.
-/* Name2    – the second name is the name of styled-sub-entity, not required. We can have
+/* .CB � from Casablanca prefixes any style selector, so it�s a required field.
+/* Name1    � the name of the styled-entity, required field.
+/* Name2    � the second name is the name of styled-sub-entity, not required. We can have
 /*            as many sub-entity levels as we want.
-/* Type1    – the type of the styled-entity, not required.
-/* Type2    – the second type of the styled entity, not required. We can have as many types
+/* Type1    � the type of the styled-entity, not required.
+/* Type2    � the second type of the styled entity, not required. We can have as many types
 /*            as we want.
-/* Purpose  – the purpose of the styled-entity, not required.
-/* State1   – the state of the styled-entity, not required.
-/* State2   – the second state of the styled-entity, not required. We can also have as many
+/* Purpose  � the purpose of the styled-entity, not required.
+/* State1   � the state of the styled-entity, not required.
+/* State2   � the second state of the styled-entity, not required. We can also have as many
 /*            states as we want.
 /*
 /* EXAMPLES :
 /* .CBLinkLookHover:alias
-/* Link     – styled-entity name
-/* Look     – styled-entity purpose
-/* Hover    – styled-entity State
+/* Link     � styled-entity name
+/* Look     � styled-entity purpose
+/* Hover    � styled-entity State
 /* So we have a link-look generic selector in the hover state.
 /*
 /* .CBPanelHeadSelectedHover:alias
-/* Panel    – styled-entity name.
-/* Head     – styled-sub-entity name.
-/* Selected – styled-entity state.
-/* Hover    – another styled-entity state.
+/* Panel    � styled-entity name.
+/* Head     � styled-sub-entity name.
+/* Selected � styled-entity state.
+/* Hover    � another styled-entity state.
 /* We have the head of the panel complex control selector in the selected-hover state.
 /*
 /* .CBBorderStrongSolidLook:alias
-/* Border   – styled-entity name
-/* Strong   – styled-entity type
-/* Solid    – another styled-entity type
+/* Border   � styled-entity name
+/* Strong   � styled-entity type
+/* Solid    � another styled-entity type
 /* We have a strong-solid-look border generic selector.
 /*
 /*
@@ -1634,8 +1634,11 @@
 af|breadCrumbs af|breadCrumbs::step {
     -tr-rule-ref: selector("..CBBreadcrumbStep:alias");
 }
-af|breadCrumbs af|breadCrumbs::step:hover {
-    -tr-rule-ref: selector(".CBBreadcrumbStepHover:alias");
+
+@agent (touchScreen:none) {
+	af|breadCrumbs af|breadCrumbs::step:hover {
+	    -tr-rule-ref: selector(".CBBreadcrumbStepHover:alias");
+	}
 }
 
 /* Chart component -------------------------------------------------------------------------------------------------- */
@@ -1746,17 +1749,27 @@ af|chooseDate::content tr td a {
     border: none;
     display: block;
 }
-af|chooseDate::content tr td a:hover {
-    -tr-rule-ref: selector(".CBDateCellHover:alias");
-    border: none;
-    display: block;
+@agent (touchScreen:none) {
+  af|chooseDate::content tr td a:hover {
+      -tr-rule-ref: selector(".CBDateCellHover:alias");
+      border: none;
+      display: block;
+  }
+  af|chooseDate::content tr af|chooseDate::disabled:hover {
+      -tr-rule-ref: selector(".CBDateCellDisabled:alias");
+  }
+  af|chooseDate::nav[align="left"] a:hover {
+      -tr-rule-ref: selector(".CBDateNavPrevMonthHover:alias");
+  }
+  af|chooseDate::nav[align="right"] a:hover {
+      -tr-rule-ref: selector(".CBDateNavNextMonthHover:alias");
+  }
 }
 af|chooseDate::content tr td af|chooseDate::selected {
     -tr-rule-ref: selector(".CBDateCellSelected:alias");
     /*padding: 0;*/
 }
-af|chooseDate::content tr af|chooseDate::disabled,
-af|chooseDate::content tr af|chooseDate::disabled:hover {
+af|chooseDate::content tr af|chooseDate::disabled {
     -tr-rule-ref: selector(".CBDateCellDisabled:alias");
 }
 /* month navigation controls */
@@ -1766,12 +1779,6 @@ af|chooseDate::nav[align="left"] a {
 af|chooseDate::nav[align="right"] a {
     -tr-rule-ref: selector(".CBDateNavNextMonth:alias");
 }
-af|chooseDate::nav[align="left"] a:hover {
-    -tr-rule-ref: selector(".CBDateNavPrevMonthHover:alias");
-}
-af|chooseDate::nav[align="right"] a:hover {
-    -tr-rule-ref: selector(".CBDateNavNextMonthHover:alias");
-}
 af|chooseDate::nav[align="left"] a span {
     display: none;   
 }
@@ -1797,9 +1804,12 @@ af|chooseDate::nav[align="right"] a span
 af|commandButton, af|goButton, af|resetButton, button, button.OraLink, .OraNavBarActiveLink {
     -tr-rule-ref: selector(".CBCommandButton:alias");
 }
-af|commandButton:hover, af|goButton:hover, af|resetButton:hover, button:hover, button.OraLink:hover,
-.OraNavBarActiveLink:hover {
-    -tr-rule-ref: selector(".CBCommandButtonHover:alias");
+
+@agent (touchScreen:none) {
+  af|commandButton:hover, af|goButton:hover, af|resetButton:hover, button:hover, button.OraLink:hover,
+  .OraNavBarActiveLink:hover {
+      -tr-rule-ref: selector(".CBCommandButtonHover:alias");
+  }
 }
 af|commandButton.p_AFDisabled {
     -tr-rule-ref: selector(".CBCommandButtonDisabled:alias");
@@ -1827,15 +1837,17 @@ af|commandButton.p_AFDisabled {
 a, .OraLink, .OraLink:link, .OraLink:active, .OraLink:visited, .AFLinkForeground:alias {
     -tr-rule-ref: selector(".CBCommandLink:alias");
 }
-a:hover, .OraLink:hover, .OraLink:link:hover {
-    -tr-rule-ref: selector(".CBCommandLinkHover:alias");
+@agent (touchScreen:none) {
+  a:hover, .OraLink:hover, .OraLink:link:hover {
+      -tr-rule-ref: selector(".CBCommandLinkHover:alias");
+  }
+  .OraLinkDisabled:hover {
+      -tr-rule-ref: selector(".CBCommandLinkDisabledHover:alias");
+  }
 }
 .OraLinkDisabled {
     -tr-rule-ref: selector(".CBCommandLinkDisabled:alias");
 }
-.OraLinkDisabled:hover {
-    -tr-rule-ref: selector(".CBCommandLinkDisabledHover:alias");
-}
 
 /* Command Navigation Item component -------------------------------------------------------------------------------- */
 /* CasaBlanca styles */
@@ -1878,8 +1890,11 @@ a:hover, .OraLink:hover, .OraLink:link:h
 af|goButton {
     -tr-rule-ref: selector(".CBGoButton:alias");
 }
-af|goButton:hover {
-    -tr-rule-ref: selector(".CBGoButtonHover:alias");
+
+@agent (touchScreen:none) {
+  af|goButton:hover {
+      -tr-rule-ref: selector(".CBGoButtonHover:alias");
+  }
 }
 
 /* Go Link component ------------------------------------------------------------------------------------------------ */
@@ -1980,8 +1995,11 @@ af|inputColor::content {
 af|inputColor a .p_OraColorFieldSwatch {
     -tr-rule-ref: selector(".CBInputColorCurrentColor:alias");
 }
-af|inputColor a:hover .p_OraColorFieldSwatch {
-    -tr-rule-ref: selector(".CBInputColorCurrentColorHover:alias");    
+
+@agent (touchScreen:none) {
+  af|inputColor a:hover .p_OraColorFieldSwatch {
+      -tr-rule-ref: selector(".CBInputColorCurrentColorHover:alias");
+  }
 }
 /* Clear some legacy stuff */
 af|inputColor af|inputColor::swatch-overlay {
@@ -2023,8 +2041,10 @@ af|inputDate::content {
 af|inputDate a {
     -tr-rule-ref: selector(".CBInputDateIconStyle:alias");
 }
-af|inputDate a:hover {
-    -tr-rule-ref: selector(".CBInputDateIconHover:alias");
+@agent (touchScreen:none) {
+  af|inputDate a:hover {
+      -tr-rule-ref: selector(".CBInputDateIconHover:alias");
+  }
 }
 /* Clear some legacy stuff */
 af|inputDate img {
@@ -2069,13 +2089,15 @@ af|inputListOfValues  {
 af|inputListOfValues a {
     -tr-rule-ref: selector(".CBListOfValuesIconStyle:alias");
 }
-af|inputListOfValues a:hover {
-    -tr-rule-ref: selector(".CBListOfValuesIconHover:alias");
+@agent (touchScreen:none) {
+  af|inputListOfValues a:hover {
+      -tr-rule-ref: selector(".CBListOfValuesIconHover:alias");
+  }
 }
 af|inputListOfValues af|inputListOfValues::content {
     -tr-rule-ref: selector(".CBListOfValuesInputBox:alias");
 }
-/* It’s not a specific enough selector, but is all we can do and it works */
+/* It's not a specific enough selector, but is all we can do and it works */
 af|panelButtonBar {
     -tr-rule-ref: selector(".CBListOfValuesPanelButtonBar:alias");
 }
@@ -2192,15 +2214,32 @@ af|navigationPane::bar {
 af|navigationPane::bar-active-enabled af|navigationPane::bar-content a {
     -tr-rule-ref: selector(".CBNavPaneBarOptionSelected:alias");
 }
-af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneBarOptionSelectedHover:alias");
+@agent (touchScreen:none) {
+  af|navigationPane::bar-active-enabled af|navigationPane::bar-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneBarOptionSelectedHover:alias");
+  }
+  af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneBarOptionHover:alias");
+  }
+  af|navigationPane::buttons-inactive-enabled af|navigationPane::buttons-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneButtonOptionHover:alias");
+  }
+  af|navigationPane::buttons-active-enabled af|navigationPane::buttons-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneButtonOptionSelectedHover:alias");
+  }
+  af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneListOptionHover:alias");
+  }
+  af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
+      -tr-rule-ref: selector(".CBNavPaneListOptionSelectedHover:alias");
+  }
+  af|navigationPane af|navigationPane::choice-button:hover {
+      -tr-rule-ref: selector(".CBNavPaneChoiceButtonHover:alias");
+  }
 }
 af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a {
     -tr-rule-ref: selector(".CBNavPaneBarOption:alias");
 }
-af|navigationPane::bar-inactive-enabled af|navigationPane::bar-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneBarOptionHover:alias");
-}
 af|navigationPane::bar-active-disabled af|navigationPane::bar-content,
 af|navigationPane::bar-inactive-disabled af|navigationPane::bar-content {
     -tr-rule-ref: selector(".CBNavPaneBarOptionDisabled:alias");
@@ -2253,12 +2292,6 @@ af|navigationPane::buttons-active-enable
 af|navigationPane::buttons-inactive-enabled af|navigationPane::buttons-content a {
     -tr-rule-ref: selector(".CBNavPaneButtonOption:alias");
 }
-af|navigationPane::buttons-inactive-enabled af|navigationPane::buttons-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneButtonOptionHover:alias");
-}
-af|navigationPane::buttons-active-enabled af|navigationPane::buttons-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneButtonOptionSelectedHover:alias");
-}
 af|navigationPane::buttons-active-disabled af|navigationPane::buttons-content,
 af|navigationPane::buttons-inactive-disabled af|navigationPane::buttons-content {
     -tr-rule-ref: selector(".CBNavPaneButtonOptionDisabled:alias");
@@ -2321,12 +2354,6 @@ af|navigationPane::list-active-enabled a
 af|navigationPane::list-inactive-enabled af|navigationPane::list-content a {
     -tr-rule-ref: selector(".CBNavPaneListOption:alias");
 }
-af|navigationPane::list-inactive-enabled af|navigationPane::list-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneListOptionHover:alias");
-}
-af|navigationPane::list-active-enabled af|navigationPane::list-content a:hover {
-    -tr-rule-ref: selector(".CBNavPaneListOptionSelectedHover:alias");
-}
 af|navigationPane::list-active-disabled af|navigationPane::list-content,
 af|navigationPane::list-inactive-disabled af|navigationPane::list-content {
     -tr-rule-ref: selector(".CBNavPaneListListOptionDisabled:alias");
@@ -2393,9 +2420,6 @@ af|navigationPane::choice-options option
 af|navigationPane af|navigationPane::choice-button {
     -tr-rule-ref: selector(".CBNavPaneChoiceButton:alias");
 }
-af|navigationPane af|navigationPane::choice-button:hover {
-    -tr-rule-ref: selector(".CBNavPaneChoiceButtonHover:alias");
-}
 
 /* Tabs style --------------------------------------------*/
 .CBNavPane:alias {
@@ -2458,22 +2482,25 @@ af|navigationPane::tabs {
 af|navigationPane::tabs-inactive af|navigationPane::tabs-mid a {
     -tr-rule-ref: selector(".CBNavPaneTabs:alias");
 }
-af|navigationPane::tabs-inactive af|navigationPane::tabs-mid a:hover {
-    -tr-rule-ref: selector(".CBNavPaneTabsHover:alias");
-}
 af|navigationPane::tabs-active af|navigationPane::tabs-mid a {
     -tr-rule-ref: selector(".CBNavPaneTabsSelected:alias");
 }
-af|navigationPane::tabs-active af|navigationPane::tabs-mid a:hover {
-    -tr-rule-ref: selector(".CBNavPaneTabsSelectedHover:alias");
-}
 af|navigationPane::tabs .p_AFDisabled af|navigationPane::tabs-mid {
     -tr-rule-ref: selector(".CBNavPaneTabsDisabled:alias");
 }
-af|navigationPane::tabs .p_AFDisabled af|navigationPane::tabs-mid:hover {
-    -tr-rule-ref: selector(".CBNavPaneTabsDisabledHover:alias");       
-}
 
+
+@agent (touchScreen:none) {
+  af|navigationPane::tabs-inactive af|navigationPane::tabs-mid a:hover {
+      -tr-rule-ref: selector(".CBNavPaneTabsHover:alias");
+  }
+  af|navigationPane::tabs-active af|navigationPane::tabs-mid a:hover {
+      -tr-rule-ref: selector(".CBNavPaneTabsSelectedHover:alias");
+  }
+  af|navigationPane::tabs .p_AFDisabled af|navigationPane::tabs-mid:hover {
+      -tr-rule-ref: selector(".CBNavPaneTabsDisabledHover:alias");
+  }
+}
 /* Navigation Tree component -----------------------------------------------------------------------------------------*/
 /* Also valable for the tree component because the lack of CSS class hooks */
 /* CasaBlanca styles */
@@ -2511,17 +2538,31 @@ af|navigationPane::tabs .p_AFDisabled af
 .p_OraTreeRowSelected a:visited {
     -tr-rule-ref: selector(".CBNavigationTreeLink:alias");
 }
-.p_OraTreeRow a:hover,
-.p_OraTreeRow a:link:hover,
-.p_OraTreeRow a:active:hover,
-.p_OraTreeRow a:visited:hover,
-.p_OraTreeRowSelected a:hover,
-.p_OraTreeRowSelected a:link:hover,
-.p_OraTreeRowSelected a:active:hover,
-.p_OraTreeRowSelected a:visited:hover,
-.p_OraTreeRow a.OraLink:hover,
-.p_OraTreeRowSelected a.OraLink:hover {
-    -tr-rule-ref: selector(".CBNavigationTreeLinkHover:alias");
+@agent (touchScreen:none) {
+  .p_OraTreeRow a:hover,
+  .p_OraTreeRow a:link:hover,
+  .p_OraTreeRow a:active:hover,
+  .p_OraTreeRow a:visited:hover,
+  .p_OraTreeRowSelected a:hover,
+  .p_OraTreeRowSelected a:link:hover,
+  .p_OraTreeRowSelected a:active:hover,
+  .p_OraTreeRowSelected a:visited:hover,
+  .p_OraTreeRow a.OraLink:hover,
+  .p_OraTreeRowSelected a.OraLink:hover {
+      -tr-rule-ref: selector(".CBNavigationTreeLinkHover:alias");
+  }
+  .p_OraTreeDisclosedSymbol a:hover,
+  .p_OraTreeDisclosedSymbol a:link:hover,
+  .p_OraTreeDisclosedSymbol a:active:hover,
+  .p_OraTreeDisclosedSymbol a:visited:hover,
+  .p_OraTreeDisclosedSymbol a.OraLink:hover {
+      -tr-rule-ref: selector(".CBNavigationTreeExpandCollapseItemHover:alias");
+  }
+  .p_OraTreeDisclosedSymbol .OraLinkDisabled:hover,
+  .p_OraTreeRow .OraLinkDisabled:hover,
+  .p_OraTreeRowSelected .OraLinkDisabled:hover {
+      -tr-rule-ref: selector(".CBNavigationTreeLinkDisabledHover:alias") ;
+  }
 }
 .p_OraTreeDisclosedSymbol a,
 .p_OraTreeDisclosedSymbol a:link,
@@ -2529,23 +2570,11 @@ af|navigationPane::tabs .p_AFDisabled af
 .p_OraTreeDisclosedSymbol a:visited {
     -tr-rule-ref: selector(".CBNavigationTreeExpandCollapseItem:alias");
 }
-.p_OraTreeDisclosedSymbol a:hover,
-.p_OraTreeDisclosedSymbol a:link:hover,
-.p_OraTreeDisclosedSymbol a:active:hover,
-.p_OraTreeDisclosedSymbol a:visited:hover,
-.p_OraTreeDisclosedSymbol a.OraLink:hover {
-    -tr-rule-ref: selector(".CBNavigationTreeExpandCollapseItemHover:alias");
-}
 .p_OraTreeDisclosedSymbol .OraLinkDisabled,
 .p_OraTreeRow .OraLinkDisabled,
 .p_OraTreeRowSelected .OraLinkDisabled {
     -tr-rule-ref: selector(".CBNavigationTreeLinkDisabled:alias") ;
 }
-.p_OraTreeDisclosedSymbol .OraLinkDisabled:hover,
-.p_OraTreeRow .OraLinkDisabled:hover,
-.p_OraTreeRowSelected .OraLinkDisabled:hover {
-    -tr-rule-ref: selector(".CBNavigationTreeLinkDisabledHover:alias") ;
-}
 
 /* Output Document componnet ---------------------------------------------------------------------------------------- */
 /* CasaBlanca styles */
@@ -2647,12 +2676,25 @@ af|panelAccordion::header-collapsed af|p
     -tr-rule-ref: selector(".CBIconLook:alias");
     -tr-rule-ref: selector(".CBIconArrowDown:alias");
 }
-af|panelAccordion::header-collapsed af|panelAccordion::title-link:hover {
-    -tr-rule-ref: selector(".CBAccordionPanelHeadHover:alias");
-}
-af|panelAccordion::header-collapsed af|panelAccordion::title-link:hover .p_OraHideShowDisclosedSymbol {
-    -tr-rule-ref: selector(".CBIconLookHover:alias");
-    -tr-rule-ref: selector(".CBIconArrowDown:alias");
+@agent (touchScreen:none) {
+  af|panelAccordion::header-collapsed af|panelAccordion::title-link:hover {
+      -tr-rule-ref: selector(".CBAccordionPanelHeadHover:alias");
+  }
+  af|panelAccordion::header-collapsed af|panelAccordion::title-link:hover .p_OraHideShowDisclosedSymbol {
+      -tr-rule-ref: selector(".CBIconLookHover:alias");
+      -tr-rule-ref: selector(".CBIconArrowDown:alias");
+  }
+  af|panelAccordion::header-expanded af|panelAccordion::title-link:hover .p_OraHideShowDisclosedSymbol {
+      -tr-rule-ref: selector(".CBIconLookSelectedHover:alias");
+      -tr-rule-ref: selector(".CBIconArrowUp:alias");
+  }
+  af|panelAccordion::header-expanded af|panelAccordion::title-link:hover {
+      -tr-rule-ref: selector(".CBAccordionPanelHeadSelectedHover:alias");
+      margin-bottom: 0;
+  }
+  af|panelAccordion::header-disabled af|panelAccordion::title-disabled-link:hover {
+      -tr-rule-ref: selector(".CBAccordionPanelHeadDisabledHover:alias");
+  }
 }
 af|panelAccordion::header-expanded af|panelAccordion::title-link {
     -tr-rule-ref: selector(".CBAccordionPanelHeadSelected:alias");
@@ -2662,20 +2704,9 @@ af|panelAccordion::header-expanded af|pa
     -tr-rule-ref: selector(".CBIconLookSelected:alias");
     -tr-rule-ref: selector(".CBIconArrowUp:alias");
 }
-af|panelAccordion::header-expanded af|panelAccordion::title-link:hover {
-    -tr-rule-ref: selector(".CBAccordionPanelHeadSelectedHover:alias");
-    margin-bottom: 0;
-}
-af|panelAccordion::header-expanded af|panelAccordion::title-link:hover .p_OraHideShowDisclosedSymbol {
-    -tr-rule-ref: selector(".CBIconLookSelectedHover:alias");
-    -tr-rule-ref: selector(".CBIconArrowUp:alias");
-}
 af|panelAccordion::header-disabled af|panelAccordion::title-disabled-link {
     -tr-rule-ref: selector(".CBAccordionPanelHeadDisabled:alias");
 }
-af|panelAccordion::header-disabled af|panelAccordion::title-disabled-link:hover {
-    -tr-rule-ref: selector(".CBAccordionPanelHeadDisabledHover:alias");
-}
 af|panelAccordion::content {
     -tr-rule-ref: selector(".CBAccordionPanelBody:alias");
 }
@@ -2755,8 +2786,28 @@ af|panelButtonBar td img {
 af|panelButtonBar af|commandButton {
     -tr-rule-ref: selector(".CBPanelButtonBarButton:alias");
 }
-af|panelButtonBar af|commandButton:hover {
-    -tr-rule-ref: selector(".CBPanelButtonBarButtonHover:alias");
+@agent (touchScreen:none) {
+  af|panelButtonBar af|commandButton:hover {
+      -tr-rule-ref: selector(".CBPanelButtonBarButtonHover:alias");
+  }
+  af|panelTabbed::orientation-top af|panelTabbed::tab a:hover {
+      -tr-rule-ref: selector(".CBPanelTabTopHover:alias");
+  }
+  af|panelTabbed::orientation-top af|panelTabbed::tab-selected a:hover {
+      -tr-rule-ref: selector(".CBPanelTabTopSelectedHover:alias");
+  }
+  af|panelTabbed::orientation-top af|panelTabbed::tab a.p_OraDisabled:hover {
+      -tr-rule-ref: selector(".CBPanelTabTopDisabledHover:alias");
+  }
+  af|panelTabbed::orientation-bottom af|panelTabbed::tab-selected a:hover {
+      -tr-rule-ref: selector(".CBPanelTabBottomSelectedHover:alias");
+  }
+  af|panelTabbed::orientation-bottom af|panelTabbed::tab a:hover {
+      -tr-rule-ref: selector(".CBPanelTabBottomHover:alias");
+  }
+  af|panelTabbed::orientation-bottom af|panelTabbed::tab a.p_OraDisabled:hover {
+      -tr-rule-ref: selector(".CBPanelTabBottomDisabledHover:alias");
+  }
 }
 af|panelButtonBar af|singleStepButtonBar::label {
     -tr-rule-ref: selector(".CBPanelButtonBarLabel:alias");
@@ -2981,42 +3032,24 @@ af|panelTabbed::orientation-top af|panel
 af|panelTabbed::orientation-top af|panelTabbed::tab a {
     -tr-rule-ref: selector(".CBPanelTabTop:alias");
 }
-af|panelTabbed::orientation-top af|panelTabbed::tab a:hover {
-    -tr-rule-ref: selector(".CBPanelTabTopHover:alias");
-}
 af|panelTabbed::orientation-top af|panelTabbed::tab-selected a {
     -tr-rule-ref: selector(".CBPanelTabTopSelected:alias");
 }
-af|panelTabbed::orientation-top af|panelTabbed::tab-selected a:hover {
-    -tr-rule-ref: selector(".CBPanelTabTopSelectedHover:alias");
-}
 af|panelTabbed::orientation-top af|panelTabbed::tab a.p_OraDisabled {
     -tr-rule-ref: selector(".CBPanelTabTopDisabled:alias");
 }
-af|panelTabbed::orientation-top af|panelTabbed::tab a.p_OraDisabled:hover {
-    -tr-rule-ref: selector(".CBPanelTabTopDisabledHover:alias");
-}
 af|panelTabbed::orientation-bottom af|panelTabbed::tab, af|panelTabbed::tab-selected {
     padding: 0 1px 0 0;
 }
 af|panelTabbed::orientation-bottom af|panelTabbed::tab a {
     -tr-rule-ref: selector(".CBPanelTabBottom:alias");
 }
-af|panelTabbed::orientation-bottom af|panelTabbed::tab a:hover {
-    -tr-rule-ref: selector(".CBPanelTabBottomHover:alias");
-}
 af|panelTabbed::orientation-bottom af|panelTabbed::tab-selected a {
     -tr-rule-ref: selector(".CBPanelTabBottomSelected:alias");
 }
-af|panelTabbed::orientation-bottom af|panelTabbed::tab-selected a:hover {
-    -tr-rule-ref: selector(".CBPanelTabBottomSelectedHover:alias");
-}
 af|panelTabbed::orientation-bottom af|panelTabbed::tab a.p_OraDisabled {
     -tr-rule-ref: selector(".CBPanelTabBottomDisabled:alias");
 }
-af|panelTabbed::orientation-bottom af|panelTabbed::tab a.p_OraDisabled:hover {
-    -tr-rule-ref: selector(".CBPanelTabBottomDisabledHover:alias");
-}
 af|panelTabbed::body {
     -tr-rule-ref: selector(".CBPanelTabBody:alias");
 }
@@ -3066,10 +3099,12 @@ af|panelTip::content {
 af|resetButton {
    -tr-rule-ref: selector(".CBResetButton:alias");
 }
-af|resetButton:hover {
-   -tr-rule-ref: selector(".CBResetButtonHover:alias"); 
-}
 
+@agent (touchScreen:none) {
+  af|resetButton:hover {
+     -tr-rule-ref: selector(".CBResetButtonHover:alias");
+  }
+}
 /* Select Boolean CheckBox component -------------------------------------------------------------------------------- */
 /* CasaBlanca styles */
 .CBSelectBooleanCheckBox:alias {
@@ -3233,8 +3268,10 @@ af|selectManyShuttle::box-content af|sel
 af|selectManyShuttle a.OraLink {
     -tr-rule-ref: selector(".CBSelectManyShuttleButton:alias");
 }
-af|selectManyShuttle a.OraLink:hover {
-    -tr-rule-ref: selector(".CBSelectManyShuttleButtonHover:alias");
+@agent (touchScreen:none) {
+  af|selectManyShuttle a.OraLink:hover {
+      -tr-rule-ref: selector(".CBSelectManyShuttleButtonHover:alias");
+  }
 }
 af|selectManyShuttle::box-content af|selectManyListbox {
     -tr-rule-ref: selector(".CBSelectManyShuttleListBoxContainer:alias");
@@ -3361,8 +3398,10 @@ af|selectOrderShuttle::box-content af|se
 af|selectOrderShuttle::box-content a {
     -tr-rule-ref: selector(".CBSelectOrderShuttleButton:alias");
 }
-af|selectOrderShuttle::box-content a:hover {
-    -tr-rule-ref: selector(".CBSelectOrderShuttleButtonHover:alias");
+@agent (touchScreen:none) {
+  af|selectOrderShuttle::box-content a:hover {
+      -tr-rule-ref: selector(".CBSelectOrderShuttleButtonHover:alias");
+  }
 }
 af|selectOrderShuttle::box-content af|selectManyListbox {
     -tr-rule-ref: selector(".CBSelectOrderShuttleListBoxContainer:alias");
@@ -3414,12 +3453,13 @@ h1.af|showDetailHeader {
 h1.af|showDetailHeader af|showDetail::disclosure-icon-link span {
     -tr-rule-ref: selector(".CBShowDetailHeaderExpandCollapseItem:alias");
 }
-h1.af|showDetailHeader af|showDetail::disclosure-icon-link:hover,
-h1.af|showDetailHeader af|showDetail::disclosure-icon-link span:hover {
-    -tr-rule-ref: selector(".CBShowDetailHeaderExpandCollapseItemHover:alias");
+@agent (touchScreen:none) {
+  h1.af|showDetailHeader af|showDetail::disclosure-icon-link:hover,
+  h1.af|showDetailHeader af|showDetail::disclosure-icon-link span:hover {
+      -tr-rule-ref: selector(".CBShowDetailHeaderExpandCollapseItemHover:alias");
+  }
 }
 
-
 /* Show Detail Item component --------------------------------------------------------------------------------------- */
 /* CasaBlanca styles */
 .CBShowDetailItem:alias {
@@ -3441,19 +3481,21 @@ h1.af|showDetailHeader af|showDetail::di
 af|showDetail::disclosure-icon-link .p_OraHideShowDisclosedSymbol {
     -tr-rule-ref: selector(".CBShowDetailExpandCollapseItem:alias");
 }
-af|showDetail::prompt-undisclosed af|showDetail::disclosure-icon-link:hover,
-af|showDetail::prompt-disclosed af|showDetail::disclosure-icon-link:hover {
-    -tr-rule-ref: selector(".CBShowDetailExpandCollapseItemHover:alias");
-}
 af|showDetail::prompt-undisclosed af|showDetail::prompt-link,
 af|showDetail::prompt-disclosed af|showDetail::prompt-link {
     -tr-rule-ref: selector(".CBShowDetailTitle:alias");
 }
-af|showDetail::prompt-undisclosed af|showDetail::prompt-link:hover,
-af|showDetail::prompt-disclosed af|showDetail::prompt-link:hover {
-    -tr-rule-ref: selector(".CBShowDetailTitleHover:alias");    
-}
 
+@agent (touchScreen:none) {
+  af|showDetail::prompt-undisclosed af|showDetail::disclosure-icon-link:hover,
+  af|showDetail::prompt-disclosed af|showDetail::disclosure-icon-link:hover {
+      -tr-rule-ref: selector(".CBShowDetailExpandCollapseItemHover:alias");
+  }
+  af|showDetail::prompt-undisclosed af|showDetail::prompt-link:hover,
+  af|showDetail::prompt-disclosed af|showDetail::prompt-link:hover {
+      -tr-rule-ref: selector(".CBShowDetailTitleHover:alias");
+  }
+}
 /* Single step Button Bar component --------------------------------------------------------------------------------- */
 /* CasaBlanca styles */
 .CBSingleStepButtonBar:alias {
@@ -3477,8 +3519,10 @@ af|singleStepButtonBar {
 af|singleStepButtonBar af|commandButton {
     -tr-rule-ref: selector(".CBSingleStepButtonBarButton:alias");
 }
-af|singleStepButtonBar af|commandButton:hover {
-    -tr-rule-ref: selector(".CBSingleStepButtonBarButtonHover:alias");
+@agent (touchScreen:none) {
+  af|singleStepButtonBar af|commandButton:hover {
+      -tr-rule-ref: selector(".CBSingleStepButtonBarButtonHover:alias");
+  }
 }
 af|singleStepButtonBar af|singleStepButtonBar::label {
     -tr-rule-ref: selector(".CBSingleStepButtonBarLabel:alias");
@@ -3529,21 +3573,23 @@ af|train::stop {
 .p_AFSelected af|train::link {
     -tr-rule-ref: selector(".CBTrainTrainStopSelected:alias");
 }
-.p_AFSelected af|train::link:hover {
-    -tr-rule-ref: selector(".CBTrainTrainStopSelectedHover:alias");
+@agent (touchScreen:none) {
+  .p_AFSelected af|train::link:hover {
+      -tr-rule-ref: selector(".CBTrainTrainStopSelectedHover:alias");
+  }
+  .p_AFVisited af|train::link:hover {
+      -tr-rule-ref: selector(".CBTrainTrainStopVisitedHover:alias");
+  }
+  .p_AFUnvisited af|train::link:hover {
+      -tr-rule-ref: selector(".CBTrainTrainStopUnvisitedHover:alias");
+  }
 }
 .p_AFVisited af|train::link {
     -tr-rule-ref: selector(".CBTrainTrainStopVisited:alias");
 }
-.p_AFVisited af|train::link:hover {
-    -tr-rule-ref: selector(".CBTrainTrainStopVisitedHover:alias");
-}
 .p_AFUnvisited af|train::link {
     -tr-rule-ref: selector(".CBTrainTrainStopUnvisited:alias");
 }
-.p_AFUnvisited af|train::link:hover {
-    -tr-rule-ref: selector(".CBTrainTrainStopUnvisitedHover:alias");
-}
 /* Clear some legacy stuff */
 af|train::join {
     display: none ! important;
@@ -3649,9 +3695,15 @@ af|table::sub-control-bar af|showDetail:
     -tr-rule-ref: selector(".CBTableBarButton:alias") ;
 }
 /* active hover navigation buttons */
-af|table::sub-control-bar .OraLink:hover,
-af|table::sub-control-bar af|showDetail::prompt-link:hover {
-    -tr-rule-ref: selector(".CBTableBarButtonHover:alias");
+@agent (touchScreen:none) {
+  af|table::sub-control-bar .OraLink:hover,
+  af|table::sub-control-bar af|showDetail::prompt-link:hover {
+      -tr-rule-ref: selector(".CBTableBarButtonHover:alias");
+  }
+  af|table::sub-control-bar .OraNavBarActiveLink:hover,
+  af|table::sub-control-bar af|showDetail::prompt-link:hover {
+      -tr-rule-ref: selector(".CBTableBarButtonHover:alias");
+  }
 }
 /* inactive navigation buttons */
 af|table::control-bar-top table td span,
@@ -3674,10 +3726,6 @@ af|table::sub-control-bar .OraNavBarActi
     display: block;
     margin-right: 2px;
 }
-af|table::sub-control-bar .OraNavBarActiveLink:hover,
-af|table::sub-control-bar af|showDetail::prompt-link:hover {
-    -tr-rule-ref: selector(".CBTableBarButtonHover:alias");
-}
 af|table::select-all-icon {
     content:url(/adf/images/casablanca/icons/selectAll.png);
 }
@@ -3860,9 +3908,11 @@ af|treeTable::sub-control-bar .OraNavBar
     display: block;
     margin-right: 2px;
 }
-af|treeTable::sub-control-bar .OraNavBarActiveLink:hover,
-af|treeTable::sub-control-bar af|showDetail::prompt-link:hover {
-    -tr-rule-ref: selector(".CBTreeTableBarButtonHover:alias");
+@agent (touchScreen:none) {
+  af|treeTable::sub-control-bar .OraNavBarActiveLink:hover,
+  af|treeTable::sub-control-bar af|showDetail::prompt-link:hover {
+      -tr-rule-ref: selector(".CBTreeTableBarButtonHover:alias");
+  }
 }
 af|treeTable::select-all-icon {
     content:url(/adf/images/casablanca/icons/selectAll.png);

Modified: myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/capabilities.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/capabilities.xml?rev=1241072&r1=1241071&r2=1241072&view=diff
==============================================================================
--- myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/capabilities.xml (original)
+++ myfaces/trinidad/branches/sobryan_ios_changes/trinidad-impl/src/main/resources/META-INF/agent/capabilities.xml Mon Feb  6 16:48:10 2012
@@ -94,6 +94,20 @@
       <include src="email.xml" />
     </capabilities>
 
+    <capabilities id="ios" agents="webkit/500+" platforms="ipad iphone ipod">
+      <!-- note, version included to give it a higher score than the webkit312 below -->
+      <include refid="html" />
+      <include src="webkit312.xml"/>
+      <include src="ios.xml"/>
+    </capabilities>
+
+    <capabilities id="android" agents="webkit/500+" platforms="android">
+      <!-- note, version included to give it a higher score than the webkit312 below -->
+      <include refid="html" />
+      <include src="webkit312.xml"/>
+      <include src="android.xml"/>
+    </capabilities>
+
     <capabilities id="webkit" agents="webkit">
       <include refid="html" />
       <include src="webkit.xml"/>