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.renderkit.html.standard.standard.tag;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.internal.component.AbstractUIGridLayout;
24  import org.apache.myfaces.tobago.internal.layout.Cell;
25  import org.apache.myfaces.tobago.internal.layout.Grid;
26  import org.apache.myfaces.tobago.internal.layout.OriginCell;
27  import org.apache.myfaces.tobago.layout.LayoutToken;
28  import org.apache.myfaces.tobago.layout.LayoutTokens;
29  import org.apache.myfaces.tobago.layout.Measure;
30  import org.apache.myfaces.tobago.renderkit.RendererBase;
31  import org.apache.myfaces.tobago.renderkit.css.Classes;
32  import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
33  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
34  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
35  import org.apache.myfaces.tobago.renderkit.html.HtmlRoleValues;
36  import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
37  import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
38  import org.apache.myfaces.tobago.util.ComponentUtils;
39  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  import javax.faces.component.UIComponent;
44  import javax.faces.context.FacesContext;
45  import java.io.IOException;
46  
47  public class GridLayoutRenderer extends RendererBase {
48  
49    private static final Logger LOG = LoggerFactory.getLogger(GridLayoutRenderer.class);
50  
51    // todo: may use: http://www.w3.org/TR/css3-grid-layout/ (currently only IE 10 and higher)
52  
53    @Override
54    public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {
55      final AbstractUIGridLayout gridLayout = (AbstractUIGridLayout) component;
56      final TobagoResponseWriter writer = getResponseWriter(facesContext);
57  
58      writer.startElement(HtmlElements.TABLE);
59      writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.PRESENTATION.toString(), false);
60      writer.writeClassAttribute(Classes.create(gridLayout));
61  
62      final StringBuilder builder = new StringBuilder();
63  
64      builder.append("{\"columns\":");
65      JsonUtils.encode(gridLayout.getGrid().getColumns(), builder);
66      builder.append(",");
67  
68      builder.append("\"rows\":");
69      JsonUtils.encode(gridLayout.getGrid().getRows(), builder);
70      builder.append("}");
71  
72      writer.writeAttribute(DataAttributes.LAYOUT, builder.toString(), true);
73  
74      writer.startElement(HtmlElements.COLGROUP);
75      final LayoutTokens columns = gridLayout.getGrid().getColumns();
76      for (LayoutToken column : columns.getTokens()) {
77          writer.startElement(HtmlElements.COL);
78          writer.endElement(HtmlElements.COL);
79      }
80      writer.endElement(HtmlElements.COLGROUP);
81      writer.startElement(HtmlElements.TBODY);
82    }
83  
84    @Override
85    public void encodeChildren(final FacesContext facesContext, final UIComponent component) throws IOException {
86      final AbstractUIGridLayout gridLayout = (AbstractUIGridLayout) component;
87  /*
88      final UIComponent container = gridLayout.getParent();
89      if (!container.isRendered()) {
90        return;
91      }
92      RenderUtils.encodeChildren(facesContext, container);
93  */
94  
95      final TobagoResponseWriter writer = getResponseWriter(facesContext);
96      final Grid grid = gridLayout.getGrid();
97      final int columns = grid.getColumnCount();
98      final int rows = grid.getRowCount();
99  
100     for (int i = 0; i < rows; i++) {
101       writer.startElement(HtmlElements.TR);
102       for (int j = 0; j < columns; j++) {
103         final Cell cell = grid.getCell(j, i);
104         if (cell instanceof OriginCell) {
105           writer.startElement(HtmlElements.TD);
106           final int columnSpan = cell.getColumnSpan();
107           if (columnSpan > 1) {
108             writer.writeAttribute(HtmlAttributes.COLSPAN, columnSpan);
109           }
110           final int rowSpan = cell.getRowSpan();
111           if (rowSpan > 1) {
112             writer.writeAttribute(HtmlAttributes.ROWSPAN, rowSpan);
113           }
114 
115           final UIComponent element = cell.getComponent();
116           StringBuilder builder = new StringBuilder();
117           builder.append("{");
118           final Measure width = Measure.valueOf(ComponentUtils.getAttribute(element, Attributes.width));
119           if (width != null) {
120             builder.append("\"width\":");
121 //            builder.append("{\"pixel\":");
122             builder.append(width.serialize());
123 //            builder.append("}");
124             builder.append(",");
125           }
126           final Measure height = Measure.valueOf(ComponentUtils.getAttribute(element, Attributes.height));
127           if (height != null) {
128             builder.append("\"height\":");
129 //            builder.append("{\"pixel\":");
130             builder.append(height.serialize());
131 //            builder.append("}");
132             builder.append(",");
133           }
134           if (builder.length() > 1) {
135             builder.deleteCharAt(builder.length() - 1);
136           }
137           // todo: add more attributes
138           builder.append("}");
139 
140           if (builder.length() > 2) { // empty is not need to render
141             ComponentUtils.putDataAttribute(element, "tobago-layout", builder.toString());
142           }
143           RenderUtils.encode(facesContext, element);
144 
145           writer.endElement(HtmlElements.TD);
146         }
147       }
148       writer.endElement(HtmlElements.TR);
149     }
150   }
151 
152   @Override
153   public void encodeEnd(final FacesContext facesContext, final UIComponent component) throws IOException {
154     final TobagoResponseWriter writer = getResponseWriter(facesContext);
155 
156     writer.endElement(HtmlElements.TBODY);
157     writer.endElement(HtmlElements.TABLE);
158   }
159 }