...
This change will some existing code as all calls to setClicked that passed a IClicked2 instance now need to use setClicked2.
INodeContentRenderer removed (breaking change)
This interface was the main interface to render generic content inside some NodeContainer. Its definition was this:
Code Block |
---|
public interface INodeContentRenderer<T> {
void renderNodeContent(@Nonnull NodeBase component, @Nonnull NodeContainer node, @Nullable T object, @Nullable Object parameters) throws Exception;
} |
This interface was abused all over the place and makes it very unclear what parameters are actually passed into renderers, as the parameters component and parameters were often used in non-obvious ways. It also opened the doors for wide abuse, because renderers could abuse the values in component to actually "fix" the components rendering. This of course makes it impossible to maintain those components.
In addition the "object" parameter needed to be @Nullable because a lot of usages of this interface sometimes do pass a null value. But this makes it hard for the zillion places where this value is never null: it forces a check to be needed inside the implementation always.
The interface was replaced by the following:
Code Block |
---|
public interface IRenderInto<T> {
void render(@Nonnull NodeContainer node, @Nonnull T object) throws Exception;
default void renderOpt(@Nonnull NodeContainer node, @Nullable T object) throws Exception {
if(null != object)
render(node, object);
}
} |
The implementer usually implements the render() method only. When there is a need to also handle nulls in a special way then the renderOpt() method needs to be overridden too.
This interface is used at most places where INodeContentRenderer was used. At places where indeed more than these two parameters are needed new interfaces will have been introduced which better describe the parameters and their expected use. Also see the notes about the content renderers for the LookupInput control.
For those not eager to replace all occurrences of INodeContentRenderer: you might be able to define it again in your own code, making it extend IRenderInto, and make the render() method call the old method inside INodeContentRenderer, something like:
Code Block |
---|
public interface INodeContentRenderer<T> extends IRenderInto<T> {
void renderNodeContent(@Nonnull NodeBase component, @Nonnull NodeContainer node, @Nullable T object, @Nullable Object parameters) throws Exception;
default void render(@Nonnull NodeContainer node, @Nonnull T object) throws Exception {
renderNodeContent(node, node, object, null);
}
} |
Private and protected properties can be used in binding/metadata
...
The generated html code for the control has been changed so that style fixes could be applied. This breaks the existing legacy stylesheets. For fixes look at _lookupInput.scss.
The value renderers used by this component have changed. In 1.0 the value renderers were not just responsible for rendering a value: they also placed the control's buttons and did a lot for the layout for the control. This was a bad plan, because it tightly couples those renderers to the control and anyone overridding those also need to know how the control renders. This made it impossible to change the rendering of the control.
The new renderers are solely responsible for rendering the value in some reasonable way. All of the main layout of the control is done by the control itself. Consequently these renderers no longer need all the extra "hidden" parameters passed to INodeContentRenderer, and they now implement IRenderInto.
Look and feel
The following things have changed regarding themes, styles and look-and-feel.
...