001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/tags/sakai_2-4-1/samigo-app/src/java/org/sakaiproject/jsf/renderer/RichTextEditArea.java $
003: * $Id: RichTextEditArea.java 28714 2007-04-12 00:23:01Z ajpoland@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.jsf.renderer;
021:
022: import java.io.IOException;
023: import java.util.Map;
024: import java.util.regex.Pattern;
025:
026: import javax.faces.component.UIComponent;
027: import javax.faces.component.UIInput;
028: import javax.faces.component.ValueHolder;
029: import javax.faces.context.FacesContext;
030: import javax.faces.context.ResponseWriter;
031: import javax.faces.render.Renderer;
032:
033: import org.sakaiproject.component.cover.ServerConfigurationService;
034: import org.sakaiproject.tool.cover.ToolManager;
035: import org.sakaiproject.content.cover.ContentHostingService;
036: import org.sakaiproject.util.FormattedText;
037: import org.sakaiproject.util.ResourceLoader;
038:
039: /**
040: *
041: * <p>Quick port of the Sakai rich text editor from htmlarea to FCKeditor </p>
042: * <p>Slight differences in path definition </p>
043: * <p>Copyright: Copyright (c) 2004 Sakai</p>
044: * <p> </p>
045: * @author cwen@iu.edu
046: * @author Ed Smiley esmiley@stanford.edu (modifications)
047: * @author Joshua Ryan joshua.ryan@asu.edu (added FCKEditor)
048: * @version $Id: RichTextEditArea.java 28714 2007-04-12 00:23:01Z ajpoland@iupui.edu $
049: */
050: public class RichTextEditArea extends Renderer {
051: //FCK config paths
052: private static final String FCK_BASE = "/library/editor/FCKeditor/";
053: private static final String FCK_SCRIPT = "fckeditor.js";
054:
055: //htmlarea script path
056: private static final String SCRIPT_PATH = "/jsf/widget/wysiwyg/htmlarea/";
057:
058: public boolean supportsComponentType(UIComponent component) {
059: return (component instanceof org.sakaiproject.jsf.component.RichTextEditArea);
060: }
061:
062: public void encodeBegin(FacesContext context, UIComponent component)
063: throws IOException {
064: String editor = ServerConfigurationService
065: .getString("wysiwyg.editor");
066:
067: String clientId = component.getClientId(context);
068:
069: String contextPath = context.getExternalContext()
070: .getRequestContextPath()
071: + SCRIPT_PATH;
072:
073: ResponseWriter writer = context.getResponseWriter();
074:
075: Object value = null;
076: if (component instanceof UIInput) {
077: value = ((UIInput) component).getSubmittedValue();
078: }
079: if (value == null && component instanceof ValueHolder) {
080: value = ((ValueHolder) component).getValue();
081:
082: }
083:
084: boolean valueHasRichText = false;
085: if ((String) value != null) {
086: String valueNoNewLine = ((String) value).replaceAll("\\n",
087: "").replaceAll("\\r", "");
088: //really simple regex to detect presence of any html tags in the value
089: valueHasRichText = Pattern.compile(".*<.*?>.*",
090: Pattern.CASE_INSENSITIVE).matcher(valueNoNewLine)
091: .matches();
092: //valueHasRichText = Pattern.compile(".*(<)[^\n^<]+(>).*", Pattern.CASE_INSENSITIVE).matcher((String) value).matches();
093: }
094: String hasToggle = (String) component.getAttributes().get(
095: "hasToggle");
096:
097: //fixes SAK-3116, I'm not sure if this logic really belongs in a renderer, but it
098: //need to happen before the wysiwig is written or the editor tries to be too smart
099: value = FormattedText
100: .escapeHtmlFormattedTextarea((String) value);
101:
102: String tmpCol = (String) component.getAttributes().get(
103: "columns");
104: String tmpRow = (String) component.getAttributes().get("rows");
105: int col;
106: int row;
107: if (tmpCol != null) {
108: col = new Integer(tmpCol).intValue();
109: } else {
110: col = 450;
111: }
112: if (tmpRow != null) {
113: row = new Integer(tmpRow).intValue();
114: } else {
115: row = 80;
116:
117: }
118: String outCol;
119: String outRow;
120: int lineOfToolBar;
121: if ((row < 80) && (col < 450)) {
122: outRow = "80";
123: outCol = "450";
124: lineOfToolBar = 3;
125: } else if ((row >= 80) && (col < 450)) {
126: outRow = Integer.toString(row);
127: outCol = "450";
128: lineOfToolBar = 3;
129: } else if ((row >= 80) && (col >= 450) && (col < 630)) {
130: outRow = Integer.toString(row);
131: outCol = Integer.toString(col);
132: lineOfToolBar = 3;
133: } else if ((row >= 80) && (col >= 630)) {
134: outRow = Integer.toString(row);
135: outCol = Integer.toString(col);
136: lineOfToolBar = 2;
137: } else if ((row < 80) && (col >= 630)) {
138: outRow = "80";
139: outCol = Integer.toString(col);
140: lineOfToolBar = 2;
141: } else {
142: outRow = "80";
143: outCol = new Integer(col).toString();
144: lineOfToolBar = 3;
145: }
146:
147: String justArea = (String) component.getAttributes().get(
148: "justArea");
149:
150: if (editor.equals("FCKeditor")) {
151: encodeFCK(writer, contextPath, (String) value, outCol,
152: outRow, justArea, clientId, valueHasRichText,
153: hasToggle);
154: } else {
155: encodeHtmlarea(writer, contextPath, (String) value, outCol
156: + "px", outRow + "px", tmpCol, tmpRow,
157: lineOfToolBar, justArea, clientId);
158: }
159: }
160:
161: private void encodeHtmlarea(ResponseWriter writer,
162: String contextPath, String value, String outCol,
163: String outRow, String tmpCol, String tmpRow,
164: int lineOfToolBar, String justArea, String clientId)
165: throws IOException {
166:
167: writer
168: .write("<script type=\"text/javascript\">var _editor_url = \""
169: + contextPath + "\";</script>\n");
170: writer.write("<script type=\"text/javascript\" src=\""
171: + contextPath + "htmlarea.js\"></script>\n");
172: writer.write("<script type=\"text/javascript\" src=\""
173: + contextPath + "dialog.js\"></script>\n");
174: writer.write("<script type=\"text/javascript\" src=\""
175: + contextPath + "popupwin.js\"></script>\n");
176: writer.write("<script type=\"text/javascript\" src=\""
177: + contextPath + "lang/en.js\"></script>\n");
178:
179: if ((justArea != null) && (justArea.equals("yes"))) {
180: writer.write("<textarea name=\"");
181: writer.write(clientId);
182: writer.write("_textinput\" id=\"");
183: writer.write(clientId);
184: writer.write("_textinput\" disabled>");
185: writer.write((String) value);
186: writer.write("</textarea>\n");
187: if ((tmpCol != null) && (tmpRow != null)) {
188: writer
189: .write("<script type=\"text/javascript\">var config=new HTMLArea.Config();");
190: writer.write("config.toolbar=[];config.width=\'");
191: writer.write(tmpCol);
192: writer.write("px\';config.height=\'");
193: writer.write(tmpRow);
194: writer.write("px\';");
195:
196: writer.write("var editor = HTMLArea.replace(\'");
197: writer.write(clientId);
198: writer.write("_textinput\',config);\n");
199:
200: writer.write(" if(document.htmlareas==undefined)");
201: writer.write(" {");
202: writer.write(" document.htmlareas = new Array();");
203: writer.write(" }");
204: writer
205: .write(" var counter = document.htmlareas.length;");
206: writer.write(" var textareaId = '" + clientId
207: + "_textinput';");
208: writer
209: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
210: writer.write("</script>\n");
211: } else if (tmpCol != null) {
212: writer
213: .write("<script type=\"text/javascript\">var config=new HTMLArea.Config();");
214: writer.write("config.toolbar=[];config.width=\'");
215: writer.write(tmpCol);
216: writer.write("px\';config.height=\'200px\';");
217: writer.write("var editor = HTMLArea.replace(\'");
218: writer.write(clientId);
219: writer.write("_textinput\',config);\n");
220:
221: writer.write(" if(document.htmlareas==undefined)");
222: writer.write(" {");
223: writer.write(" document.htmlareas = new Array();");
224: writer.write(" }");
225: writer
226: .write(" var counter = document.htmlareas.length;");
227: writer.write(" var textareaId = '" + clientId
228: + "_textinput';");
229: writer
230: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
231: writer.write("</script>\n");
232: } else {
233: writer
234: .write("<script type=\"text/javascript\">var config=new HTMLArea.Config();");
235: writer
236: .write("config.toolbar=[];config.width=\'400px\';config.height=\'100px\';");
237: writer.write("var editor = HTMLArea.replace(\'");
238: writer.write("_textinput\',config);\n");
239:
240: writer.write(" if(document.htmlareas==undefined)");
241: writer.write(" {");
242: writer.write(" document.htmlareas = new Array();");
243: writer.write(" }");
244: writer
245: .write(" var counter = document.htmlareas.length;");
246: writer.write(" var textareaId = '" + clientId
247: + "_textinput';");
248: writer
249: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
250: writer.write("</script>\n");
251: }
252: } else {
253: if (value == null) {
254: writer.write("<textarea name=\"");
255: writer.write(clientId);
256: writer.write("_textinput\" id=\"");
257: writer.write(clientId);
258: writer.write("_textinput\"");
259: writer.write("></textarea>\n");
260:
261: if (lineOfToolBar == 3) {
262: writer
263: .write("<script type=\"text/javascript\"> var config=new HTMLArea.Config();");
264: writer
265: .write("config.toolbar = [[\'fontname\', \'space\',\'fontsize\', \'space\',\'formatblock\', \'space\',\'bold\', \'italic\', \'underline\'],");
266: writer
267: .write("[\'separator\',\'strikethrough\', \'subscript\', \'superscript\', \'separator\', \'space\', \'undo\', \'redo\', \'separator\', \'justifyleft\', \'justifycenter\', \'justifyright\', \'justifyfull\', \'separator\',\'outdent\', \'indent\'],");
268: writer
269: .write("[\'separator\',\'forecolor\', \'hilitecolor\', \'textindicator\', \'separator\',\'inserthorizontalrule\', \'createlink\', \'insertimage\', \'separator\', \'showhelp\', \'about\' ],");
270: writer.write("];config.width=\'");
271: writer.write(outCol);
272: writer.write("\';config.height=\'");
273: writer.write(outRow);
274: writer.write("\';var editor = HTMLArea.replace(\'");
275: writer.write(clientId);
276: writer.write("_textinput\',config);\n");
277:
278: writer.write(" if(document.htmlareas==undefined)");
279: writer.write(" {");
280: writer
281: .write(" document.htmlareas = new Array();");
282: writer.write(" }");
283: writer
284: .write(" var counter = document.htmlareas.length;");
285: writer.write(" var textareaId = '" + clientId
286: + "_textinput';");
287: writer
288: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
289: writer.write("</script>\n");
290:
291: } else {
292: writer
293: .write("<script type=\"text/javascript\">var config=new HTMLArea.Config();");
294: writer
295: .write("config.toolbar = [[\'fontname\', \'space\',\'fontsize\', \'space\',\'formatblock\', \'space\',\'bold\', \'italic\', \'underline\',\'separator\',\'strikethrough\', \'subscript\', \'superscript\', \'separator\', \'space\', \'undo\', \'redo\'],");
296: writer
297: .write("[\'separator\', \'justifyleft\', \'justifycenter\', \'justifyright\', \'justifyfull\', \'separator\',\'outdent\', \'indent\',\'separator\',\'forecolor\', \'hilitecolor\', \'textindicator\', \'separator\',\'inserthorizontalrule\', \'createlink\', \'insertimage\', \'separator\', \'showhelp\', \'about\' ],");
298: writer.write("];config.width=\'");
299: writer.write(outCol);
300: writer.write("\';config.height=\'");
301: writer.write(outRow);
302: writer.write("\';var editor = HTMLArea.replace(\'");
303: writer.write(clientId);
304: writer.write("_textinput\',config);\n");
305:
306: writer.write(" if(document.htmlareas==undefined)");
307: writer.write(" {");
308: writer
309: .write(" document.htmlareas = new Array();");
310: writer.write(" }");
311: writer
312: .write(" var counter = document.htmlareas.length;");
313: writer.write(" var textareaId = '" + clientId
314: + "_textinput';");
315: writer
316: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
317: writer.write("</script>\n");
318: }
319: } else {
320: writer.write("<textarea name=\"");
321: writer.write(clientId);
322: writer.write("_textinput\" id=\"");
323: writer.write(clientId);
324: writer.write("_textinput\">");
325: writer.write((String) value);
326: writer.write("</textarea>\n");
327: if (lineOfToolBar == 3) {
328: writer
329: .write("<script type=\"text/javascript\"> var config=new HTMLArea.Config();");
330: writer
331: .write("config.toolbar = [[\'fontname\', \'space\',\'fontsize\', \'space\',\'formatblock\', \'space\',\'bold\', \'italic\', \'underline\'],");
332: writer
333: .write("[\'separator\',\'strikethrough\', \'subscript\', \'superscript\', \'separator\', \'space\', \'undo\', \'redo\', \'separator\', \'justifyleft\', \'justifycenter\', \'justifyright\', \'justifyfull\', \'separator\',\'outdent\', \'indent\'],");
334: writer
335: .write("[\'separator\',\'forecolor\', \'hilitecolor\', \'textindicator\', \'separator\',\'inserthorizontalrule\', \'createlink\', \'insertimage\', \'separator\', \'showhelp\', \'about\' ],");
336: writer.write("];config.width=\'");
337: writer.write(outCol);
338: writer.write("\';config.height=\'");
339: writer.write(outRow);
340: writer.write("\';var editor = HTMLArea.replace(\'");
341: writer.write(clientId);
342: writer.write("_textinput\',config);\n");
343:
344: writer.write(" if(document.htmlareas==undefined)");
345: writer.write(" {");
346: writer
347: .write(" document.htmlareas = new Array();");
348: writer.write(" }");
349: writer
350: .write(" var counter = document.htmlareas.length;");
351: writer.write(" var textareaId = '" + clientId
352: + "_textinput';");
353: writer
354: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
355: writer.write("</script>\n");
356:
357: } else {
358: writer
359: .write("<script type=\"text/javascript\">var config=new HTMLArea.Config();");
360: writer
361: .write("config.toolbar = [[\'fontname\', \'space\',\'fontsize\', \'space\',\'formatblock\', \'space\',\'bold\', \'italic\', \'underline\',\'separator\',\'strikethrough\', \'subscript\', \'superscript\', \'separator\', \'space\', \'undo\', \'redo\'],");
362: writer
363: .write("[\'separator\', \'justifyleft\', \'justifycenter\', \'justifyright\', \'justifyfull\', \'separator\',\'outdent\', \'indent\',\'separator\',\'forecolor\', \'hilitecolor\', \'textindicator\', \'separator\',\'inserthorizontalrule\', \'createlink\', \'insertimage\', \'separator\', \'showhelp\', \'about\' ],");
364: writer.write("];config.width=\'");
365: writer.write(outCol);
366: writer.write("\';");
367: writer.write("config.height=\'");
368: writer.write(outRow);
369: writer.write("\';var editor = HTMLArea.replace(\'");
370: writer.write(clientId);
371: writer.write("_textinput\',config);\n");
372:
373: writer.write(" if(document.htmlareas==undefined)");
374: writer.write(" {");
375: writer
376: .write(" document.htmlareas = new Array();");
377: writer.write(" }");
378: writer
379: .write(" var counter = document.htmlareas.length;");
380: writer.write(" var textareaId = '" + clientId
381: + "_textinput';");
382: writer
383: .write(" document.htmlareas[counter] = new Array(textareaId, editor, false);");
384: writer.write("</script>\n");
385: }
386: }
387: }
388: }
389:
390: private void encodeFCK(ResponseWriter writer, String contextPath,
391: String value, String outCol, String outRow,
392: String justArea, String clientId, boolean valueHasRichText,
393: String hasToggle) throws IOException {
394: //come up w/ rows/cols for the textarea if needed
395: int textBoxRows = (new Integer(outRow).intValue() / 20);
396: int textBoxCols = (new Integer(outRow).intValue() / 3);
397:
398: ResourceLoader rb = new ResourceLoader(
399: "org.sakaiproject.tool.assessment.bundle.AuthorMessages");
400: //fck's tool bar can get pretty big
401: if (new Integer(outRow).intValue() < 300) {
402: outRow = (new Integer(outRow).intValue() + 100) + "";
403: }
404:
405: //figure out if the toggle should be on
406: boolean shouldToggle = ((hasToggle != null)
407: && (hasToggle.equals("yes")) && !valueHasRichText);
408:
409: if (shouldToggle) {
410: //String show_hide_editor = (String) ContextUtil.getLocalizedString(
411: // "org.sakaiproject.tool.assessment.bundle.AuthorMessages", "show_hide_editor");
412: String show_hide_editor = rb.getString("show_hide_editor");
413: writer
414: .write("<div class=\"toggle_link_container\"><a class=\"toggle_link\" id=\""
415: + clientId
416: + "_toggle\" href=\"javascript:show_hide_editor('"
417: + clientId
418: + "');\">"
419: + show_hide_editor
420: + "</a></div>\n");
421: }
422:
423: writer.write("<textarea name=\"" + clientId
424: + "_textinput\" id=\"" + clientId
425: + "_textinput\" rows=\"" + textBoxRows + "\" cols=\""
426: + textBoxCols + "\" class=\"simple_text_area\">");
427: writer.write((String) value);
428: writer.write("</textarea>");
429: writer.write("<input type=\"hidden\" name=\"" + clientId
430: + "_textinput_current_status\" id=\"" + clientId
431: + "_textinput_current_status\" value=\"firsttime\">");
432:
433: writer.write("\n\t<script type=\"text/javascript\" src=\""
434: + FCK_BASE + FCK_SCRIPT + "\"></script>");
435:
436: writer
437: .write("<script type=\"text/javascript\" language=\"JavaScript\">\n");
438:
439: writer.write("\nfunction show_hide_editor(client_id){");
440: writer
441: .write("\n\tvar status = document.getElementById(client_id + '_textinput_current_status');");
442: writer.write("\n\tif (status.value == \"firsttime\") {");
443: writer.write("\n\t\tstatus.value = \"expaneded\";");
444: writer
445: .write("\n\t\tchef_setupformattedtextarea(client_id, true);\n\t}");
446: writer.write("\n\telse if (status.value == \"collapsed\") {");
447: writer.write("\n\t\tstatus.value = \"expaneded\";");
448: writer.write("\n\t\texpandMenu(client_id);\n\t}");
449: writer.write("\n\telse if (status.value == \"expaneded\") {");
450: writer.write("\n\t\tstatus.value = \"collapsed\";");
451: writer.write("\n\t\tcollapseMenu(client_id);\n\t}");
452: writer.write("\n}\n");
453:
454: writer
455: .write("function chef_setupformattedtextarea(client_id,shouldToggle){\n");
456:
457: writer
458: .write("\tvar textarea_id = client_id + \"_textinput\";\n");
459:
460: //if toggling is on, hide the toggle when the user goes to richText
461: //writer.write("\tif(shouldToggle){\n");
462: //writer.write("\t\tvar toggle_id = client_id + \"_toggle\";\n");
463: //writer.write("\tvar oToggleDiv = document.getElementById(toggle_id);\n");
464: //writer.write("\toToggleDiv.style.display=\"none\";\n");
465: //writer.write("\t}\n");
466:
467: writer.write("var oFCKeditor = new FCKeditor(textarea_id);\n");
468: writer.write("\n\toFCKeditor.BasePath = \"" + FCK_BASE + "\";");
469: writer.write("\n\toFCKeditor.Height = " + outRow + ";");
470: writer.write("\n\n\toFCKeditor.Width = " + outCol + ";");
471:
472: if ((justArea != null) && (justArea.equals("yes"))) {
473: writer.write("\n\toFCKeditor.ToolbarSet = \"plain\";");
474: } else {
475:
476: String connector = "/sakai-fck-connector/web/editor/filemanager/browser/default/connectors/jsp/connector";
477: String collectionId = ContentHostingService
478: .getSiteCollection(ToolManager
479: .getCurrentPlacement().getContext());
480:
481: if ("archival".equals(ServerConfigurationService
482: .getString("tags.focus")))
483: writer
484: .write("\n\toFCKeditor.Config['CustomConfigurationsPath'] = \"/library/editor/FCKeditor/archival_config.js\";\n");
485: else {
486: writer.write("\n\t\tvar courseId = \"" + collectionId
487: + "\";");
488: writer
489: .write("\n\toFCKeditor.Config['ImageBrowserURL'] = oFCKeditor.BasePath + "
490: + "\"editor/filemanager/browser/default/browser.html?Connector="
491: + connector
492: + "&Type=Image&CurrentFolder=\" + courseId;");
493: writer
494: .write("\n\toFCKeditor.Config['LinkBrowserURL'] = oFCKeditor.BasePath + "
495: + "\"editor/filemanager/browser/default/browser.html?Connector="
496: + connector
497: + "&Type=Link&CurrentFolder=\" + courseId;");
498: writer
499: .write("\n\toFCKeditor.Config['FlashBrowserURL'] = oFCKeditor.BasePath + "
500: + "\"editor/filemanager/browser/default/browser.html?Connector="
501: + connector
502: + "&Type=Flash&CurrentFolder=\" + courseId;");
503: writer
504: .write("\n\toFCKeditor.Config['ImageUploadURL'] = oFCKeditor.BasePath + "
505: + "\""
506: + connector
507: + "?Type=Image&Command=QuickUpload&Type=Image&CurrentFolder=\" + courseId;");
508: writer
509: .write("\n\toFCKeditor.Config['FlashUploadURL'] = oFCKeditor.BasePath + "
510: + "\""
511: + connector
512: + "?Type=Flash&Command=QuickUpload&Type=Flash&CurrentFolder=\" + courseId;");
513: writer
514: .write("\n\toFCKeditor.Config['LinkUploadURL'] = oFCKeditor.BasePath + "
515: + "\""
516: + connector
517: + "?Type=File&Command=QuickUpload&Type=Link&CurrentFolder=\" + courseId;");
518:
519: writer
520: .write("\n\n\toFCKeditor.Config['CurrentFolder'] = courseId;");
521:
522: writer
523: .write("\n\toFCKeditor.Config['CustomConfigurationsPath'] = \"/library/editor/FCKeditor/config.js\";\n");
524:
525: }
526:
527: }
528: writer.write("\n\tdocument.wysiwyg = \"FCKeditor\";");
529: writer.write("\n\n\toFCKeditor.ReplaceTextarea();\n\t}\n");
530:
531: writer.write("\nfunction collapseMenu(client_id){");
532: writer
533: .write("\n\tvar editor = FCKeditorAPI.GetInstance(client_id + '_textinput');");
534: writer.write("\n\teditor.ToolbarSet.Collapse();");
535: writer.write("\n\tdocument.wysiwyg = \"textarea\";");
536: writer.write("\n}\n");
537:
538: writer.write("\nfunction expandMenu(client_id){");
539: writer
540: .write("\n\tvar editor = FCKeditorAPI.GetInstance(client_id + '_textinput');");
541: writer.write("\n\teditor.ToolbarSet.Expand();");
542: writer.write("\n\tdocument.wysiwyg = \"FCKeditor\";");
543: writer.write("\n}\n");
544:
545: writer.write("</script>\n");
546:
547: //if toggling is off or the content is already rich, make the editor show up immediately
548: if (!shouldToggle) {
549: writer
550: .write("<script type=\"text/javascript\" defer=\"1\">chef_setupformattedtextarea('"
551: + clientId + "',false);</script>");
552: }
553:
554: }
555:
556: public void decode(FacesContext context, UIComponent component) {
557: if (null == context
558: || null == component
559: || !(component instanceof org.sakaiproject.jsf.component.RichTextEditArea)) {
560: throw new IllegalArgumentException();
561: }
562:
563: String clientId = component.getClientId(context);
564:
565: Map requestParameterMap = context.getExternalContext()
566: .getRequestParameterMap();
567:
568: String newValue = (String) requestParameterMap.get(clientId
569: + "_textinput");
570:
571: org.sakaiproject.jsf.component.RichTextEditArea comp = (org.sakaiproject.jsf.component.RichTextEditArea) component;
572: comp.setSubmittedValue(newValue);
573: }
574: }
|