();
+ }
+
+ /**
+ * Adds number param to config.
+ * Usage:
+ * config.addConfigValue("width", 100);
+ * config.addConfigValue("dialog_backgroundCoverOpacity", 0.7);
+ * @param key config param key
+ * @param value config param value.
+ */
+ public void addConfigValue(final String key, final Number value) {
+ config.put(key, value);
+ }
+
+ /**
+ * Adds String param to config.
+ * Usage:
+ * config.addConfigValue("baseHref", "http://www.example.com/path/");
+ * config.addConfigValue("toolbar", [[ 'Source', '-', 'Bold', 'Italic' ]]);
+ * @param key config param key
+ * @param value config param value.
+ */
+ public void addConfigValue(final String key, final String value) {
+ config.put(key, value);
+ }
+
+ /**
+ * Adds Map param to config.
+ * Usage:
+ * Map map = new HashMap();
+ * map.put("element", "span");
+ * map.put("styles", "{'background-color' : '#(color)'}");
+ * config.addConfigValue("colorButton_backStyle", map);
+ * @param key config param key
+ * @param value config param value.
+ */
+ public void addConfigValue(final String key,
+ final Map value) {
+ config.put(key, value);
+ }
+
+ /**
+ * Adds List param to config.
+ * Usage:
+ *
+ List> list = new ArrayList>();
+ List subList = new ArrayList();
+ subList.add("Source");
+ subList.add("-");
+ subList.add("Bold");
+ subList.add("Italic");
+ list.add(subList);
+ config.addConfigValue("toolbar", list);
+
+ * @param key config param key
+ * @param value config param value.
+ */
+ public void addConfigValue(final String key, final List extends Object> value) {
+ config.put(key, value);
+ }
+
+ /**
+ * Adds boolean param to config.
+ * Usage:
+ * config.addConfigValue("autoUpdateElement", true);
+ * @param key config param key
+ * @param value config param value.
+ */
+ public void addConfigValue(final String key, final Boolean value) {
+ config.put(key, value);
+ }
+
+
+ /**
+ * Gets config value by key.
+ * @param key config param key
+ * @return config param value.
+ */
+ Object getConfigValue(final String key) {
+ return config.get(key);
+ }
+
+ /**
+ * @return all config values.
+ */
+ Map getConfigValues() {
+ return config;
+ }
+
+ /**
+ * Removes config value by key.
+ * Usage:
+ * config.removeConfigValue("toolbar");
+ * @param key config param key.
+ */
+ public void removeConfigValue(final String key) {
+ config.remove(key);
+ }
+
+ /**
+ * Configure settings. Merge config and event handlers.
+ * @return setting config.
+ * @param eventHandler events
+ */
+ CKEditorConfig configSettings(final EventHandler eventHandler) {
+ try {
+ CKEditorConfig cfg = (CKEditorConfig) this.clone();
+ if (eventHandler != null) {
+ for (String eventName : eventHandler.events.keySet()) {
+ Set set = eventHandler.events.get(eventName);
+ if (set.isEmpty()) {
+ continue;
+ } else if (set.size() == 1) {
+ Map hm = new HashMap();
+ for (String code : set) {
+ hm.put(eventName, "@@" + code);
+ }
+ cfg.addConfigValue("on", hm);
+ } else {
+ Map hm = new HashMap();
+ StringBuilder sb = new StringBuilder("@@function (ev){");
+ for (String code : set) {
+ sb.append("(");
+ sb.append(code);
+ sb.append(")(ev);");
+ }
+ sb.append("}");
+ hm.put(eventName, sb.toString());
+ cfg.addConfigValue("on", hm);
+ }
+ }
+ }
+ return cfg;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+
+
+ }
+
+ /**
+ * Checks if config is empty.
+ * @return true if is
+ */
+ public boolean isEmpty() {
+ return config.isEmpty();
+ }
+
+ /**
+ * Override.
+ */
+ protected Object clone() throws CloneNotSupportedException {
+ CKEditorConfig cfg = (CKEditorConfig) super.clone();
+ cfg.config = new HashMap(this.config);
+ return cfg;
+ }
+
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorInsertTag.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorInsertTag.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorInsertTag.java (revision 6775)
@@ -0,0 +1,153 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+
+/**
+ * <ck:editor> tag code.
+ * Usage:
+ * <ckeditor:editor basePath="../../ckeditor/" editor="editor1" />
+ */
+public class CKEditorInsertTag extends CKEditorTag {
+
+ private static final long serialVersionUID = 1316780332328233835L;
+
+ private static final String DEFAULT_TEXTAREA_ROWS = "8";
+ private static final String DEFAULT_TEXTAREA_COLS = "60";
+
+
+ private String editor;
+ private String value;
+ private Map textareaAttributes;
+
+
+
+ /**
+ * Default constructor.
+ */
+ public CKEditorInsertTag() {
+ textareaAttributes = new HashMap();
+ editor = "";
+ value = "";
+ }
+
+ @Override
+ public int doStartTag() throws JspException {
+ JspWriter out = pageContext.getOut();
+ try {
+ out.write(createTextareaTag());
+ } catch (Exception e) {
+ try {
+ HttpServletResponse resp = (HttpServletResponse)
+ pageContext.getResponse();
+ resp.reset();
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Problem with creating tag");
+ } catch (IOException e1) {
+ throw new JspException(e1);
+ }
+ }
+ return EVAL_PAGE;
+ }
+
+
+ @Override
+ protected String getTagOutput(final CKEditorConfig config) {
+ if (config != null && !config.isEmpty()) {
+ return "CKEDITOR.replace('" + editor + "', "
+ + TagHelper.jsEncode(config) + ");";
+ } else {
+ return "CKEDITOR.replace('" + editor + "');";
+ }
+ }
+
+ /**
+ * creates HTML code to insert textarea into page.
+ * @return textarea code.
+ */
+ private String createTextareaTag() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("");
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ /**
+ * Creates string from textarea attributes map.
+ * @return textarea attributes string.
+ */
+ private String createTextareaAttributesText() {
+ if (textareaAttributes.isEmpty()) {
+ textareaAttributes.put("rows", DEFAULT_TEXTAREA_ROWS);
+ textareaAttributes.put("cols", DEFAULT_TEXTAREA_COLS);
+ }
+ StringBuilder sb = new StringBuilder();
+ for (String s : textareaAttributes.keySet()) {
+ sb.append(" ");
+ sb.append(s + "=\"" + textareaAttributes.get(s) + "\"");
+ }
+ return sb.toString();
+ }
+
+
+
+ /**
+ * @return the editor
+ */
+ public final String getEditor() {
+ return editor;
+ }
+
+ /**
+ * @param editor the editor to set
+ */
+ public final void setEditor(final String editor) {
+ this.editor = editor;
+ }
+
+ /**
+ * @return the value
+ */
+ public final String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value the value to set
+ */
+ public final void setValue(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * @return the textareaAttributes
+ */
+ public final Map getTextareaAttributes() {
+ return textareaAttributes;
+ }
+
+ /**
+ * @param textareaAttr the textareaAttributes to set
+ */
+ public final void setTextareaAttributes(final Map textareaAttr) {
+ this.textareaAttributes = textareaAttr;
+ }
+
+
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceAllTag.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceAllTag.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceAllTag.java (revision 6775)
@@ -0,0 +1,67 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+/**
+ * <ck:repalceAll> tag code.
+ * Usage:
+ * <ckeditor:replaceAll basePath="../../ckeditor/" />
+ */
+public class CKEditorReplaceAllTag extends CKEditorTag {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7331873466295495480L;
+ private String className;
+
+ /**
+ * Default constructor.
+ */
+ public CKEditorReplaceAllTag() {
+ this.className = "";
+ }
+
+ @Override
+ protected String getTagOutput(final CKEditorConfig config) {
+ if (config == null || config.isEmpty()) {
+ if (className == null || "".equals(className)) {
+ return "CKEDITOR.replaceAll();";
+ } else {
+ return "CKEDITOR.replaceAll('" + className + "');";
+ }
+ } else {
+ StringBuilder sb = new StringBuilder(
+ "CKEDITOR.replaceAll( function(textarea, config) {\n");
+ if (className == null || "".equals(className)) {
+ sb.append(" var classRegex = new RegExp('(?:^| )' + '");
+ sb.append(className);
+ sb.append("' + '(?:$| )');\n");
+ sb.append(" if (!classRegex.test(textarea.className))\n");
+ sb.append(" return false;\n");
+ }
+ sb.append(" CKEDITOR.tools.extend(config, ");
+ sb.append(TagHelper.jsEncode(config));
+ sb.append(", true);} );");
+ return sb.toString();
+ }
+ }
+
+ /**
+ * @return the className
+ */
+ public final String getClassName() {
+ return className;
+ }
+
+ /**
+ * @param className the className to set
+ */
+ public final void setClassName(final String className) {
+ this.className = className;
+ }
+
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceTag.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceTag.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorReplaceTag.java (revision 6775)
@@ -0,0 +1,53 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+
+/**
+ * <ck:repalce> tag code.
+ * Usage:
+ * <ckeditor:replace replace="editor1" basePath="../../ckeditor/" />
+ */
+public class CKEditorReplaceTag extends CKEditorTag {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1316780332328233835L;
+ private String replace;
+
+ /**
+ * Default constructor.
+ */
+ public CKEditorReplaceTag() {
+ replace = "";
+ }
+
+ @Override
+ protected String getTagOutput(final CKEditorConfig config) {
+ if (config != null && !config.isEmpty()) {
+ return "CKEDITOR.replace('" + replace + "', "
+ + TagHelper.jsEncode(config) + ");";
+ } else {
+ return "CKEDITOR.replace('" + replace + "');";
+ }
+ }
+
+ /**
+ * @return the replace
+ */
+ public final String getReplace() {
+ return replace;
+ }
+
+ /**
+ * @param replace the replace to set
+ */
+ public final void setReplace(final String replace) {
+ this.replace = replace;
+ }
+
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorTag.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorTag.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/CKEditorTag.java (revision 6775)
@@ -0,0 +1,198 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.TagSupport;
+
+/**
+ * Base class for CKEditor tags.
+ */
+public abstract class CKEditorTag extends TagSupport {
+
+ private static final String TIMESTAMP = "B37D54V";
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5642419066547779817L;
+ private String basePath;
+ private String timestamp;
+ private boolean initialized;
+ private CKEditorConfig config;
+ private EventHandler events;
+ private GlobalEventHandler globalEvents;
+
+ /**
+ * Default constructor.
+ */
+ public CKEditorTag() {
+ timestamp = "B37D54V";
+ basePath = "";
+ initialized = false;
+ config = null;
+ events = null;
+ }
+
+
+ @Override
+ public int doEndTag() throws JspException {
+ JspWriter out = pageContext.getOut();
+ try {
+ String output = "";
+ if (!isInitialized()) {
+ out.write(init());
+ }
+ if (globalEvents != null) {
+ output += globalEvents.returnGlobalEvents();
+ }
+ CKEditorConfig cfg = null;
+ if (config != null) {
+ cfg = config.configSettings(this.events);
+ }
+ output += getTagOutput(cfg);
+ out.write(TagHelper.script(output));
+ } catch (Exception e) {
+ try {
+ HttpServletResponse resp = (HttpServletResponse)
+ pageContext.getResponse();
+ resp.reset();
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Problem with creating tag");
+ e.printStackTrace();
+ } catch (IOException e1) {
+ throw new JspException(e1);
+ }
+ }
+ return EVAL_PAGE;
+ }
+
+ /**
+ * Method retruns standard tag output.
+ * @param config config resolved to string
+ * @return tag standard output
+ */
+ protected abstract String getTagOutput(final CKEditorConfig config);
+
+ /**
+ * Init metod for tags.
+ * @return include ckfinder.js code with attributes and additional code.
+ */
+ protected String init() {
+ String out = "";
+ String args = "";
+ String ckeditorPath = basePath;
+ if (timestamp != null) {
+ args += "?t=" + timestamp;
+ }
+ if (ckeditorPath.contains("..")) {
+ out += TagHelper.script("window.CKEDITOR_BASEPATH='" + ckeditorPath + "';");
+ }
+ out += TagHelper.createCKEditorIncJS(ckeditorPath, args);
+
+ String extraCode = "";
+ if (timestamp != TIMESTAMP) {
+ extraCode += (extraCode.length() > 0) ? "\n" : ""
+ .concat("CKEDITOR.timestamp = '")
+ .concat(timestamp)
+ .concat("';");
+ }
+ if (extraCode.length() > 0) {
+ out += extraCode;
+ }
+ return out;
+ }
+
+ /**
+ * @return the basePath
+ */
+ public final String getBasePath() {
+ return basePath;
+ }
+
+ /**
+ * @param basePath the basePath to set
+ */
+ public final void setBasePath(final String basePath) {
+ this.basePath = basePath;
+ }
+
+ /**
+ * @return the timestamp
+ */
+ public final String getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * @param timestamp the timestamp to set
+ */
+ public final void setTimestamp(final String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * @return the initialized
+ */
+ public final boolean isInitialized() {
+ return initialized;
+ }
+
+ /**
+ * @param initialized the initialized to set
+ */
+ public final void setInitialized(final boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ /**
+ * @return the globalEvents
+ */
+ public final GlobalEventHandler getGlobalEvents() {
+ return globalEvents;
+ }
+
+ /**
+ * @param globalEvents the globalEvents to set
+ */
+ public final void setGlobalEvents(final GlobalEventHandler globalEvents) {
+ this.globalEvents = globalEvents;
+ }
+
+
+ /**
+ * @return the config
+ */
+ public final CKEditorConfig getConfig() {
+ return config;
+ }
+
+ /**
+ * @param config the config to set
+ */
+ public final void setConfig(final CKEditorConfig config) {
+ this.config = config;
+ }
+
+ /**
+ * @return the events
+ */
+ public final EventHandler getEvents() {
+ return events;
+ }
+
+ /**
+ * @param events the events to set
+ */
+ public final void setEvents(final EventHandler events) {
+ this.events = events;
+ }
+
+
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/EventHandler.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/EventHandler.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/EventHandler.java (revision 6775)
@@ -0,0 +1,67 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * CKEditor event handler class.
+ * Usage:
+ *
+ EventHandler eventHandler = new EventHandler();
+ eventHandler.addEvent("instanceReady","function (ev) {
+ alert(\"Loaded: \" + ev.editor.name); }");
+
+ */
+public class EventHandler {
+
+ protected Map> events;
+
+ /**
+ * Default constructor.
+ */
+ public EventHandler() {
+ events = new HashMap>();
+ }
+
+ /**
+ * Adds global event listener.
+ * @param event Event name
+ * @param jsCode Javascript anonymous function or function name
+ */
+ public void addEvent(final String event, final String jsCode) {
+ if (events.get(event) == null) {
+ events.put(event, new LinkedHashSet());
+ }
+ events.get(event).add(jsCode);
+ }
+
+ /**
+ * Clear registered global event handlers.
+ * @param event Event name, if null all event handlers will be removed (optional).
+ */
+ public void clearEventHandlers(final String event) {
+ if (event == null) {
+ events = new HashMap>();
+ } else {
+ if (events.get(event) != null) {
+ events.get(event).clear();
+ }
+ }
+ }
+
+ /**
+ * Gets all registered events.
+ * @return all registered events.
+ */
+ public Map> getEvents() {
+ return events;
+ }
+
+}
+
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/GlobalEventHandler.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/GlobalEventHandler.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/GlobalEventHandler.java (revision 6775)
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * CKEditor global events class.
+ * Usage:
+ *
+ GlobalEventHandler globalEventHandler = new GlobalEventHandler();
+ globalEventHandler.addEvent("dialogDefinition","function (ev) {
+ alert(\"Loading dialog: \" + ev.data.name); }");
+
+ */
+public class GlobalEventHandler extends EventHandler {
+
+
+ private static Map> returndEvents;
+
+ /**
+ * Resolves global events to String.
+ * @return global events resolved to String.
+ */
+ String returnGlobalEvents() {
+ String out = "";
+ if (returndEvents == null) {
+ returndEvents = new HashMap>();
+ }
+ for (String event : events.keySet()) {
+ for (String code : events.get(event)) {
+ if (returndEvents.get(event) == null) {
+ returndEvents.put(event, new LinkedHashSet());
+ }
+ out += (!code.equals("") ? "\n" : "")
+ + "CKEDITOR.on('" + event + "', " + code + ");";
+ returndEvents.get(event).add(code);
+
+ }
+ }
+ return out;
+ }
+
+}
Index: /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/TagHelper.java
===================================================================
--- /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/TagHelper.java (revision 6775)
+++ /CKEditor.Java/ckeditor-java-core/trunk/src/main/java/com/ckeditor/TagHelper.java (revision 6775)
@@ -0,0 +1,187 @@
+/*
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see http://ckeditor.com/license
+*/
+package com.ckeditor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Helper class for CKEditor tags.
+ */
+public class TagHelper {
+
+ private static final String[] CHARS_FROM
+ = {"\\", "/", "\n", "\t", "\r", "\0c", "\0c", "\""};
+ private static final String[] CHARS_TO
+ = {"\\\\", "\\/", "\\\n", "\\\t", "\\\r", "\\\b", "\\\f", "\\\""};
+
+ /**
+ * Wrap string with javascript tag.
+ * @param input input string
+ * @return input wrapped with javascript tag
+ */
+ public static String script(final String input) {
+ String out = "\n";
+ return out;
+ }
+
+ /**
+ * Creates javascript code for include ckeditor.js.
+ * @param basePath ckeditor base path
+ * @param args script agruments.
+ * @return javascript code
+ */
+ public static String createCKEditorIncJS(final String basePath, final String args) {
+ return "\n";
+ }
+
+ /**
+ * Provides a basic JSON support.
+ * @param o object to encode
+ * @return encoded config object value
+ */
+ @SuppressWarnings("unchecked")
+ public static String jsEncode(final Object o) {
+ if (o == null) {
+ return "null";
+ }
+ if (o instanceof String) {
+ return jsEncode((String) o);
+ }
+ if (o instanceof Number) {
+ return jsEncode((Number) o);
+ }
+ if (o instanceof Boolean) {
+ return jsEncode((Boolean) o);
+ }
+ if (o instanceof Map) {
+ return jsEncode((Map) o);
+ }
+ if (o instanceof List) {
+ return jsEncode((List