Skip to content

Commit

Permalink
Fixing delegate rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
cuioss committed Mar 31, 2024
1 parent ad8ae41 commit 67e83ea
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import de.cuioss.jsf.api.components.css.StyleClassBuilder;
import de.cuioss.jsf.api.components.css.StyleClassProvider;

import javax.faces.component.UIComponent;

/**
* <h2>Summary</h2>
* <p>
Expand All @@ -34,20 +32,6 @@
* </p>
* <p>
*
* <h2>Update to the state-management</h2>
* In previous versions targeted at mojarra, the logic of modifying the final style-class was in the method
* {@link #getStyleClass()}.
* With myfaces on the other hand the default Renderer use {@link UIComponent#getAttributes()} for looking up the
* styleClass, bypassing the corresponding get-method.
* The Solution:
* <ul>
* <li>The configured class, {@link #setStyleClass(String)} will be stored under the keys
* {@value ComponentStyleClassProviderImpl#KEY} and {@value ComponentStyleClassProviderImpl#LOCAL_STYLE_CLASS_KEY}</li>
* <li>Component-specific additions are to be provided via {@link #computeAndStoreFinalStyleClass(StyleClassBuilder)}.
* This must be done prior Rendering, usually by the concrete {@link javax.faces.render.Renderer}</li>
* </ul>
* <em>This workaround is only necessary for cases, where the rendering is done by the concrete implementation.</em>
*
* @author Oliver Wolff
*/
public interface ComponentStyleClassProvider extends StyleClassProvider {
Expand All @@ -59,12 +43,11 @@ public interface ComponentStyleClassProvider extends StyleClassProvider {
void setStyleClass(String styleClass);

/**
* Computes the final / effective styleClass and exposes it as 'styleClass'
* in the {@link javax.faces.component.StateHelper}
* See Class-Documentation for details.
* Computes the final / effective styleClass by concatenating the given component-style-class with the one
* configured by using {@link #getStyleClass()}
*
* @param componentSpecificStyleClass The style-classes created by the corresponding renderer,
* excluding the user-defined style-class,
*/
void computeAndStoreFinalStyleClass(StyleClassBuilder componentSpecificStyleClass);
String computeFinalStyleClass(StyleClassBuilder componentSpecificStyleClass);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ public class ComponentStyleClassProviderImpl implements ComponentStyleClassProvi
*/
public static final String KEY = "styleClass";

/**
* The key for the {@link StateHelper}
*/
public static final String LOCAL_STYLE_CLASS_KEY = "localStyleClass";

private final CuiState state;

/**
Expand All @@ -52,21 +47,17 @@ public ComponentStyleClassProviderImpl(@NonNull ComponentBridge bridge) {
@Override
public void setStyleClass(String styleClass) {
state.put(KEY, styleClass);
state.put(LOCAL_STYLE_CLASS_KEY, styleClass);
}

@Override
public void computeAndStoreFinalStyleClass(StyleClassBuilder componentSpecificStyleClass) {
state.put(KEY, componentSpecificStyleClass.append(getLocalStyleClassBuilder()).getStyleClass());
public String computeFinalStyleClass(StyleClassBuilder componentSpecificStyleClass) {
return componentSpecificStyleClass.append(getStyleClassBuilder()).getStyleClass();
}

@Override
public String getStyleClass() {
return state.get(KEY);
}

private StyleClassBuilder getLocalStyleClassBuilder() {
return new StyleClassBuilderImpl(state.get(LOCAL_STYLE_CLASS_KEY)) ;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
package de.cuioss.jsf.api.components.util.modifier.support;

import javax.faces.component.UIComponentBase;

import de.cuioss.jsf.api.components.css.StyleClassBuilder;
import de.cuioss.jsf.api.components.partial.ComponentStyleClassProvider;
import lombok.Getter;
import lombok.Setter;

import javax.faces.component.UIComponentBase;

public class StyleClassProvider extends UIComponentBase implements ComponentStyleClassProvider {

@Getter
Expand All @@ -34,7 +34,7 @@ public String getFamily() {
}

@Override
public void computeAndStoreFinalStyleClass(StyleClassBuilder componentSpecificStyleClass) {

public String computeFinalStyleClass(StyleClassBuilder componentSpecificStyleClass) {
return "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
package de.cuioss.jsf.bootstrap.button;

import java.io.IOException;
import java.util.Optional;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandButton;
import javax.faces.component.html.HtmlOutcomeTargetButton;
import javax.faces.context.FacesContext;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
Expand Down Expand Up @@ -64,13 +67,16 @@ protected void doEncodeBegin(final FacesContext context, final DecoratingRespons
final Button component) throws IOException {
var wrapped = ElementReplacingResponseWriter.createWrappedReplacingResonseWriter(context, "input", "button",
true);
// Prepare for Myfaces-rendering

component.resolveAndStoreTitle();
component.computeAndStoreFinalStyleClass(CssBootstrap.BUTTON.getStyleClassBuilder()
var finalStyleClass = component.computeFinalStyleClass(CssBootstrap.BUTTON.getStyleClassBuilder()
.append(ButtonState.getForContextState(component.getState()))
.append(ButtonSize.getForContextSize(component.resolveContextSize())));
var delegate = createButtonAndCopyAttributes(context, component);
delegate.setStyleClass(finalStyleClass);

JsfHtmlComponent.BUTTON.renderer(context).encodeBegin(wrapped, delegate);

JsfHtmlComponent.BUTTON.renderer(context).encodeBegin(wrapped, component);
if (component.isDisplayIconLeft()) {
var icon = IconComponent.createComponent(context);
icon.setIcon(component.getIcon());
Expand Down Expand Up @@ -102,4 +108,18 @@ protected void doEncodeEnd(final FacesContext context, final DecoratingResponseW
writer.withEndElement(Node.BUTTON);
}

static HtmlOutcomeTargetButton createButtonAndCopyAttributes(FacesContext facesContext, HtmlOutcomeTargetButton source) {
var delegate = JsfHtmlComponent.BUTTON.component(facesContext);
Optional.ofNullable(source.getId()).ifPresent(delegate::setId);
Optional.ofNullable(source.getStyle()).ifPresent(delegate::setStyle);
Optional.ofNullable(source.getTitle()).ifPresent(delegate::setTitle);
Optional.ofNullable(source.getValue()).ifPresent(delegate::setValue);
Optional.ofNullable(source.getAlt()).ifPresent(delegate::setAlt);
Optional.ofNullable(source.getDir()).ifPresent(delegate::setDir);
Optional.of(source.isDisabled()).ifPresent(delegate::setDisabled);
Optional.ofNullable(source.getAccesskey()).ifPresent(delegate::setAccesskey);
Optional.ofNullable(source.getImage()).ifPresent(delegate::setImage);
delegate.getPassThroughAttributes(true).putAll(source.getPassThroughAttributes(true));
return delegate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
*/
package de.cuioss.jsf.bootstrap.button;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.FacesRenderer;

import de.cuioss.jsf.api.components.JsfHtmlComponent;
import de.cuioss.jsf.api.components.html.AttributeName;
import de.cuioss.jsf.api.components.html.AttributeValue;
Expand All @@ -31,6 +25,11 @@
import de.cuioss.jsf.bootstrap.BootstrapFamily;
import de.cuioss.jsf.bootstrap.CssBootstrap;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.FacesRenderer;
import java.io.IOException;

/**
* <h2>Rendering</h2>
* <p>
Expand All @@ -47,20 +46,20 @@ public CloseCommandButtonRenderer() {

@Override
protected void doEncodeBegin(final FacesContext context, final DecoratingResponseWriter<CloseCommandButton> writer,
final CloseCommandButton component) throws IOException {
final CloseCommandButton component) throws IOException {

var wrapped = ElementReplacingResponseWriter.createWrappedReplacingResonseWriter(context, "input", "button",
true);
// Prepare for Myfaces-rendering
true);
component.resolveAndStoreTitle();
component.computeAndStoreFinalStyleClass(CssBootstrap.BUTTON_CLOSE.getStyleClassBuilder());

JsfHtmlComponent.COMMAND_BUTTON.renderer(context).encodeBegin(wrapped, component);
var finalStyleClass = component.computeFinalStyleClass(CssBootstrap.BUTTON_CLOSE.getStyleClassBuilder());
var delegate = CommandButtonRenderer.createButtonAndCopyAttributes(context, component);
delegate.setStyleClass(finalStyleClass);
JsfHtmlComponent.COMMAND_BUTTON.renderer(context).encodeBegin(wrapped, delegate);

var output = JsfHtmlComponent.SPAN.component(context);

output.getPassThroughAttributes(true).put(AttributeName.ARIA_HIDDEN.getContent(),
AttributeValue.TRUE.getContent());
AttributeValue.TRUE.getContent());

output.setValue("&#xD7;");
output.setEscape(false);
Expand All @@ -76,7 +75,7 @@ public void decode(final FacesContext context, final UIComponent component) {

@Override
protected void doEncodeEnd(final FacesContext context, final DecoratingResponseWriter<CloseCommandButton> writer,
final CloseCommandButton component) throws IOException {
final CloseCommandButton component) throws IOException {
writer.withEndElement(Node.BUTTON);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
import de.cuioss.jsf.bootstrap.icon.IconComponent;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandButton;
import javax.faces.context.FacesContext;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import java.io.IOException;
import java.util.Optional;

/**
* <h2>Rendering</h2>
Expand Down Expand Up @@ -66,12 +68,16 @@ protected void doEncodeBegin(final FacesContext context, final DecoratingRespons
final CommandButton component) throws IOException {
var wrapped = ElementReplacingResponseWriter.createWrappedReplacingResonseWriter(context, "input", "button",
true);
// Prepare for Myfaces-rendering

component.resolveAndStoreTitle();
component.computeAndStoreFinalStyleClass(CssBootstrap.BUTTON.getStyleClassBuilder()
var finalStyleClass = component.computeFinalStyleClass(CssBootstrap.BUTTON.getStyleClassBuilder()
.append(ButtonState.getForContextState(component.getState()))
.append(ButtonSize.getForContextSize(component.resolveContextSize())));
JsfHtmlComponent.COMMAND_BUTTON.renderer(context).encodeBegin(wrapped, component);

var delegate = createButtonAndCopyAttributes(context, component);
delegate.setStyleClass(finalStyleClass);

JsfHtmlComponent.COMMAND_BUTTON.renderer(context).encodeBegin(wrapped, delegate);

if (component.isDisplayIconLeft()) {
var icon = IconComponent.createComponent(context);
Expand Down Expand Up @@ -103,4 +109,18 @@ protected void doEncodeEnd(final FacesContext context, final DecoratingResponseW
final CommandButton component) throws IOException {
writer.withEndElement(Node.BUTTON);
}

static HtmlCommandButton createButtonAndCopyAttributes(FacesContext facesContext, HtmlCommandButton source) {
var delegate = JsfHtmlComponent.COMMAND_BUTTON.component(facesContext);
Optional.ofNullable(source.getId()).ifPresent(delegate::setId);
Optional.ofNullable(source.getStyle()).ifPresent(delegate::setStyle);
Optional.ofNullable(source.getTitle()).ifPresent(delegate::setTitle);
Optional.ofNullable(source.getAlt()).ifPresent(delegate::setAlt);
Optional.ofNullable(source.getDir()).ifPresent(delegate::setDir);
Optional.of(source.isDisabled()).ifPresent(delegate::setDisabled);
Optional.ofNullable(source.getAccesskey()).ifPresent(delegate::setAccesskey);
Optional.ofNullable(source.getImage()).ifPresent(delegate::setImage);
delegate.getPassThroughAttributes(true).putAll(source.getPassThroughAttributes(true));
return delegate;
}
}

0 comments on commit 67e83ea

Please sign in to comment.