Package de.agilecoders.wicket.core.markup.html.bootstrap.block

Source Code of de.agilecoders.wicket.core.markup.html.bootstrap.block.CodeBehavior

package de.agilecoders.wicket.core.markup.html.bootstrap.block;

import de.agilecoders.wicket.core.markup.html.bootstrap.block.prettyprint.PrettifyCssResourceReference;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import de.agilecoders.wicket.core.Bootstrap;
import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.BootstrapBaseBehavior;
import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.CssClassNameAppender;
import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.ICssClassNameProvider;
import de.agilecoders.wicket.core.markup.html.bootstrap.block.prettyprint.PrettifyJavaScriptReference;
import de.agilecoders.wicket.core.util.Components;
import de.agilecoders.wicket.core.util.CssClassNames;
import de.agilecoders.wicket.core.util.References;
import de.agilecoders.wicket.jquery.util.Strings2;

/**
* #### Description
*
* Wrap inline snippets of code with <code> and use <pre> for multiple
* lines of code. Angle brackets will be escaped in the code for proper rendering.
*
* #### Usage
*
* ```java
* component.add(new CodeBehavior()
*                  .setShowLineNumbers(true) // whether to show line numbers or not
*                  .setLanguage(Language.JAVA) // use java as code language; default is dynamic
*                  .setStartFromLine(20)); // hide first 20 lines
* ```
*
* ```html
* <code wicket:id="id">content</code>
* ```
*
* It's possible to use `pre`, `code` and `xmp` as tag name.
*
* @author Michael Haitz <michael.haitz@agilecoders.de>
*/
public class CodeBehavior extends Behavior {

    /**
     * enum that holds all possible languages
     */
    public enum Language implements ICssClassNameProvider {
        DYNAMIC, // use this or don't set a lang for auto detection

        // auto detected
        BSH, C, CC, CPP, CS, CSH, CYC, CV, HTM, HTML,
        JAVA, JS, M, MXML, PERL, PL, PM, PY, RB, SH,
        XHTML, XML, XSL,

        // plugins
        APOLLO, BASIC, CLJ, CSS, DART, ERLANG, GO, HS, LISP,
        LLVM, LUA, MATLAB, ML, MUMPS, N, PASCAL, PROTO, R, RD,
        SCALA, SQL, TCL, TEX, VB, VHDL, WIKI, XQ, YAML;

        @Override
        public String cssClassName() {
            if (!DYNAMIC.equals(this)) {
                return "lang-" + name().toLowerCase();
            }

            return "";
        }

    }

    private final IModel<Boolean> lineNumbers;
    private final IModel<String> cssClassNameModel;
    private final IModel<Language> language;
    private final IModel<Integer> from;

    private final CssClassNameAppender cssClassNameAppender;

    /**
     * Constructor.
     */
    public CodeBehavior() {
        super();

        lineNumbers = Model.of(false);
        cssClassNameModel = Model.of("");
        language = Model.of(Language.DYNAMIC);
        from = Model.of(0);

        cssClassNameAppender = new CssClassNameAppender(cssClassNameModel);
    }

    @Override
    public void detach(Component component) {
        super.detach(component);

        lineNumbers.detach();
        cssClassNameModel.detach();
        language.detach();
        from.detach();
    }

    @Override
    public void renderHead(final Component component, final IHeaderResponse response) {
        super.renderHead(component, response);

        response.render(CssHeaderItem.forReference(PrettifyCssResourceReference.INSTANCE));

        References.renderWithFilter(Bootstrap.getSettings(), response, JavaScriptHeaderItem.forReference(PrettifyJavaScriptReference.INSTANCE));

        response.render(OnDomReadyHeaderItem.forScript(createInitializerScript(Strings2.getMarkupId(component))));
    }

    private CharSequence createInitializerScript(CharSequence markupId) {
        return "$('#" + markupId + "').html(PR.prettyPrintOne($('#" + markupId + "').html().replace(/\\r\\n|\\r|\\n/g,'<br>'), '', $('#" + markupId + "').attr('class')));";
    }

    @Override
    public void bind(final Component component) {
        super.bind(component);

        BootstrapBaseBehavior.addTo(component);
        component.add(cssClassNameAppender);
    }

    @Override
    public void unbind(final Component component) {
        super.unbind(component);

        BootstrapBaseBehavior.removeFrom(component);
        component.remove(cssClassNameAppender);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onConfigure(final Component component) {
        super.onConfigure(component);

        cssClassNameModel.setObject(createCssClassNames());
    }

    /**
     * @return a list of css class names
     */
    private String createCssClassNames() {
        return CssClassNames.parse("prettyprint").add(
                createLineNumbersCssClass(),
                language.getObject().cssClassName()).asString();
    }

    /**
     * @return the css class name for the line number class
     */
    private String createLineNumbersCssClass() {
        if (hasLineNumbers()) {
            return "linenums" + (from.getObject() > 0 ? ":" + from.getObject() : "");
        }

        return "";
    }

    /**
     * @return true, if line numbers will be rendered
     */
    public final boolean hasLineNumbers() {
        return lineNumbers.getObject();
    }

    /**
     * adds line numbers on the left side of code block.
     *
     * @return this instance
     */
    public final CodeBehavior setShowLineNumbers(final boolean showLineNumbers) {
        this.lineNumbers.setObject(showLineNumbers);

        return this;
    }

    /**
     * defines from which line number the counting will start.
     *
     * @param from which line the numbers will count
     * @return this instance
     */
    public final CodeBehavior setStartFromLine(final int from) {
        setShowLineNumbers(true);
        this.from.setObject(from);

        return this;
    }

    /**
     * sets the language.
     *
     * @param language the language to use
     * @return this instance
     */
    public final CodeBehavior setLanguage(final Language language) {
        this.language.setObject(language);

        return this;
    }

    @Override
    public void onComponentTag(Component component, ComponentTag tag) {
        super.onComponentTag(component, tag);

        Components.assertTag(component, tag, "code", "pre","xmp");
    }
}
TOP

Related Classes of de.agilecoders.wicket.core.markup.html.bootstrap.block.CodeBehavior

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.