Author: nbelaevski
Date: 2007-06-14 20:03:21 -0400 (Thu, 14 Jun 2007)
New Revision: 1193
Added:
trunk/richfaces/common/src/main/java/org/richfaces/json/JSContentHandler.java
trunk/richfaces/common/src/main/java/org/richfaces/renderkit/TemplateUtil.java
trunk/richfaces/common/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js
trunk/sandbox/calendar/src/main/java/org/richfaces/renderkit/
trunk/sandbox/calendar/src/main/java/org/richfaces/renderkit/CalendarRendererBase.java
trunk/sandbox/calendar/src/test/java/org/richfaces/component/CalendarComponentTest.java
Removed:
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/TemplateUtil.java
Modified:
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/DragIndicatorRendererBase.java
trunk/sandbox/calendar/pom.xml
trunk/sandbox/calendar/src/main/java/org/richfaces/component/UICalendar.java
trunk/sandbox/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx
Log:
- Client templating being moved to common
- Improved client templating in calendar project started
Added: trunk/richfaces/common/src/main/java/org/richfaces/json/JSContentHandler.java
===================================================================
--- trunk/richfaces/common/src/main/java/org/richfaces/json/JSContentHandler.java
(rev 0)
+++
trunk/richfaces/common/src/main/java/org/richfaces/json/JSContentHandler.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -0,0 +1,583 @@
+package org.richfaces.json;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+
+import org.ajax4jsf.framework.util.javascript.JSEncoder;
+import org.ajax4jsf.framework.util.message.Messages;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+
+/**
+ * @author shura
+ * SAX content handler for serialise events as JavaScript function.
+ */
+public class JSContentHandler implements ContentHandler,LexicalHandler {
+
+ protected Writer outputWriter;
+
+ private static final JSEncoder encoder = new JSEncoder();
+
+ private static final char S_EOL[] = System.getProperty("line.separator")
+ .toCharArray();
+
+ private static final char S_DOCUMENT_START[] = "(".toCharArray();
+
+ private static final char S_DOCUMENT_ENF[] = ");".toCharArray();
+
+ private static final char S_DOCUMENT_3[] = "\"?>".toCharArray();
+
+ private static final char S_OBJECT_START[] = "{".toCharArray();
+ private static final char[] S_OBJECT_END = "}".toCharArray();
+
+ private static final char S_ELEMENT_START[] = "new E(".toCharArray();
+
+ private static final char[] S_ELEMENT_CLOSE = ")".toCharArray();
+
+ private static final char S_ATTRIBUTES_END[] = "}".toCharArray();
+
+ private static final char S_ATTRIBUTES_START[] = ",{".toCharArray();
+
+ private static final char S_ELEMENT_END_START_TAG[] = ",[".toCharArray();
+
+ private static final char S_ELEMENT_END[] = "])".toCharArray();
+
+ private static final char S_TEXT_START[] = "new T('".toCharArray();
+
+ private static final char S_TEXT_END[] = "')".toCharArray();
+
+ private static final char S_CDATA_START[] = "new D('".toCharArray();
+
+ private static final char S_CDATA_END[] = "')".toCharArray();
+
+ private static final char S_COMMENT_START[] = "new C('".toCharArray();
+
+ private static final char S_COMMENT_END[] = "')".toCharArray();
+
+ private static final char S_PROCINSTR_START[] = "<?".toCharArray();
+
+ private static final char S_PROCINSTR_END[] = "?>".toCharArray();
+
+ private static final char C_LT = '<';
+
+ private static final char C_GT = '>';
+
+ private static final char C_SPACE = ' ';
+
+ private static final char C_QUOTE = '\'';
+
+ private static final char C_NSSEP = ':';
+
+ private static final char C_COMMA = ',';
+
+ private static final boolean DEBUG = false;
+
+ /* ====================================================================== */
+ private boolean hanging_element = false;
+
+ /** True if we are processing the prolog. */
+ private boolean beforeDocumentStart = true;
+
+ /** True if we are processing the DTD. */
+ private boolean processing_dtd = false;
+
+ /** True if we are processing the DTD. */
+ private boolean processing_cdata = false;
+ /** The <code>DocType</code> instance representing the document. */
+ // protected DocType doctype = null;
+
+ protected int level;
+
+ protected char[] indentBuffer;
+
+
+ private Locator locator;
+
+ public static final String DEFAULT_ENCODING = "ISO-8859-1";
+
+ public JSContentHandler() {
+ }
+ /**
+ * @param outputWriter
+ */
+ public JSContentHandler(Writer outputWriter) {
+ this.outputWriter = outputWriter;
+ }
+ /**
+ * @throws java.io.IOException
+ */
+ public void close() throws IOException {
+ outputWriter.close();
+ }
+
+ // ContentHandler Methods
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+ */
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (this.beforeDocumentStart || level < 0)
+ return;
+ try {
+ if (!this.closeElement(false) && this.processing_cdata == false) {
+ this.outputWriter.write(C_COMMA);
+ }
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(Integer.toString(level));
+ this.outputWriter.write(']');
+ }
+ if (this.processing_cdata == false) {
+ this.outputWriter.write(S_TEXT_START);
+ }
+ this.encode(ch, start, length);
+ if (this.processing_cdata == false) {
+ this.outputWriter.write(S_TEXT_END);
+ }
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#endDocument()
+ */
+ public void endDocument() throws SAXException {
+ this.beforeDocumentStart = true;
+
+ if (this.level != 0) {
+ throw new
SAXException(Messages.getMessage(Messages.OPEN_CLOSE_TAGS_DO_NOT_MATCH_ERROR));
+ }
+ // Write parameters after parsing and final function )
+ try {
+ this.outputWriter.write(S_EOL);
+ this.outputWriter.flush();
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String,
java.lang.String)
+ */
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ this.level--;
+ if (closeElement(true))
+ return;
+ try {
+ this.outputWriter.write(S_ELEMENT_END); // [</]
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(qName);
+ this.outputWriter.write('-');
+ this.outputWriter.write(uri);
+ this.outputWriter.write(']');
+ }
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ // this.outputWriter.write(qual);
+ // this.outputWriter.write(C_GT); // [>]
+ }
+
+ /**
+ * Write the end part of a start element (if necessary).
+ *
+ * @param end_element
+ * Whether this method was called because an element is being
+ * closed or not.
+ * @return <b>true </b> if this call successfully closed the element (and
no
+ * further <code></element></code> is required.
+ */
+ protected boolean closeElement(boolean end_element) throws SAXException {
+ if (!end_element && level == 0)
+ return true;
+
+ if (!hanging_element)
+ return (false);
+ try {
+ if (end_element)
+ this.outputWriter.write(S_ELEMENT_CLOSE); // [ />]
+ else
+ this.outputWriter.write(S_ELEMENT_END_START_TAG); // [>]
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ this.hanging_element = false;
+ return (true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+ */
+ public void endPrefixMapping(String prefix) throws SAXException {
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+ */
+ public void ignorableWhitespace(char[] ch, int start, int length)
+ throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
java.lang.String)
+ */
+ public void processingInstruction(String target, String data)
+ throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* ====================================================================== */
+
+ /**
+ * Receive an object for locating the origin of SAX document events.
+ */
+ public final void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ /**
+ * Return the public identifier for the current document event.
+ *
+ * @return A <code>String</code> containing the public identifier,
+ * or <b>null</b> if none is available.
+ */
+ public String getPublicId() {
+ return(this.locator == null? null: this.locator.getPublicId());
+ }
+
+ /**
+ * Return the system identifier for the current document event.
+ *
+ * @return A <code>String</code> containing the system identifier,
+ * or <b>null</b> if none is available.
+ */
+ public String getSystemId() {
+ return(this.locator == null? null: this.locator.getSystemId());
+ }
+
+ /**
+ * Return the line number where the current document event ends.
+ *
+ * @return The line number, or -1 if none is available.
+ */
+ public int getLineNumber() {
+ return(this.locator == null? -1: this.locator.getLineNumber());
+ }
+
+ /**
+ * Return the column number where the current document event ends.
+ *
+ * @return The column number, or -1 if none is available.
+ */
+ public int getColumnNumber() {
+ return(this.locator == null? -1: this.locator.getColumnNumber());
+ }
+
+ /**
+ * Return a <code>String</code> describing the current location.
+ */
+ protected String getLocation() {
+ if (this.locator == null) return("");
+ StringBuffer buf = new StringBuffer(" (");
+ if (this.getSystemId() != null) {
+ buf.append(this.getSystemId());
+ buf.append(' ');
+ }
+ buf.append("line " + this.getLineNumber());
+ buf.append(" col " + this.getColumnNumber());
+ buf.append(')');
+ return(buf.toString());
+ }
+
+ /* ====================================================================== */
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
+ */
+ public void skippedEntity(String name) throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#startDocument()
+ */
+ public void startDocument() throws SAXException {
+ this.beforeDocumentStart = false;
+ this.processing_cdata = false;
+ this.level = 0;
+ /* We have a document type. */
+// if (this.doctype != null) {
+//
+// String root_name = this.doctype.getName();
+// /* Check the DTD and the root element */
+// if (!root_name.equals(qual)) {
+// throw new SAXException("Root element name \"" +
root_name
+// + "\" declared by document type declaration differs
"
+// + "from actual root element name \"" + qual +
"\"");
+// }
+ /* Output the <!DOCTYPE ...> declaration. */
+ // this.outputWriter.write(this.doctype.toString());
+// }
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String,
java.lang.String, org.xml.sax.Attributes)
+ */
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes) throws SAXException {
+ try {
+ if (!this.closeElement(false) && this.level > 0) {
+ this.outputWriter.write(C_COMMA);
+ }
+ this.outputWriter.write(S_ELEMENT_START); // [<]
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(uri);
+ this.outputWriter.write(']');
+ }
+ this.outputWriter.write(C_QUOTE);
+ this.outputWriter.write(qName);
+ this.outputWriter.write(C_QUOTE);
+
+// if (attributes.getLength() > 0) {
+ this.outputWriter.write(S_ATTRIBUTES_START);
+ // TODO - implementing namespaces !
+ // for (int x = 0; x < namespaces.length; x++) {
+ // this.outputWriter.write(S_ELEMENT_4); // [ xmlns]
+ // if (namespaces[x][Namespaces.NAMESPACE_PREFIX].length()
> 0) {
+ // this.outputWriter.write(C_NSSEP); // [:]
+ //
this.outputWriter.write(namespaces[x][Namespaces.NAMESPACE_PREFIX]);
+ // }
+ // this.outputWriter.write(S_ELEMENT_1); // [="]
+ // this.encode(namespaces[x][Namespaces.NAMESPACE_URI]);
+ // this.outputWriter.write(C_QUOTE); // ["]
+ // }
+ for (int x = 0; x < attributes.getLength(); x++) {
+ if (0 != x) {
+ this.outputWriter.write(C_COMMA);
+ this.outputWriter.write(C_SPACE); // [ ]
+ }
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(attributes.getURI(x));
+ this.outputWriter.write(']');
+ }
+ String attrName = attributes.getQName(x);
+ // For JavaScript any attributes names illegal ...
+ // replate with correct names.
+ if (attrName.equalsIgnoreCase("class")) {
+ attrName = "className";
+ }
+ this.outputWriter.write(C_QUOTE); // [']
+ this.outputWriter.write(attrName);
+ this.outputWriter.write(C_QUOTE); // [']
+ this.outputWriter.write(C_NSSEP); // [:]
+ this.encodeAttributeValue(attributes, x);
+ }
+
+ this.outputWriter.write(S_ATTRIBUTES_END);
+// }
+ this.level++;
+ this.hanging_element = true;
+ } catch (IOException e) {
+
+ throw new SAXException("write error",e);
+ }
+ }
+
+ protected void encodeAttributeValue(Attributes attributes, int idx) throws
SAXException, IOException {
+ //TODO by nick - fix namespace handling
+ this.outputWriter.write(C_QUOTE); // [']
+ this.encode(attributes.getValue(idx));
+ this.outputWriter.write(C_QUOTE); // [']
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
java.lang.String)
+ */
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+ */
+ public void comment(char[] ch, int start, int length) throws SAXException {
+ if (this.beforeDocumentStart || level < 0)
+ return;
+ try {
+ if (!this.closeElement(false)) {
+ this.outputWriter.write(C_COMMA);
+ }
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(Integer.toString(level));
+ this.outputWriter.write(']');
+ }
+// this.outputWriter.write(C_QUOTE);
+ this.outputWriter.write(S_COMMENT_START);
+ this.encode(ch, start, length);
+ this.outputWriter.write(S_COMMENT_END);
+// this.outputWriter.write(C_QUOTE);
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+ */
+ public void endCDATA() throws SAXException {
+ if (this.beforeDocumentStart || level < 0)
+ return;
+ try {
+ if (this.closeElement(false)) {
+ return;
+ }
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(Integer.toString(level));
+ this.outputWriter.write(']');
+ }
+ this.outputWriter.write(S_CDATA_END);
+ this.processing_cdata = false;
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#endDTD()
+ */
+ public void endDTD() throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
+ */
+ public void endEntity(String name) throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+ */
+ public void startCDATA() throws SAXException {
+ if (this.beforeDocumentStart || level < 0)
+ return;
+ try {
+ if (!this.closeElement(false)) {
+ this.outputWriter.write(C_COMMA);
+ }
+ if (DEBUG) {
+ this.outputWriter.write('[');
+ this.outputWriter.write(Integer.toString(level));
+ this.outputWriter.write(']');
+ }
+ this.outputWriter.write(S_CDATA_START);
+ this.processing_cdata = true;
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String,
java.lang.String)
+ */
+ public void startDTD(String name, String publicId, String systemId)
+ throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
+ */
+ public void startEntity(String name) throws SAXException {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.cocoon.components.serializers.EncodingSerializer#writeIndent(int)
+ */
+ protected void writeIndent(int indent) throws SAXException {
+ try {
+ this.outputWriter.write("\n".toCharArray(), 0, 1);
+ if (indent > 0) {
+ this.outputWriter.write(assureIndentBuffer(indent), 0, indent);
+ }
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+
+ }
+
+ private char[] assureIndentBuffer(int size) {
+ if (indentBuffer == null || indentBuffer.length < size) {
+ indentBuffer = new char[size];
+ Arrays.fill(indentBuffer, ' ');
+ }
+ return indentBuffer;
+ }
+
+ /**
+ * Encode and write a <code>String</code>
+ */
+ protected void encode(String data)
+ throws SAXException {
+ char array[] = data.toCharArray();
+ this.encode(array, 0, array.length);
+ }
+
+ /**
+ * Encode and write an array of characters.
+ */
+ protected void encode(char data[])
+ throws SAXException {
+ this.encode(data, 0, data.length);
+ }
+
+ /**
+ * Encode and write a specific part of an array of characters.
+ */
+ protected void encode(char data[], int start, int length)
+ throws SAXException {
+ int end = start + length;
+
+ if (data == null) throw new NullPointerException("Null data");
+ if ((start < 0) || (start > data.length) || (length < 0) ||
+ (end > data.length) || (end < 0))
+ throw new IndexOutOfBoundsException("Invalid data");
+ if (length == 0) return;
+
+ try {
+ for (int x = start; x < end; x++) {
+ char c = data[x];
+
+ if ( JSContentHandler.encoder.compile(c)) {
+ continue;
+ }
+
+ if (start != x) this.outputWriter.write(data, start, x - start );
+ this.outputWriter.write(JSContentHandler.encoder.encode(c));
+ start = x + 1;
+ continue;
+ }
+ if (start != end) this.outputWriter.write(data, start, end - start );
+ } catch (IOException e) {
+ throw new SAXException("Write error",e);
+ }
+ }
+
+}
Copied: trunk/richfaces/common/src/main/java/org/richfaces/renderkit/TemplateUtil.java
(from rev 1117,
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/TemplateUtil.java)
===================================================================
--- trunk/richfaces/common/src/main/java/org/richfaces/renderkit/TemplateUtil.java
(rev 0)
+++
trunk/richfaces/common/src/main/java/org/richfaces/renderkit/TemplateUtil.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -0,0 +1,71 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces 3.0 - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.renderkit;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.richfaces.org.apache.commons.lang.StringEscapeUtils;
+
+/**
+ * @author Nick Belaevski - nbelaevski(a)exadel.com
+ * created 11.12.2006
+ *
+ */
+public class TemplateUtil {
+
+ public static interface MacroTemplateHandler {
+ public String handle(String body);
+ };
+
+ private final static Pattern PARAMETER_REPLACER_PATTERN =
Pattern.compile("(\\\\)?\\{([^\\}]+)\\}");
+
+ public static String replaceParams(String string, MacroTemplateHandler handler) {
+ Matcher m = PARAMETER_REPLACER_PATTERN.matcher(string);
+ StringBuffer sb = new StringBuffer("\"");
+
+ int lastPosition = 0;
+
+ while (m.find()) {
+ String firstGroup = m.group(1);
+ if (firstGroup == null || firstGroup.length() == 0) {
+ sb.append(StringEscapeUtils.escapeJavaScript(string.substring(lastPosition,
m.start(2) - 1)));
+ sb.append("\" + " + handler.handle(m.group(2)) + " +
\"");
+ } else {
+ StringBuffer sbUnEsc = new StringBuffer();
+ sbUnEsc.append(string.substring(lastPosition, m.end(1) - 1));
+ sbUnEsc.append("{");
+ sbUnEsc.append(m.group(2));
+ sbUnEsc.append("}");
+
+ sb.append(StringEscapeUtils.escapeJavaScript(sbUnEsc.toString()));
+ }
+
+ lastPosition = m.end(2) + 1;
+ }
+ if (lastPosition < string.length()) {
+ sb.append(StringEscapeUtils.escapeJavaScript(string.substring(lastPosition)));
+ }
+ sb.append("\"");
+ return sb.toString();
+ }
+}
Added:
trunk/richfaces/common/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js
===================================================================
---
trunk/richfaces/common/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js
(rev 0)
+++
trunk/richfaces/common/src/main/resources/org/richfaces/renderkit/html/scripts/json/json-dom.js 2007-06-15
00:03:21 UTC (rev 1193)
@@ -0,0 +1,195 @@
+// AJAX-JSF AJAX-like library, for communicate with view Tree on server side.
+// In case of XMLHttpRequest don't worked, use :
+// JSHttpRequest v1.12. (C) Dmitry Koterov, 2005-01-27.
+//
http://forum.dklab.ru/users/DmitryKoterov/
+//
+// Do not remove this comment if you want to use script!
+// ?? ???????? ?????? ???????????, ???? ?? ?????? ???????????? ??????!
+//
+// Modified by Alexander J. Smirnov to use as JSF AJAX-like components.
+
+ JSDocument = function(js) {
+// AJAX_Log( " Response document "+Dump(js,1));
+// AJAX_Log( " Response document buildCache: "+typeof(js.buildCache));
+ this.idsCache = {};
+ js.buildCache(this.idsCache);
+ this.documentElement = js;//this._parseJS(js);
+ }
+
+// DOM document like class for parsing javaScript response.
+ JSDocument.prototype = {
+// idsCache: {},
+
+
+// documentElement : null,
+
+
+ getElementById: function( elementId ){
+ return this.idsCache[elementId];
+ },
+
+ getElementsByTagName: function( tagname ){
+ return [];
+ },
+ createElement: function(js){
+ return new E(js.tag);
+ },
+
+
+ createTextNode: function(text){
+ return new T(text);
+ },
+
+ createComment: function(text){
+ return new C(text);
+ },
+
+ createCDATASection: function(text){
+ return new D(text);
+ }
+
+
+ }
+
+// DOM - like elements for JSRequest. JS serialiser encode
+// XML sax events to creation of corresponding objects.
+ JSNode = function(){
+// this.tag = null;
+// this.attrs = {};
+// this.childs = [];
+// this.value = "";
+ };
+
+ JSNode.prototype = {
+ tag : null,
+ attrs : {},
+ childs : [],
+ parentNode : null,
+ value : "",
+ _symbols : {
+ '&':"&",
+ '<':"<",
+ '>':">",
+ '"':""",
+ '\'':"'",
+ '\u00A0':" "
+ },
+ // Public functions
+ getAttribute : function(aname) {
+ return this.attrs[aname];
+ },
+ setAttribute : function(aname,avalue){
+ this.attrs[aname]=avalue;
+ },
+ getInnerHTML : function(context){
+ var html = "";
+ for( var i = 0; i < this.childs.length; i++ ){
+ html += this.childs[i].getOuterHTML(context);
+ }
+ return html;
+ },
+// getOuterHTML : function(){return ""},
+
+ appendChild : function(child){
+ this.childs[this.childs.length]=child;
+ child.parentNode = this;
+ },
+
+ buildCache : function(cache){
+ if(this.attrs.id){
+ cache[this.attrs.id]=this;
+ }
+ for( var i in this.childs ){
+ this.childs[i].buildCache(cache);
+ this.childs[i].parentNode = this;
+ }
+ },
+
+ // TODO - make real clone ...
+ cloneNode : function(withChildren){
+ },
+
+ // Escape XML symbols - < > & ' ...
+ xmlescape : function(text){
+ for( var i in this._symbols ){
+// text = text.replace(i,this._symbols[i]);
+ text = text.split(i).join(this._symbols[i])
+ }
+ return text;
+ },
+
+ // Escape JavaScript function
+ JSEscape : function(text){
+// for( var i in this._symbols ){
+// text = text.replace(i,this._symbols[i]);
+// text = text.split(i).join(this._symbols[i])
+// }
+ return text;
+ }
+ }
+ // Element node
+ E = function(tagname,attributes,childnodes){
+
+ this.tag = tagname;
+ this.attrs = attributes;
+ if(childnodes){
+ this.childs = childnodes;
+ } else {
+ this.childs = [];
+ }
+ };
+
+ E.prototype = new JSNode();
+ E.prototype.getOuterHTML = function(context){
+ // AJAX_Log("Get Outer HTML for object:"+Dump(this);
+ var html = "<"+this.tag;
+ var inner = this.getInnerHTML();
+ for( var i in this.attrs ){
+ var attrValue = this.attrs[i];
+ if (typeof attrValue == "function") {
+ attrValue = attrValue(context);
+ }
+
+ if (attrValue) {
+ html += "
"+(i=='className'?'class':i)+'="'+(i.substring(0,2)=="on"?this.JSEscape(attrValue):this.xmlescape(attrValue))+'"';
+ // html+= "
"+i+'="'+this.xmlescape(this.attrs[i])+'"';
+ }
+ }
+ if(inner == ""){
+ html+= " />";
+ } else {
+ html+= " >"+inner+"</"+this.tag+">";
+ }
+ return html;
+ };
+
+ // Text node
+ T = function(text) {
+ this.value = text;
+ }
+
+ T.prototype = new JSNode();
+ T.prototype.getOuterHTML = function(context){
+ return this.xmlescape(this.value);
+ }
+
+ // Comment node
+ C = function(text) {
+ this.value = text;
+ }
+
+ C.prototype = new JSNode();
+ C.prototype.getOuterHTML = function(context){
+ return "<!--"+this.value+"-->";
+ }
+
+ // CDATA Section node.
+ D = function(text) {
+ this.value = text;
+ }
+
+ D.prototype = new JSNode();
+ D.prototype.getOuterHTML = function(context){
+ return "<![CDATA["+this.value+"]]>";
+ }
+
Modified:
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/DragIndicatorRendererBase.java
===================================================================
---
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/DragIndicatorRendererBase.java 2007-06-14
19:19:27 UTC (rev 1192)
+++
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/DragIndicatorRendererBase.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -37,6 +37,7 @@
import org.richfaces.component.UIDragIndicator;
import org.richfaces.component.nsutils.NSUtils;
import org.richfaces.org.apache.commons.lang.StringEscapeUtils;
+import org.richfaces.renderkit.TemplateUtil.MacroTemplateHandler;
/**
* Base renderer class for drag indicator ( marker ).
@@ -44,6 +45,16 @@
*
*/
public class DragIndicatorRendererBase extends HeaderResourcesRendererBase {
+ private final static MacroTemplateHandler macroTemplateHandler = new
MacroTemplateHandler() {
+
+ public String handle(String body) {
+ String paramAccess = "jsParams['" + body + "']";
+
+ return ("((!!" + paramAccess + ") ? " + paramAccess + " :
\"\")");
+ }
+
+ };
+
public static final String ACCEPT_CLASS = "acceptClass";
public static final String REJECT_CLASS = "rejectClass";
public static final String RENDERER_TYPE =
"com.exadel.jsf.renderer.DropIndicatorRenderer";
@@ -176,7 +187,7 @@
responseWriter.write("elt.indicatorTemplates['" + facetName +
"'] = function(element, jsParams) {\n");
responseWriter.write("var content = ");
- String result = TemplateUtil.replaceParams(dumpWriter.getBuffer().toString(),
"jsParams");
+ String result = TemplateUtil.replaceParams(dumpWriter.getBuffer().toString(),
macroTemplateHandler);
responseWriter.write(result + ";\n new Insertion.Top(element,
content);\n");
responseWriter.write("};");
}
Deleted:
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/TemplateUtil.java
===================================================================
---
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/TemplateUtil.java 2007-06-14
19:19:27 UTC (rev 1192)
+++
trunk/richfaces/drag-drop/src/main/java/org/richfaces/renderkit/TemplateUtil.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -1,74 +0,0 @@
-/**
- * License Agreement.
- *
- * JBoss RichFaces 3.0 - Ajax4jsf Component Library
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.renderkit;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.richfaces.org.apache.commons.lang.StringEscapeUtils;
-
-/**
- * @author Nick Belaevski - nbelaevski(a)exadel.com
- * created 11.12.2006
- *
- */
-public class TemplateUtil {
-
- private final static Pattern PARAMETER_REPLACER_PATTERN =
Pattern.compile("(\\\\)?\\{([^\\}]+)\\}");
-
- public static String replaceParams(String string, String paramsVarName) {
- Matcher m = PARAMETER_REPLACER_PATTERN.matcher(string);
- StringBuffer sb = new StringBuffer("\"");
-
- int lastPosition = 0;
-
- while (m.find()) {
- String firstGroup = m.group(1);
- if (firstGroup == null || firstGroup.length() == 0) {
- sb.append(StringEscapeUtils.escapeJavaScript(string.substring(lastPosition,
m.start(2) - 1)));
-
- String paramAccess = paramsVarName + "['" + m.group(2) +
"']";
-
- sb.append("\" + ((!!" + paramAccess + ") ? " + paramAccess +
" : \"\") + \"");
- } else {
- StringBuffer sbUnEsc = new StringBuffer();
- sbUnEsc.append(string.substring(lastPosition, m.end(1) - 1));
- sbUnEsc.append("{");
- sbUnEsc.append(m.group(2));
- sbUnEsc.append("}");
-
- sb.append(StringEscapeUtils.escapeJavaScript(sbUnEsc.toString()));
- }
-
- lastPosition = m.end(2) + 1;
- }
- if (lastPosition < string.length()) {
- sb.append(StringEscapeUtils.escapeJavaScript(string.substring(lastPosition)));
- }
- sb.append("\"");
- return sb.toString();
- }
-
- public static void main(String[] args) {
- System.out.println(TemplateUtil.replaceParams("test string \" \n with
\\{pa\\rams} {name} \"and {value}1", "params"));
- }
-}
Modified: trunk/sandbox/calendar/pom.xml
===================================================================
--- trunk/sandbox/calendar/pom.xml 2007-06-14 19:19:27 UTC (rev 1192)
+++ trunk/sandbox/calendar/pom.xml 2007-06-15 00:03:21 UTC (rev 1193)
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
- <artifactId>sandbox-parent</artifactId>
+ <artifactId>richfaces-parent</artifactId>
<groupId>org.richfaces</groupId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>3.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces</groupId>
@@ -17,14 +17,14 @@
<version>1.1.2-SNAPSHOT</version>
<executions>
<execution>
- <id>generate-sources</id>
+ <id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
<execution>
- <id>generate-test-sources</id>
+ <id>generate-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generate-tests</goal>
@@ -50,3 +50,4 @@
</dependency>
</dependencies>
</project>
+
Modified: trunk/sandbox/calendar/src/main/java/org/richfaces/component/UICalendar.java
===================================================================
---
trunk/sandbox/calendar/src/main/java/org/richfaces/component/UICalendar.java 2007-06-14
19:19:27 UTC (rev 1192)
+++
trunk/sandbox/calendar/src/main/java/org/richfaces/component/UICalendar.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -1,5 +1,22 @@
/**
+ * License Agreement.
*
+ * JBoss RichFaces 3.0 - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.richfaces.component;
@@ -12,7 +29,7 @@
*/
public abstract class UICalendar extends UIComponentBase {
- private static final String COMPONENT_TYPE = "org.richfaces.Calendar";
+ public static final String COMPONENT_TYPE = "org.richfaces.Calendar";
private static final String COMPONENT_FAMILY = "org.richfaces.Calendar";
Added:
trunk/sandbox/calendar/src/main/java/org/richfaces/renderkit/CalendarRendererBase.java
===================================================================
---
trunk/sandbox/calendar/src/main/java/org/richfaces/renderkit/CalendarRendererBase.java
(rev 0)
+++
trunk/sandbox/calendar/src/main/java/org/richfaces/renderkit/CalendarRendererBase.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -0,0 +1,157 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces 3.0 - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.renderkit;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Properties;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.ajax4jsf.framework.ajax.xmlfilter.tidy.TidyParser;
+import org.ajax4jsf.framework.ajax.xmlfilter.tidy.TidyXMLFilter;
+import org.ajax4jsf.framework.renderer.HeaderResourcesRendererBase;
+import org.richfaces.component.UICalendar;
+import org.richfaces.json.JSContentHandler;
+import org.richfaces.org.apache.commons.lang.StringEscapeUtils;
+import org.richfaces.renderkit.TemplateUtil.MacroTemplateHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Nick Belaevski - mailto:nbelaevski@exadel.com
+ * created 08.06.2007
+ *
+ */
+public class CalendarRendererBase extends HeaderResourcesRendererBase {
+
+ private static final MacroTemplateHandler macroTemplateHandler = new
MacroTemplateHandler() {
+
+ public String handle(String body) {
+ return "calendarEval(\"" +
+ StringEscapeUtils.escapeJavaScript(body) + "\", context)";
+ }
+
+ };
+
+ private TransformerFactory transformerFactory;
+
+ public CalendarRendererBase() {
+ super();
+
+ transformerFactory = TransformerFactory.newInstance();
+ }
+
+ /* (non-Javadoc)
+ * @see org.ajax4jsf.framework.renderer.RendererBase#getComponentClass()
+ */
+ protected Class getComponentClass() {
+ return UICalendar.class;
+ }
+
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ public void encodeChildren(FacesContext context, UIComponent component)
+ throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+ StringWriter dumpingWriter = new StringWriter();
+ ResponseWriter clonedWriter = writer.cloneWithWriter(dumpingWriter);
+ context.setResponseWriter(clonedWriter);
+ try {
+ renderChildren(context, component);
+ } finally {
+ clonedWriter.flush();
+ context.setResponseWriter(writer);
+ }
+
+ Properties tidyProperties = new Properties();
+ InputStream propertiesStream = null;
+ try {
+ propertiesStream =
TidyXMLFilter.class.getResourceAsStream("tidy.properties");
+ tidyProperties.load(propertiesStream);
+ } finally {
+ if (propertiesStream != null) {
+ propertiesStream.close();
+ }
+ }
+
+ TidyParser tidyParser = new TidyParser(tidyProperties);
+ Document parsedHtml = tidyParser.parseHtmlByTidy(new
StringReader(dumpingWriter.toString()), null);
+ NodeList nodeList = parsedHtml.getDocumentElement().getChildNodes();
+ Node bodyNode = nodeList.item(nodeList.getLength() - 1);
+ NodeList bodyChildren = bodyNode.getChildNodes();
+ int bodyChildrenLength = bodyChildren.getLength();
+
+ writer.startElement("script", component);
+ writer.write("var calendarEval = function (string, context) { return string;
};");
+
+ writer.write("var evaluator = new Object(); evaluator.parts = [ ");
+
+ try {
+ Transformer transformer = transformerFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+
+ JSContentHandler contentHandler = new JSContentHandler(writer) {
+ protected void encodeAttributeValue(Attributes attributes,
+ int idx) throws SAXException, IOException {
+
+ String value = attributes.getValue(idx);
+ outputWriter.write("function (context) { return " +
TemplateUtil.replaceParams(value, macroTemplateHandler) + ";}");
+ }
+ };
+ Result result = new SAXResult(contentHandler);
+
+ for (int i = 0; i < bodyChildrenLength; i++) {
+ if (i != 0) {
+ writer.write(", ");
+ }
+ transformer.transform(new DOMSource(bodyChildren.item(i)), result);
+ }
+ } catch (TransformerException e) {
+ throw new IOException(e.getMessage(), e);
+ }
+
+ writer.write("]; evaluator.evaluate = function (context) { var result =
'';");
+ writer.write(" for (var i = 0; i < this.parts.length; i++) result +=
this.parts[i].getOuterHTML(context); return result;};\n");
+
+ writer.write("new Insertion.Top($('" + component.getClientId(context) +
"'), evaluator.evaluate(null));");
+ writer.endElement("script");
+ }
+}
Modified: trunk/sandbox/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx
===================================================================
--- trunk/sandbox/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx 2007-06-14
19:19:27 UTC (rev 1192)
+++ trunk/sandbox/calendar/src/main/templates/org/richfaces/htmlCalendar.jspx 2007-06-15
00:03:21 UTC (rev 1193)
@@ -5,13 +5,17 @@
xmlns:ui="
http://ajax4jsf.org/cdk/ui"
xmlns:u="
http://ajax4jsf.org/cdk/u"
xmlns:x="
http://ajax4jsf.org/cdk/x"
+ xmlns:vcp="
http://ajax4jsf.org/cdk/vcp"
class="org.richfaces.renderkit.html.CalendarRenderer"
- baseclass="org.ajax4jsf.framework.renderer.AjaxComponentRendererBase"
+ baseclass="org.richfaces.renderkit.CalendarRendererBase"
component="org.richfaces.component.UICalendar"
<f:clientid var="clientId"/>
+ <h:scripts>new
org.ajax4jsf.framework.resource.PrototypeScript(),/org/richfaces/renderkit/html/scripts/json/json-dom.js</h:scripts>
<div id="#{clientId}"
x:passThruWithExclusions="value,name,type,id"
+
+ <vcp:body />
</div>
</f:root>
\ No newline at end of file
Added:
trunk/sandbox/calendar/src/test/java/org/richfaces/component/CalendarComponentTest.java
===================================================================
---
trunk/sandbox/calendar/src/test/java/org/richfaces/component/CalendarComponentTest.java
(rev 0)
+++
trunk/sandbox/calendar/src/test/java/org/richfaces/component/CalendarComponentTest.java 2007-06-15
00:03:21 UTC (rev 1193)
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+import java.util.List;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlOutputText;
+
+import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
+
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+
+/**
+ * @author Nick Belaevski - mailto:nbelaevski@exadel.com
+ * created 08.06.2007
+ *
+ */
+public class CalendarComponentTest extends AbstractAjax4JsfTestCase {
+
+ public CalendarComponentTest(String name) {
+ super(name);
+ }
+
+ public void testTidy() throws Exception {
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ List children = viewRoot.getChildren();
+ UIComponent calendar = application.createComponent(UICalendar.COMPONENT_TYPE);
+ children.add(calendar);
+ HtmlOutputText output = (HtmlOutputText)
application.createComponent(HtmlOutputText.COMPONENT_TYPE);
+ output.setValue("<br> &<a href='#'>");
+ output.setEscape(false);
+ calendar.getChildren().add(output);
+
+ HtmlPage renderView = renderView();
+ System.out.println(renderView.asXml());
+ }
+}