fiftyfive.wicket.css.CssClassModifier.java Source code

Java tutorial

Introduction

Here is the source code for fiftyfive.wicket.css.CssClassModifier.java

Source

/**
 * Copyright 2013 55 Minutes (http://www.55minutes.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fiftyfive.wicket.css;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.parser.XmlTag.TagType;
import org.apache.wicket.util.string.Strings;

/**
 * A behavior simliar to {@link org.apache.wicket.AttributeModifier AttributeModifier} but
 * specially tuned for modifying the HTML {@code class} attribute. When this behavior is bound
 * to a component it does the following:
 * <ul>
 * <li>Always adds the {@code class} attribute, even if it did not already exist.</li>
 * <li>Ensures that duplicate CSS classes will not be emitted in the attribute.</li>
 * <li>Each class will be separated by a space character.</li>
 * </ul>
 * Note that this class is abstract. Subclasses must implement the
 * {@link #modifyClasses modifyClasses()} to specify what classes are added (or subtracted!)
 * from the {@code class} attribute.
 * 
 * @since 2.0.4
 * @see fiftyfive.wicket.util.Shortcuts#toggledCssClass(String,org.apache.wicket.model.IModel)
 */
public abstract class CssClassModifier extends Behavior {
    /**
     * Implemented by subclasses to specify what CSS classes should be added or subtracted
     * to the HTML for this component.
     * 
     * @param component The component whose HTML element is being rendered.
     * 
     * @param cssClasses A set containing all the CSS classes that were declared in the markup
     *                   for this component, if any. If values are added to this set, they will
     *                   be emitted in the {@code class} attribute of the element when the
     *                   component renders, with a space separating each value. Values may also
     *                   be removed in order to prevent them from being emitted.
     */
    protected abstract void modifyClasses(Component component, Set<String> cssClasses);

    /**
     * Parse any existing classes declared in the markup for this component and then delegate
     * to {@link #modifyClasses modifyClasses()}. Set resulting set of classes on the component
     * tag to render its {@code class} attribute with the desired values.
     */
    @Override
    public void onComponentTag(Component component, ComponentTag tag) {
        if (tag.getType() != TagType.CLOSE) {
            Set<String> values = new LinkedHashSet<String>();
            String existing = tag.getAttribute("class");
            if (existing != null) {
                values.addAll(Arrays.asList(existing.split("\\s+")));
            }
            modifyClasses(component, values);
            tag.put("class", Strings.join(" ", values.toArray(new String[0])));
        }
    }
}