/** * 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 brix.codepress; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.ajax.WicketEventJQueryResourceReference; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.ComponentTag; 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.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.request.Url; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.resource.JavaScriptResourceReference; public class CodePressEnabler extends Behavior { private final String language; private final boolean lineNumbers; private Component owner; private static final JavaScriptResourceReference JS = new JavaScriptResourceReference(CodePressEnabler.class, "codepress.js"); public CodePressEnabler(String language, boolean lineNumbers) { this.language = language; this.lineNumbers = lineNumbers; } @Override public void bind(Component component) { if (owner != null) { throw new IllegalStateException("This behavior is already bound to a component"); } // TODO validate markup id of owner will not contain any funky // characters // because codepress creates a javascript variable whose name is the // html id attribute owner = component; owner.setOutputMarkupId(true); } @Override public void beforeRender(Component component) { if (component instanceof FormComponent) { ((FormComponent<?>)component).getForm().getRootForm().setOutputMarkupId(true); } } @Override public void renderHead(Component component, IHeaderResponse response) { response.renderJavaScriptReference(JS); response.renderJavaScript(codePressInitializer(), "codePressInitializer"); if (owner instanceof FormComponent) { response.renderJavaScriptReference(WicketEventReference.INSTANCE); final FormComponent<?> fc = (FormComponent<?>)component; final Form<?> form = fc.getForm().getRootForm(); response.renderOnDomReadyJavaScript("Wicket.Event.add(document.getElementById('" + form.getMarkupId() + "'), 'submit', function() { " + fc.getMarkupId() + ".toggleEditor();});")); } } private String codePressInitializer() { return new StringBuilder() .append("CodePress.path = '").append(getCodePressPath()).append("/';\n") .append( "if(window.attachEvent) {window.attachEvent('onload',CodePress.run);}" + "else {window.addEventListener('DOMContentLoaded',CodePress.run,false);}") .toString(); } private String getCodePressPath() { RequestCycle requestCycle = RequestCycle.get(); Url urlFor = requestCycle.mapUrlFor(JS, null); List<String> segments = urlFor.getSegments(); segments.remove(segments.size()-1); return requestCycle.getOriginalResponse().encodeURL(requestCycle.getUrlRenderer().renderUrl(urlFor)); } @Override public void onComponentTag(Component component, ComponentTag tag) { String clazz = (String)tag.getAttributes().get("class"); clazz = (clazz == null) ? "" : clazz + " "; clazz += "codepress "; clazz += language; clazz += " linenumbers-"; clazz += (lineNumbers) ? "on" : "off"; tag.put("class", clazz); } }