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 2017/03/30 11:44:44 UTC

svn commit: r1789500 - in /myfaces/tobago/trunk/tobago-core/src/main: java/org/apache/myfaces/tobago/component/ java/org/apache/myfaces/tobago/internal/renderkit/renderer/ java/org/apache/myfaces/tobago/internal/taglib/component/ java/org/apache/myface...

Author: lofwyr
Date: Thu Mar 30 11:44:44 2017
New Revision: 1789500

URL: http://svn.apache.org/viewvc?rev=1789500&view=rev
Log:
TOBAGO-1721 Optimize HTML output when two renderer are involved
* RadioButtons, checkboxes and links in a dropdown menu improved
[developed by hnoeth]

Added:
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonAlternativeInRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeCommandRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeLinksRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxAlternativeCommandRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxAlternativeCommandRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioAlternativeCommandRenderer.java
Modified:
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceAlternativeInRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonTagDeclaration.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinkTagDeclaration.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Measure.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java
    myfaces/tobago/trunk/tobago-core/src/main/resources/scss/_tobago.scss

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java Thu Mar 30 11:44:44 2017
@@ -27,6 +27,7 @@ public enum RendererTypes {
   Bar,
   Box,
   Button,
+  ButtonAlternativeIn,
   Buttons,
   Calendar,
   Column,
@@ -45,6 +46,8 @@ public enum RendererTypes {
   In,
   Image,
   Link,
+  LinkAlternativeCommand,
+  LinkAlternativeLinks,
   Links,
   Label,
   Messages,
@@ -60,12 +63,15 @@ public enum RendererTypes {
   Section,
   SegmentLayout,
   SelectBooleanCheckbox,
+  SelectBooleanCheckboxAlternativeCommand,
   SelectManyCheckbox,
+  SelectManyCheckboxAlternativeCommand,
   SelectManyListbox,
   SelectManyShuttle,
   SelectOneChoice,
   SelectOneChoiceAlternativeIn,
   SelectOneRadio,
+  SelectOneRadioAlternativeCommand,
   SelectOneListbox,
   SelectReference,
   Separator,
@@ -91,6 +97,7 @@ public enum RendererTypes {
   public static final String BAR = "Bar";
   public static final String BOX = "Box";
   public static final String BUTTON = "Button";
+  public static final String BUTTON_ALTERNATIVE_IN = "ButtonAlternativeIn";
   public static final String BUTTONS = "Buttons";
   public static final String CALENDAR = "Calendar";
   public static final String COLUMN = "Column";
@@ -109,6 +116,8 @@ public enum RendererTypes {
   public static final String IN = "In";
   public static final String IMAGE = "Image";
   public static final String LINK = "Link";
+  public static final String LINK_ALTERNATIVE_COMMAND = "LinkAlternativeCommand";
+  public static final String LINK_ALTERNATIVE_LINKS = "LinkAlternativeLinks";
   public static final String LINKS = "Links";
   public static final String LABEL = "Label";
   public static final String MESSAGES = "Messages";
@@ -124,12 +133,15 @@ public enum RendererTypes {
   public static final String SECTION = "Section";
   public static final String SEGMENT_LAYOUT = "SegmentLayout";
   public static final String SELECT_BOOLEAN_CHECKBOX = "SelectBooleanCheckbox";
+  public static final String SELECT_BOOLEAN_CHECKBOX_ALTERNATIVE_COMMAND = "SelectBooleanCheckboxAlternativeCommand";
   public static final String SELECT_MANY_CHECKBOX = "SelectManyCheckbox";
+  public static final String SELECT_MANY_CHECKBOX_ALTERNATIVE_COMMAND = "SelectManyCheckboxAlternativeCommand";
   public static final String SELECT_MANY_LISTBOX = "SelectManyListbox";
   public static final String SELECT_MANY_SHUTTLE = "SelectManyShuttle";
   public static final String SELECT_ONE_CHOICE = "SelectOneChoice";
   public static final String SELECT_ONE_CHOICE_ALTERNATIVE_IN = "SelectOneChoiceAlternativeIn";
   public static final String SELECT_ONE_RADIO = "SelectOneRadio";
+  public static final String SELECT_ONE_RADIO_ALTERNATIVE_COMMAND = "SelectOneRadioAlternativeCommand";
   public static final String SELECT_ONE_LISTBOX = "SelectOneListbox";
   public static final String SELECT_REFERENCE = "SelectReference";
   public static final String SEPARATOR = "Separator";

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonAlternativeInRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonAlternativeInRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonAlternativeInRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonAlternativeInRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,36 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+
+import javax.faces.context.FacesContext;
+import java.util.List;
+
+public class ButtonAlternativeInRenderer extends ButtonRenderer {
+
+  @Override
+  protected void addOuterCssItems(final FacesContext facesContext, final AbstractUICommand command,
+                                  final List<CssItem> collected) {
+    collected.add(BootstrapClass.INPUT_GROUP_BTN);
+  }
+}

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ButtonsRenderer.java Thu Mar 30 11:44:44 2017
@@ -43,13 +43,11 @@ public class ButtonsRenderer extends Ren
 
     writer.startElement(HtmlElements.DIV);
     writer.writeIdAttribute(buttons.getClientId(facesContext));
-    writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.GROUP.toString(), false);
     writer.writeClassAttribute(
         Classes.create(buttons),
         buttons.getCustomClass(),
-        BootstrapClass.BTN_TOOLBAR,
-        BootstrapClass.BTN_GROUP,
-        BootstrapClass.NAVBAR_NAV);
+        BootstrapClass.BTN_GROUP);
+    writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.GROUP.toString(), false);
     writer.writeStyleAttribute(buttons.getStyle());
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, buttons);
     final String tip = buttons.getTip();

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java Thu Mar 30 11:44:44 2017
@@ -20,9 +20,13 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.Attributes;
-import org.apache.myfaces.tobago.internal.component.AbstractUIButton;
+import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
 import org.apache.myfaces.tobago.internal.component.AbstractUIFormBase;
+import org.apache.myfaces.tobago.internal.component.AbstractUILink;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectBooleanCheckbox;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyCheckbox;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneRadio;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.JsonUtils;
@@ -32,17 +36,18 @@ import org.apache.myfaces.tobago.renderk
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.Arias;
 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.HtmlRoleValues;
 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.component.UIComponent;
+import javax.faces.component.UIParameter;
 import javax.faces.context.FacesContext;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -62,18 +67,11 @@ public abstract class CommandRendererBas
     final boolean link = command.getLink() != null && !disabled;
     final String target = command.getTarget();
     final boolean parentOfCommands = command.isParentOfCommands();
+    final boolean dropdownSubmenu = this instanceof LinkAlternativeCommandRenderer;
 
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
-    if (parentOfCommands) { // extra span
-      writer.startElement(HtmlElements.SPAN);
-      writer.writeIdAttribute(clientId);
-      if (component instanceof AbstractUIButton) { // todo: check if we should differ here
-        writer.writeClassAttribute(BootstrapClass.BTN_GROUP);
-      } else {
-        writer.writeClassAttribute(BootstrapClass.DROPDOWN);
-      }
-    }
+    encodeBeginOuter(facesContext, command);
 
     if (link) {
       writer.startElement(HtmlElements.A);
@@ -112,9 +110,10 @@ public abstract class CommandRendererBas
 
     final List<CssItem> cssItems = new ArrayList<CssItem>();
     if (parentOfCommands) {
-      // XXX BootstrapClass.NAV_LINK should only be shown inside of UICommands or UIButtons
-      cssItems.add(BootstrapClass.DROPDOWN_TOGGLE);
+      cssItems.add(dropdownSubmenu ? null : BootstrapClass.DROPDOWN_TOGGLE);
       writer.writeAttribute(DataAttributes.TOGGLE, "dropdown", false);
+    } else {
+      addOuterCssItems(facesContext, command, cssItems);
     }
     addCssItems(facesContext, command, cssItems);
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, command);
@@ -143,12 +142,6 @@ public abstract class CommandRendererBas
     } else {
       writer.endElement(HtmlElements.BUTTON);
     }
-
-    if (parentOfCommands) {
-      writer.startElement(HtmlElements.UL);
-      writer.writeClassAttribute(BootstrapClass.DROPDOWN_MENU);
-      writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.MENU.toString(), false);
-    }
   }
 
   @Override
@@ -158,50 +151,82 @@ public abstract class CommandRendererBas
 
   @Override
   public void encodeChildren(final FacesContext facesContext, final UIComponent component) throws IOException {
-
     final AbstractUICommand command = (AbstractUICommand) component;
+    final boolean parentOfCommands = command.isParentOfCommands();
 
-    if (command.isParentOfCommands()) {
-      final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    if (parentOfCommands) {
+      writer.startElement(HtmlElements.DIV);
+      writer.writeClassAttribute(BootstrapClass.DROPDOWN_MENU);
+      writer.writeAttribute(Arias.LABELLEDBY, "dropdownMenuButton", false);
 
       for (final UIComponent child : component.getChildren()) {
-        if (child.isRendered()) {
-          writer.startElement(HtmlElements.LI);
-          final CssItem submenu;
-          final CssItem disabled;
-          if (child instanceof AbstractUICommand) {
-            final AbstractUICommand c = (AbstractUICommand) child;
-            submenu = c.isParentOfCommands() ? TobagoClass.DROPDOWN__SUBMENU : null;
-            disabled = c.isDisabled() ? BootstrapClass.DISABLED : null;
+        if (!(child instanceof UIParameter) && child.isRendered()) {
+          if (child instanceof AbstractUILink) {
+            child.setRendererType(RendererTypes.LINK_ALTERNATIVE_COMMAND);
+            child.encodeAll(facesContext);
+          } else if (child instanceof AbstractUISelectBooleanCheckbox) {
+            child.setRendererType(RendererTypes.SELECT_BOOLEAN_CHECKBOX_ALTERNATIVE_COMMAND);
+            child.encodeAll(facesContext);
+          } else if (child instanceof AbstractUISelectManyCheckbox) {
+            child.setRendererType(RendererTypes.SELECT_MANY_CHECKBOX_ALTERNATIVE_COMMAND);
+            child.encodeAll(facesContext);
+          } else if (child instanceof AbstractUISelectOneRadio) {
+            child.setRendererType(RendererTypes.SELECT_ONE_RADIO_ALTERNATIVE_COMMAND);
+            child.encodeAll(facesContext);
           } else {
-            submenu = null;
-            disabled = null;
+            writer.startElement(HtmlElements.DIV);
+            writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM);
+            child.encodeAll(facesContext);
+            writer.endElement(HtmlElements.DIV);
           }
-          writer.writeClassAttribute(BootstrapClass.DROPDOWN_ITEM, submenu, disabled);
-          child.encodeAll(facesContext);
-          writer.endElement(HtmlElements.LI);
         }
       }
+      writer.endElement(HtmlElements.DIV);
     } else {
       super.encodeChildren(facesContext, component);
     }
-
   }
 
   @Override
   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
-
     final AbstractUICommand command = (AbstractUICommand) component;
+    encodeEndOuter(facesContext, command);
+  }
+
+  protected void encodeBeginOuter(final FacesContext facesContext, final AbstractUICommand command) throws IOException {
+    final String clientId = command.getClientId(facesContext);
+    final boolean parentOfCommands = command.isParentOfCommands();
+    final boolean dropdownSubmenu = this instanceof LinkAlternativeCommandRenderer;
+
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
 
+    if (parentOfCommands) {
+      writer.startElement(HtmlElements.SPAN);
+      writer.writeIdAttribute(clientId);
+
+      final List<CssItem> cssItemsForSpan = new ArrayList<CssItem>();
+      addOuterCssItems(facesContext, command, cssItemsForSpan);
+      writer.writeClassAttribute(
+          dropdownSubmenu ? TobagoClass.DROPDOWN__SUBMENU : BootstrapClass.DROPDOWN,
+          null,
+          cssItemsForSpan.toArray(new CssItem[cssItemsForSpan.size()]));
+    }
+  }
+
+  protected void encodeEndOuter(final FacesContext facesContext, final AbstractUICommand command) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
     if (command.isParentOfCommands()) {
-      writer.endElement(HtmlElements.UL);
       writer.endElement(HtmlElements.SPAN);
     }
   }
 
-  protected void addCssItems(
-      final FacesContext facesContext, final AbstractUICommand command, final List<CssItem> collected) {
+  protected void addOuterCssItems(final FacesContext facesContext, final AbstractUICommand command,
+                                  final List<CssItem> collected) {
   }
 
+  protected void addCssItems(final FacesContext facesContext, final AbstractUICommand command,
+                             final List<CssItem> collected) {
+  }
 }

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FormRenderer.java Thu Mar 30 11:44:44 2017
@@ -43,7 +43,7 @@ public class FormRenderer extends Render
     writer.writeIdAttribute(clientId);
     writer.writeClassAttribute(
         TobagoClass.FORM,
-        inline ? BootstrapClass.D_INLINE : null);
+        inline ? BootstrapClass.FORM_INLINE : null);
   }
 
   @Override
@@ -51,5 +51,4 @@ public class FormRenderer extends Render
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     writer.endElement(HtmlElements.DIV);
   }
-
 }

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java Thu Mar 30 11:44:44 2017
@@ -173,3 +173,27 @@ public class InRenderer extends MessageL
       throws IOException {
   }
 }
+/*
+for (UIComponent child : children) {
+    if (child instanceof AbstractUIButton && ((AbstractUIButton) child).isParentOfCommands()) {
+    child.setRendererType(RendererTypes.BUTTON_ALTERNATIVE_IN);
+    RenderUtils.encode(facesContext, child);
+    } else {
+    writer.startElement(HtmlElements.SPAN);
+
+final CssItem cssItem;
+    if (child instanceof AbstractUIButton) {
+    cssItem = BootstrapClass.INPUT_GROUP_BTN;
+    } else if (child instanceof AbstractUISelectOneChoice) {
+    cssItem = BootstrapClass.INPUT_GROUP_BTN;
+    child.setRendererType(RendererTypes.SELECT_ONE_CHOICE_ALTERNATIVE_IN);
+    } else {
+    cssItem = BootstrapClass.INPUT_GROUP_ADDON;
+    }
+
+    writer.writeClassAttribute(cssItem);
+    RenderUtils.encode(facesContext, child);
+    writer.endElement(HtmlElements.SPAN);
+    }
+    }
+*/

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeCommandRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeCommandRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeCommandRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeCommandRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,36 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+
+import javax.faces.context.FacesContext;
+import java.util.List;
+
+public class LinkAlternativeCommandRenderer extends LinkRenderer {
+
+  @Override
+  protected void addOuterCssItems(
+      final FacesContext facesContext, final AbstractUICommand command, final List<CssItem> collected) {
+    collected.add(BootstrapClass.DROPDOWN_ITEM);
+  }
+}

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeLinksRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeLinksRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeLinksRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinkAlternativeLinksRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,62 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.util.List;
+
+public class LinkAlternativeLinksRenderer extends LinkRenderer {
+
+  @Override
+  protected void encodeBeginOuter(final FacesContext facesContext, final AbstractUICommand command) throws IOException {
+    final String clientId = command.getClientId(facesContext);
+    final boolean parentOfCommands = command.isParentOfCommands();
+
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    writer.startElement(HtmlElements.LI);
+    if (parentOfCommands) {
+      writer.writeIdAttribute(clientId);
+    }
+
+    writer.writeClassAttribute(
+        BootstrapClass.NAV_ITEM,
+        parentOfCommands ? BootstrapClass.DROPDOWN : null);
+  }
+
+  @Override
+  protected void encodeEndOuter(final FacesContext facesContext, final AbstractUICommand command) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    writer.endElement(HtmlElements.LI);
+  }
+
+  @Override
+  protected void addCssItems(
+      final FacesContext facesContext, final AbstractUICommand command, final List<CssItem> collected) {
+    collected.add(BootstrapClass.NAV_LINK);
+  }
+}

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java Thu Mar 30 11:44:44 2017
@@ -19,12 +19,11 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
-import org.apache.myfaces.tobago.internal.component.AbstractUILinks;
-import org.apache.myfaces.tobago.internal.component.AbstractUIFormBase;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.component.AbstractUILink;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
-import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
 import javax.faces.component.UIComponent;
@@ -53,13 +52,12 @@ public class LinksRenderer extends Rende
 
     for (UIComponent child : component.getChildren()) {
       if (child.isRendered()) {
-        if (child instanceof AbstractUIFormBase) { // XXX hack! TBD: How to walk through the children, or do that in JS?
-          encodeChildren(facesContext, child);
+        if (child instanceof AbstractUILink) {
+          child.setRendererType(RendererTypes.LINK_ALTERNATIVE_LINKS);
+          child.encodeAll(facesContext);
         } else {
-          // fixme: only a temporary workaround
-          final AbstractUILinks commands = ComponentUtils.findAncestor(component, AbstractUILinks.class);
           writer.startElement(HtmlElements.LI);
-          writer.writeClassAttribute(BootstrapClass.NAV_ITEM, BootstrapClass.DROPDOWN);
+          writer.writeClassAttribute(BootstrapClass.NAV_ITEM);
           child.encodeAll(facesContext);
           writer.endElement(HtmlElements.LI);
         }

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxAlternativeCommandRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxAlternativeCommandRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxAlternativeCommandRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxAlternativeCommandRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,58 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectBooleanCheckbox;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.util.List;
+
+public class SelectBooleanCheckboxAlternativeCommandRenderer extends SelectBooleanCheckboxRenderer {
+
+  @Override
+  public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeBeginField(facesContext, component);
+  }
+
+  @Override
+  public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeEndField(facesContext, component);
+  }
+
+  @Override
+  protected boolean renderClientId() {
+    return true;
+  }
+
+  @Override
+  protected void addOuterCssItems(final FacesContext facesContext, final AbstractUISelectBooleanCheckbox select,
+                                  final List<CssItem> collected) {
+  }
+
+  @Override
+  protected void addCssItems(final FacesContext facesContext, final AbstractUISelectBooleanCheckbox select,
+                             final List<CssItem> collected) {
+    collected.add(BootstrapClass.DROPDOWN_ITEM);
+  }
+}

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java Thu Mar 30 11:44:44 2017
@@ -21,15 +21,16 @@ package org.apache.myfaces.tobago.intern
 
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectBooleanCheckbox;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
+import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
+import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 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.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 import org.slf4j.Logger;
@@ -39,6 +40,8 @@ import javax.faces.component.UIComponent
 import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 public class SelectBooleanCheckboxRenderer extends MessageLayoutRendererBase {
 
@@ -80,19 +83,29 @@ public class SelectBooleanCheckboxRender
     final String itemLabel = select.getItemLabel();
 
     writer.startElement(HtmlElements.DIV);
+    if (renderClientId()) {
+      writer.writeIdAttribute(clientId);
+    }
     writer.writeStyleAttribute(select.getStyle());
-    writer.writeClassAttribute(
-        Classes.create(select),
-        BootstrapClass.FORM_CHECK,
+
+    final List<CssItem> outerCssItems = new ArrayList<CssItem>();
+    addOuterCssItems(facesContext, select, outerCssItems);
+    outerCssItems.add(select.getCustomClass());
+    writer.writeClassAttribute(Classes.create(select),
         disabled ? BootstrapClass.DISABLED : null,
-        select.getCustomClass());
+        outerCssItems.toArray(new CssItem[outerCssItems.size()]));
+
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, select);
     if (title != null) {
       writer.writeAttribute(HtmlAttributes.TITLE, title, true);
     }
 
     writer.startElement(HtmlElements.LABEL);
-    writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL);
+    final List<CssItem> cssItems = new ArrayList<CssItem>();
+    addCssItems(facesContext, select, cssItems);
+    writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL,
+        null,
+        cssItems.toArray(new CssItem[cssItems.size()]));
     if (!disabled && label.getAccessKey() != null) {
       writer.writeAttribute(HtmlAttributes.ACCESSKEY, Character.toString(label.getAccessKey()), false);
       AccessKeyLogger.addAccessKey(facesContext, label.getAccessKey(), clientId);
@@ -123,4 +136,17 @@ public class SelectBooleanCheckboxRender
     writer.endElement(HtmlElements.LABEL);
     writer.endElement(HtmlElements.DIV);
   }
+
+  protected boolean renderClientId() {
+    return false;
+  }
+
+  protected void addOuterCssItems(final FacesContext facesContext, final AbstractUISelectBooleanCheckbox select,
+                                  final List<CssItem> collected) {
+    collected.add(BootstrapClass.FORM_CHECK);
+  }
+
+  protected void addCssItems(final FacesContext facesContext, final AbstractUISelectBooleanCheckbox select,
+                             final List<CssItem> collected) {
+  }
 }

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxAlternativeCommandRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxAlternativeCommandRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxAlternativeCommandRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxAlternativeCommandRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,58 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.component.UISelectManyCheckbox;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.util.List;
+
+public class SelectManyCheckboxAlternativeCommandRenderer extends SelectManyCheckboxRenderer {
+
+  @Override
+  public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeBeginField(facesContext, component);
+  }
+
+  @Override
+  public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeEndField(facesContext, component);
+  }
+
+  @Override
+  protected boolean renderClientId() {
+    return true;
+  }
+
+  @Override
+  protected boolean renderOuterItem() {
+    return false;
+  }
+
+  @Override
+  protected void addCssItems(final FacesContext facesContext, final UISelectManyCheckbox select,
+                             final List<CssItem> collected) {
+    collected.add(BootstrapClass.DROPDOWN_ITEM);
+  }
+}

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java Thu Mar 30 11:44:44 2017
@@ -20,16 +20,17 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.UISelectManyCheckbox;
+import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
+import org.apache.myfaces.tobago.internal.util.RenderUtils;
+import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 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.TobagoClass;
 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.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
-import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
@@ -37,6 +38,8 @@ import javax.faces.component.UIComponent
 import javax.faces.context.FacesContext;
 import javax.faces.model.SelectItem;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 public class SelectManyCheckboxRenderer extends SelectManyRendererBase {
 
@@ -52,7 +55,10 @@ public class SelectManyCheckboxRenderer
     final boolean required = select.isRequired();
     final boolean inline = select.isInline();
 
-    writer.startElement(HtmlElements.OL);
+    writer.startElement(HtmlElements.DIV);
+    if (renderClientId()) {
+      writer.writeIdAttribute(id);
+    }
     writer.writeStyleAttribute(select.getStyle());
     writer.writeClassAttribute(
         Classes.create(select),
@@ -69,13 +75,19 @@ public class SelectManyCheckboxRenderer
     for (final SelectItem item : SelectItemUtils.getItemIterator(facesContext, select)) {
       final boolean itemDisabled = item.isDisabled() || disabled;
       final String itemId = id + ComponentUtils.SUB_SEPARATOR + i++;
-      writer.startElement(HtmlElements.LI);
-      writer.writeClassAttribute(
-          BootstrapClass.FORM_CHECK,
-          inline ? BootstrapClass.FORM_CHECK_INLINE : null,
-          itemDisabled ? BootstrapClass.DISABLED : null);
+      if (renderOuterItem()) {
+        writer.startElement(HtmlElements.DIV);
+        writer.writeClassAttribute(
+            BootstrapClass.FORM_CHECK,
+            inline ? BootstrapClass.FORM_CHECK_INLINE : null,
+            itemDisabled ? BootstrapClass.DISABLED : null);
+      }
       writer.startElement(HtmlElements.LABEL);
-      writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL);
+      final List<CssItem> cssItems = new ArrayList<CssItem>();
+      addCssItems(facesContext, select, cssItems);
+      writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL,
+          null,
+          cssItems.toArray(new CssItem[cssItems.size()]));
       writer.startElement(HtmlElements.INPUT);
       writer.writeClassAttribute(BootstrapClass.FORM_CHECK_INPUT);
       writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.CHECKBOX);
@@ -107,13 +119,27 @@ public class SelectManyCheckboxRenderer
       }
 
       writer.endElement(HtmlElements.LABEL);
-      writer.endElement(HtmlElements.LI);
+      if (renderOuterItem()) {
+        writer.endElement(HtmlElements.DIV);
+      }
     }
   }
 
   @Override
   public void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
-    writer.endElement(HtmlElements.OL);
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  protected boolean renderClientId() {
+    return false;
+  }
+
+  protected boolean renderOuterItem() {
+    return true;
+  }
+
+  protected void addCssItems(final FacesContext facesContext, final UISelectManyCheckbox select,
+                             final List<CssItem> collected) {
   }
 }

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceAlternativeInRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceAlternativeInRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceAlternativeInRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceAlternativeInRenderer.java Thu Mar 30 11:44:44 2017
@@ -19,6 +19,19 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+
 public class SelectOneChoiceAlternativeInRenderer extends SelectOneChoiceRenderer {
 
+  @Override
+  public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
+    encodeBeginField(facesContext, component);
+  }
+
+  @Override
+  public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
+    encodeEndField(facesContext, component);
+  }
 }

Added: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioAlternativeCommandRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioAlternativeCommandRenderer.java?rev=1789500&view=auto
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioAlternativeCommandRenderer.java (added)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioAlternativeCommandRenderer.java Thu Mar 30 11:44:44 2017
@@ -0,0 +1,58 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.component.UISelectOneRadio;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.util.List;
+
+public class SelectOneRadioAlternativeCommandRenderer extends SelectOneRadioRenderer {
+
+  @Override
+  public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeBeginField(facesContext, component);
+  }
+
+  @Override
+  public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
+    encodeEndField(facesContext, component);
+  }
+
+  @Override
+  protected boolean renderClientId() {
+    return true;
+  }
+
+  @Override
+  protected boolean renderOuterItem() {
+    return false;
+  }
+
+  @Override
+  protected void addCssItems(final FacesContext facesContext, final UISelectOneRadio select,
+                             final List<CssItem> collected) {
+    collected.add(BootstrapClass.DROPDOWN_ITEM);
+  }
+}

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java Thu Mar 30 11:44:44 2017
@@ -27,6 +27,7 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 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.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
@@ -38,6 +39,8 @@ import javax.faces.component.UIComponent
 import javax.faces.context.FacesContext;
 import javax.faces.model.SelectItem;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 public class SelectOneRadioRenderer extends SelectOneRendererBase {
 
@@ -54,7 +57,10 @@ public class SelectOneRadioRenderer exte
     final boolean required = select.isRequired();
     final boolean inline = select.isInline();
 
-    writer.startElement(HtmlElements.OL);
+    writer.startElement(HtmlElements.DIV);
+    if (renderClientId()) {
+      writer.writeIdAttribute(id);
+    }
     writer.writeStyleAttribute(select.getStyle());
     writer.writeClassAttribute(
         Classes.create(select),
@@ -71,13 +77,19 @@ public class SelectOneRadioRenderer exte
     for (final SelectItem item : items) {
       final boolean itemDisabled = item.isDisabled() || disabled;
       final String itemId = id + ComponentUtils.SUB_SEPARATOR + i++;
-      writer.startElement(HtmlElements.LI);
-      writer.writeClassAttribute(
-          BootstrapClass.FORM_CHECK,
-          inline ? BootstrapClass.FORM_CHECK_INLINE : null,
-          itemDisabled ? BootstrapClass.DISABLED : null);
+      if (renderOuterItem()) {
+        writer.startElement(HtmlElements.DIV);
+        writer.writeClassAttribute(
+            BootstrapClass.FORM_CHECK,
+            inline ? BootstrapClass.FORM_CHECK_INLINE : null,
+            itemDisabled ? BootstrapClass.DISABLED : null);
+      }
       writer.startElement(HtmlElements.LABEL);
-      writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL);
+      final List<CssItem> cssItems = new ArrayList<CssItem>();
+      addCssItems(facesContext, select, cssItems);
+      writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL,
+          null,
+          cssItems.toArray(new CssItem[cssItems.size()]));
       writer.startElement(HtmlElements.INPUT);
       writer.writeClassAttribute(BootstrapClass.FORM_CHECK_INPUT);
       writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.RADIO);
@@ -120,13 +132,27 @@ public class SelectOneRadioRenderer exte
       }
 
       writer.endElement(HtmlElements.LABEL);
-      writer.endElement(HtmlElements.LI);
+      if (renderOuterItem()) {
+        writer.endElement(HtmlElements.DIV);
+      }
     }
   }
 
   @Override
   protected void encodeEndField(FacesContext facesContext, UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
-    writer.endElement(HtmlElements.OL);
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  protected boolean renderClientId() {
+    return false;
+  }
+
+  protected boolean renderOuterItem() {
+    return true;
+  }
+
+  protected void addCssItems(final FacesContext facesContext, final UISelectOneRadio select,
+                             final List<CssItem> collected) {
   }
 }

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonTagDeclaration.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonTagDeclaration.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonTagDeclaration.java Thu Mar 30 11:44:44 2017
@@ -60,7 +60,7 @@ import javax.faces.component.UICommand;
         "org.apache.myfaces.tobago.component.SupportsAccessKey"
     },
     componentFamily = UICommand.COMPONENT_FAMILY,
-    rendererType = RendererTypes.BUTTON,
+    rendererType = {RendererTypes.BUTTON, RendererTypes.BUTTON_ALTERNATIVE_IN},
     allowedChildComponenents = "NONE",
     facets = {
         @Facet(

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinkTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinkTagDeclaration.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinkTagDeclaration.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinkTagDeclaration.java Thu Mar 30 11:44:44 2017
@@ -57,7 +57,7 @@ import javax.faces.component.UICommand;
     uiComponentFacesClass = "javax.faces.component.UICommand",
     interfaces = "org.apache.myfaces.tobago.component.SupportsAccessKey",
     componentFamily = UICommand.COMPONENT_FAMILY,
-    rendererType = RendererTypes.LINK,
+    rendererType = {RendererTypes.LINK, RendererTypes.LINK_ALTERNATIVE_COMMAND, RendererTypes.LINK_ALTERNATIVE_LINKS},
     allowedChildComponenents = "NONE",
     facets = {
         @Facet(

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java Thu Mar 30 11:44:44 2017
@@ -57,7 +57,7 @@ import javax.faces.component.UISelectBoo
     uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUISelectBooleanCheckbox",
     uiComponentFacesClass = "javax.faces.component.UISelectBoolean",
     componentFamily = UISelectBoolean.COMPONENT_FAMILY,
-    rendererType = RendererTypes.SELECT_BOOLEAN_CHECKBOX,
+    rendererType = {RendererTypes.SELECT_BOOLEAN_CHECKBOX, RendererTypes.SELECT_BOOLEAN_CHECKBOX_ALTERNATIVE_COMMAND},
     allowedChildComponenents = "NONE",
     behaviors = {
         @Behavior(

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java Thu Mar 30 11:44:44 2017
@@ -60,7 +60,7 @@ import javax.faces.component.UISelectMan
     uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUISelectManyCheckbox",
     uiComponentFacesClass = "javax.faces.component.UISelectMany",
     componentFamily = UISelectMany.COMPONENT_FAMILY,
-    rendererType = RendererTypes.SELECT_MANY_CHECKBOX,
+    rendererType = {RendererTypes.SELECT_MANY_CHECKBOX, RendererTypes.SELECT_MANY_CHECKBOX_ALTERNATIVE_COMMAND},
     allowedChildComponenents = {
         "javax.faces.SelectItem",
         "javax.faces.SelectItems"},

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java Thu Mar 30 11:44:44 2017
@@ -60,7 +60,7 @@ import javax.faces.component.UISelectOne
     uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUISelectOneRadio",
     uiComponentFacesClass = "javax.faces.component.UISelectOne",
     componentFamily = UISelectOne.COMPONENT_FAMILY,
-    rendererType = RendererTypes.SELECT_ONE_RADIO,
+    rendererType = {RendererTypes.SELECT_ONE_RADIO, RendererTypes.SELECT_ONE_RADIO_ALTERNATIVE_COMMAND},
     allowedChildComponenents = {
         "javax.faces.SelectItem",
         "javax.faces.SelectItems"

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Measure.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Measure.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Measure.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Measure.java Thu Mar 30 11:44:44 2017
@@ -163,7 +163,7 @@ public final class Measure implements Se
     return result;
   }
 
-  private enum Unit {
+  public enum Unit {
 
     EM,
     PX,

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java Thu Mar 30 11:44:44 2017
@@ -208,11 +208,13 @@ public abstract class TobagoResponseWrit
       builder.append(' ');
       render = true;
     }
-    for (CssItem other : others) {
-      if (other != null) {
-        builder.append(other.getName());
-        builder.append(' ');
-        render = true;
+    if (others != null) {
+      for (CssItem other : others) {
+        if (other != null) {
+          builder.append(other.getName());
+          builder.append(' ');
+          render = true;
+        }
       }
     }
     if (render) {

Modified: myfaces/tobago/trunk/tobago-core/src/main/resources/scss/_tobago.scss
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/resources/scss/_tobago.scss?rev=1789500&r1=1789499&r2=1789500&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/resources/scss/_tobago.scss (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/resources/scss/_tobago.scss Thu Mar 30 11:44:44 2017
@@ -23,6 +23,15 @@ $brand-info: #00f !default;
 $zindex-dropdown: 1000 !default;
 $zindex-popover: 1060 !default;
 
+/* fix bootstrap ---------------------------------------------------- */
+span.dropdown {
+  display: inline-flex;
+}
+
+.form-check-label.dropdown-item {
+  padding-left: 1.25rem;
+}
+
 /*
 Todo: check, if this is needed? (It doesn't work with the build system)
 
@@ -288,21 +297,29 @@ table.tobago-gridLayout > tbody > tr > t
   white-space: normal
 }
 
-button.tobago-link, button.tobago-command, button.tobago-treeCommand {
-  color: #0275d8;
-  border-width: 0;
-  padding: 0;
-  background-color: transparent;
-  text-align: left;
-}
-
-button.tobago-link:focus, button.tobago-link:hover,
-button.tobago-command:focus, button.tobago-command:hover,
-button.tobago-treeCommand:focus, button.tobago-treeCommand:hover {
-  color: #014c8c;
-  text-decoration: underline;
-  background-color: transparent;
-  outline: none;
+button {
+  &.tobago-link, &.tobago-linkAlternativeLinks, &.tobago-treeCommand {
+    color: #0275d8;
+    border-width: 0;
+    padding: 0;
+    background-color: transparent;
+    text-align: left;
+  }
+}
+
+button {
+  &.tobago-link, &.tobago-linkAlternativeLinks, &.tobago-treeCommand {
+    &:focus, &:hover {
+      color: $link-hover-color;
+      background-color: transparent;
+      outline: none;
+    }
+  }
+  &.tobago-link, &.tobago-treeCommand {
+    &:focus, &:hover {
+      text-decoration: underline;
+    }
+  }
 }
 
 button.tobago-link-markup-disabled, button.tobago-command-markup-disabled {
@@ -315,6 +332,12 @@ button.tobago-link-markup-disabled:hover
   text-decoration: none;
 }
 
+.tobago-button, .tobago-link, .tobago-linkAlternativeCommand {
+  > *:nth-child(n+2) {
+    margin-left: .4em;
+  }
+}
+
 /* messages ----------------------------------------------------------- */
 
 .tobago-messages-container {
@@ -356,10 +379,6 @@ a.tobago-messages-button {
   text-decoration: none;
 }
 
-/* styles for drop down menu with deeper level */
-.tobago-dropdown-submenu {
-  position: relative;
-}
 
 /* no bottom border in navtabs, if panel-body under it */
 .nav-tabs {
@@ -376,23 +395,37 @@ a.tobago-messages-button {
   border-bottom: #dddddd;
 }
 
-.tobago-dropdown-submenu > span {
-  display: inline-block;
-  width: 100%;
+.dropdown-menu .form-check {
+  display: block;
 }
 
-.tobago-dropdown-submenu > span > .dropdown-menu {
-  top: 0;
-  left: 100%;
-  margin-top: -6px;
-  margin-left: -1px;
-  -webkit-border-radius: 6px 6px 6px 6px;
-  -moz-border-radius: 6px 6px 6px 6px;
-  border-radius: 6px 6px 6px 6px;
-}
+/* dropdown-submenu ------------------------------------------------------- */
+.tobago-dropdown-submenu {
+  position: relative;
+  display: inline-block;
+  width: 100%;
 
-.tobago-dropdown-submenu:hover > span > .dropdown-menu {
-  display: block;
+  > .dropdown-menu {
+    top: 0;
+    left: 100%;
+    margin-top: -6px;
+    margin-left: -1px;
+    -webkit-border-radius: 6px 6px 6px 6px;
+    -moz-border-radius: 6px 6px 6px 6px;
+    border-radius: 6px 6px 6px 6px;
+  }
+
+  > button:after {
+    display: none;
+  }
+
+  > .tobago-linkAlternativeCommand {
+    border-width: 0;
+    color: $dropdown-link-color;
+    padding: 0;
+    background-color: transparent;
+    text-align: left;
+  }
 }
 
 .tobago-dropdown-submenu:after {
@@ -406,28 +439,24 @@ a.tobago-messages-button {
   margin-right: -10px;
 }
 
-.tobago-dropdown-submenu > span > button:after {
-  display: none;
-}
+.tobago-dropdown-submenu:hover > .dropdown-menu {
+  display: block;
 
-.tobago-dropdown-submenu:hover > span > a:after {
-  border-left-color: #ffffff;
+  > a:after {
+    border-left-color: $dropdown-bg;
+  }
 }
 
 .tobago-dropdown-submenu.pull-left {
   float: none;
-}
-
-.tobago-dropdown-submenu.pull-left > .dropdown-menu {
-  left: -100%;
-  margin-left: 10px;
-  -webkit-border-radius: 6px 0 6px 6px;
-  -moz-border-radius: 6px 0 6px 6px;
-  border-radius: 6px 0 6px 6px;
-}
 
-.dropdown-menu .form-check {
-  display: block;
+  > .dropdown-menu {
+    left: -100%;
+    margin-left: 10px;
+    -webkit-border-radius: 6px 0 6px 6px;
+    -moz-border-radius: 6px 0 6px 6px;
+    border-radius: 6px 0 6px 6px;
+  }
 }
 
 /* out -------------------------------------------------------------------- */
@@ -536,10 +565,13 @@ h6 > .fa:first-child {
 }
 
 /* selectBooleanCheckbox ----------------------------------------------- */
-.tobago-selectBooleanCheckbox input {
-  margin-right: 0.3em;
-  margin-bottom: 0.4ex;
-  vertical-align: text-bottom;
+
+.tobago-selectBooleanCheckbox, .tobago-selectBooleanCheckboxAlternativeCommand {
+  input {
+    margin-right: 0.3em;
+    margin-bottom: 0.4ex;
+    vertical-align: text-bottom;
+  }
 }
 
 .tobago-selectBooleanCheckbox .form-check-label {
@@ -554,10 +586,12 @@ h6 > .fa:first-child {
   list-style: none;
 }
 
-.tobago-selectManyCheckbox input {
-  margin-right: 0.3em;
-  margin-bottom: 0.4ex;
-  vertical-align: text-bottom;
+.tobago-selectManyCheckbox, .tobago-selectManyCheckboxAlternativeCommand {
+  input {
+    margin-right: 0.3em;
+    margin-bottom: 0.4ex;
+    vertical-align: text-bottom;
+  }
 }
 
 .tobago-selectManyCheckbox-inline {
@@ -606,10 +640,12 @@ h6 > .fa:first-child {
   list-style: none;
 }
 
-.tobago-selectOneRadio input {
-  margin-right: 0.3em;
-  margin-bottom: 0.4ex;
-  vertical-align: text-bottom;
+.tobago-selectOneRadio, .tobago-selectOneRadioAlternativeCommand {
+  input {
+    margin-right: 0.3em;
+    margin-bottom: 0.4ex;
+    vertical-align: text-bottom;
+  }
 }
 
 .tobago-selectOneRadio-inline {
@@ -617,8 +653,28 @@ h6 > .fa:first-child {
   margin-top: 6px;
 }
 
-.dropdown-menu .tobago-selectOneRadio > .form-check {
-  display: block;
+/* selectOneChoice ---------------------------------------------------------- */
+
+.input-group-btn:not(:last-child) > .tobago-selectOneChoiceAlternativeIn { /* before facet */
+  width: 100%;
+  -webkit-appearance: none;
+  margin-right: -1px;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.input-group-btn:not(:first-child) > .tobago-selectOneChoiceAlternativeIn { /* after facet */
+  width: 100%;
+  -webkit-appearance: none;
+  margin-left: -1px;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+/* selectOneRadio, selectManyCheckbox -------------------------------------- */
+
+.dropdown-item .form-check-input {
+  margin-left: 0;
 }
 
 /* segmentLayout ----------------------------------------------------------- */