You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2016/02/08 10:37:49 UTC

svn commit: r1729111 [1/2] - in /myfaces/tobago/branches/tobago-3.0.x: tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/model/ tobago-core/src/main/java/org/apache/myfaces/tobag...

Author: lofwyr
Date: Mon Feb  8 09:37:48 2016
New Revision: 1729111

URL: http://svn.apache.org/viewvc?rev=1729111&view=rev
Log:
TOBAGO-1502: Advanced tc:sheet support for Bootstrap
 - some progress
 - test with an alternate renderer (using display: block and some other CSS to use fix header cells)

Added:
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNodeBase.java
      - copied, changed from r1729106, myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java
Removed:
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java
Modified:
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumn.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnNode.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnSelector.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Selectable.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeCommandRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeIndentRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRendererBase.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-sheet.js
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago.js
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/tobago.css

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumn.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumn.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumn.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumn.java Mon Feb  8 09:37:48 2016
@@ -30,4 +30,6 @@ public abstract class AbstractUIColumn e
   public boolean isResizable() {
     return false;
   }
+
+  public abstract String getLabel();
 }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnNode.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnNode.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnNode.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnNode.java Mon Feb  8 09:37:48 2016
@@ -22,7 +22,7 @@ package org.apache.myfaces.tobago.intern
 import org.apache.myfaces.tobago.component.Visual;
 
 /**
- * @since 2.0.0
+ * @since Tobago 2.0.0
  */
-public abstract class AbstractUIColumnNode extends AbstractUITreeNode implements Visual {
+public abstract class AbstractUIColumnNode extends AbstractUITreeNodeBase implements Visual {
 }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnSelector.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnSelector.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnSelector.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIColumnSelector.java Mon Feb  8 09:37:48 2016
@@ -27,4 +27,9 @@ public abstract class AbstractUIColumnSe
     return null;
   }
 */
+
+  @Override
+  public String getLabel() {
+    return null;
+  }
 }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java Mon Feb  8 09:37:48 2016
@@ -93,7 +93,7 @@ public abstract class AbstractUITree ext
   public UIComponent getRoot() {
     // find the UITreeNode in the children.
     for (final UIComponent child : getChildren()) {
-      if (child instanceof AbstractUITreeNode) {
+      if (child instanceof AbstractUITreeNodeBase) {
         return child;
       }
     }

Copied: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNodeBase.java (from r1729106, myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNodeBase.java?p2=myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNodeBase.java&p1=myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java&r1=1729106&r2=1729111&rev=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNodeBase.java Mon Feb  8 09:37:48 2016
@@ -29,7 +29,7 @@ import javax.faces.context.FacesContext;
 import java.io.IOException;
 import java.util.List;
 
-public abstract class AbstractUITreeNode
+public abstract class AbstractUITreeNodeBase
     extends AbstractUIColumn implements Visual {
 
   @Override

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Selectable.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Selectable.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Selectable.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Selectable.java Mon Feb  8 09:37:48 2016
@@ -166,6 +166,10 @@ public enum Selectable {
     return this == single || this == singleOrNone || this == singleLeafOnly;
   }
 
+  public boolean isMulti() {
+    return this == multi || this == multiLeafOnly || this == multiCascade;
+  }
+
   public boolean isSupportedBySheet() {
     return SHEET_VALUES.contains(this);
   }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java Mon Feb  8 09:37:48 2016
@@ -33,7 +33,6 @@ public enum DataAttributes implements Ma
     COLUMN_INDEX("data-tobago-column-index"),
 
   /**
-   * TBD: needed? may replace with value?
    * Custom command attribute. Is used to mark different client side JavaScript buttons.
    * Should only contain the command name as a keyword, for security reasons.
    */

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml Mon Feb  8 09:37:48 2016
@@ -41,7 +41,7 @@
 
   <resource-dir>tobago-resource</resource-dir>
 
-  <content-security-policy mode="on">
+  <content-security-policy mode="off">
     <directive>frame-src https://maps.google.com</directive>
   </content-security-policy>
 

Added: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java?rev=1729111&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java (added)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java Mon Feb  8 09:37:48 2016
@@ -0,0 +1,666 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
+
+import org.apache.myfaces.tobago.component.Attributes;
+import org.apache.myfaces.tobago.component.Facets;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.component.UIColumn;
+import org.apache.myfaces.tobago.component.UIColumnSelector;
+import org.apache.myfaces.tobago.component.UICommand;
+import org.apache.myfaces.tobago.component.UIReload;
+import org.apache.myfaces.tobago.component.UISheet;
+import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.context.ResourceManagerUtils;
+import org.apache.myfaces.tobago.event.PageAction;
+import org.apache.myfaces.tobago.internal.component.AbstractUIColumn;
+import org.apache.myfaces.tobago.internal.util.StringUtils;
+import org.apache.myfaces.tobago.layout.ShowPosition;
+import org.apache.myfaces.tobago.layout.TextAlign;
+import org.apache.myfaces.tobago.model.Selectable;
+import org.apache.myfaces.tobago.model.SheetState;
+import org.apache.myfaces.tobago.renderkit.RendererBase;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.Classes;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+import org.apache.myfaces.tobago.renderkit.css.Icons;
+import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.Arias;
+import org.apache.myfaces.tobago.renderkit.html.Command;
+import org.apache.myfaces.tobago.renderkit.html.CommandMap;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
+import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
+import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.renderkit.util.EncodeUtils;
+import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.faces.application.Application;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+* TBD: This is a temporary version of the SheetRenderer.
+ *
+ * Evaluating the best implementation... This is a try to use modern CSS for scrollable tables with fixed headers.
+* */
+public class SheetRenderer extends RendererBase {
+
+  private static final Logger LOG = LoggerFactory.getLogger(SheetRenderer.class);
+
+  protected static final String WIDTHS = ComponentUtils.SUB_SEPARATOR + "widths";
+  protected static final String SCROLL_POSITION = ComponentUtils.SUB_SEPARATOR + "scrollPosition";
+  protected static final String SELECTED = ComponentUtils.SUB_SEPARATOR + "selected";
+  protected static final String SELECTOR_DROPDOWN = ComponentUtils.SUB_SEPARATOR + "selectorDropdown";
+
+  @Override
+  public void decode(FacesContext facesContext, UIComponent component) {
+    final UISheet sheet = (UISheet) component;
+    final String clientId = sheet.getClientId(facesContext);
+
+    final String value = facesContext.getExternalContext().getRequestParameterMap().get(clientId + SCROLL_POSITION);
+    if (value != null) {
+      sheet.getState().getScrollPosition().update(value);
+    }
+  }
+
+  @Override
+  public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
+    final UISheet sheet = (UISheet) component;
+    final String clientId = sheet.getClientId(facesContext);
+    final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+    final List<AbstractUIColumn> columns = sheet.getRenderedColumns();
+    final Selectable selectable = sheet.getSelectable();
+    final List<Integer> selectedRows = getSelectedRows(sheet);
+
+    writer.startElement(HtmlElements.DIV);
+    writer.writeIdAttribute(clientId);
+    HtmlRendererUtils.writeDataAttributes(facesContext, writer, sheet);
+    writer.writeClassAttribute(Classes.create(sheet), sheet.getCustomClass());
+    writer.writeStyleAttribute(sheet.getStyle());
+    final UIComponent facetReload = ComponentUtils.getFacet(sheet, Facets.reload);
+    if (facetReload != null && facetReload instanceof UIReload && facetReload.isRendered()) {
+      final UIReload update = (UIReload) facetReload;
+      writer.writeAttribute(DataAttributes.RELOAD, update.getFrequency());
+    }
+    final String[] clientIds = ComponentUtils.evaluateClientIds(facesContext, sheet, sheet.getRenderedPartially());
+    if (clientIds.length > 0) {
+      writer.writeAttribute(DataAttributes.PARTIAL_IDS, JsonUtils.encode(clientIds), true);
+    }
+    writer.writeAttribute(DataAttributes.SELECTION_MODE, sheet.getSelectable().name(), false);
+    writer.writeAttribute(DataAttributes.FIRST, Integer.toString(sheet.getFirst()), false);
+
+//    writer.startElement(HtmlElements.INPUT);
+//    writer.writeIdAttribute(clientId + WIDTHS);
+//    writer.writeNameAttribute(clientId + WIDTHS);
+//    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+//    writer.writeAttribute(HtmlAttributes.VALUE, StringUtils.joinWithSurroundingSeparator(columnWidths), false);
+//    writer.endElement(HtmlElements.INPUT);
+
+    writer.startElement(HtmlElements.INPUT);
+    writer.writeIdAttribute(clientId + SCROLL_POSITION);
+    writer.writeNameAttribute(clientId + SCROLL_POSITION);
+    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+    writer.writeAttribute(HtmlAttributes.VALUE, sheet.getState().getScrollPosition().encode(), false);
+    writer.writeAttribute(DataAttributes.SCROLL_POSITION, Boolean.TRUE.toString(), true);
+    writer.endElement(HtmlElements.INPUT);
+
+    if (selectable != Selectable.none) {
+      writer.startElement(HtmlElements.INPUT);
+      writer.writeIdAttribute(clientId + SELECTED);
+      writer.writeNameAttribute(clientId + SELECTED);
+      writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+      writer.writeAttribute(HtmlAttributes.VALUE, StringUtils.joinWithSurroundingSeparator(selectedRows), true);
+      writer.endElement(HtmlElements.INPUT);
+    }
+
+    writer.startElement(HtmlElements.DIV);
+    writer.writeClassAttribute(Classes.create(sheet, "body"));
+
+    writer.startElement(HtmlElements.TABLE);
+    writer.writeClassAttribute(Classes.create(sheet, "fixHeader"), BootstrapClass.TABLE);
+
+    writer.startElement(HtmlElements.THEAD);
+    writer.startElement(HtmlElements.TR);
+    for (AbstractUIColumn column : columns) {
+      writer.startElement(HtmlElements.TH);
+      writer.writeIdAttribute(column.getClientId(facesContext));
+      if (column instanceof UIColumn) {
+        writer.writeText(column.getLabel());
+      } else if (column instanceof UIColumnSelector && selectable.isMulti()) {
+        writer.writeClassAttribute(Classes.create(sheet, "selectorDropdown"));
+
+        writer.startElement(HtmlElements.DIV);
+        writer.writeClassAttribute(BootstrapClass.DROPDOWN);
+        writer.startElement(HtmlElements.BUTTON);
+        writer.writeClassAttribute(BootstrapClass.BTN, BootstrapClass.BTN_SECONDARY, BootstrapClass.DROPDOWN_TOGGLE);
+        writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+        writer.writeIdAttribute(clientId + SELECTOR_DROPDOWN);
+        writer.writeAttribute(DataAttributes.TOGGLE, "dropdown", false);
+        writer.writeAttribute(Arias.HASPOPUP, Boolean.TRUE.toString(), false);
+        writer.writeAttribute(Arias.EXPANDED, Boolean.FALSE.toString(), false);
+        writer.endElement(HtmlElements.BUTTON);
+        writer.startElement(HtmlElements.DIV);
+        writer.writeClassAttribute(BootstrapClass.DROPDOWN_MENU);
+        writer.writeAttribute(Arias.LABELLEDBY, clientId + SELECTOR_DROPDOWN, false);
+        writer.startElement(HtmlElements.BUTTON);
+        writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+        writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+        writer.writeAttribute(DataAttributes.COMMAND, "sheetSelectAll", false);
+        writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuSelect"));
+        writer.endElement(HtmlElements.BUTTON);
+        writer.startElement(HtmlElements.BUTTON);
+        writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+        writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+        writer.writeAttribute(DataAttributes.COMMAND, "sheetDeselectAll", false);
+        writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuUnselect"));
+        writer.endElement(HtmlElements.BUTTON);
+        writer.startElement(HtmlElements.BUTTON);
+        writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+        writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+        writer.writeAttribute(DataAttributes.COMMAND, "sheetToggleAll", false);
+        writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuToggleselect"));
+        writer.endElement(HtmlElements.BUTTON);
+        writer.endElement(HtmlElements.DIV);
+        writer.endElement(HtmlElements.DIV);
+      } else {
+
+      }
+      writer.endElement(HtmlElements.TH);
+    }
+    writer.endElement(HtmlElements.TR);
+    writer.endElement(HtmlElements.THEAD);
+
+  }
+
+  @Override
+  public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException {
+    final UISheet sheet = (UISheet) component;
+    final String clientId = sheet.getClientId(facesContext);
+    final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+    final List<AbstractUIColumn> columns = sheet.getRenderedColumns();
+    final boolean hasClickAction = HtmlRendererUtils.renderSheetCommands(sheet, facesContext, writer);
+    final List<Integer> selectedRows = getSelectedRows(sheet);
+
+    writer.startElement(HtmlElements.TBODY);
+    final String var = sheet.getVar();
+
+    boolean emptySheet = true;
+    // rows = 0 means: show all
+    final int last = sheet.isRowsUnlimited() ? Integer.MAX_VALUE : sheet.getFirst() + sheet.getRows();
+    for (int rowIndex = sheet.getFirst(); rowIndex < last; rowIndex++) {
+      sheet.setRowIndex(rowIndex);
+      if (!sheet.isRowAvailable()) {
+        break;
+      }
+
+      final Object rowRendered = sheet.getAttributes().get("rowRendered");
+      if (rowRendered instanceof Boolean && !((Boolean) rowRendered)) {
+        continue;
+      }
+
+      emptySheet = false;
+
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("var       " + var);
+        LOG.debug("list      " + sheet.getValue());
+      }
+
+      writer.startElement(HtmlElements.TR);
+
+      final boolean selected = selectedRows.contains(rowIndex);
+      final String[] rowMarkups = (String[]) sheet.getAttributes().get("rowMarkup");
+      Markup rowMarkup = Markup.NULL;
+      if (selected) {
+        rowMarkup = rowMarkup.add(Markup.SELECTED);
+      }
+      if (rowMarkups != null) {
+        rowMarkup = rowMarkup.add(Markup.valueOf(rowMarkups));
+      }
+      writer.writeClassAttribute(Classes.create(sheet, "row", rowMarkup), selected ? BootstrapClass.INFO : null);
+
+      for (AbstractUIColumn column : columns) {
+
+        writer.startElement(HtmlElements.TD);
+
+        Markup markup = column.getMarkup();
+        if (markup == null) {
+          markup = Markup.NULL;
+        }
+        if (hasClickAction) {
+          markup = markup.add(Markup.CLICKABLE);
+        }
+        final String textAlign = ComponentUtils.getStringAttribute(column, Attributes.align);
+        if (textAlign != null) {
+          switch (TextAlign.valueOf(textAlign)) {
+            case right:
+              markup = markup.add(Markup.RIGHT);
+              break;
+            case center:
+              markup = markup.add(Markup.CENTER);
+              break;
+            case justify:
+              markup = markup.add(Markup.JUSTIFY);
+              break;
+            default:
+              // nothing to do
+          }
+        }
+        writer.writeClassAttribute(Classes.create(sheet, "cell", markup));
+LOG.info("" + column);
+        if (column instanceof UIColumnSelector) {
+          UIColumnSelector selector = (UIColumnSelector) column;
+          writer.startElement(HtmlElements.INPUT);
+          if (sheet.getSelectable().isSingle()) {
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.RADIO);
+          } else {
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.CHECKBOX);
+          }
+          writer.writeAttribute(HtmlAttributes.CHECKED, selected);
+          writer.writeAttribute(HtmlAttributes.DISABLED, selector.isDisabled());
+          writer.writeClassAttribute(Classes.create(sheet, "columnSelector"));
+          writer.endElement(HtmlElements.INPUT);
+        } else if (column instanceof UIColumn) {
+          for (final UIComponent grandKid : column.getChildren()) {
+            if (grandKid.isRendered()) {
+              EncodeUtils.prepareRendererAll(facesContext, grandKid);
+              RenderUtils.encode(facesContext, grandKid);
+            }
+          }
+        } else {
+
+        }
+        writer.endElement(HtmlElements.TD);
+      }
+
+      writer.endElement(HtmlElements.TR);
+
+    }
+    writer.endElement(HtmlElements.TBODY);
+  }
+
+  @Override
+  public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
+    final UISheet sheet = (UISheet) component;
+    final String clientId = sheet.getClientId(facesContext);
+    final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+    final Application application = facesContext.getApplication();
+
+    writer.endElement(HtmlElements.TABLE);
+    writer.endElement(HtmlElements.DIV);
+
+    if (sheet.isPagingVisible()) {
+      writer.startElement(HtmlElements.FOOTER);
+      writer.writeClassAttribute(Classes.create(sheet, "footer"));
+
+      // show row range
+      final Markup showRowRange = markupForLeftCenterRight(sheet.getShowRowRange());
+      if (showRowRange != Markup.NULL) {
+        final UICommand command
+            = ensurePagingCommand(application, sheet, Facets.pagerRow.name(), PageAction.TO_ROW, false);
+        final String pagerCommandId = command.getClientId(facesContext);
+
+        writer.startElement(HtmlElements.UL);
+        writer.writeClassAttribute(Classes.create(sheet, "paging", showRowRange), BootstrapClass.PAGINATION);
+        writer.startElement(HtmlElements.LI);
+        writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
+        writer.writeAttribute(HtmlAttributes.TITLE,
+            ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetPagingInfoRowPagingTip"), true);
+        writer.startElement(HtmlElements.SPAN);
+        writer.writeClassAttribute(Classes.create(sheet, "pagingText"), BootstrapClass.PAGE_LINK);
+        if (sheet.getRowCount() != 0) {
+          final Locale locale = facesContext.getViewRoot().getLocale();
+          final int first = sheet.getFirst() + 1;
+          final int last1 = sheet.hasRowCount()
+              ? sheet.getLastRowIndexOfCurrentPage()
+              : -1;
+          final boolean unknown = !sheet.hasRowCount();
+          final String key; // plural
+          if (unknown) {
+            if (first == last1) {
+              key = "sheetPagingInfoUndefinedSingleRow";
+            } else {
+              key = "sheetPagingInfoUndefinedRows";
+            }
+          } else {
+            if (first == last1) {
+              key = "sheetPagingInfoSingleRow";
+            } else {
+              key = "sheetPagingInfoRows";
+            }
+          }
+          final String inputMarker = "{#}";
+          final Object[] args = {inputMarker, last1 == -1 ? "?" : last1, unknown ? "" : sheet.getRowCount()};
+          final MessageFormat detail = new MessageFormat(
+              ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", key), locale);
+          final String formatted = detail.format(args);
+          final int pos = formatted.indexOf(inputMarker);
+          if (pos >= 0) {
+            writer.writeText(formatted.substring(0, pos));
+            writer.startElement(HtmlElements.SPAN);
+            writer.writeClassAttribute(TobagoClass.SHEET__PAGING_OUTPUT);
+            writer.writeText(Integer.toString(first));
+            writer.endElement(HtmlElements.SPAN);
+            writer.startElement(HtmlElements.INPUT);
+            writer.writeIdAttribute(pagerCommandId + ComponentUtils.SUB_SEPARATOR + "value");
+            writer.writeNameAttribute(pagerCommandId + ComponentUtils.SUB_SEPARATOR + "value");
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
+            writer.writeClassAttribute(TobagoClass.SHEET__PAGING_INPUT);
+            writer.writeAttribute(HtmlAttributes.VALUE, first);
+            if (!unknown) {
+              writer.writeAttribute(HtmlAttributes.MAXLENGTH, Integer.toString(sheet.getRowCount()).length());
+            }
+            writer.endElement(HtmlElements.INPUT);
+            writer.writeText(formatted.substring(pos + inputMarker.length()));
+          } else {
+            writer.writeText(formatted);
+          }
+        } else {
+          writer.write(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetPagingInfoEmptyRow"));
+        }
+        writer.endElement(HtmlElements.SPAN);
+        writer.endElement(HtmlElements.LI);
+        writer.endElement(HtmlElements.UL);
+      }
+
+      // show direct links
+      final Markup showDirectLinks = markupForLeftCenterRight(sheet.getShowDirectLinks());
+      if (showDirectLinks != Markup.NULL) {
+        writer.startElement(HtmlElements.UL);
+        writer.writeClassAttribute(
+            Classes.create(sheet, "paging", showDirectLinks), BootstrapClass.PAGINATION);
+        if (sheet.isShowDirectLinksArrows()) {
+          final boolean disabled = sheet.isAtBeginning();
+          encodeLink(facesContext, sheet, application, disabled, PageAction.FIRST, null, Icons.STEP_BACKWARD, null);
+          encodeLink(facesContext, sheet, application, disabled, PageAction.PREV, null, Icons.BACKWARD, null);
+        }
+        encodeDirectPagingLinks(facesContext, application, sheet);
+        if (sheet.isShowDirectLinksArrows()) {
+          final boolean disabled = sheet.isAtEnd();
+          encodeLink(facesContext, sheet, application, disabled, PageAction.NEXT, null, Icons.FORWARD, null);
+          encodeLink(facesContext, sheet, application, disabled || !sheet.hasRowCount(), PageAction.LAST, null,
+              Icons.STEP_FORWARD, null);
+        }
+        writer.endElement(HtmlElements.UL);
+      }
+
+      // show page range
+      final Markup showPageRange = markupForLeftCenterRight(sheet.getShowPageRange());
+      if (showPageRange != Markup.NULL) {
+        final UICommand command
+            = ensurePagingCommand(application, sheet, Facets.pagerPage.name(), PageAction.TO_PAGE, false);
+        final String pagerCommandId = command.getClientId(facesContext);
+
+        writer.startElement(HtmlElements.UL);
+        writer.writeClassAttribute(Classes.create(sheet, "paging", showPageRange), BootstrapClass.PAGINATION);
+
+        if (sheet.isShowPageRangeArrows()) {
+          final boolean disabled = sheet.isAtBeginning();
+          encodeLink(facesContext, sheet, application, disabled, PageAction.FIRST, null, Icons.STEP_BACKWARD, null);
+          encodeLink(facesContext, sheet, application, disabled, PageAction.PREV, null, Icons.BACKWARD, null);
+        }
+        writer.startElement(HtmlElements.LI);
+        writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
+        writer.startElement(HtmlElements.SPAN);
+        writer.writeClassAttribute(Classes.create(sheet, "pagingText"), BootstrapClass.PAGE_LINK);
+        writer.writeAttribute(HtmlAttributes.TITLE,
+            ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetPagingInfoPagePagingTip"), true);
+        if (sheet.getRowCount() != 0) {
+          final Locale locale = facesContext.getViewRoot().getLocale();
+          final int first = sheet.getCurrentPage() + 1;
+          final boolean unknown = !sheet.hasRowCount();
+          final int pages = unknown ? -1 : sheet.getPages();
+          final String key;
+          if (unknown) {
+            if (first == pages) {
+              key = "sheetPagingInfoUndefinedSinglePage";
+            } else {
+              key = "sheetPagingInfoUndefinedPages";
+            }
+          } else {
+            if (first == pages) {
+              key = "sheetPagingInfoSinglePage";
+            } else {
+              key = "sheetPagingInfoPages";
+            }
+          }
+          final String inputMarker = "{#}";
+          final Object[] args = {inputMarker, pages == -1 ? "?" : pages};
+          final MessageFormat detail = new MessageFormat(
+              ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", key), locale);
+          final String formatted = detail.format(args);
+          final int pos = formatted.indexOf(inputMarker);
+          if (pos >= 0) {
+            writer.writeText(formatted.substring(0, pos));
+            writer.startElement(HtmlElements.SPAN);
+            writer.writeClassAttribute(TobagoClass.SHEET__PAGING_OUTPUT);
+            writer.writeText(Integer.toString(first));
+            writer.endElement(HtmlElements.SPAN);
+            writer.startElement(HtmlElements.INPUT);
+            writer.writeIdAttribute(pagerCommandId + ComponentUtils.SUB_SEPARATOR + "value");
+            writer.writeNameAttribute(pagerCommandId + ComponentUtils.SUB_SEPARATOR + "value");
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
+            writer.writeClassAttribute(TobagoClass.SHEET__PAGING_INPUT);
+            writer.writeAttribute(HtmlAttributes.VALUE, first);
+            if (!unknown) {
+              writer.writeAttribute(HtmlAttributes.MAXLENGTH, Integer.toString(pages).length());
+            }
+            writer.endElement(HtmlElements.INPUT);
+            writer.writeText(formatted.substring(pos + inputMarker.length()));
+          } else {
+            writer.writeText(formatted);
+          }
+        } else {
+          writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetPagingInfoEmptyPage"));
+        }
+        writer.endElement(HtmlElements.SPAN);
+        writer.endElement(HtmlElements.LI);
+        if (sheet.isShowPageRangeArrows()) {
+          final boolean disabled = sheet.isAtEnd();
+          encodeLink(facesContext, sheet, application, disabled, PageAction.NEXT, null, Icons.FORWARD, null);
+          encodeLink(facesContext, sheet, application, disabled || !sheet.hasRowCount(), PageAction.LAST, null,
+              Icons.STEP_FORWARD, null);
+        }
+        writer.endElement(HtmlElements.UL);
+      }
+
+      writer.endElement(HtmlElements.FOOTER);
+    }
+
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  private List<Integer> getSelectedRows(final UISheet sheet) {
+    final SheetState state = sheet.getState();
+    List<Integer> selected = (List<Integer>) ComponentUtils.getAttribute(sheet, Attributes.selectedListString);
+    if (selected == null && state != null) {
+      selected = state.getSelectedRows();
+    }
+    if (selected == null) {
+      selected = Collections.emptyList();
+    }
+    return selected;
+  }
+
+  private void encodeDirectPagingLinks(
+      final FacesContext facesContext, final Application application, final UISheet sheet)
+      throws IOException {
+
+    final UICommand command
+        = ensurePagingCommand(application, sheet, Facets.PAGER_PAGE_DIRECT, PageAction.TO_PAGE, false);
+    int linkCount = ComponentUtils.getIntAttribute(sheet, Attributes.directLinkCount);
+    linkCount--;  // current page needs no link
+    final ArrayList<Integer> prevs = new ArrayList<Integer>(linkCount);
+    int page = sheet.getCurrentPage() + 1;
+    for (int i = 0; i < linkCount && page > 1; i++) {
+      page--;
+      if (page > 0) {
+        prevs.add(0, page);
+      }
+    }
+
+    final ArrayList<Integer> nexts = new ArrayList<Integer>(linkCount);
+    page = sheet.getCurrentPage() + 1;
+    final int pages = sheet.hasRowCount() || sheet.isRowsUnlimited() ? sheet.getPages() : Integer.MAX_VALUE;
+    for (int i = 0; i < linkCount && page < pages; i++) {
+      page++;
+      if (page > 1) {
+        nexts.add(page);
+      }
+    }
+
+    if (prevs.size() > (linkCount / 2)
+        && nexts.size() > (linkCount - (linkCount / 2))) {
+      while (prevs.size() > (linkCount / 2)) {
+        prevs.remove(0);
+      }
+      while (nexts.size() > (linkCount - (linkCount / 2))) {
+        nexts.remove(nexts.size() - 1);
+      }
+    } else if (prevs.size() <= (linkCount / 2)) {
+      while (prevs.size() + nexts.size() > linkCount) {
+        nexts.remove(nexts.size() - 1);
+      }
+    } else {
+      while (prevs.size() + nexts.size() > linkCount) {
+        prevs.remove(0);
+      }
+    }
+
+    int skip = prevs.size() > 0 ? prevs.get(0) : 1;
+    if (!sheet.isShowDirectLinksArrows() && skip > 1) {
+      skip -= (linkCount - (linkCount / 2));
+      skip--;
+      if (skip < 1) {
+        skip = 1;
+      }
+      encodeLink(facesContext, sheet, application, false, PageAction.TO_PAGE, skip, Icons.ELLIPSIS_H, null);
+    }
+    for (final Integer prev : prevs) {
+      encodeLink(facesContext, sheet, application, false, PageAction.TO_PAGE, prev, null, null);
+    }
+    encodeLink(facesContext, sheet, application, false, PageAction.TO_PAGE,
+        sheet.getCurrentPage() + 1, null, BootstrapClass.ACTIVE);
+
+    for (final Integer next : nexts) {
+      encodeLink(facesContext, sheet, application, false, PageAction.TO_PAGE, next, null, null);
+    }
+
+    skip = nexts.size() > 0 ? nexts.get(nexts.size() - 1) : pages;
+    if (!sheet.isShowDirectLinksArrows() && skip < pages) {
+      skip += linkCount / 2;
+      skip++;
+      if (skip > pages) {
+        skip = pages;
+      }
+      encodeLink(facesContext, sheet, application, false, PageAction.TO_PAGE, skip, Icons.ELLIPSIS_H, null);
+    }
+  }
+
+  @Override
+  public boolean getRendersChildren() {
+    return true;
+  }
+
+  private void encodeLink(
+      final FacesContext facesContext, final UISheet data, final Application application,
+      final boolean disabled, final PageAction action, Integer target, Icons icon, CssItem liClass)
+      throws IOException {
+
+    final String facet = action == PageAction.TO_PAGE || action == PageAction.TO_ROW
+        ? action.getToken() + "-" + target
+        : action.getToken();
+    final UICommand command = ensurePagingCommand(application, data, facet, action, disabled);
+    if (target != null) {
+      ComponentUtils.setAttribute(command, Attributes.pagingTarget, target);
+    }
+    command.setRenderedPartially(new String[]{data.getId()});
+
+    final Locale locale = facesContext.getViewRoot().getLocale();
+    final String message = ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheet" + action.getToken());
+    final String tip = new MessageFormat(message, locale).format(new Integer[]{target}); // needed fot ToPage
+
+    final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+    writer.startElement(HtmlElements.LI);
+    writer.writeClassAttribute(liClass, disabled ? BootstrapClass.DISABLED : null, BootstrapClass.PAGE_ITEM);
+    writer.startElement(HtmlElements.A);
+    writer.writeClassAttribute(BootstrapClass.PAGE_LINK);
+    writer.writeAttribute(HtmlAttributes.HREF, "#", false);
+    writer.writeIdAttribute(command.getClientId(facesContext));
+    writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
+    if (!disabled) {
+      final CommandMap map = new CommandMap(new Command(facesContext, command));
+      writer.writeAttribute(DataAttributes.COMMANDS, JsonUtils.encode(map), true);
+    }
+    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
+    if (icon != null) {
+      writer.writeIcon(icon);
+    } else {
+      writer.writeText(String.valueOf(target));
+    }
+    writer.endElement(HtmlElements.A);
+    writer.endElement(HtmlElements.LI);
+  }
+
+  private UICommand ensurePagingCommand(
+      final Application application, final UISheet sheet, final String facet, final PageAction action,
+      final boolean disabled) {
+
+    final Map<String, UIComponent> facets = sheet.getFacets();
+    UICommand command = (UICommand) facets.get(facet);
+    if (command == null) {
+      command = (UICommand) application.createComponent(UICommand.COMPONENT_TYPE);
+      command.setRendererType(RendererTypes.SHEET_PAGE_COMMAND);
+      command.setRendered(true);
+      ComponentUtils.setAttribute(command, Attributes.pageAction, action);
+      command.setDisabled(disabled);
+      facets.put(facet, command);
+    }
+    return command;
+  }
+
+  private Markup markupForLeftCenterRight(final ShowPosition position) {
+    switch (position) {
+      case left:
+        return Markup.LEFT;
+      case center:
+        return Markup.CENTER;
+      case right:
+        return Markup.RIGHT;
+      default:
+        return Markup.NULL;
+    }
+  }
+
+}

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java Mon Feb  8 09:37:48 2016
@@ -135,6 +135,7 @@ public enum BootstrapClass implements Cs
   NAVBAR_NAV("navbar-nav"),
   NAVBAR_TOGGLEABLE_XS("navbar-toggleable-xs"),
   NAVBAR_TOGGLER("navbar-toggler"),
+  OPEN("open"),
   PAGE_ITEM("page-item"),
   PAGE_LINK("page-link"),
   PAGINATION("pagination"),

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SheetRenderer.java Mon Feb  8 09:37:48 2016
@@ -25,13 +25,10 @@ import org.apache.myfaces.tobago.compone
 import org.apache.myfaces.tobago.component.UIColumnSelector;
 import org.apache.myfaces.tobago.component.UICommand;
 import org.apache.myfaces.tobago.component.UILink;
-import org.apache.myfaces.tobago.component.UIMenu;
-import org.apache.myfaces.tobago.component.UIMenuCommand;
 import org.apache.myfaces.tobago.component.UIOut;
 import org.apache.myfaces.tobago.component.UIPanel;
 import org.apache.myfaces.tobago.component.UIReload;
 import org.apache.myfaces.tobago.component.UISheet;
-import org.apache.myfaces.tobago.component.UIToolBar;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
@@ -61,10 +58,12 @@ import org.apache.myfaces.tobago.renderk
 import org.apache.myfaces.tobago.renderkit.css.Icons;
 import org.apache.myfaces.tobago.renderkit.css.Style;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.Arias;
 import org.apache.myfaces.tobago.renderkit.html.Command;
 import org.apache.myfaces.tobago.renderkit.html.CommandMap;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
 import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
@@ -95,8 +94,10 @@ public class SheetRenderer extends Rende
 
   private static final Logger LOG = LoggerFactory.getLogger(SheetRenderer.class);
 
-  public static final String WIDTHS_POSTFIX = ComponentUtils.SUB_SEPARATOR + "widths";
-  public static final String SELECTED_POSTFIX = ComponentUtils.SUB_SEPARATOR + "selected";
+  protected static final String WIDTHS = ComponentUtils.SUB_SEPARATOR + "widths";
+  protected static final String SCROLL_POSITION = ComponentUtils.SUB_SEPARATOR + "scrollPosition";
+  protected static final String SELECTED = ComponentUtils.SUB_SEPARATOR + "selected";
+  protected static final String SELECTOR_DROPDOWN = ComponentUtils.SUB_SEPARATOR + "selectorDropdown";
 
   @Override
   public void prepareRender(final FacesContext facesContext, final UIComponent component) throws IOException {
@@ -182,18 +183,25 @@ public class SheetRenderer extends Rende
     final List<AbstractUIColumn> renderedColumnList = sheet.getRenderedColumns();
 
     writer.startElement(HtmlElements.INPUT);
-    writer.writeIdAttribute(sheetId + WIDTHS_POSTFIX);
-    writer.writeNameAttribute(sheetId + WIDTHS_POSTFIX);
+    writer.writeIdAttribute(sheetId + WIDTHS);
+    writer.writeNameAttribute(sheetId + WIDTHS);
     writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
     writer.writeAttribute(HtmlAttributes.VALUE, StringUtils.joinWithSurroundingSeparator(columnWidths), false);
     writer.endElement(HtmlElements.INPUT);
 
-    RenderUtils.writeScrollPosition(facesContext, writer, sheet, sheet.getState());
+    final String clientId = sheet.getClientId(facesContext);
+    writer.startElement(HtmlElements.INPUT);
+    writer.writeIdAttribute(clientId + SCROLL_POSITION);
+    writer.writeNameAttribute(clientId + SCROLL_POSITION);
+    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+    writer.writeAttribute(HtmlAttributes.VALUE, sheet.getState().getScrollPosition().encode(), false);
+    writer.writeAttribute(DataAttributes.SCROLL_POSITION, Boolean.TRUE.toString(), true);
+    writer.endElement(HtmlElements.INPUT);
 
     if (selectable != Selectable.none) {
       writer.startElement(HtmlElements.INPUT);
-      writer.writeIdAttribute(sheetId + SELECTED_POSTFIX);
-      writer.writeNameAttribute(sheetId + SELECTED_POSTFIX);
+      writer.writeIdAttribute(sheetId + SELECTED);
+      writer.writeNameAttribute(sheetId + SELECTED);
       writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
       writer.writeAttribute(
           HtmlAttributes.VALUE, StringUtils.joinWithSurroundingSeparator(selectedRows), true);
@@ -341,7 +349,6 @@ public class SheetRenderer extends Rende
           }
           writer.writeAttribute(HtmlAttributes.CHECKED, selected);
           writer.writeAttribute(HtmlAttributes.DISABLED, selector.isDisabled());
-          writer.writeIdAttribute(sheetId + "_data_row_selector_" + rowIndex);
           writer.writeClassAttribute(Classes.create(sheet, "columnSelector"));
           writer.endElement(HtmlElements.INPUT);
         } else if (column instanceof AbstractUIColumnNode) {
@@ -634,7 +641,7 @@ public class SheetRenderer extends Rende
 
     final UISheet sheet = (UISheet) component;
 
-    String key = sheet.getClientId(facesContext) + WIDTHS_POSTFIX;
+    String key = sheet.getClientId(facesContext) + WIDTHS;
 
     final Map requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
     if (requestParameterMap.containsKey(key)) {
@@ -644,7 +651,7 @@ public class SheetRenderer extends Rende
       }
     }
 
-    key = sheet.getClientId(facesContext) + SELECTED_POSTFIX;
+    key = sheet.getClientId(facesContext) + SELECTED;
     if (requestParameterMap.containsKey(key)) {
       final String selected = (String) requestParameterMap.get(key);
       if (LOG.isDebugEnabled()) {
@@ -661,7 +668,11 @@ public class SheetRenderer extends Rende
       ComponentUtils.setAttribute(sheet, Attributes.selectedListString, selectedRows);
     }
 
-    RenderUtils.decodeScrollPosition(facesContext, sheet, sheet.getState());
+    final String value = facesContext.getExternalContext().getRequestParameterMap().get(
+        sheet.getClientId(facesContext) + SCROLL_POSITION);
+    if (value != null) {
+      sheet.getState().getScrollPosition().update(value);
+    }
     RenderUtils.decodedStateOfTreeData(facesContext, sheet);
   }
 
@@ -759,6 +770,8 @@ public class SheetRenderer extends Rende
       final List<AbstractUIColumn> renderedColumnList)
       throws IOException {
 
+    final Selectable selectable = sheet.getSelectable();
+
     final Grid grid = sheet.getHeaderGrid();
     if (grid == null) {
       LOG.warn("Can't render column headers, because grid == null. One reason can be, the you use nested sheets. "
@@ -869,8 +882,43 @@ public class SheetRenderer extends Rende
           writer.writeClassAttribute(Classes.create(sheet, "header", markup));
           writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
 
-          if (column instanceof UIColumnSelector) {
-            renderColumnSelectorHeader(facesContext, writer, sheet);
+          if (column instanceof UIColumnSelector && selectable.isMulti()) {
+            writer.writeClassAttribute(Classes.create(sheet, "selectorDropdown"));
+
+            writer.startElement(HtmlElements.DIV);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN);
+            writer.startElement(HtmlElements.BUTTON);
+            writer.writeClassAttribute(
+                BootstrapClass.BTN, BootstrapClass.BTN_SECONDARY, BootstrapClass.DROPDOWN_TOGGLE);
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+            writer.writeIdAttribute(sheet.getClientId(facesContext) + SELECTOR_DROPDOWN);
+            writer.writeAttribute(DataAttributes.TOGGLE, "dropdown", false);
+            writer.writeAttribute(Arias.HASPOPUP, Boolean.TRUE.toString(), false);
+            writer.writeAttribute(Arias.EXPANDED, Boolean.FALSE.toString(), false);
+            writer.endElement(HtmlElements.BUTTON);
+            writer.startElement(HtmlElements.DIV);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN_MENU);
+            writer.writeAttribute(Arias.LABELLEDBY, sheet.getClientId(facesContext) + SELECTOR_DROPDOWN, false);
+            writer.startElement(HtmlElements.BUTTON);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+            writer.writeAttribute(DataAttributes.COMMAND, "sheetSelectAll", false);
+            writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuSelect"));
+            writer.endElement(HtmlElements.BUTTON);
+            writer.startElement(HtmlElements.BUTTON);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+            writer.writeAttribute(DataAttributes.COMMAND, "sheetDeselectAll", false);
+            writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuUnselect"));
+            writer.endElement(HtmlElements.BUTTON);
+            writer.startElement(HtmlElements.BUTTON);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+            writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
+            writer.writeAttribute(DataAttributes.COMMAND, "sheetToggleAll", false);
+            writer.writeText(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", "sheetMenuToggleselect"));
+            writer.endElement(HtmlElements.BUTTON);
+            writer.endElement(HtmlElements.DIV);
+            writer.endElement(HtmlElements.DIV);
           } else {
             RenderUtils.encode(facesContext, cellComponent);
 
@@ -940,58 +988,6 @@ public class SheetRenderer extends Rende
 */
   }
 
-  protected void renderColumnSelectorHeader(
-      final FacesContext facesContext, final TobagoResponseWriter writer, final UISheet sheet)
-      throws IOException {
-
-    final UIToolBar toolBar = createToolBar(facesContext, sheet);
-    writer.startElement(HtmlElements.DIV);
-    writer.writeClassAttribute(Classes.create(sheet, "toolBar"));
-
-    if (Selectable.multi == sheet.getSelectable()) {
-      EncodeUtils.prepareRendererAll(facesContext, toolBar);
-      RenderUtils.encode(facesContext, toolBar);
-    }
-
-    writer.endElement(HtmlElements.DIV);
-  }
-
-  private UIToolBar createToolBar(final FacesContext facesContext, final UISheet sheet) {
-    final Application application = facesContext.getApplication();
-    final UICommand dropDown = (UICommand) CreateComponentUtils.createComponent(
-        facesContext, UICommand.COMPONENT_TYPE, null, "dropDown");
-    dropDown.setOmit(true);
-    final UIMenu menu = (UIMenu) CreateComponentUtils.createComponent(
-        facesContext, UIMenu.COMPONENT_TYPE, RendererTypes.Menu, "menu");
-    FacetUtils.setDropDownMenu(dropDown, menu);
-    final String sheetId = sheet.getClientId(facesContext);
-
-    createMenuItem(facesContext, menu, "sheetMenuSelect", Markup.SHEET_SELECT_ALL, sheetId);
-    createMenuItem(facesContext, menu, "sheetMenuUnselect", Markup.SHEET_DESELECT_ALL, sheetId);
-    createMenuItem(facesContext, menu, "sheetMenuToggleselect", Markup.SHEET_TOGGLE_ALL, sheetId);
-
-    final UIToolBar toolBar = (UIToolBar) application.createComponent(UIToolBar.COMPONENT_TYPE);
-    toolBar.setId(facesContext.getViewRoot().createUniqueId());
-    toolBar.setRendererType("TabGroupToolBar");
-    toolBar.setTransient(true);
-    toolBar.getChildren().add(dropDown);
-    ComponentUtils.setFacet(sheet, Facets.toolBar, toolBar);
-    return toolBar;
-  }
-
-  private void createMenuItem(
-      final FacesContext facesContext, final UIMenu menu, final String label, final Markup markup,
-      final String sheetId) {
-    final String id = markup.toString();
-    final UIMenuCommand menuItem = (UIMenuCommand) CreateComponentUtils.createComponent(
-        facesContext, UIMenuCommand.COMPONENT_TYPE, RendererTypes.MenuCommand, id);
-    menuItem.setLabel(ResourceManagerUtils.getPropertyNotNull(facesContext, "tobago", label));
-    menuItem.setMarkup(markup);
-    menuItem.setOmit(true);
-    ComponentUtils.putDataAttributeWithPrefix(menuItem, DataAttributes.SHEET_ID, sheetId);
-    menu.getChildren().add(menuItem);
-  }
-
   private void encodeDirectPagingLinks(
       final FacesContext facesContext, final Application application, final UISheet sheet)
       throws IOException {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeCommandRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeCommandRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeCommandRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeCommandRenderer.java Mon Feb  8 09:37:48 2016
@@ -22,7 +22,7 @@ package org.apache.myfaces.tobago.render
 import org.apache.myfaces.tobago.component.UITreeCommand;
 import org.apache.myfaces.tobago.component.UITreeNode;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
-import org.apache.myfaces.tobago.internal.component.AbstractUITreeNode;
+import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.layout.Measure;
 import org.apache.myfaces.tobago.renderkit.CommandRendererBase;
@@ -67,7 +67,7 @@ public class TreeCommandRenderer extends
     final LabelWithAccessKey label = new LabelWithAccessKey(command);
     final boolean disabled = command.isDisabled();
 
-    final AbstractUITreeNode node = ComponentUtils.findAncestor(command, AbstractUITreeNode.class);
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(command, AbstractUITreeNodeBase.class);
     final AbstractUIData data = ComponentUtils.findAncestor(command, AbstractUIData.class);
     Style style = command.getStyle();
     if (style == null) {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeIndentRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeIndentRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeIndentRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeIndentRenderer.java Mon Feb  8 09:37:48 2016
@@ -24,7 +24,7 @@ import org.apache.myfaces.tobago.compone
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
-import org.apache.myfaces.tobago.internal.component.AbstractUITreeNode;
+import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
@@ -45,7 +45,7 @@ public class TreeIndentRenderer extends
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
     final UITreeIndent indent = (UITreeIndent) component;
-    final AbstractUITreeNode node = ComponentUtils.findAncestor(indent, AbstractUITreeNode.class);
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(indent, AbstractUITreeNodeBase.class);
     final AbstractUIData data = ComponentUtils.findAncestor(indent, AbstractUIData.class);
 
     final boolean folder = node.isFolder();
@@ -80,7 +80,7 @@ public class TreeIndentRenderer extends
   }
 
   private void encodeIndent(
-      final FacesContext facesContext, final TobagoResponseWriter writer, final AbstractUITreeNode node,
+      final FacesContext facesContext, final TobagoResponseWriter writer, final AbstractUITreeNodeBase node,
       final boolean showLines, final boolean showIcons, final boolean showRootJunction, final boolean showRoot,
       final List<Boolean> junctions)
       throws IOException {
@@ -107,7 +107,7 @@ public class TreeIndentRenderer extends
   }
 
   private void encodeTreeJunction(
-      final FacesContext facesContext, final TobagoResponseWriter writer, final AbstractUITreeNode node,
+      final FacesContext facesContext, final TobagoResponseWriter writer, final AbstractUITreeNodeBase node,
       final boolean showLines, final boolean showIcons, final boolean showRootJunction, final List<Boolean> junctions,
       final boolean expanded, final boolean folder, final boolean root)
       throws IOException {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRenderer.java Mon Feb  8 09:37:48 2016
@@ -20,7 +20,7 @@
 package org.apache.myfaces.tobago.renderkit.html.standard.standard.tag;
 
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
-import org.apache.myfaces.tobago.internal.component.AbstractUITreeNode;
+import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.layout.Display;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
@@ -39,7 +39,7 @@ public class TreeNodeRenderer extends Tr
   @Override
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
-    final AbstractUITreeNode node = (AbstractUITreeNode) component;
+    final AbstractUITreeNodeBase node = (AbstractUITreeNodeBase) component;
     final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
 
     final boolean dataRendersRowContainer = data.isRendersRowContainer();

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRendererBase.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRendererBase.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeNodeRendererBase.java Mon Feb  8 09:37:48 2016
@@ -22,7 +22,7 @@ package org.apache.myfaces.tobago.render
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.component.AbstractUITree;
-import org.apache.myfaces.tobago.internal.component.AbstractUITreeNode;
+import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 
@@ -36,7 +36,7 @@ public class TreeNodeRendererBase extend
   public void prepareRender(final FacesContext facesContext, final UIComponent component) throws IOException {
     super.prepareRender(facesContext, component);
 
-    final AbstractUITreeNode node = (AbstractUITreeNode) component;
+    final AbstractUITreeNodeBase node = (AbstractUITreeNodeBase) component;
     final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
     if (data instanceof AbstractUITree && data.getSelectedState().isSelected(node.getPath())) {
       ComponentUtils.addCurrentMarkup(node, Markup.SELECTED);

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeRenderer.java Mon Feb  8 09:37:48 2016
@@ -48,10 +48,16 @@ public class TreeRenderer extends Render
 
   private static final Logger LOG = LoggerFactory.getLogger(TreeRenderer.class);
 
+  protected static final String SCROLL_POSITION = ComponentUtils.SUB_SEPARATOR + "scrollPosition";
+
   @Override
   public void decode(final FacesContext facesContext, final UIComponent component) {
     final AbstractUITree tree = (AbstractUITree) component;
-    RenderUtils.decodeScrollPosition(facesContext, tree, tree.getState());
+    final String value = facesContext.getExternalContext().getRequestParameterMap().get(
+        tree.getClientId(facesContext) + SCROLL_POSITION);
+    if (value != null) {
+      tree.getState().getScrollPosition().update(value);
+    }
     RenderUtils.decodedStateOfTreeData(facesContext, tree);
   }
 
@@ -142,7 +148,13 @@ public class TreeRenderer extends Render
     writer.writeAttribute(HtmlAttributes.VALUE, expandedValue.toString(), false);
     writer.endElement(HtmlElements.INPUT);
 
-    RenderUtils.writeScrollPosition(facesContext, writer, tree, tree.getState());
+    writer.startElement(HtmlElements.INPUT);
+    writer.writeIdAttribute(clientId + SCROLL_POSITION);
+    writer.writeNameAttribute(clientId + SCROLL_POSITION);
+    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+    writer.writeAttribute(HtmlAttributes.VALUE, tree.getState().getScrollPosition().encode(), false);
+    writer.writeAttribute(DataAttributes.SCROLL_POSITION, Boolean.TRUE.toString(), true);
+    writer.endElement(HtmlElements.INPUT);
 
     writer.endElement(HtmlElements.DIV);
   }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/TreeSelectRenderer.java Mon Feb  8 09:37:48 2016
@@ -22,7 +22,7 @@ package org.apache.myfaces.tobago.render
 import org.apache.myfaces.tobago.component.UITreeSelect;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeListbox;
-import org.apache.myfaces.tobago.internal.component.AbstractUITreeNode;
+import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.model.Selectable;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
@@ -48,7 +48,7 @@ public class TreeSelectRenderer extends
   public void decode(final FacesContext facesContext, final UIComponent component) {
 
     final UITreeSelect select = (UITreeSelect) component;
-    final AbstractUITreeNode node = ComponentUtils.findAncestor(select, AbstractUITreeNode.class);
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(select, AbstractUITreeNodeBase.class);
     final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
 
     if (ComponentUtils.isOutputOnly(select)) {
@@ -79,7 +79,7 @@ public class TreeSelectRenderer extends
   public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
 
     final UITreeSelect select = (UITreeSelect) component;
-    final AbstractUITreeNode node = ComponentUtils.findAncestor(select, AbstractUITreeNode.class);
+    final AbstractUITreeNodeBase node = ComponentUtils.findAncestor(select, AbstractUITreeNodeBase.class);
     final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
 
     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java?rev=1729111&r1=1729110&r2=1729111&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java Mon Feb  8 09:37:48 2016
@@ -24,15 +24,9 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.model.ExpandedState;
-import org.apache.myfaces.tobago.model.ScrollPositionState;
 import org.apache.myfaces.tobago.model.SelectedState;
 import org.apache.myfaces.tobago.model.TreePath;
-import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
-import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
-import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
-import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
 import org.apache.myfaces.tobago.util.ComponentUtils;
-import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,8 +48,6 @@ public class RenderUtils {
 
   private static final Logger LOG = LoggerFactory.getLogger(RenderUtils.class);
 
-  public static final String SCROLL_POSTFIX = ComponentUtils.SUB_SEPARATOR + "scrollPosition";
-
   private RenderUtils() {
     // to prevent instantiation
   }
@@ -266,29 +258,6 @@ public class RenderUtils {
     return null;
   }
 
-  public static void writeScrollPosition(
-      final FacesContext facesContext, final TobagoResponseWriter writer, final UIComponent component,
-      final ScrollPositionState state)
-      throws IOException {
-    final String clientId = component.getClientId(facesContext);
-    writer.startElement(HtmlElements.INPUT);
-    writer.writeIdAttribute(clientId + SCROLL_POSTFIX);
-    writer.writeNameAttribute(clientId + SCROLL_POSTFIX);
-    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
-    writer.writeAttribute(HtmlAttributes.VALUE, state.getScrollPosition().encode(), false);
-    writer.writeAttribute(DataAttributes.SCROLL_POSITION, Boolean.TRUE.toString(), true);
-    writer.endElement(HtmlElements.INPUT);
-  }
-
-  public static void decodeScrollPosition(
-      final FacesContext facesContext, final UIComponent component, final ScrollPositionState state) {
-    final String key = component.getClientId(facesContext) + SCROLL_POSTFIX;
-    final String value = facesContext.getExternalContext().getRequestParameterMap().get(key);
-    if (value != null) {
-      state.getScrollPosition().update(value);
-    }
-  }
-
   public static String generateUrl(final FacesContext facesContext, final AbstractUICommand component) {
 
     final Application application = facesContext.getApplication();