in tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java [96:296]
public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
final TobagoContext tobagoContext = TobagoContext.getInstance(facesContext);
if (tobagoContext.getFocusId() == null && !StringUtils.isBlank(component.getFocusId())) {
tobagoContext.setFocusId(component.getFocusId());
}
final TobagoResponseWriter writer = getResponseWriter(facesContext);
// reset responseWriter and render page
facesContext.setResponseWriter(writer);
if (tobagoConfig.isPreventFrameAttacks()) {
ResponseUtils.ensureXFrameOptionsHeader(facesContext);
}
ResponseUtils.ensureNoCacheHeader(facesContext);
ResponseUtils.ensureContentSecurityPolicyHeader(facesContext, tobagoConfig.getContentSecurityPolicy());
if (LOG.isDebugEnabled()) {
for (final Object o : component.getAttributes().entrySet()) {
final Map.Entry entry = (Map.Entry) o;
LOG.debug("*** '" + entry.getKey() + "' -> '" + entry.getValue() + "'");
}
}
final ExternalContext externalContext = facesContext.getExternalContext();
final String contextPath = externalContext.getRequestContextPath();
final Object request = externalContext.getRequest();
final Object response = externalContext.getResponse();
final Application application = facesContext.getApplication();
final ViewHandler viewHandler = application.getViewHandler();
final UIViewRoot viewRoot = facesContext.getViewRoot();
final String viewId = viewRoot.getViewId();
final String formAction = externalContext.encodeActionURL(viewHandler.getActionURL(facesContext, viewId));
final boolean ajax = facesContext.getPartialViewContext().isAjaxRequest();
final String contentType = writer.getContentTypeWithCharSet();
ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
if (tobagoConfig.isSetNosniffHeader()) {
ResponseUtils.ensureNosniffHeader(facesContext);
}
final Theme theme = tobagoContext.getTheme();
final String clientId = component.getClientId(facesContext);
final boolean productionMode = facesContext.isProjectStage(ProjectStage.Production);
final Markup markup = component.getMarkup();
final TobagoClass spread = markup != null && markup.contains(Markup.SPREAD) ? TobagoClass.SPREAD : null;
final String title = component.getLabel();
final Locale locale = viewRoot.getLocale();
writer.startElement(HtmlElements.HTML);
if (locale != null) {
final String language = locale.getLanguage();
if (language != null) {
writer.writeAttribute(HtmlAttributes.LANG, language, false);
}
}
writer.writeClassAttribute(spread);
writer.startElement(HtmlElements.HEAD);
final HeadResources headResources = new HeadResources(
facesContext, viewRoot.getComponentResources(facesContext, HEAD_TARGET), writer.getCharacterEncoding());
// meta tags
for (final UIComponent metas : headResources.getMetas()) {
metas.encodeAll(facesContext);
}
// title
writer.startElement(HtmlElements.TITLE);
writer.writeText(title != null ? title : "");
writer.endElement(HtmlElements.TITLE);
// style files from theme
AbstractUIStyle style = null;
for (final ThemeStyle themeStyle : theme.getStyleResources(productionMode)) {
if (style == null) {
style = (AbstractUIStyle) facesContext.getApplication()
.createComponent(facesContext, Tags.style.componentType(), RendererTypes.Style.name());
style.setTransient(true);
}
style.setFile(contextPath + themeStyle.getName());
style.encodeAll(facesContext);
}
// style files individual files
for (final UIComponent styles : headResources.getStyles()) {
styles.encodeAll(facesContext);
}
// script files from theme
for (final ThemeScript themeScript : theme.getScriptResources(productionMode)) {
final AbstractUIScript script = (AbstractUIScript) facesContext.getApplication()
.createComponent(facesContext, Tags.script.componentType(), RendererTypes.Script.name());
script.setTransient(true);
script.setFile(contextPath + themeScript.getName());
script.setType(themeScript.getType());
script.encodeAll(facesContext);
}
// script files individual files
for (final UIComponent scripts : headResources.getScripts()) {
scripts.encodeAll(facesContext);
}
for (final UIComponent misc : headResources.getMisc()) {
misc.encodeAll(facesContext);
}
writer.endElement(HtmlElements.HEAD);
writer.startElement(HtmlElements.BODY);
writer.writeClassAttribute(spread);
writer.startElement(HtmlElements.TOBAGO_PAGE);
writer.writeAttribute(CustomAttributes.LOCALE, locale.toString(), false);
writer.writeClassAttribute(
BootstrapClass.CONTAINER_FLUID,
spread,
component.getCustomClass());
writer.writeIdAttribute(clientId);
HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
// write the config
writer.writeAttribute(HtmlAttributes.FOCUS_ON_ERROR, Boolean.toString(tobagoContext.getFocusOnError()), false);
writer.writeAttribute(HtmlAttributes.WAIT_OVERLAY_DELAY_FULL, tobagoContext.getWaitOverlayDelayFull());
writer.writeAttribute(HtmlAttributes.WAIT_OVERLAY_DELAY_AJAX, tobagoContext.getWaitOverlayDelayAjax());
encodeBehavior(writer, facesContext, component);
writer.startElement(HtmlElements.FORM);
writer.writeClassAttribute(spread);
writer.writeAttribute(HtmlAttributes.ACTION, formAction, true);
writer.writeIdAttribute(component.getFormId(facesContext));
writer.writeAttribute(HtmlAttributes.METHOD, getMethod(component), false);
final String enctype = tobagoContext.getEnctype();
if (enctype != null) {
writer.writeAttribute(HtmlAttributes.ENCTYPE, enctype, false);
}
// TODO: enable configuration of 'accept-charset'
writer.writeAttribute(HtmlAttributes.ACCEPT_CHARSET, AbstractUIPage.FORM_ACCEPT_CHARSET.name(), false);
// TODO evaluate 'accept' attribute usage
//writer.writeAttribute(HtmlAttributes.ACCEPT, );
writer.writeAttribute(DataAttributes.CONTEXT_PATH, contextPath, true);
writer.startElement(HtmlElements.INPUT);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
writer.writeNameAttribute("jakarta.faces.source");
writer.writeIdAttribute("jakarta.faces.source");
writer.writeAttribute(HtmlAttributes.DISABLED, true);
writer.endElement(HtmlElements.INPUT);
final String lastFocusId = clientId + ComponentUtils.SUB_SEPARATOR + "lastFocusId";
writer.startElement(HtmlElements.TOBAGO_FOCUS);
writer.writeIdAttribute(lastFocusId);
writer.startElement(HtmlElements.INPUT);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
writer.writeNameAttribute(lastFocusId);
writer.writeIdAttribute(lastFocusId + ComponentUtils.SUB_SEPARATOR + "field");
writer.writeAttribute(HtmlAttributes.VALUE, tobagoContext.getFocusId(), true);
writer.endElement(HtmlElements.INPUT);
writer.endElement(HtmlElements.TOBAGO_FOCUS);
if (tobagoConfig.isCheckSessionSecret()) {
final Secret secret = Secret.getInstance(facesContext);
if (secret != null) {
writer.startElement(HtmlElements.INPUT);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
writer.writeAttribute(HtmlAttributes.NAME, Secret.KEY, false);
writer.writeAttribute(HtmlAttributes.ID, Secret.KEY, false);
writer.writeAttribute(HtmlAttributes.VALUE, secret.getSecret(), false);
writer.endElement(HtmlElements.INPUT);
} else {
LOG.warn("Missing session secret!");
}
}
// placeholder for menus
writer.startElement(HtmlElements.DIV);
writer.writeClassAttribute(TobagoClass.PAGE__MENU_STORE);
writer.endElement(HtmlElements.DIV);
writer.startElement(HtmlElements.SPAN);
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "faces-state-container");
writer.flush();
if (!ajax) {
viewHandler.writeState(facesContext);
}
writer.endElement(HtmlElements.SPAN);
if (component.getFacet("backButtonDetector") != null) {
final UIComponent hidden = component.getFacet("backButtonDetector");
hidden.encodeAll(facesContext);
}
}