001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.ui.input.tinymce;
029
030import org.opencms.gwt.client.CmsCoreProvider;
031import org.opencms.util.CmsStringUtil;
032import org.opencms.workplace.editors.CmsTinyMceToolbarHelper;
033
034import java.util.ArrayList;
035import java.util.List;
036
037import com.google.gwt.core.client.JavaScriptObject;
038import com.google.gwt.core.client.JsArray;
039
040/**
041 * Helper class for dealing wth TinyMCE widgets.<p>
042 */
043public final class CmsTinyMCEHelper {
044
045    /**
046     * Hidden default constructor.<p>
047     */
048    private CmsTinyMCEHelper() {
049
050        // nothing here
051    }
052
053    /**
054     * Generate options for TinyMCE.<p>
055     *
056     * @param configuration the widget configuration generated by the server
057     *
058     * @return the TinyMCE configuration
059     */
060    public static JavaScriptObject generateOptionsForTiny(String configuration) {
061
062        return generateOptionsForTiny(configuration, getCodeMirrorPath());
063    }
064
065    /**
066    * Generates the tinyMCE editor options according to the configuration.<p>
067    *
068    * @param configuration the widget configuration
069    * @param codeMirrorPath the path to the CodeMirror editor
070    *
071    * @return the tinyMCE options
072    */
073    public static native JavaScriptObject generateOptionsForTiny(String configuration, String codeMirrorPath)/*-{
074
075                var options = null;
076                try {
077                        var config = @org.opencms.gwt.client.util.CmsDomUtil::parseJSON(Ljava/lang/String;)(configuration);
078                        options = {
079                                entity_encoding : 'named',
080                                entities : '160,nbsp',
081                                // the browser call back function is defined in /system/workplace/editors/tinymce/opencms_plugin.js
082                                file_picker_callback : $wnd.cmsTinyMceFileBrowser
083                        };
084                        if (config.downloadGalleryConfig) {
085                                options.downloadGalleryConfig = config.downloadGalleryConfig;
086                        }
087
088                        if (config.imageGalleryConfig) {
089                                options.imageGalleryConfig = config.imageGalleryConfig;
090                        }
091
092                        if (config.content_css) {
093                                options.content_css = config.content_css;
094                        }
095                        options.importcss_append = true;
096                        if (config.importCss) {
097                                options.importcss_selector_filter = ""; // always matches
098                        } else {
099                                options.importcss_selector_filter = new $wnd.RegExp("$.^"); // never matches
100                        }
101                        if (config.height) {
102                                var height = parseInt(config.height);
103                                if (height != NaN) {
104                                        options.editorHeight = height;
105                                }
106                        }
107                        if (config.block_formats) {
108                                options.block_formats = config.block_formats;
109                        }
110                        if (config.style_formats) {
111                                var temp = null;
112                                try {
113                                        temp = eval('(' + config.style_formats + ')');
114                                } catch (error) {
115                                        $wnd.alert("Could not parse WYSIWYG editor options: "
116                                                        + error);
117                                }
118                                if (typeof temp != 'undefined' && temp != null) {
119                                        options.style_formats = temp;
120                                }
121                        }
122                        if (config.cmsGalleryEnhancedOptions) {
123                                options.cmsGalleryEnhancedOptions = config.cmsGalleryEnhancedOptions;
124                        }
125                        if (config.cmsGalleryUseThickbox) {
126                                options.cmsGalleryUseThickbox = config.cmsGalleryUseThickbox;
127                        }
128                        options.plugins = "anchor charmap importcss autolink lists pagebreak table save hr codemirror image link emoticons insertdatetime preview media searchreplace print paste directionality fullscreen noneditable visualchars nonbreaking template wordcount advlist spellchecker -opencms";
129                        options.preview_styles="font-family font-size font-weight font-style text-decoration text-transform border border-radius outline text-shadow";
130                        if (config.fullpage) {
131                                options.plugins += " fullpage";
132                        }
133                        // add codemirror source view plugin configuration
134                        options.codemirror = {
135                                indentOnInit : true, // whether or not to indent code on init.
136                                path : @org.opencms.gwt.client.ui.input.tinymce.CmsTinyMCEHelper::getCodeMirrorPath()(), // path to CodeMirror distribution
137                                config : { // CodeMirror config object
138                                        lineNumbers : true
139                                }
140                        };
141                        if (config.allowscripts) {
142                                options.valid_elements = "*[*]";
143                                options.allow_script_urls = true;
144                        }
145                        if (config.link_default_protocol) {
146                                options.link_default_protocol = config.link_default_protocol;
147                        }
148                        if (config.toolbar_items) {
149                                toolbarGroup = @org.opencms.gwt.client.ui.input.tinymce.CmsTinyMCEHelper::createToolbar(Lcom/google/gwt/core/client/JavaScriptObject;)(config.toolbar_items);
150                                toolbarGroup += " | spellchecker";
151                                options.toolbar1 = toolbarGroup;
152                                var contextmenu = @org.opencms.gwt.client.ui.input.tinymce.CmsTinyMCEHelper::createContextMenu(Lcom/google/gwt/core/client/JavaScriptObject;)(config.toolbar_items);
153
154                                if (config.spellcheck_url) {
155                                        options.spellchecker_language = config.spellcheck_language;
156                                        options.spellchecker_languages = config.spellcheck_language;
157                                        options.spellchecker_rpc_url = config.spellcheck_url;
158                                        options.spellchecker_callback = function(name, text,
159                                                        onSuccess, onFailure) {
160                                                $wnd.tinymce.util.JSONRequest.sendRPC({
161                                                        url : config.spellcheck_url,
162                                                        method : "spellcheck",
163                                                        params : {
164                                                                lang : this.getLanguage(),
165                                                                words : text.match(this.getWordCharPattern())
166                                                        },
167                                                        success : function(result) {
168                                                                onSuccess({
169                                                                        words : result
170                                                                });
171                                                        },
172                                                        error : function(error, xhr) {
173                                                                onFailure("Spellcheck error:" + xhr.status);
174                                                        }
175                                                });
176                                        };
177                                        contextmenu += " spellchecker"
178                                }
179                                if (contextmenu != "") {
180                                        options.contextmenu = contextmenu;
181                                }
182                                if (config.pasteOptions) {
183                                        options.paste_as_text = config.pasteOptions.paste_text_sticky_default ? true
184                                                        : false;
185                                }
186                                if (config.directOptions) {
187                                    for (var key in config.directOptions) {
188                                        options[key] = config.directOptions[key];
189                                    }
190                                }
191                        }
192
193                } catch (e) {
194                        // nothing to do
195                }
196
197                return options;
198    }-*/;
199
200    /**
201     * Returns the code mirror path.<p>
202     *
203     * @return the code mirror resource path
204     */
205    public static String getCodeMirrorPath() {
206
207        return CmsStringUtil.joinPaths(CmsCoreProvider.get().getWorkplaceResourcesPrefix(), "editors/codemirror/dist/");
208    }
209
210    /**
211     * Creates the TinyMCE toolbar config string from a Javascript config object.<p>
212     *
213     * @param jso a Javascript array of toolbar items
214     *
215     * @return the TinyMCE toolbar config string
216     */
217    protected static String createContextMenu(JavaScriptObject jso) {
218
219        JsArray<?> jsItemArray = jso.<JsArray<?>> cast();
220        List<String> jsItemList = new ArrayList<String>();
221        for (int i = 0; i < jsItemArray.length(); i++) {
222            jsItemList.add(jsItemArray.get(i).toString());
223        }
224        return CmsTinyMceToolbarHelper.getContextMenuEntries(jsItemList);
225    }
226
227    /**
228     * Creates the TinyMCE toolbar config string from a Javascript config object.<p>
229     *
230     * @param jso a Javascript array of toolbar items
231     *
232     * @return the TinyMCE toolbar config string
233     */
234    protected static String createToolbar(JavaScriptObject jso) {
235
236        JsArray<?> jsItemArray = jso.<JsArray<?>> cast();
237        List<String> jsItemList = new ArrayList<String>();
238        for (int i = 0; i < jsItemArray.length(); i++) {
239            jsItemList.add(jsItemArray.get(i).toString());
240        }
241        return CmsTinyMceToolbarHelper.createTinyMceToolbarStringFromGenericToolbarItems(jsItemList);
242    }
243
244}