package org.richfaces.renderkit; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import javax.faces.application.Resource; import javax.faces.application.ResourceDependencies; import javax.faces.application.ResourceDependency; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.richfaces.component.AbstractPage; import org.richfaces.component.LayoutPosition; import org.richfaces.skin.SkinFactory; import org.richfaces.skin.Theme; import org.richfaces.ui.common.HtmlConstants; @ResourceDependencies({ @ResourceDependency(library = "org.richfaces", name = "page.ecss", target = "head") }) public abstract class AbstractPageRenderer extends RendererBase { // ------------------------------ FIELDS ------------------------------ public static final String RENDERER_TYPE = "org.richfaces.PageRenderer"; private static final Map<String, String[]> doctypes; // -------------------------- STATIC METHODS -------------------------- static { // Fill doctype, content-type and namespace map for different formats. doctypes = new HashMap<String, String[]>(); doctypes .put( "html-transitional", new String[]{ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n", "text/html", null}); doctypes.put("html", new String[]{ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n" + "\"http://www.w3.org/TR/html4/strict.dtd\">\n", "text/html", null}); doctypes.put("html-frameset", new String[]{ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\n" + "\"http://www.w3.org/TR/html4/frameset.dtd\">\n", "text/html", null}); doctypes .put( "xhtml", new String[]{ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n", "application/xhtml+xml", "http://www.w3.org/1999/xhtml"}); doctypes .put( "xhtml-transitional", new String[]{ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n", "application/xhtml+xml", "http://www.w3.org/1999/xhtml"}); doctypes .put( "xhtml-frameset", new String[]{ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n" + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n", "application/xhtml+xml", "http://www.w3.org/1999/xhtml"}); doctypes.put("html-3.2", new String[]{ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", "text/html", null}); } // -------------------------- OTHER METHODS -------------------------- public void encodeBodyResources(FacesContext context) throws IOException { for (UIComponent child : context.getViewRoot().getComponentResources(context, "body")) { child.encodeAll(context); } } public void encodeHeadResources(FacesContext context) throws IOException { for (UIComponent child : context.getViewRoot().getComponentResources(context, "head")) { child.encodeAll(context); } } public Theme getTheme(FacesContext context, UIComponent component) { Theme theme = null; String themeName = ((AbstractPage) component).getTheme(); if (null != themeName && themeName.length() > 0) { theme = SkinFactory.getInstance().getTheme(context, themeName); } return theme; } public boolean hasFacet(UIComponent component, String facet) { return null != component.getFacet(facet); } public boolean hasTitle(FacesContext context, UIComponent component) { AbstractPage page = (AbstractPage) component; String pageTitle = page.getPageTitle(); return pageTitle != null && !pageTitle.trim().equals(""); } public void insertFacet(String facetName, FacesContext context, UIComponent component) throws IOException { UIComponent indexChildren = component.getFacet(facetName); if (null != indexChildren && indexChildren.isRendered()) { renderChild(context, indexChildren); } } public void pageStyle(FacesContext context, UIComponent component) throws IOException { // Write body class. AbstractPage page = (AbstractPage) component; ResponseWriter writer = context.getResponseWriter(); writer.startElement("style", component); writer.writeAttribute(HtmlConstants.TYPE_ATTR, HtmlConstants.CSS_TYPE, null); // Calculate page width Integer width = page.getWidth(); if (null != width && width > 0) { float nonIeWidth = (width.floatValue() / 13.0f); float ieWidth = (width.floatValue() / 13.333f); StringBuilder format = new StringBuilder( ".rf-pg{margin:auto;text-align:left;"); format.append("width:").append(nonIeWidth).append("em;"); format.append("*width:").append(ieWidth).append("em;\n"); format.append("}\n"); writer.write(format.toString()); } else { writer.write(".rf-pg{margin:auto 10px;width:auto;}\n"); } // Calculate sidebar width if (component.getFacet("sidebar") != null) { LayoutPosition sidebarPosition = page.getSidebarPosition(); if (LayoutPosition.right.equals(sidebarPosition)) { writer .write(".rf-pg-m{float:left;margin-right:-30em;}\n"); } else { writer .write(".rf-pg-m{float:right;margin-left:-30em;}\n"); sidebarPosition = LayoutPosition.left; } Integer sidebarWidth = page.getSidebarWidth(); if (null != sidebarWidth && sidebarWidth > 0) { float nonIeWidth = (sidebarWidth.floatValue() / 13.0f); float ieWidth = (sidebarWidth.floatValue() / 13.333f); StringBuilder format = new StringBuilder( ".rf-pg-sb{float:"); format.append(sidebarPosition).append(";"); format.append("width:").append(nonIeWidth).append("em;"); format.append("*width:").append(ieWidth).append("em;}\n"); format.append(".rf-pg-bd{margin-"); format.append(sidebarPosition).append(":").append(nonIeWidth + 1.0f) .append("em;"); format.append("*margin").append(sidebarPosition).append(":").append( ieWidth + .975f).append("em;}\n"); writer.write(format.toString()); } } // Cleanup writer.write(".rf-pg-bd{float:none;width:auto;}\n"); writer.endElement("style"); } public String prolog(FacesContext context, UIComponent component) throws IOException { ResponseWriter out = context.getResponseWriter(); AbstractPage page = (AbstractPage) component; String format = page.getMarkupType(); String contentType = page.getContentType(); String namespace = page.getNamespace(); // String characterEncoding = out.getCharacterEncoding(); String[] docType = null; if (null != format) { docType = doctypes.get(format); } else { contentType = out.getContentType(); for (String[] types : doctypes.values()) { if (types[1].equals(contentType)) { docType = types; break; } } } if (null != docType) { if (null == contentType) { contentType = docType[1]; } // https://jira.jboss.org/jira/browse/RF-7367 if (null == namespace) { namespace = docType[2]; } out.write(docType[0]); } if (null != contentType) { // response.setContentType(contentType /*+ ";charset=" + // characterEncoding*/); } return namespace; } public void renderChild(FacesContext facesContext, UIComponent child) throws IOException { if (!child.isRendered()) { return; } child.encodeBegin(facesContext); if (child.getRendersChildren()) { child.encodeChildren(facesContext); } else { renderChildren(facesContext, child); } child.encodeEnd(facesContext); } public void themeScript(FacesContext context, UIComponent component) throws IOException { Theme theme = getTheme(context, component); if (null != theme) { String script = theme.getScript(); if (null != script) { ResponseWriter writer = context.getResponseWriter(); writer.startElement(HtmlConstants.SCRIPT_ELEM, component); writer.writeAttribute(HtmlConstants.TYPE_ATTR, HtmlConstants.JAVASCRIPT_TYPE, null); script = context.getApplication().getViewHandler().getResourceURL(context, script); script = context.getExternalContext().encodeResourceURL(script); writer.writeAttribute(HtmlConstants.SRC_ATTRIBUTE, script, null); writer.endElement(HtmlConstants.SCRIPT_ELEM); } } } public void themeStyle(FacesContext context, UIComponent component) throws IOException { Theme theme = getTheme(context, component); if (null != theme) { String style = theme.getStyle(); if (null != style) { ResponseWriter writer = context.getResponseWriter(); writer.startElement(HtmlConstants.LINK_ELEMENT, component); writer.writeAttribute(HtmlConstants.TYPE_ATTR, HtmlConstants.CSS_TYPE, null); writer.writeAttribute(HtmlConstants.REL_ATTR, HtmlConstants.REL_STYLESHEET, null); writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, "component", null); String library = null, resourceName = null; if (style.contains(":")) { StringTokenizer stringTokenizer = new StringTokenizer(style, ":"); library = stringTokenizer.nextToken(); resourceName = stringTokenizer.nextToken(); } else { resourceName = style; } Resource resource = context.getApplication().getResourceHandler().createResource(resourceName, library); style = context.getExternalContext().encodeResourceURL(resource.getRequestPath()); writer.writeAttribute(HtmlConstants.HREF_ATTR, style, null); writer.endElement(HtmlConstants.LINK_ELEMENT); } } } }