001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 016 * 017 * $Id: HtmlEditorRenderer.java 28610 2008-01-09 17:13:52Z sfermigier $ 018 */ 019 020package org.nuxeo.ecm.platform.ui.web.component.editor; 021 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Locale; 027import java.util.Map; 028 029import javax.faces.component.UIComponent; 030import javax.faces.component.UIInput; 031import javax.faces.context.FacesContext; 032import javax.faces.context.ResponseWriter; 033 034import org.apache.commons.lang.StringUtils; 035import org.nuxeo.ecm.platform.ui.web.htmleditor.api.HtmlEditorPluginService; 036import org.nuxeo.runtime.api.Framework; 037 038import com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer; 039 040/** 041 * Renderer for html editor component. 042 * <p> 043 * Uses TinyMCE javascript editor. 044 * 045 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 046 */ 047public class HtmlEditorRenderer extends HtmlBasicInputRenderer { 048 049 private static Map<String, String> pluginsOptions; 050 051 private static Map<String, String> toolbarPluginsOptions; 052 053 @Override 054 public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 055 if (!component.isRendered()) { 056 return; 057 } 058 059 UIHtmlEditor editorComp = (UIHtmlEditor) component; 060 ResponseWriter writer = context.getResponseWriter(); 061 Locale locale = context.getViewRoot().getLocale(); 062 063 // tiny MCE generic scripts now included in every page header 064 065 // script to actually init tinyMCE with configured options 066 String editorSelector = editorComp.getEditorSelector(); 067 // plugins registration 068 if (pluginsOptions == null) { 069 final HtmlEditorPluginService pluginService = Framework.getLocalService(HtmlEditorPluginService.class); 070 pluginsOptions = new HashMap<String, String>(); 071 pluginsOptions.put("plugins", pluginService.getFormattedPluginsNames()); 072 toolbarPluginsOptions = new HashMap<String, String>(); 073 toolbarPluginsOptions.put("toolbar", pluginService.getFormattedToolbarsButtonsNames()); 074 } 075 076 String clientId = editorComp.getClientId(context); 077 boolean disableHtmlInit = Boolean.TRUE.equals(editorComp.getDisableHtmlInit()); 078 079 // input text area 080 writer.startElement("textarea", editorComp); 081 writer.writeAttribute("id", clientId, null); 082 writer.writeAttribute("name", clientId, null); 083 if (Boolean.TRUE.equals(editorComp.getDisableHtmlInit())) { 084 writer.writeAttribute("class", editorSelector + ",disableMCEInit", null); 085 } else { 086 writer.writeAttribute("class", editorSelector, null); 087 } 088 writer.writeAttribute("rows", editorComp.getRows(), null); 089 writer.writeAttribute("cols", editorComp.getCols(), null); 090 Object currentValue = getCurrentValue(editorComp); 091 if (currentValue != null) { 092 writer.writeText(currentValue, null); 093 } else { 094 writer.writeText("", null); 095 } 096 writer.endElement("textarea"); 097 098 if (!disableHtmlInit) { 099 writer.startElement("script", editorComp); 100 writer.writeAttribute("type", "text/javascript", null); 101 // Since 5.7.3, use unique clientId instead of editorSelector value 102 // so that tiny mce editors are initialized individually: no need 103 // anymore to specify a class to know which one should or should 104 // not be initialized 105 String scriptContent = String.format("initTinyMCE(%s, %s, '%s', '%s', '%s', '%s');", editorComp.getWidth(), 106 editorComp.getHeight(), clientId, pluginsOptions.get("plugins"), locale.getLanguage(), 107 toolbarPluginsOptions.get("toolbar")); 108 writer.writeText(scriptContent, null); 109 String ajaxScriptContent = String.format( 110 "jsf.ajax.addOnEvent(function(data) {if (data.status == \"success\") {%s}});", scriptContent); 111 writer.writeText(ajaxScriptContent, null); 112 String scriptContent2 = String.format( 113 "jQuery(document.getElementById('%s')).closest('form').bind('ajaxsubmit', function() { var editor = tinyMCE.editors['%s']; if (editor != undefined) {editor.save()};});", 114 clientId, clientId); 115 writer.writeText(scriptContent2, null); 116 writer.endElement("script"); 117 } 118 119 writer.flush(); 120 } 121 122 protected static Object getCurrentValue(UIInput comp) { 123 Object submitted = comp.getSubmittedValue(); 124 if (submitted != null) { 125 return submitted; 126 } 127 return comp.getValue(); 128 } 129 130 protected static String generateOptions(Map<String, String> options) { 131 List<String> strOptions = new ArrayList<String>(); 132 for (Map.Entry<String, String> option : options.entrySet()) { 133 strOptions.add(String.format("%s : \"%s\"", option.getKey(), option.getValue())); 134 } 135 StringBuilder res = new StringBuilder(); 136 res.append('{'); 137 res.append(StringUtils.join(strOptions.toArray(), ", ")); 138 res.append('}'); 139 return res.toString(); 140 } 141 142}