View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.internal.renderkit.renderer;
21  
22  import org.apache.myfaces.tobago.component.Facets;
23  import org.apache.myfaces.tobago.context.Markup;
24  import org.apache.myfaces.tobago.internal.component.AbstractUIBar;
25  import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
26  import org.apache.myfaces.tobago.renderkit.RendererBase;
27  import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
28  import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
29  import org.apache.myfaces.tobago.renderkit.html.Arias;
30  import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
31  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
32  import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
33  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
34  import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
35  import org.apache.myfaces.tobago.util.ComponentUtils;
36  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
37  
38  import javax.faces.component.UIComponent;
39  import javax.faces.context.FacesContext;
40  import java.io.IOException;
41  
42  public class BarRenderer<T extends AbstractUIBar> extends RendererBase<T> {
43  
44    @Override
45    public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
46  
47      insideBegin(facesContext, HtmlElements.TOBAGO_BAR);
48  
49      final TobagoResponseWriter writer = getResponseWriter(facesContext);
50  
51      final String clientId = component.getClientId(facesContext);
52      final String navbarId = clientId + "::navbar";
53      final Markup markup = component.getMarkup();
54  
55      writer.startElement(HtmlElements.TOBAGO_BAR);
56      writer.writeIdAttribute(clientId);
57      writer.writeClassAttribute(
58          BootstrapClass.NAVBAR,
59          TobagoClass.BAR.createMarkup(component.getMarkup()),
60          getNavbarExpand(markup),
61          getNavbarColorScheme(markup),
62          component.getCustomClass());
63      writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.NAVIGATION.toString(), false);
64      HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
65  
66      encodeOpener(facesContext, component, writer, navbarId);
67  
68      writer.startElement(HtmlElements.DIV);
69      writer.writeIdAttribute(navbarId);
70      writer.writeClassAttribute(
71          BootstrapClass.COLLAPSE,
72          BootstrapClass.NAVBAR_COLLAPSE,
73          BootstrapClass.ALIGN_ITEMS_CENTER);
74    }
75  
76    private BootstrapClass getNavbarExpand(final Markup markup) {
77      if (markup != null) {
78        if (markup.contains(Markup.EXTRA_LARGE)) {
79          return BootstrapClass.NAVBAR_EXPAND_XL;
80        } else if (markup.contains(Markup.LARGE)) {
81          return BootstrapClass.NAVBAR_EXPAND_LG;
82        } else if (markup.contains(Markup.MEDIUM)) {
83          return BootstrapClass.NAVBAR_EXPAND_MD;
84        } else if (markup.contains(Markup.SMALL)) {
85          return BootstrapClass.NAVBAR_EXPAND_SM;
86        }
87      }
88      return BootstrapClass.NAVBAR_EXPAND;
89    }
90  
91    private BootstrapClass getNavbarColorScheme(final Markup markup) {
92      if (markup != null) {
93        if (markup.contains(Markup.DARK)) {
94          return BootstrapClass.NAVBAR_DARK;
95        } else if (markup.contains(Markup.LIGHT)) {
96          return BootstrapClass.NAVBAR_LIGHT;
97        }
98      }
99      return null;
100   }
101 
102   @Override
103   public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
104     final TobagoResponseWriter writer = getResponseWriter(facesContext);
105     final UIComponent after = ComponentUtils.getFacet(component, Facets.after);
106 
107     if (after != null) {
108       writer.startElement(HtmlElements.DIV);
109       writer.writeClassAttribute(BootstrapClass.MY_LG_0, BootstrapClass.ML_AUTO);
110       after.encodeAll(facesContext);
111       writer.endElement(HtmlElements.DIV);
112     }
113     writer.endElement(HtmlElements.DIV);
114     writer.endElement(HtmlElements.TOBAGO_BAR);
115 
116     insideEnd(facesContext, HtmlElements.TOBAGO_BAR);
117   }
118 
119   private void encodeOpener(
120       final FacesContext facesContext, final AbstractUIBar bar, final TobagoResponseWriter writer,
121       final String navbarId)
122       throws IOException {
123     final boolean togglerLeft = bar.getMarkup() != null && bar.getMarkup().contains(Markup.TOGGLER_LEFT);
124     final UIComponent brand = ComponentUtils.getFacet(bar, Facets.brand);
125 
126     if (brand != null && !togglerLeft) {
127       writer.startElement(HtmlElements.SPAN);
128       writer.writeClassAttribute(BootstrapClass.NAVBAR_BRAND);
129       brand.encodeAll(facesContext);
130       writer.endElement(HtmlElements.SPAN);
131     }
132 
133     writer.startElement(HtmlElements.BUTTON);
134     writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
135     writer.writeClassAttribute(BootstrapClass.NAVBAR_TOGGLER);
136     writer.writeAttribute(DataAttributes.TOGGLE, "collapse", false);
137     writer.writeAttribute(DataAttributes.TARGET, "#" + navbarId, true);
138     writer.writeAttribute(Arias.EXPANDED, Boolean.FALSE.toString(), false);
139     writer.writeAttribute(Arias.CONTROLS, navbarId, false);
140     writer.writeAttribute(Arias.LABEL, "Toggle navigation", false);
141 
142     writer.startElement(HtmlElements.SPAN);
143     writer.writeClassAttribute(BootstrapClass.NAVBAR_TOGGLER_ICON);
144     writer.endElement(HtmlElements.SPAN);
145 
146     writer.endElement(HtmlElements.BUTTON);
147 
148     if (brand != null && togglerLeft) {
149       writer.startElement(HtmlElements.SPAN);
150       writer.writeClassAttribute(BootstrapClass.NAVBAR_BRAND);
151       brand.encodeAll(facesContext);
152       writer.endElement(HtmlElements.SPAN);
153     }
154   }
155 }