All Downloads are FREE. Search and download functionalities are using the official Maven repository.

echopointng.ui.syncpeer.RichTextAreaPeer Maven / Gradle / Ivy

Go to download

Echo2 bundled with Echo2_Extras, Echo2_FileTransfer and echopointing and various improvements/bugfixes

There is a newer version: 2.0.4
Show newest version
/*
 * This file is part of the Echo Point Project. This project is a collection of
 * Components that have extended the Echo Web Application Framework.
 * 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * 
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or the
 * GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
 * case the provisions of the GPL or the LGPL are applicable instead of those
 * above. If you wish to allow use of your version of this file only under the
 * terms of either the GPL or the LGPL, and not to allow others to use your
 * version of this file under the terms of the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice and other
 * provisions required by the GPL or the LGPL. If you do not delete the
 * provisions above, a recipient may use your version of this file under the
 * terms of any one of the MPL, the GPL or the LGPL.
 */
package echopointng.ui.syncpeer;

import nextapp.echo2.app.Alignment;
import nextapp.echo2.app.ApplicationInstance;
import nextapp.echo2.app.Color;
import nextapp.echo2.app.Component;
import nextapp.echo2.app.ImageReference;
import nextapp.echo2.app.ResourceImageReference;
import nextapp.echo2.app.Style;
import nextapp.echo2.app.text.TextComponent;
import nextapp.echo2.app.update.ServerComponentUpdate;
import nextapp.echo2.webcontainer.ActionProcessor;
import nextapp.echo2.webcontainer.ContainerContext;
import nextapp.echo2.webcontainer.ContainerInstance;
import nextapp.echo2.webcontainer.PartialUpdateParticipant;
import nextapp.echo2.webcontainer.PropertyUpdateProcessor;
import nextapp.echo2.webcontainer.RenderContext;
import nextapp.echo2.webrender.ClientProperties;
import nextapp.echo2.webrender.ServerMessage;
import nextapp.echo2.webrender.Service;
import nextapp.echo2.webrender.WebRenderServlet;
import nextapp.echo2.webrender.servermessage.DomUpdate;
import nextapp.echo2.webrender.service.JavaScriptService;
import nextapp.echo2.webrender.util.DomUtil;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import echopointng.ButtonEx;
import echopointng.EPNG;
import echopointng.RichTextArea;
import echopointng.richtext.RichTextRenderer;
import echopointng.richtext.RichTextSpellChecker;
import echopointng.ui.resource.Resources;
import echopointng.ui.util.CssStyleEx;
import echopointng.ui.util.HtmlNodeLexer;
import echopointng.ui.util.HtmlTable;
import echopointng.ui.util.ImageManager;
import echopointng.ui.util.LayoutStrut;
import echopointng.ui.util.Render;
import echopointng.ui.util.RenderingContext;

public class RichTextAreaPeer extends AbstractEchoPointPeer implements PropertyUpdateProcessor, ActionProcessor
{

	/**
	 * Service to provide supporting JavaScript library.
	 */
	public static final Service RICH_TEXT_SERVICE = JavaScriptService.forResource("EPNG.RichTextArea", "/echopointng/ui/resource/js/rta.js");
	static {
		WebRenderServlet.getServiceRegistry().add(RICH_TEXT_SERVICE);
	}

	private static final ImageReference IMAGE_WIGGLY_RED_LINE = new ResourceImageReference("/echopointng/resource/images/richtext/ep_rt_wiggly_redline.gif");
	
     /**
     * Constructs a RichTextAreaPeer
     */
    public RichTextAreaPeer() {
    	super();
		partialUpdateManager.add(RichTextArea.TEXT_CHANGED_PROPERTY, new PartialUpdateParticipant() {
			public boolean canRenderProperty(RenderContext rc, ServerComponentUpdate update) {
				return true;
			}
			public void renderProperty(RenderContext rc, ServerComponentUpdate update) {
				htmlChanged(rc,update);
			}
		});

		partialUpdateManager.add(RichTextArea.PROPERTY_SPELL_CHECK_IN_PROGRESS, new PartialUpdateParticipant() {
			public boolean canRenderProperty(RenderContext rc, ServerComponentUpdate update) {
				return true;
			}
			public void renderProperty(RenderContext rc, ServerComponentUpdate update) {
				htmlChanged(rc,update);
			}
		});
    	
    }
    
    /**
     * Called when a RTA property has changed that may require spelling checking to occur.
     */
    private void htmlChanged(RenderContext rc, ServerComponentUpdate update) {
		RichTextArea rta = (RichTextArea) update.getParent();
		String text = rta.getText();

		// an XML message directive please to tell the popup to expand!
		Element itemizedUpdateElement = rc.getServerMessage().getItemizedDirective(ServerMessage.GROUP_ID_POSTUPDATE,
				"EPRTA.MessageProcessor", "htmlChanged", new String[0], new String[0]);
		Element itemElement = rc.getServerMessage().getDocument().createElement("item");
		itemizedUpdateElement.appendChild(itemElement);
		itemElement.setAttribute("eid", ContainerInstance.getElementId(rta));
		
		boolean spellCheckInProgress = ((Boolean) rta.getRenderProperty(RichTextArea.PROPERTY_SPELL_CHECK_IN_PROGRESS)).booleanValue(); 
		text = spellCheckText(rc,itemElement,rta,text,spellCheckInProgress);
		itemElement.setAttribute("html", text);
		itemElement.setAttribute("spellCheckInProgress", String.valueOf(spellCheckInProgress));
    }

	/**
	 * @see nextapp.echo2.webcontainer.SynchronizePeer#getContainerId(nextapp.echo2.app.Component)
	 */
	public String getContainerId(Component child) {
		throw new UnsupportedOperationException("RichTextArea does not support children.");
	}

	/**
	 * @see nextapp.echo2.webcontainer.PropertyUpdateProcessor#processPropertyUpdate(nextapp.echo2.webcontainer.ContainerInstance,
	 *      nextapp.echo2.app.Component, org.w3c.dom.Element)
	 */
	public void processPropertyUpdate(ContainerInstance ci, Component component, Element propertyElement) {
		String propertyName = propertyElement.getAttribute(PropertyUpdateProcessor.PROPERTY_NAME);
		if (TextComponent.TEXT_CHANGED_PROPERTY.equals(propertyName)) {
			String propertyValue = DomUtil.getElementText(propertyElement);
			propertyValue = removeSpellCheckText(propertyValue);
			ci.getUpdateManager().getClientUpdateManager().setComponentProperty(component, TextComponent.TEXT_CHANGED_PROPERTY, propertyValue);
		}
	}
	
	/**
	 * @see nextapp.echo2.webcontainer.ActionProcessor#processAction(nextapp.echo2.webcontainer.ContainerInstance, nextapp.echo2.app.Component, org.w3c.dom.Element)
	 */
	public void processAction(ContainerInstance ci, Component component, Element actionElement) {
		String actionName = actionElement.getAttribute(ACTION_NAME); 
		String actionValue = actionElement.getAttribute(ACTION_VALUE);
        ci.getUpdateManager().getClientUpdateManager().setComponentAction(component, actionName, actionValue);

	}
	
	/**
	 * This will remove any spell check markup that has been placed in the
	 * RTA HTML text.
	 */
	private String removeSpellCheckText(String htmlText) {
		htmlText = HtmlNodeLexer.lex(htmlText,new HtmlNodeLexer.HtmlLexerCallBack() {
			boolean deleting = false;
			String currentTag = null;
			int depthCount;
			public StringBuffer onCommentNode(StringBuffer comment) {
				return deleting ? null : comment;
			}
			public StringBuffer onTextNode(StringBuffer textNode) {
				if (deleting) {
					if ("span".equalsIgnoreCase(currentTag)) {
						// we want the text inside a spell span but not the span itself
						return textNode;
					}
					return null;
				} else {
					return textNode;
				}
			}
			public StringBuffer onElementNode(StringBuffer element) {
				if (deleting) {
					boolean isTagStart = element.indexOf("<"+currentTag) == 0;
					boolean isTagEnd   = element.indexOf("')
						break;
					tagName.append(chars[i]);
					
					
				}
				return tagName.toString();
			}
			
			
		});
		return htmlText;
	}
	
	/**
	 * If the spelling checking is on, then we need to go through and check each word
	 * in the HTML and "hilight" it with our spell check support.
	 * 

*/ private String spellCheckText(final RenderContext rc, final Element directiveItem, final RichTextArea rta, String htmlText, boolean spellCheckInProgress) { final String elementId = ContainerInstance.getElementId(rta); final RichTextSpellChecker spellChecker = rta.getSpellChecker(); if (htmlText == null || htmlText.trim().length() == 0 || spellChecker == null) { return htmlText; } boolean alreadyHasSpellingMarkup = false; if (htmlText.indexOf("class=\"epspell\"") != -1) { alreadyHasSpellingMarkup = true; } else if (htmlText.indexOf("class=epspell") != -1) { alreadyHasSpellingMarkup = true; } if (spellCheckInProgress) { if (alreadyHasSpellingMarkup) { return htmlText; } String newHtmlText = HtmlNodeLexer.lex(htmlText, new HtmlNodeLexer.HtmlLexerCallBack() { int spellCount = 0; /** * @see echopointng.ui.util.HtmlNodeLexer.HtmlLexerCallBack#onCommentNode(java.lang.StringBuffer) */ public StringBuffer onCommentNode(StringBuffer comment) { return comment; } /** * @see echopointng.ui.util.HtmlNodeLexer.HtmlLexerCallBack#onElementNode(java.lang.StringBuffer) */ public StringBuffer onElementNode(StringBuffer element) { return element; } /** * @see echopointng.ui.util.HtmlNodeLexer.HtmlLexerCallBack#onTextNode(java.lang.StringBuffer) */ public StringBuffer onTextNode(StringBuffer textNode) { StringBuffer newTextNode = new StringBuffer(); RichTextSpellChecker.SpellCheckerWord[] words = spellChecker.parseWords(textNode.toString()); int lastStartIndex = 0; for (int i = 0; i < words.length; i++) { int startIndex = words[i].getStartIndex(); int endIndex = words[i].getEndIndex(); // copy the previous text into the new text node String prevText = textNode.substring(lastStartIndex,startIndex); newTextNode.append(prevText); lastStartIndex = endIndex; String word = textNode.substring(startIndex, endIndex); if (word.length() > 0) { String[] alternatives = spellChecker.checkWord(word); // is it badly spelt if (alternatives != null) { StringBuffer specialSpanText = new StringBuffer(); String spellId = elementId + '|' + spellCount; spellCount++; specialSpanText.append(""); specialSpanText.append(word); specialSpanText.append(""); newTextNode.append(specialSpanText); // // create spelling entry StringBuffer spellings = new StringBuffer(); if (alternatives.length == 0) { spellings.append(words); } else { for (int j = 0; j < alternatives.length; j++) { if (j > 0) { spellings.append("##"); } spellings.append(alternatives[j]); } } Element spellingItem = rc.getServerMessage().getDocument().createElement("spelling"); directiveItem.appendChild(spellingItem); spellingItem.setAttribute("spellId",spellId); spellingItem.setAttribute("spellings",spellings.toString()); } else { // just append the word newTextNode.append(word); } } } // do we have any residual text if (lastStartIndex < textNode.length()) { String endText = textNode.substring(lastStartIndex,textNode.length()); newTextNode.append(endText); } return newTextNode; } }); if (!newHtmlText.equals(htmlText)) { return newHtmlText; } else { return htmlText; } } else { // no spell check in operation so return the text. return htmlText; } } /** * @see echopointng.ui.syncpeer.AbstractEchoPointPeer#renderDispose(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, * nextapp.echo2.app.Component) */ public void renderDispose(RenderContext rc, ServerComponentUpdate update, Component component) { super.renderDispose(rc, update, component); createDisposeDirective(rc.getServerMessage(), ContainerInstance.getElementId(component)); // because we have "reparented" the floating ColorChooser divs, we need // to remove them String boxId = ContainerInstance.getElementId(component) + "CC"; DomUpdate.renderElementRemove(rc.getServerMessage(), boxId); rc.getServerMessage().addLibrary(Resources.EP_SCRIPT_SERVICE.getId()); rc.getServerMessage().addLibrary(RICH_TEXT_SERVICE.getId()); rc.getServerMessage().addLibrary(ColorChooserPeer.CC_SERVICE.getId()); } /** * @see echopointng.ui.syncpeer.AbstractEchoPointContainerPeer#renderUpdate(nextapp.echo2.webcontainer.RenderContext, * nextapp.echo2.app.update.ServerComponentUpdate, java.lang.String) */ public boolean renderUpdate(RenderContext rc, ServerComponentUpdate update, String targetId) { boolean fullReplace = false; if (update.hasUpdatedProperties()) { if (partialUpdateManager.canProcess(rc, update)) { partialUpdateManager.process(rc, update); } else { fullReplace = true; } } // because we have "reparented" floating Box divs, we need to remove // them as well as ourself from the DOM tree. if (fullReplace) { // Perform full update. String elementId = ContainerInstance.getElementId(update.getParent()); DomUpdate.renderElementRemove(rc.getServerMessage(), elementId); renderAdd(rc, update, targetId, update.getParent()); } return false; } /** * @see echopointng.ui.syncpeer.AbstractEchoPointPeer#renderHtml(echopointng.ui.util.RenderingContext, * Node, nextapp.echo2.app.Component) */ public void renderHtml(RenderingContext rc, Node parent, Component component) { Style fallbackStyle = EPNG.getFallBackStyle(component); String elementId = rc.getElementId(); RichTextArea rta = (RichTextArea) component; RichTextRenderer rtaRenderer = (RichTextRenderer) rc.getRP(RichTextArea.PROPERTY_RENDERER, fallbackStyle); ApplicationInstance app = ApplicationInstance.getActive(); ContainerContext containerContext = (ContainerContext) app.getContextProperty(ContainerContext.CONTEXT_PROPERTY_NAME); ClientProperties clientProperties = containerContext.getClientProperties(); String userAgent = clientProperties.getString(ClientProperties.NAVIGATOR_USER_AGENT); //////////////////////////////////////////////////////// // script support //////////////////////////////////////////////////////// rc.addLibrary(Resources.EP_SCRIPT_SERVICE); rc.addLibrary(RICH_TEXT_SERVICE); rc.addLibrary(ColorChooserPeer.CC_SERVICE); //////////////////////////////////////////////////////// // styles //////////////////////////////////////////////////////// CssStyleEx style; int toolbarAligment = rc.getRP(RichTextArea.PROPERTY_TOOLBAR_ALIGNMENT, fallbackStyle, Alignment.TOP); String ifwidth = "100%"; String ifheight = "100%"; style = new CssStyleEx(); style.setAttribute("height", ifheight); style.setAttribute("width", ifwidth); Render.asColors(style, rta, RichTextArea.PROPERTY_EDITOR_BACKGROUND, RichTextArea.PROPERTY_EDITOR_BACKGROUND, fallbackStyle); Render.asFont(style, rta, RichTextArea.PROPERTY_EDITOR_FONT, fallbackStyle); Render.asBorder(style, rta, RichTextArea.PROPERTY_EDITOR_BORDER, fallbackStyle); String styleIFRAME = style.renderInline(); style = new CssStyleEx(); style.setBackground((Color) rc.getRP(RichTextArea.PROPERTY_TOOLBAR_BACKGROUND, fallbackStyle)); style.setAttribute("text-align", "left"); String styleToolbarContainer = style.renderInline(); style = new CssStyleEx(); style.setAttribute("padding-right", "2px"); style.setAttribute("vertical-align", "top"); String rtatbCell = style.renderInline(); //////////////////////////////////////////////////////// // iframe for RTA editing //////////////////////////////////////////////////////// Element iframe = rc.createE("iframe"); iframe.setAttribute("style", styleIFRAME); iframe.setAttribute("id", elementId + "IFrame"); iframe.setAttribute("src", "about:blank"); // iframe.setAttribute("frameborder", "0"); // iframe.setAttribute("hspace", "1"); // iframe.setAttribute("vspace", "0"); if (!rc.getRP(RichTextArea.PROPERTY_EDITABLE, fallbackStyle, true)) { iframe.setAttribute("readonly", "readonly"); } if (!rta.isRenderEnabled()) { iframe.setAttribute("disabled", "disabled"); } Element iframeContainer = iframe; //iframeContainer.appendChild(iframe); //////////////////////////////////////////////////////// // Toolbar //////////////////////////////////////////////////////// HtmlTable tableToolbarContainer = new HtmlTable(rc.getDocument(), 0, 0, 0); tableToolbarContainer.setAttribute("style", styleToolbarContainer); Element td = tableToolbarContainer.getTD(); int cellCount = 0; //////////////////////////////////////////////////////// // Select fields (in their own table) //////////////////////////////////////////////////////// HtmlTable tableSelectFields = new HtmlTable(rc.getDocument(), 0, 0, 0); String[][] paragraphStyles = rtaRenderer.getParagraphStyles(rta, userAgent); String[][] fontNames = rtaRenderer.getFontNames(rta, userAgent); String[][] fontSizes = rtaRenderer.getFontSizes(rta, userAgent); if (paragraphStyles != null || fontNames != null || fontSizes != null) { if (paragraphStyles != null) { tableSelectFields.getTD().setAttribute("style", rtatbCell); tableSelectFields.getTD().appendChild(renderSelect(rc, elementId, "formatblock", "Paragraph Style", paragraphStyles)); cellCount++; } if (fontNames != null) { if (cellCount > 0) tableSelectFields.newTD(); tableSelectFields.getTD().setAttribute("style", rtatbCell); tableSelectFields.getTD().appendChild(renderSelect(rc, elementId, "fontname", "Font Name", fontNames)); cellCount++; } if (fontSizes != null) { if (cellCount > 0) tableSelectFields.newTD(); tableSelectFields.getTD().setAttribute("style", rtatbCell); tableSelectFields.getTD().appendChild(renderSelect(rc, elementId, "fontsize", "Font Size", fontSizes)); cellCount++; } td.appendChild(tableSelectFields.getTABLE()); if (toolbarAligment == Alignment.BOTTOM) { td.setAttribute("style", "padding-top:2px;padding-bottom:2px;"); } else { td.setAttribute("style", "padding-bottom:2px;"); } } //////////////////////////////////////////////////////// // Buttons //////////////////////////////////////////////////////// renderAllButtons(rc, tableToolbarContainer, rta, elementId, rtatbCell, userAgent); //////////////////////////////////////////////////////// // Editor Table (toolbar + iframe) //////////////////////////////////////////////////////// HtmlTable tableEditor = new HtmlTable(rc.getDocument(), 0, 0, 0); tableEditor.setAttribute("width", "100%"); tableEditor.setAttribute("height", "100%"); // // finally align the toolbar above or below the iframe Element tdIframe; Element tdToolbar; if (toolbarAligment == Alignment.BOTTOM) { tdIframe = tableEditor.getTD(); tdToolbar = tableEditor.newTR(); } else { tdToolbar = tableEditor.getTD(); tdIframe = tableEditor.newTR(); } tdToolbar.appendChild(tableToolbarContainer.getTABLE()); tdIframe.appendChild(iframeContainer); //tdIframe.setAttribute("height", "100%"); tdIframe.setAttribute("style","height:100%"); //////////////////////////////////////////////////////// // Outer Most Container //////////////////////////////////////////////////////// style = new CssStyleEx(rta,fallbackStyle); Render.asFillImage(style, rta, RichTextArea.PROPERTY_BACKGROUND_IMAGE, fallbackStyle, rc); if (! rta.isRenderEnabled()) { Render.asColors(style,rta,RichTextArea.PROPERTY_DISABLED_BACKGROUND,ButtonEx.PROPERTY_DISABLED_FOREGROUND, fallbackStyle); Render.asFont(style,rta,RichTextArea.PROPERTY_DISABLED_FONT, fallbackStyle); Render.asBorder(style,rta,RichTextArea.PROPERTY_DISABLED_BORDER, fallbackStyle); Render.asFillImage(style,rta,RichTextArea.PROPERTY_DISABLED_BACKGROUND_IMAGE, fallbackStyle,rc); } Element divOuter = rc.createE("div"); divOuter.setAttribute("id", elementId); divOuter.setAttribute("style", style.renderInline()); rc.addStandardWebSupport(divOuter); divOuter.appendChild(tableEditor.getTABLE()); parent.appendChild(divOuter); //renderColorChooser(rc, rta, parent, userAgent); createInitDirective(rc, rta, userAgent); } private Element renderAButton(RenderingContext rc, String rtaId, String cmd, ImageReference imageReference, String tooltip) { Element imgE = ImageManager.createImgE(rc,imageReference); imgE.setAttribute("id", rtaId + "_" + cmd); imgE.setAttribute("title", tooltip); return imgE; } /* * Renders all the supported button commands */ private void renderAllButtons(RenderingContext rc, HtmlTable tableOut, RichTextArea rta, String rtaId, String rtatbCell, String userAgent) { RichTextRenderer rtaRenderer = rta.getRenderer(); HtmlTable tableIn = new HtmlTable(rc.getDocument()); tableOut.getTD().appendChild(tableIn.getTABLE()); Element td = null; int cellCount = 0; String[][] commands = rtaRenderer.getSupportedCommands(rta, userAgent); for (int i = 0; i < commands.length; i++) { String cmd = commands[i][0]; String toolTip = commands[i][1]; // // set up images ImageReference image = rtaRenderer.getCommandImage(rta, userAgent, cmd); if (cmd == RichTextRenderer.CMD_HINT_NEWLINE) { tableIn = new HtmlTable(rc.getDocument()); tableOut.newTR(); tableOut.getTD().appendChild(tableIn.getTABLE()); cellCount = 0; continue; } else if (cmd == RichTextRenderer.CMD_HINT_SPACER) { td = tableIn.newTD(); td.appendChild(LayoutStrut.createStrut(rc, 5,1)); continue; } if (cellCount == 0) td = tableIn.getTD(); else td = tableIn.newTD(); td.setAttribute("style", rtatbCell); td.setAttribute("align", "left"); td.appendChild(renderAButton(rc, rtaId, cmd, image, toolTip)); cellCount++; } } private boolean isCommandSupported(String command, RichTextArea rta, RichTextRenderer rtaRenderer, String userAgent) { String commands[][] = rtaRenderer.getSupportedCommands(rta, userAgent); if (commands != null) { for (int i = 0; i < commands.length; i++) { if (commands[i][0].equals(command)) return true; } } return false; } /* * Renders a Select Field with the given values */ private Element renderSelect(RenderingContext rc, String rtaId, String cmd, String tooltip, String[][] valuesAndNames) { Element select = rc.createE("select"); Element option; select.setAttribute("id", rtaId + "_" + cmd); select.setAttribute("title", tooltip); for (int i = 0; i < valuesAndNames.length; i++) { option = rc.createE("option"); select.appendChild(option); option.setAttribute("value", valuesAndNames[i][0]); option.appendChild(rc.createText(valuesAndNames[i][1])); } // // add our intdeterminate values in option = rc.createE("option"); select.appendChild(option); option.setAttribute("value", ""); option.appendChild(rc.createText(" ")); return select; } /** * Strips new lines from the string writer and quotes any quoteChar * characters for use in JavaScript */ public static String removeNewLinesAndJSQuote(java.io.StringWriter sw, char quoteChar) { return removeNewLinesAndJSQuote(sw.toString(), quoteChar); } /** * Strips new lines from the string writer and quotes any quoteChar * characters for use in JavaScript */ public static String removeNewLinesAndJSQuote(String s, char quoteChar) { if (s == null) return null; StringBuffer sbTemp = new StringBuffer(s.length()); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == quoteChar) { sbTemp.append('\\'); sbTemp.append(quoteChar); } else { if (c != '\r' && c != '\n') sbTemp.append(c); } } return sbTemp.toString(); } /** * Renders a directive to the outgoing ServerMessage to * dispose the state of a RichTextItem, performing tasks such as * deregistering event listeners on the client and deleting its JS object. */ protected void createDisposeDirective(ServerMessage serverMessage, String elementId) { Element itemizedUpdateElement = serverMessage.getItemizedDirective(ServerMessage.GROUP_ID_PREREMOVE, "EPRTA.MessageProcessor", "dispose", new String[0], new String[0]); Element itemElement = serverMessage.getDocument().createElement("item"); itemElement.setAttribute("eid", elementId); itemizedUpdateElement.appendChild(itemElement); } /** * Renders a directive to the outgoing ServerMessage to * initialize the state of a RichTextItem, performing tasks such as * registering event listeners on the client and creating the JS object. */ protected void createInitDirective(RenderingContext rc, RichTextArea rta, String userAgent) { RichTextRenderer rtaRenderer = rta.getRenderer(); RichTextRenderer.CommandAppearance appearance = rtaRenderer.getCommandAppearance(rta, userAgent); CssStyleEx style; style = new CssStyleEx(); style.setAttribute("left", "0"); style.setAttribute("top", "0"); style.setAttribute("position", "relative"); if (appearance != null) { Render.asBorder(style, appearance.getBorder()); Render.asColor(style, appearance.getBackground(), "background-color"); } else { style.setAttribute("background-color", "#efefef"); style.setAttribute("border-bottom", "buttonface solid 1px"); style.setAttribute("border-left", "buttonface solid 1px"); style.setAttribute("border-right", "buttonface solid 1px"); style.setAttribute("border-top", "buttonface solid 1px"); } String upItemStyle = style.renderInline(); style = new CssStyleEx(); style.setAttribute("left", "0"); style.setAttribute("top", "0"); style.setAttribute("position", "relative"); if (appearance != null) { Render.asBorder(style, appearance.getSelectedBorder()); Render.asColor(style, appearance.getSelectedBackground(), "background-color"); } else { style.setAttribute("background-color", "buttonface"); style.setAttribute("border-bottom", "buttonhighlight solid 1px"); style.setAttribute("border-left", "buttonshadow solid 1px"); style.setAttribute("border-right", "buttonhighlight solid 1px"); style.setAttribute("border-top", "buttonshadow solid 1px"); } String downItemStyle = style.renderInline(); style = new CssStyleEx(); style.setAttribute("position", "relative"); style.setAttribute("left", "0"); style.setAttribute("top", "0"); if (appearance != null) { Render.asBorder(style, appearance.getRolloverBorder()); Render.asColor(style, appearance.getRolloverBackground(), "background-color"); } else { style.setAttribute("background-color", "#efefef"); style.setAttribute("border-bottom", "buttonshadow solid 1px"); style.setAttribute("border-left", "buttonhighlight solid 1px"); style.setAttribute("border-right", "buttonshadow solid 1px"); style.setAttribute("border-top", "buttonhighlight solid 1px"); } String upMouseOverStyle = style.renderInline(); style = new CssStyleEx(); style.setAttribute("position", "relative"); style.setAttribute("left", "0"); style.setAttribute("top", "0"); if (appearance != null) { Render.asBorder(style, appearance.getRolloverBorder()); Render.asColor(style, appearance.getRolloverBackground(), "background-color"); } else { style.setAttribute("background-color", "#efefef"); style.setAttribute("border-bottom", "buttonhighlight solid 1px"); style.setAttribute("border-left", "buttonshadow solid 1px"); style.setAttribute("border-right", "buttonhighlight solid 1px"); style.setAttribute("border-top", "buttonshadow solid 1px"); } String downMouseOverStyle = style.renderInline(); style = new CssStyleEx(); style.setAttribute("font-size", "10pt"); String selectStyle = style.renderInline(); //-------------------------------------------------- // directive creation //-------------------------------------------------- Element itemizedUpdateElement = rc.getServerMessage().getItemizedDirective(ServerMessage.GROUP_ID_POSTUPDATE, "EPRTA.MessageProcessor", "init", new String[0], new String[0]); Element itemElement = rc.createE("item"); itemElement.setAttribute("eid", rc.getElementId()); itemizedUpdateElement.appendChild(itemElement); style = new CssStyleEx(); Render.asColors(style, rta, RichTextArea.PROPERTY_EDITOR_BACKGROUND, RichTextArea.PROPERTY_EDITOR_FOREGROUND); Render.asFont(style, rta, RichTextArea.PROPERTY_EDITOR_FONT); String cssText = ""; cssText += "body { "; cssText += style.renderInline(); cssText += "}"; // cssText += ".epspell { "; // cssText += " background-color : yellow;"; // cssText += " color : red;"; // cssText += " text-decoration : line-though;"; // cssText += "}"; String wigglyUrl = ImageManager.getURI(rc,IMAGE_WIGGLY_RED_LINE); cssText += ".epspell { "; cssText += " background : url(" + wigglyUrl + ") repeat-x bottom"; cssText += "}"; cssText += ".epspellplain { "; cssText += "}"; cssText += ".epspellbox {"; cssText += " background-color : #C6DBFF;"; /* #C6DBFF #EFEFDE */ cssText += " border-color : EFEFDE; ;"; /* #9CAECE */ cssText += " border-width : 2px;"; cssText += " border-style : outset;"; cssText += " padding : 2px;"; cssText += "}"; cssText += ".epspelloption {"; cssText += " color : #000000;"; cssText += " background-color : #C6DBFF;"; cssText += " padding-left : 5px;"; //cssText += " width : 100%;"; cssText += "}"; cssText += ".epspelloptionhilight {"; cssText += " color : #ffffff;"; cssText += " background-color : #5271CE;"; cssText += " padding-left : 5px;"; //cssText += " width : 100%;"; cssText += "}"; boolean spellCheckInProgress = ((Boolean) rta.getRenderProperty(RichTextArea.PROPERTY_SPELL_CHECK_IN_PROGRESS)).booleanValue(); String htmlText = rta.getText(); htmlText = htmlText == null ? "" : htmlText; htmlText = spellCheckText(rc,itemElement,rta,htmlText,spellCheckInProgress); // // build our RTA document which goes inside the editing iframe StringBuffer htmlDocument = new StringBuffer(); htmlDocument.append(""); htmlDocument.append(""); htmlDocument.append(""); htmlDocument.append(""); htmlDocument.append(""); htmlDocument.append(htmlText); htmlDocument.append(""); htmlDocument.append(""); itemElement.setAttribute("htmlDocument", htmlDocument.toString()); itemElement.setAttribute("initialText", htmlText); itemElement.setAttribute("spellCheckInProgress", String.valueOf(spellCheckInProgress)); // // look and feel objects Element landfItem; landfItem = rc.createE("landf"); landfItem.setAttribute("tag", "button"); landfItem.setAttribute("upItemStyle", upItemStyle); landfItem.setAttribute("downItemStyle", downItemStyle); landfItem.setAttribute("upMouseOverStyle", upMouseOverStyle); landfItem.setAttribute("downMouseOverStyle", downMouseOverStyle); itemElement.appendChild(landfItem); landfItem = rc.createE("landf"); landfItem.setAttribute("tag", "select"); landfItem.setAttribute("selectStyle", selectStyle); itemElement.appendChild(landfItem); // // commands if (isCommandSupported(RichTextRenderer.CMD_BOLD, rta, rtaRenderer, userAgent)) { createButtonCommand(rc, itemElement, "bold", true); } if (isCommandSupported(RichTextRenderer.CMD_ITALIC, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "italic", true); if (isCommandSupported(RichTextRenderer.CMD_UNDERLINE, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "underline", true); if (isCommandSupported(RichTextRenderer.CMD_SUBSCRIPT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "subscript", true); if (isCommandSupported(RichTextRenderer.CMD_SUPERSCRIPT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "superscript", true); if (isCommandSupported(RichTextRenderer.CMD_REMOVEFORMAT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "removeformat", true); if (isCommandSupported(RichTextRenderer.CMD_FORECOLOR, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "forecolor", false); if (isCommandSupported(RichTextRenderer.CMD_BACKCOLOR, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "hilitecolor", false); if (isCommandSupported(RichTextRenderer.CMD_ALIGN_LEFT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "justifyleft", true); if (isCommandSupported(RichTextRenderer.CMD_ALIGN_CENTER, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "justifycenter", true); if (isCommandSupported(RichTextRenderer.CMD_ALIGN_RIGHT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "justifyright", true); if (isCommandSupported(RichTextRenderer.CMD_JUSTIFY, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "justifyfull", true); if (isCommandSupported(RichTextRenderer.CMD_INDENT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "indent", false); if (isCommandSupported(RichTextRenderer.CMD_OUTDENT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "outdent", false); if (isCommandSupported(RichTextRenderer.CMD_NUMBERS, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "insertorderedlist", true); if (isCommandSupported(RichTextRenderer.CMD_BULLETS, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "insertunorderedlist", true); if (isCommandSupported(RichTextRenderer.CMD_COPY, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "copy", false); if (isCommandSupported(RichTextRenderer.CMD_CUT, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "cut", false); if (isCommandSupported(RichTextRenderer.CMD_PASTE, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "paste", false); if (isCommandSupported(RichTextRenderer.CMD_SELECTALL, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "selectall", false); if (isCommandSupported(RichTextRenderer.CMD_UNDO, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "undo", false); if (isCommandSupported(RichTextRenderer.CMD_REDO, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "redo", false); if (isCommandSupported(RichTextRenderer.CMD_SPELLCHECK, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "spellcheck", false); if (isCommandSupported(RichTextRenderer.CMD_INSERTHR, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "inserthorizontalrule", false); if (isCommandSupported(RichTextRenderer.CMD_CREATELINK, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "createlink", false); if (isCommandSupported(RichTextRenderer.CMD_INSERTIMAGE, rta, rtaRenderer, userAgent)) createButtonCommand(rc, itemElement, "insertimage", false); //if (isCommandSupported(rc,rta,RichTextRenderer.CMD_INSERTTABLE)) //createCommandE(rc,itemElement,"inserttable",false); if (rtaRenderer.getFontNames(rta, userAgent) != null) createSelectCommand(rc, itemElement, "fontname"); if (rtaRenderer.getFontSizes(rta, userAgent) != null) createSelectCommand(rc, itemElement, "fontsize"); if (rtaRenderer.getParagraphStyles(rta, userAgent) != null) createSelectCommand(rc, itemElement, "formatblock"); } private void createButtonCommand(RenderingContext rc, Element parentE, String cmd, boolean isStateful) { createCommandImpl(rc, parentE, "button", cmd, isStateful); } private void createSelectCommand(RenderingContext rc, Element parentE, String cmd) { createCommandImpl(rc, parentE, "select", cmd, false); } private void createCommandImpl(RenderingContext rc, Element parentE, String tag, String cmd, boolean isStateful) { Element cmdE = rc.createE("command"); cmdE.setAttribute("tag", tag); cmdE.setAttribute("cmd", cmd); cmdE.setAttribute("isStateful", String.valueOf(isStateful)); parentE.appendChild(cmdE); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy