You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/05/13 18:37:00 UTC
svn commit: r406128 [15/27] - in
/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo:
./ src/ src/animation/ src/collections/ src/compat/ src/crypto/ src/data/
src/data/format/ src/data/provider/ src/debug/ src/dnd/ src/event/ sr...
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/storage/storage_dialog.fla
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/storage/storage_dialog.fla?rev=406128&view=auto
==============================================================================
Binary file - no diff available.
Propchange: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/storage/storage_dialog.fla
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string.js Sat May 13 09:36:25 2006
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.string");
+dojo.require("dojo.string.common");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/Builder.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/Builder.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/Builder.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/Builder.js Sat May 13 09:36:25 2006
@@ -0,0 +1,105 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.string.Builder");
+dojo.require("dojo.string");
+
+// NOTE: testing shows that direct "+=" concatenation is *much* faster on
+// Spidermoneky and Rhino, while arr.push()/arr.join() style concatenation is
+// significantly quicker on IE (Jscript/wsh/etc.).
+
+dojo.string.Builder = function(str){
+ this.arrConcat = (dojo.render.html.capable && dojo.render.html["ie"]);
+
+ var a = [];
+ var b = str || "";
+ var length = this.length = b.length;
+
+ if(this.arrConcat){
+ if(b.length > 0){
+ a.push(b);
+ }
+ b = "";
+ }
+
+ this.toString = this.valueOf = function(){
+ return (this.arrConcat) ? a.join("") : b;
+ };
+
+ this.append = function(s){
+ if(this.arrConcat){
+ a.push(s);
+ }else{
+ b+=s;
+ }
+ length += s.length;
+ this.length = length;
+ return this;
+ };
+
+ this.clear = function(){
+ a = [];
+ b = "";
+ length = this.length = 0;
+ return this;
+ };
+
+ this.remove = function(f,l){
+ var s = "";
+ if(this.arrConcat){
+ b = a.join("");
+ }
+ a=[];
+ if(f>0){
+ s = b.substring(0, (f-1));
+ }
+ b = s + b.substring(f + l);
+ length = this.length = b.length;
+ if(this.arrConcat){
+ a.push(b);
+ b="";
+ }
+ return this;
+ };
+
+ this.replace = function(o,n){
+ if(this.arrConcat){
+ b = a.join("");
+ }
+ a = [];
+ b = b.replace(o,n);
+ length = this.length = b.length;
+ if(this.arrConcat){
+ a.push(b);
+ b="";
+ }
+ return this;
+ };
+
+ this.insert = function(idx,s){
+ if(this.arrConcat){
+ b = a.join("");
+ }
+ a=[];
+ if(idx == 0){
+ b = s + b;
+ }else{
+ var t = b.split("");
+ t.splice(idx,0,s);
+ b = t.join("")
+ }
+ length = this.length = b.length;
+ if(this.arrConcat){
+ a.push(b);
+ b="";
+ }
+ return this;
+ };
+};
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/__package__.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/__package__.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/__package__.js Sat May 13 09:36:25 2006
@@ -0,0 +1,19 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+ common: [
+ "dojo.string",
+ "dojo.string.common",
+ "dojo.string.extras",
+ "dojo.string.Builder"
+ ]
+});
+dojo.provide("dojo.string.*");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/common.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/common.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/common.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/common.js Sat May 13 09:36:25 2006
@@ -0,0 +1,87 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.string.common");
+
+dojo.require("dojo.string");
+
+/**
+ * Trim whitespace from 'str'. If 'wh' > 0,
+ * only trim from start, if 'wh' < 0, only trim
+ * from end, otherwise trim both ends
+ */
+dojo.string.trim = function(str, wh){
+ if(!str.replace){ return str; }
+ if(!str.length){ return str; }
+ var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g);
+ return str.replace(re, "");
+}
+
+/**
+ * Trim whitespace at the beginning of 'str'
+ */
+dojo.string.trimStart = function(str) {
+ return dojo.string.trim(str, 1);
+}
+
+/**
+ * Trim whitespace at the end of 'str'
+ */
+dojo.string.trimEnd = function(str) {
+ return dojo.string.trim(str, -1);
+}
+
+/**
+ * Return 'str' repeated 'count' times, optionally
+ * placing 'separator' between each rep
+ */
+dojo.string.repeat = function(str, count, separator) {
+ var out = "";
+ for(var i = 0; i < count; i++) {
+ out += str;
+ if(separator && i < count - 1) {
+ out += separator;
+ }
+ }
+ return out;
+}
+
+/**
+ * Pad 'str' to guarantee that it is at least 'len' length
+ * with the character 'c' at either the start (dir=1) or
+ * end (dir=-1) of the string
+ */
+dojo.string.pad = function(str, len/*=2*/, c/*='0'*/, dir/*=1*/) {
+ var out = String(str);
+ if(!c) {
+ c = '0';
+ }
+ if(!dir) {
+ dir = 1;
+ }
+ while(out.length < len) {
+ if(dir > 0) {
+ out = c + out;
+ } else {
+ out += c;
+ }
+ }
+ return out;
+}
+
+/** same as dojo.string.pad(str, len, c, 1) */
+dojo.string.padLeft = function(str, len, c) {
+ return dojo.string.pad(str, len, c, 1);
+}
+
+/** same as dojo.string.pad(str, len, c, -1) */
+dojo.string.padRight = function(str, len, c) {
+ return dojo.string.pad(str, len, c, -1);
+}
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/extras.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/extras.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/extras.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/string/extras.js Sat May 13 09:36:25 2006
@@ -0,0 +1,221 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.string.extras");
+
+dojo.require("dojo.string.common");
+dojo.require("dojo.lang");
+
+/**
+ * Parameterized string function
+ * str - formatted string with %{values} to be replaces
+ * pairs - object of name: "value" value pairs
+ * killExtra - remove all remaining %{values} after pairs are inserted
+ */
+dojo.string.paramString = function(str, pairs, killExtra) {
+ for(var name in pairs) {
+ var re = new RegExp("\\%\\{" + name + "\\}", "g");
+ str = str.replace(re, pairs[name]);
+ }
+
+ if(killExtra) { str = str.replace(/%\{([^\}\s]+)\}/g, ""); }
+ return str;
+}
+
+/** Uppercases the first letter of each word */
+dojo.string.capitalize = function (str) {
+ if (!dojo.lang.isString(str)) { return ""; }
+ if (arguments.length == 0) { str = this; }
+ var words = str.split(' ');
+ var retval = "";
+ var len = words.length;
+ for (var i=0; i<len; i++) {
+ var word = words[i];
+ word = word.charAt(0).toUpperCase() + word.substring(1, word.length);
+ retval += word;
+ if (i < len-1)
+ retval += " ";
+ }
+
+ return new String(retval);
+}
+
+/**
+ * Return true if the entire string is whitespace characters
+ */
+dojo.string.isBlank = function (str) {
+ if(!dojo.lang.isString(str)) { return true; }
+ return (dojo.string.trim(str).length == 0);
+}
+
+dojo.string.encodeAscii = function(str) {
+ if(!dojo.lang.isString(str)) { return str; }
+ var ret = "";
+ var value = escape(str);
+ var match, re = /%u([0-9A-F]{4})/i;
+ while((match = value.match(re))) {
+ var num = Number("0x"+match[1]);
+ var newVal = escape("&#" + num + ";");
+ ret += value.substring(0, match.index) + newVal;
+ value = value.substring(match.index+match[0].length);
+ }
+ ret += value.replace(/\+/g, "%2B");
+ return ret;
+}
+
+dojo.string.escape = function(type, str) {
+ var args = [];
+ for(var i = 1; i < arguments.length; i++) { args.push(arguments[i]); }
+ switch(type.toLowerCase()) {
+ case "xml":
+ case "html":
+ case "xhtml":
+ return dojo.string.escapeXml.apply(this, args);
+ case "sql":
+ return dojo.string.escapeSql.apply(this, args);
+ case "regexp":
+ case "regex":
+ return dojo.string.escapeRegExp.apply(this, args);
+ case "javascript":
+ case "jscript":
+ case "js":
+ return dojo.string.escapeJavaScript.apply(this, args);
+ case "ascii":
+ // so it's encode, but it seems useful
+ return dojo.string.encodeAscii.apply(this, args);
+ default:
+ return str;
+ }
+}
+
+dojo.string.escapeXml = function(str, noSingleQuotes) {
+ str = str.replace(/&/gm, "&").replace(/</gm, "<")
+ .replace(/>/gm, ">").replace(/"/gm, """);
+ if(!noSingleQuotes) { str = str.replace(/'/gm, "'"); }
+ return str;
+}
+
+dojo.string.escapeSql = function(str) {
+ return str.replace(/'/gm, "''");
+}
+
+dojo.string.escapeRegExp = function(str) {
+ return str.replace(/\\/gm, "\\\\").replace(/([\f\b\n\t\r[\^$|?*+(){}])/gm, "\\$1");
+}
+
+dojo.string.escapeJavaScript = function(str) {
+ return str.replace(/(["'\f\b\n\t\r])/gm, "\\$1");
+}
+
+dojo.string.escapeString = function(str){
+ return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\r]/g, "\\r");
+}
+
+// TODO: make an HTML version
+dojo.string.summary = function(str, len) {
+ if(!len || str.length <= len) {
+ return str;
+ } else {
+ return str.substring(0, len).replace(/\.+$/, "") + "...";
+ }
+}
+
+/**
+ * Returns true if 'str' ends with 'end'
+ */
+dojo.string.endsWith = function(str, end, ignoreCase) {
+ if(ignoreCase) {
+ str = str.toLowerCase();
+ end = end.toLowerCase();
+ }
+ if((str.length - end.length) < 0){
+ return false;
+ }
+ return str.lastIndexOf(end) == str.length - end.length;
+}
+
+/**
+ * Returns true if 'str' ends with any of the arguments[2 -> n]
+ */
+dojo.string.endsWithAny = function(str /* , ... */) {
+ for(var i = 1; i < arguments.length; i++) {
+ if(dojo.string.endsWith(str, arguments[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Returns true if 'str' starts with 'start'
+ */
+dojo.string.startsWith = function(str, start, ignoreCase) {
+ if(ignoreCase) {
+ str = str.toLowerCase();
+ start = start.toLowerCase();
+ }
+ return str.indexOf(start) == 0;
+}
+
+/**
+ * Returns true if 'str' starts with any of the arguments[2 -> n]
+ */
+dojo.string.startsWithAny = function(str /* , ... */) {
+ for(var i = 1; i < arguments.length; i++) {
+ if(dojo.string.startsWith(str, arguments[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Returns true if 'str' starts with any of the arguments 2 -> n
+ */
+dojo.string.has = function(str /* , ... */) {
+ for(var i = 1; i < arguments.length; i++) {
+ if(str.indexOf(arguments[i]) > -1){
+ return true;
+ }
+ }
+ return false;
+}
+
+dojo.string.normalizeNewlines = function (text,newlineChar) {
+ if (newlineChar == "\n") {
+ text = text.replace(/\r\n/g, "\n");
+ text = text.replace(/\r/g, "\n");
+ } else if (newlineChar == "\r") {
+ text = text.replace(/\r\n/g, "\r");
+ text = text.replace(/\n/g, "\r");
+ } else {
+ text = text.replace(/([^\r])\n/g, "$1\r\n");
+ text = text.replace(/\r([^\n])/g, "\r\n$1");
+ }
+ return text;
+}
+
+dojo.string.splitEscaped = function (str,charac) {
+ var components = [];
+ for (var i = 0, prevcomma = 0; i < str.length; i++) {
+ if (str.charAt(i) == '\\') { i++; continue; }
+ if (str.charAt(i) == charac) {
+ components.push(str.substring(prevcomma, i));
+ prevcomma = i + 1;
+ }
+ }
+ components.push(str.substr(prevcomma));
+ return components;
+}
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/style.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/style.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/style.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/style.js Sat May 13 09:36:25 2006
@@ -0,0 +1,782 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.style");
+dojo.require("dojo.graphics.color");
+dojo.require("dojo.uri.Uri");
+dojo.require("dojo.lang.common");
+
+(function(){
+ var h = dojo.render.html;
+ var ds = dojo.style;
+ var db = document["body"]||document["documentElement"];
+
+ ds.boxSizing = {
+ MARGIN_BOX: "margin-box",
+ BORDER_BOX: "border-box",
+ PADDING_BOX: "padding-box",
+ CONTENT_BOX: "content-box"
+ };
+ var bs = ds.boxSizing;
+
+ ds.getBoxSizing = function(node){
+ if((h.ie)||(h.opera)){
+ var cm = document["compatMode"];
+ if((cm == "BackCompat")||(cm == "QuirksMode")){
+ return bs.BORDER_BOX;
+ }else{
+ return bs.CONTENT_BOX;
+ }
+ }else{
+ if(arguments.length == 0){ node = document.documentElement; }
+ var sizing = ds.getStyle(node, "-moz-box-sizing");
+ if(!sizing){ sizing = ds.getStyle(node, "box-sizing"); }
+ return (sizing ? sizing : bs.CONTENT_BOX);
+ }
+ }
+
+ /*
+
+ The following several function use the dimensions shown below
+
+ +-------------------------+
+ | margin |
+ | +---------------------+ |
+ | | border | |
+ | | +-----------------+ | |
+ | | | padding | | |
+ | | | +-------------+ | | |
+ | | | | content | | | |
+ | | | +-------------+ | | |
+ | | +-|-------------|-+ | |
+ | +-|-|-------------|-|-+ |
+ +-|-|-|-------------|-|-|-+
+ | | | | | | | |
+ | | | |<- content ->| | | |
+ | |<------ inner ------>| |
+ |<-------- outer -------->|
+ +-------------------------+
+
+ * content-box
+
+ |m|b|p| |p|b|m|
+ | |<------ offset ----->| |
+ | | |<---- client --->| | |
+ | | | |<-- width -->| | | |
+
+ * border-box
+
+ |m|b|p| |p|b|m|
+ | |<------ offset ----->| |
+ | | |<---- client --->| | |
+ | |<------ width ------>| |
+ */
+
+ /*
+ Notes:
+
+ General:
+ - Uncomputable values are returned as NaN.
+ - setOuterWidth/Height return *false* if the outer size could not
+ be computed, otherwise *true*.
+ - (sjmiles) knows no way to find the calculated values for auto-margins.
+ - All returned values are floating point in 'px' units. If a
+ non-zero computed style value is not specified in 'px', NaN is
+ returned.
+
+ FF:
+ - styles specified as '0' (unitless 0) show computed as '0pt'.
+
+ IE:
+ - clientWidth/Height are unreliable (0 unless the object has 'layout').
+ - margins must be specified in px, or 0 (in any unit) for any
+ sizing function to work. Otherwise margins detect as 'auto'.
+ - padding can be empty or, if specified, must be in px, or 0 (in
+ any unit) for any sizing function to work.
+
+ Safari:
+ - Safari defaults padding values to 'auto'.
+
+ See the unit tests for examples of (un)computable values in a given browser.
+
+ */
+
+ // FIXME: these work for some elements (e.g. DIV) but not others (e.g. TABLE, TEXTAREA)
+
+ ds.isBorderBox = function(node){
+ return (ds.getBoxSizing(node) == bs.BORDER_BOX);
+ }
+
+ ds.getUnitValue = function(node, cssSelector, autoIsZero){
+ var s = ds.getComputedStyle(node, cssSelector);
+ if((!s)||((s == 'auto')&&(autoIsZero))){ return { value: 0, units: 'px' }; }
+ if(dojo.lang.isUndefined(s)){return ds.getUnitValue.bad;}
+ // FIXME: is regex inefficient vs. parseInt or some manual test?
+ var match = s.match(/(\-?[\d.]+)([a-z%]*)/i);
+ if (!match){return ds.getUnitValue.bad;}
+ return { value: Number(match[1]), units: match[2].toLowerCase() };
+ }
+ // FIXME: 'bad' value should be 0?
+ ds.getUnitValue.bad = { value: NaN, units: '' };
+
+ ds.getPixelValue = function(node, cssSelector, autoIsZero){
+ var result = ds.getUnitValue(node, cssSelector, autoIsZero);
+ // FIXME: there is serious debate as to whether or not this is the right solution
+ if(isNaN(result.value)){ return 0; }
+ // FIXME: code exists for converting other units to px (see Dean Edward's IE7)
+ // but there are cross-browser complexities
+ if((result.value)&&(result.units != 'px')){ return NaN; }
+ return result.value;
+ }
+
+ // FIXME: deprecated
+ ds.getNumericStyle = function() {
+ dojo.deprecated('dojo.(style|html).getNumericStyle', 'in favor of dojo.(style|html).getPixelValue', '0.4');
+ return ds.getPixelValue.apply(this, arguments);
+ }
+
+ ds.setPositivePixelValue = function(node, selector, value){
+ if(isNaN(value)){return false;}
+ node.style[selector] = Math.max(0, value) + 'px';
+ return true;
+ }
+
+ ds._sumPixelValues = function(node, selectors, autoIsZero){
+ var total = 0;
+ for(x=0; x<selectors.length; x++){
+ total += ds.getPixelValue(node, selectors[x], autoIsZero);
+ }
+ return total;
+ }
+
+ ds.isPositionAbsolute = function(node){
+ return (ds.getComputedStyle(node, 'position') == 'absolute');
+ }
+
+ ds.getBorderExtent = function(node, side){
+ return (ds.getStyle(node, 'border-' + side + '-style') == 'none' ? 0 : ds.getPixelValue(node, 'border-' + side + '-width'));
+ }
+
+ ds.getMarginWidth = function(node){
+ return ds._sumPixelValues(node, ["margin-left", "margin-right"], ds.isPositionAbsolute(node));
+ }
+
+ ds.getBorderWidth = function(node){
+ return ds.getBorderExtent(node, 'left') + ds.getBorderExtent(node, 'right');
+ }
+
+ ds.getPaddingWidth = function(node){
+ return ds._sumPixelValues(node, ["padding-left", "padding-right"], true);
+ }
+
+ ds.getPadBorderWidth = function(node) {
+ return ds.getPaddingWidth(node) + ds.getBorderWidth(node);
+ }
+
+ ds.getContentBoxWidth = function(node){
+ node = dojo.byId(node);
+ return node.offsetWidth - ds.getPadBorderWidth(node);
+ }
+
+ ds.getBorderBoxWidth = function(node){
+ node = dojo.byId(node);
+ return node.offsetWidth;
+ }
+
+ ds.getMarginBoxWidth = function(node){
+ return ds.getInnerWidth(node) + ds.getMarginWidth(node);
+ }
+
+ ds.setContentBoxWidth = function(node, pxWidth){
+ node = dojo.byId(node);
+ if (ds.isBorderBox(node)){
+ pxWidth += ds.getPadBorderWidth(node);
+ }
+ return ds.setPositivePixelValue(node, "width", pxWidth);
+ }
+
+ ds.setMarginBoxWidth = function(node, pxWidth){
+ node = dojo.byId(node);
+ if (!ds.isBorderBox(node)){
+ pxWidth -= ds.getPadBorderWidth(node);
+ }
+ pxWidth -= ds.getMarginWidth(node);
+ return ds.setPositivePixelValue(node, "width", pxWidth);
+ }
+
+ // FIXME: deprecate and remove
+ ds.getContentWidth = ds.getContentBoxWidth;
+ ds.getInnerWidth = ds.getBorderBoxWidth;
+ ds.getOuterWidth = ds.getMarginBoxWidth;
+ ds.setContentWidth = ds.setContentBoxWidth;
+ ds.setOuterWidth = ds.setMarginBoxWidth;
+
+ ds.getMarginHeight = function(node){
+ return ds._sumPixelValues(node, ["margin-top", "margin-bottom"], ds.isPositionAbsolute(node));
+ }
+
+ ds.getBorderHeight = function(node){
+ return ds.getBorderExtent(node, 'top') + ds.getBorderExtent(node, 'bottom');
+ }
+
+ ds.getPaddingHeight = function(node){
+ return ds._sumPixelValues(node, ["padding-top", "padding-bottom"], true);
+ }
+
+ ds.getPadBorderHeight = function(node) {
+ return ds.getPaddingHeight(node) + ds.getBorderHeight(node);
+ }
+
+ ds.getContentBoxHeight = function(node){
+ node = dojo.byId(node);
+ return node.offsetHeight - ds.getPadBorderHeight(node);
+ }
+
+ ds.getBorderBoxHeight = function(node){
+ node = dojo.byId(node);
+ return node.offsetHeight; // FIXME: does this work?
+ }
+
+ ds.getMarginBoxHeight = function(node){
+ return ds.getInnerHeight(node) + ds.getMarginHeight(node);
+ }
+
+ ds.setContentBoxHeight = function(node, pxHeight){
+ node = dojo.byId(node);
+ if (ds.isBorderBox(node)){
+ pxHeight += ds.getPadBorderHeight(node);
+ }
+ return ds.setPositivePixelValue(node, "height", pxHeight);
+ }
+
+ ds.setMarginBoxHeight = function(node, pxHeight){
+ node = dojo.byId(node);
+ if (!ds.isBorderBox(node)){
+ pxHeight -= ds.getPadBorderHeight(node);
+ }
+ pxHeight -= ds.getMarginHeight(node);
+ return ds.setPositivePixelValue(node, "height", pxHeight);
+ }
+
+ // FIXME: deprecate and remove
+ ds.getContentHeight = ds.getContentBoxHeight;
+ ds.getInnerHeight = ds.getBorderBoxHeight;
+ ds.getOuterHeight = ds.getMarginBoxHeight;
+ ds.setContentHeight = ds.setContentBoxHeight;
+ ds.setOuterHeight = ds.setMarginBoxHeight;
+
+ /**
+ * dojo.style.getAbsolutePosition(xyz, true) returns xyz's position relative to the document.
+ * Itells you where you would position a node
+ * inside document.body such that it was on top of xyz. Most people set the flag to true when calling
+ * getAbsolutePosition().
+ *
+ * dojo.style.getAbsolutePosition(xyz, false) returns xyz's position relative to the viewport.
+ * It returns the position that would be returned
+ * by event.clientX/Y if the mouse were directly over the top/left of this node.
+ */
+ ds.getAbsolutePosition = ds.abs = function(node, includeScroll){
+ var ret = [];
+ ret.x = ret.y = 0;
+ var st = dojo.html.getScrollTop();
+ var sl = dojo.html.getScrollLeft();
+
+ if(h.ie){
+ with(node.getBoundingClientRect()){
+ ret.x = left-2;
+ ret.y = top-2;
+ }
+/**
+ }else if(document.getBoxObjectFor){
+ // mozilla
+ var bo=document.getBoxObjectFor(node);
+ ret.x=bo.x-sl;
+ ret.y=bo.y-st;
+**/ }else{
+ if(node["offsetParent"]){
+ var endNode;
+ // in Safari, if the node is an absolutely positioned child of
+ // the body and the body has a margin the offset of the child
+ // and the body contain the body's margins, so we need to end
+ // at the body
+ if( (h.safari)&&
+ (node.style.getPropertyValue("position") == "absolute")&&
+ (node.parentNode == db)){
+ endNode = db;
+ }else{
+ endNode = db.parentNode;
+ }
+
+ if(node.parentNode != db){
+ ret.x -= ds.sumAncestorProperties(node, "scrollLeft");
+ ret.y -= ds.sumAncestorProperties(node, "scrollTop");
+ }
+ do{
+ var n = node["offsetLeft"];
+ ret.x += isNaN(n) ? 0 : n;
+ var m = node["offsetTop"];
+ ret.y += isNaN(m) ? 0 : m;
+ node = node.offsetParent;
+ }while((node != endNode)&&(node != null));
+ }else if(node["x"]&&node["y"]){
+ ret.x += isNaN(node.x) ? 0 : node.x;
+ ret.y += isNaN(node.y) ? 0 : node.y;
+ }
+ }
+
+ // account for document scrolling!
+ if(includeScroll){
+ ret.y += st;
+ ret.x += sl;
+ }
+
+ ret[0] = ret.x;
+ ret[1] = ret.y;
+ return ret;
+ }
+
+ ds.sumAncestorProperties = function(node, prop){
+ node = dojo.byId(node);
+ if(!node){ return 0; } // FIXME: throw an error?
+
+ var retVal = 0;
+ while(node){
+ var val = node[prop];
+ if(val){
+ retVal += val - 0;
+ }
+ node = node.parentNode;
+ }
+ return retVal;
+ }
+
+ ds.getTotalOffset = function(node, type, includeScroll){
+ node = dojo.byId(node);
+ return ds.abs(node, includeScroll)[(type == "top") ? "y" : "x"];
+ }
+
+ ds.getAbsoluteX = ds.totalOffsetLeft = function(node, includeScroll){
+ return ds.getTotalOffset(node, "left", includeScroll);
+ }
+
+ ds.getAbsoluteY = ds.totalOffsetTop = function(node, includeScroll){
+ return ds.getTotalOffset(node, "top", includeScroll);
+ }
+
+ ds.styleSheet = null;
+
+ // FIXME: this is a really basic stub for adding and removing cssRules, but
+ // it assumes that you know the index of the cssRule that you want to add
+ // or remove, making it less than useful. So we need something that can
+ // search for the selector that you you want to remove.
+ ds.insertCssRule = function(selector, declaration, index) {
+ if (!ds.styleSheet) {
+ if (document.createStyleSheet) { // IE
+ ds.styleSheet = document.createStyleSheet();
+ } else if (document.styleSheets[0]) { // rest
+ // FIXME: should create a new style sheet here
+ // fall back on an exsiting style sheet
+ ds.styleSheet = document.styleSheets[0];
+ } else { return null; } // fail
+ }
+
+ if (arguments.length < 3) { // index may == 0
+ if (ds.styleSheet.cssRules) { // W3
+ index = ds.styleSheet.cssRules.length;
+ } else if (ds.styleSheet.rules) { // IE
+ index = ds.styleSheet.rules.length;
+ } else { return null; } // fail
+ }
+
+ if (ds.styleSheet.insertRule) { // W3
+ var rule = selector + " { " + declaration + " }";
+ return ds.styleSheet.insertRule(rule, index);
+ } else if (ds.styleSheet.addRule) { // IE
+ return ds.styleSheet.addRule(selector, declaration, index);
+ } else { return null; } // fail
+ }
+
+ ds.removeCssRule = function(index){
+ if(!ds.styleSheet){
+ dojo.debug("no stylesheet defined for removing rules");
+ return false;
+ }
+ if(h.ie){
+ if(!index){
+ index = ds.styleSheet.rules.length;
+ ds.styleSheet.removeRule(index);
+ }
+ }else if(document.styleSheets[0]){
+ if(!index){
+ index = ds.styleSheet.cssRules.length;
+ }
+ ds.styleSheet.deleteRule(index);
+ }
+ return true;
+ }
+
+ // calls css by XmlHTTP and inserts it into DOM as <style [widgetType="widgetType"]> *downloaded cssText*</style>
+ ds.insertCssFile = function(URI, doc, checkDuplicates){
+ if(!URI){ return; }
+ if(!doc){ doc = document; }
+ var cssStr = dojo.hostenv.getText(URI);
+ cssStr = ds.fixPathsInCssText(cssStr, URI);
+
+ if(checkDuplicates){
+ var styles = doc.getElementsByTagName("style");
+ var cssText = "";
+ for(var i = 0; i<styles.length; i++){
+ cssText = (styles[i].styleSheet && styles[i].styleSheet.cssText) ? styles[i].styleSheet.cssText : styles[i].innerHTML;
+ if(cssStr == cssText){ return; }
+ }
+ }
+
+ var style = ds.insertCssText(cssStr);
+ // insert custom attribute ex dbgHref="../foo.css" usefull when debugging in DOM inspectors, no?
+ if(style && djConfig.isDebug){
+ style.setAttribute("dbgHref", URI);
+ }
+ return style
+ }
+
+ // DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ])
+ ds.insertCssText = function(cssStr, doc, URI){
+ if(!cssStr){ return; }
+ if(!doc){ doc = document; }
+ if(URI){// fix paths in cssStr
+ cssStr = ds.fixPathsInCssText(cssStr, URI);
+ }
+ var style = doc.createElement("style");
+ style.setAttribute("type", "text/css");
+ if(style.styleSheet){// IE
+ style.styleSheet.cssText = cssStr;
+ } else {// w3c
+ var cssText = doc.createTextNode(cssStr);
+ style.appendChild(cssText);
+ }
+ var head = doc.getElementsByTagName("head")[0];
+ if(!head){ // must have a head tag
+ dojo.debug("No head tag in document, aborting styles");
+ }else{
+ head.appendChild(style);
+ }
+ return style;
+ }
+
+ // String cssText = fixPathsInCssText(String cssStr, dojo.uri.Uri URI)
+ // usage: cssText comes from dojoroot/src/widget/templates/HtmlFoobar.css
+ // it has .dojoFoo { background-image: url(images/bar.png);}
+ // then uri should point to dojoroot/src/widget/templates/
+ ds.fixPathsInCssText = function(cssStr, URI){
+ if(!cssStr || !URI){ return; }
+ var pos = 0; var str = ""; var url = "";
+ while(pos!=-1){
+ pos = 0;url = "";
+ pos = cssStr.indexOf("url(", pos);
+ if(pos<0){ break; }
+ str += cssStr.slice(0,pos+4);
+ cssStr = cssStr.substring(pos+4, cssStr.length);
+ url += cssStr.match(/^[\t\s\w()\/.\\'"-:#=&?]*\)/)[0]; // url string
+ cssStr = cssStr.substring(url.length-1, cssStr.length); // remove url from css string til next loop
+ url = url.replace(/^[\s\t]*(['"]?)([\w()\/.\\'"-:#=&?]*)\1[\s\t]*?\)/,"$2"); // clean string
+ if(url.search(/(file|https?|ftps?):\/\//)==-1){
+ url = (new dojo.uri.Uri(URI,url).toString());
+ }
+ str += url;
+ };
+ return str+cssStr;
+ }
+
+ ds.getBackgroundColor = function(node) {
+ node = dojo.byId(node);
+ var color;
+ do{
+ color = ds.getStyle(node, "background-color");
+ // Safari doesn't say "transparent"
+ if(color.toLowerCase() == "rgba(0, 0, 0, 0)") { color = "transparent"; }
+ if(node == document.getElementsByTagName("body")[0]) { node = null; break; }
+ node = node.parentNode;
+ }while(node && dojo.lang.inArray(color, ["transparent", ""]));
+ if(color == "transparent"){
+ color = [255, 255, 255, 0];
+ }else{
+ color = dojo.graphics.color.extractRGB(color);
+ }
+ return color;
+ }
+
+ ds.getComputedStyle = function(node, cssSelector, inValue){
+ node = dojo.byId(node);
+ // cssSelector may actually be in camel case, so force selector version
+ var cssSelector = ds.toSelectorCase(cssSelector);
+ var property = ds.toCamelCase(cssSelector);
+ if(!node || !node.style){
+ return inValue;
+ }else if(document.defaultView){ // W3, gecko, KHTML
+ try{
+ var cs = document.defaultView.getComputedStyle(node, "");
+ if (cs){
+ return cs.getPropertyValue(cssSelector);
+ }
+ }catch(e){ // reports are that Safari can throw an exception above
+ if (node.style.getPropertyValue){ // W3
+ return node.style.getPropertyValue(cssSelector);
+ }else return inValue;
+ }
+ }else if(node.currentStyle){ // IE
+ return node.currentStyle[property];
+ }if(node.style.getPropertyValue){ // W3
+ return node.style.getPropertyValue(cssSelector);
+ }else{
+ return inValue;
+ }
+ }
+
+ /**
+ * Retrieve a property value from a node's style object.
+ */
+ ds.getStyleProperty = function(node, cssSelector){
+ node = dojo.byId(node);
+ // FIXME: should we use node.style.getPropertyValue over style[property]?
+ // style[property] works in all (modern) browsers, getPropertyValue is W3 but not supported in IE
+ // FIXME: what about runtimeStyle?
+ return (node && node.style ? node.style[ds.toCamelCase(cssSelector)] : undefined);
+ }
+
+ /**
+ * Retrieve a property value from a node's style object.
+ */
+ ds.getStyle = function(node, cssSelector){
+ var value = ds.getStyleProperty(node, cssSelector);
+ return (value ? value : ds.getComputedStyle(node, cssSelector));
+ }
+
+ ds.setStyle = function(node, cssSelector, value){
+ node = dojo.byId(node);
+ if(node && node.style){
+ var camelCased = ds.toCamelCase(cssSelector);
+ node.style[camelCased] = value;
+ }
+ }
+
+ ds.toCamelCase = function(selector) {
+ var arr = selector.split('-'), cc = arr[0];
+ for(var i = 1; i < arr.length; i++) {
+ cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+ }
+ return cc;
+ }
+
+ ds.toSelectorCase = function(selector) {
+ return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase() ;
+ }
+
+ /* float between 0.0 (transparent) and 1.0 (opaque) */
+ ds.setOpacity = function setOpacity(node, opacity, dontFixOpacity) {
+ node = dojo.byId(node);
+ if(!dontFixOpacity){
+ if( opacity >= 1.0){
+ if(h.ie){
+ ds.clearOpacity(node);
+ return;
+ }else{
+ opacity = 0.999999;
+ }
+ }else if( opacity < 0.0){ opacity = 0; }
+ }
+ if(h.ie){
+ if(node.nodeName.toLowerCase() == "tr"){
+ // FIXME: is this too naive? will we get more than we want?
+ var tds = node.getElementsByTagName("td");
+ for(var x=0; x<tds.length; x++){
+ tds[x].style.filter = "Alpha(Opacity="+opacity*100+")";
+ }
+ }
+ node.style.filter = "Alpha(Opacity="+opacity*100+")";
+ }else if(h.moz){
+ node.style.opacity = opacity; // ffox 1.0 directly supports "opacity"
+ node.style.MozOpacity = opacity;
+ }else if(h.safari){
+ node.style.opacity = opacity; // 1.3 directly supports "opacity"
+ node.style.KhtmlOpacity = opacity;
+ }else{
+ node.style.opacity = opacity;
+ }
+ }
+
+ ds.getOpacity = function getOpacity (node){
+ node = dojo.byId(node);
+ if(h.ie){
+ var opac = (node.filters && node.filters.alpha &&
+ typeof node.filters.alpha.opacity == "number"
+ ? node.filters.alpha.opacity : 100) / 100;
+ }else{
+ var opac = node.style.opacity || node.style.MozOpacity ||
+ node.style.KhtmlOpacity || 1;
+ }
+ return opac >= 0.999999 ? 1.0 : Number(opac);
+ }
+
+ ds.clearOpacity = function clearOpacity(node){
+ node = dojo.byId(node);
+ var ns = node.style;
+ if(h.ie){
+ try {
+ if( node.filters && node.filters.alpha ){
+ ns.filter = ""; // FIXME: may get rid of other filter effects
+ }
+ } catch(e) {
+ /*
+ * IE7 gives error if node.filters not set;
+ * don't know why or how to workaround (other than this)
+ */
+ }
+ }else if(h.moz){
+ ns.opacity = 1;
+ ns.MozOpacity = 1;
+ }else if(h.safari){
+ ns.opacity = 1;
+ ns.KhtmlOpacity = 1;
+ }else{
+ ns.opacity = 1;
+ }
+ }
+
+ ds._toggle = function(node, tester, setter){
+ node = dojo.byId(node);
+ setter(node, !tester(node));
+ return tester(node);
+ }
+
+ // show/hide are library constructs
+
+ // show()
+ // if the node.style.display == 'none' then
+ // set style.display to '' or the value cached by hide()
+ ds.show = function(node){
+ node = dojo.byId(node);
+ if(ds.getStyleProperty(node, 'display')=='none'){
+ ds.setStyle(node, 'display', (node.dojoDisplayCache||''));
+ node.dojoDisplayCache = undefined; // cannot use delete on a node in IE6
+ }
+ }
+
+ // if the node.style.display == 'none' then
+ // set style.display to '' or the value cached by hide()
+ ds.hide = function(node){
+ node = dojo.byId(node);
+ if(typeof node["dojoDisplayCache"] == "undefined"){ // it could == '', so we cannot say !node.dojoDisplayCount
+ var d = ds.getStyleProperty(node, 'display')
+ if(d!='none'){
+ node.dojoDisplayCache = d;
+ }
+ }
+ ds.setStyle(node, 'display', 'none');
+ }
+
+ // setShowing() calls show() if showing is true, hide() otherwise
+ ds.setShowing = function(node, showing){
+ ds[(showing ? 'show' : 'hide')](node);
+ }
+
+ // isShowing() is true if the node.style.display is not 'none'
+ // FIXME: returns true if node is bad, isHidden would be easier to make correct
+ ds.isShowing = function(node){
+ return (ds.getStyleProperty(node, 'display') != 'none');
+ }
+
+ // Call setShowing() on node with the complement of isShowing(), then return the new value of isShowing()
+ ds.toggleShowing = function(node){
+ return ds._toggle(node, ds.isShowing, ds.setShowing);
+ }
+
+ // display is a CSS concept
+
+ // Simple mapping of tag names to display values
+ // FIXME: simplistic
+ ds.displayMap = { tr: '', td: '', th: '', img: 'inline', span: 'inline', input: 'inline', button: 'inline' };
+
+ // Suggest a value for the display property that will show 'node' based on it's tag
+ ds.suggestDisplayByTagName = function(node)
+ {
+ node = dojo.byId(node);
+ if(node && node.tagName){
+ var tag = node.tagName.toLowerCase();
+ return (tag in ds.displayMap ? ds.displayMap[tag] : 'block');
+ }
+ }
+
+ // setDisplay() sets the value of style.display to value of 'display' parameter if it is a string.
+ // Otherwise, if 'display' is false, set style.display to 'none'.
+ // Finally, set 'display' to a suggested display value based on the node's tag
+ ds.setDisplay = function(node, display){
+ ds.setStyle(node, 'display', (dojo.lang.isString(display) ? display : (display ? ds.suggestDisplayByTagName(node) : 'none')));
+ }
+
+ // isDisplayed() is true if the the computed display style for node is not 'none'
+ // FIXME: returns true if node is bad, isNotDisplayed would be easier to make correct
+ ds.isDisplayed = function(node){
+ return (ds.getComputedStyle(node, 'display') != 'none');
+ }
+
+ // Call setDisplay() on node with the complement of isDisplayed(), then
+ // return the new value of isDisplayed()
+ ds.toggleDisplay = function(node){
+ return ds._toggle(node, ds.isDisplayed, ds.setDisplay);
+ }
+
+ // visibility is a CSS concept
+
+ // setVisibility() sets the value of style.visibility to value of
+ // 'visibility' parameter if it is a string.
+ // Otherwise, if 'visibility' is false, set style.visibility to 'hidden'.
+ // Finally, set style.visibility to 'visible'.
+ ds.setVisibility = function(node, visibility){
+ ds.setStyle(node, 'visibility', (dojo.lang.isString(visibility) ? visibility : (visibility ? 'visible' : 'hidden')));
+ }
+
+ // isVisible() is true if the the computed visibility style for node is not 'hidden'
+ // FIXME: returns true if node is bad, isInvisible would be easier to make correct
+ ds.isVisible = function(node){
+ return (ds.getComputedStyle(node, 'visibility') != 'hidden');
+ }
+
+ // Call setVisibility() on node with the complement of isVisible(), then
+ // return the new value of isVisible()
+ ds.toggleVisibility = function(node){
+ return ds._toggle(node, ds.isVisible, ds.setVisibility);
+ }
+
+ // in: coordinate array [x,y,w,h] or dom node
+ // return: coordinate array
+ ds.toCoordinateArray = function(coords, includeScroll) {
+ if(dojo.lang.isArray(coords)){
+ // coords is already an array (of format [x,y,w,h]), just return it
+ while ( coords.length < 4 ) { coords.push(0); }
+ while ( coords.length > 4 ) { coords.pop(); }
+ var ret = coords;
+ } else {
+ // coords is an dom object (or dom object id); return it's coordinates
+ var node = dojo.byId(coords);
+ var pos = ds.getAbsolutePosition(node, includeScroll);
+ var ret = [
+ pos.x,
+ pos.y,
+ ds.getBorderBoxWidth(node),
+ ds.getBorderBoxHeight(node)
+ ];
+ }
+ ret.x = ret[0];
+ ret.y = ret[1];
+ ret.w = ret[2];
+ ret.h = ret[3];
+ return ret;
+ };
+})();
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/svg.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/svg.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/svg.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/svg.js Sat May 13 09:36:25 2006
@@ -0,0 +1,279 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.svg");
+dojo.require("dojo.lang");
+dojo.require("dojo.dom");
+
+dojo.lang.mixin(dojo.svg, dojo.dom);
+
+dojo.svg.graphics=dojo.svg.g=new function(/* DomDocument */ d){
+ // summary
+ // Singleton to encapsulate SVG rendering functions.
+ this.suspend=function(){
+ // summary
+ // Suspend the rendering engine
+ try { d.documentElement.suspendRedraw(0); } catch(e){ }
+ };
+ this.resume=function(){
+ // summary
+ // Resume the rendering engine
+ try { d.documentElement.unsuspendRedraw(0); } catch(e){ }
+ };
+ this.force=function(){
+ // summary
+ // Force the render engine to redraw
+ try { d.documentElement.forceRedraw(); } catch(e){ }
+ };
+}(document);
+
+dojo.svg.animations=dojo.svg.anim=new function(/* DOMDocument */ d){
+ // summary
+ // Singleton to encapsulate SVG animation functionality.
+ this.arePaused=function(){
+ // summary
+ // check to see if all animations are paused
+ try {
+ return d.documentElement.animationsPaused(); // bool
+ } catch(e){
+ return false; // bool
+ }
+ } ;
+ this.pause=function(){
+ // summary
+ // pause all animations
+ try { d.documentElement.pauseAnimations(); } catch(e){ }
+ };
+ this.resume=function(){
+ // summary
+ // resume all animations
+ try { d.documentElement.unpauseAnimations(); } catch(e){ }
+ };
+}(document);
+
+// fixme: these functions should be mixed in from dojo.style, but dojo.style is HTML-centric and needs to change.
+dojo.svg.toCamelCase=function(/* string */ selector){
+ // summary
+ // converts a CSS-style selector to a camelCased one
+ var arr=selector.split('-'), cc=arr[0];
+ for(var i=1; i < arr.length; i++) {
+ cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+ }
+ return cc; // string
+};
+dojo.svg.toSelectorCase=function(/* string */ selector) {
+ // summary
+ // converts a camelCased selector to a CSS style one
+ return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase(); // string
+};
+dojo.svg.getStyle=function(/* SVGElement */ node, /* string */ cssSelector){
+ // summary
+ // get the computed style of selector for node.
+ return document.defaultView.getComputedStyle(node, cssSelector); // object
+};
+dojo.svg.getNumericStyle=function(/* SVGElement */ node, /* string */ cssSelector){
+ // summary
+ // return the numeric version of the computed style of selector on node.
+ return parseFloat(dojo.svg.getStyle(node, cssSelector));
+};
+
+// fixme: there are different ways of doing the following, need to take into account
+dojo.svg.getOpacity=function(/* SVGElement */node){
+ // summary
+ // Return the opacity of the passed element
+ return Math.min(1.0, dojo.svg.getNumericStyle(node, "fill-opacity")); // float
+};
+dojo.svg.setOpacity=function(/* SVGElement */ node, /* float */ opacity){
+ // summary
+ // set the opacity of node using attributes.
+ node.setAttributeNS(this.xmlns.svg, "fill-opacity", opacity);
+ node.setAttributeNS(this.xmlns.svg, "stroke-opacity", opacity);
+};
+dojo.svg.clearOpacity=function(/* SVGElement */ node){
+ // summary
+ // Set any attributes setting opacity to opaque (1.0)
+ node.setAttributeNS(this.xmlns.svg, "fill-opacity", "1.0");
+ node.setAttributeNS(this.xmlns.svg, "stroke-opacity", "1.0");
+};
+
+/**
+ * Coordinates and dimensions.
+ */
+
+// TODO ////////////////////////////////////////////////////////// TODO
+dojo.svg.getCoords=function(/* SVGElement */ node){
+ if (node.getBBox) {
+ var box=node.getBBox();
+ return { x: box.x, y: box.y };
+ }
+ return null;
+};
+dojo.svg.setCoords=function(node, coords){
+ var p=dojo.svg.getCoords();
+ if (!p) return;
+ var dx=p.x - coords.x;
+ var dy=p.y - coords.y;
+ dojo.svg.translate(node, dx, dy);
+};
+dojo.svg.getDimensions=function(node){
+ if (node.getBBox){
+ var box=node.getBBox();
+ return { width: box.width, height : box.height };
+ }
+ return null;
+};
+dojo.svg.setDimensions=function(node, dim){
+ // will only support shape-based and container elements; path-based elements are ignored.
+ if (node.width){
+ node.width.baseVal.value=dim.width;
+ node.height.baseVal.value=dim.height;
+ }
+ else if (node.r){
+ node.r.baseVal.value=Math.min(dim.width, dim.height)/2;
+ }
+ else if (node.rx){
+ node.rx.baseVal.value=dim.width/2;
+ node.ry.baseVal.value=dim.height/2;
+ }
+};
+
+/**
+ * Transformations.
+ */
+dojo.svg.translate=function(node, dx, dy){
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ t.setTranslate(dx, dy);
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.scale=function(node, scaleX, scaleY){
+ if (!scaleY) var scaleY=scaleX;
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ t.setScale(scaleX, scaleY);
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.rotate=function(node, ang, cx, cy){
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ if (!cx) t.setMatrix(t.matrix.rotate(ang));
+ else t.setRotate(ang, cx, cy);
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.skew=function(node, ang, axis){
+ var dir=axis || "x";
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ if (dir != "x") t.setSkewY(ang);
+ else t.setSkewX(ang);
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.flip=function(node, axis){
+ var dir=axis || "x";
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ t.setMatrix((dir != "x") ? t.matrix.flipY() : t.matrix.flipX());
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.invert=function(node){
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var t=node.ownerSVGElement.createSVGTransform();
+ t.setMatrix(t.matrix.inverse());
+ node.transform.baseVal.appendItem(t);
+ }
+};
+dojo.svg.applyMatrix=function(node, a, b, c, d, e, f){
+ if (node.transform && node.ownerSVGElement && node.ownerSVGElement.createSVGTransform){
+ var m;
+ if (b){
+ var m=node.ownerSVGElement.createSVGMatrix();
+ m.a=a;
+ m.b=b;
+ m.c=c;
+ m.d=d;
+ m.e=e;
+ m.f=f;
+ } else m=a;
+ var t=node.ownerSVGElement.createSVGTransform();
+ t.setMatrix(m);
+ node.transform.baseVal.appendItem(t);
+ }
+};
+
+/**
+ * Grouping and z-index operations.
+ */
+dojo.svg.group=function(nodes){
+ // expect an array of nodes, attaches the group to the parent of the first node.
+ var p=nodes.item(0).parentNode;
+ var g=document.createElementNS(this.xmlns.svg, "g");
+ for (var i=0; i < nodes.length; i++) g.appendChild(nodes.item(i));
+ p.appendChild(g);
+ return g;
+};
+dojo.svg.ungroup=function(g){
+ // puts the children of the group on the same level as group was.
+ var p=g.parentNode;
+ while (g.childNodes.length > 0) p.appendChild(g.childNodes.item(0));
+ p.removeChild(g);
+};
+// if the node is part of a group, return the group, else return null.
+dojo.svg.getGroup=function(node){
+ // if the node is part of a group, return the group, else return null.
+ var a=this.getAncestors(node);
+ for (var i=0; i < a.length; i++){
+ if (a[i].nodeType == this.ELEMENT_NODE && a[i].nodeName.toLowerCase() == "g")
+ return a[i];
+ }
+ return null;
+};
+dojo.svg.bringToFront=function(node){
+ var n=this.getGroup(node) || node;
+ n.ownerSVGElement.appendChild(n);
+};
+dojo.svg.sendToBack=function(node){
+ var n=this.getGroup(node) || node;
+ n.ownerSVGElement.insertBefore(n, n.ownerSVGElement.firstChild);
+};
+
+// TODO: possibly push node up a level in the DOM if it's at the beginning or end of the childNodes list.
+dojo.svg.bringForward=function(node){
+ var n=this.getGroup(node) || node;
+ if (this.getLastChildElement(n.parentNode) != n){
+ this.insertAfter(n, this.getNextSiblingElement(n), true);
+ }
+};
+dojo.svg.sendBackward=function(node){
+ var n=this.getGroup(node) || node;
+ if (this.getFirstChildElement(n.parentNode) != n){
+ this.insertBefore(n, this.getPreviousSiblingElement(n), true);
+ }
+};
+// END TODO ////////////////////////////////////////////////////// TODO
+
+dojo.svg.createNodesFromText=function(/* string */ txt, /* bool? */ wrap){
+ // summary
+ // Create a list of nodes from text
+ var docFrag=(new DOMParser()).parseFromString(txt, "text/xml").normalize();
+ if(wrap){
+ return [docFrag.firstChild.cloneNode(true)]; // array
+ }
+ var nodes=[];
+ for(var x=0; x<docFrag.childNodes.length; x++){
+ nodes.push(docFrag.childNodes.item(x).cloneNode(true));
+ }
+ return nodes; // array
+}
+// vim:ts=4:noet:tw=0:
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Builder.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Builder.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Builder.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Builder.js Sat May 13 09:36:25 2006
@@ -0,0 +1,16 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.text.Builder");
+dojo.require("dojo.string.Builder");
+
+dojo.deprecated("dojo.text.Builder", "use dojo.string.Builder instead", "0.4");
+
+dojo.text.Builder = dojo.string.Builder;
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/String.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/String.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/String.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/String.js Sat May 13 09:36:25 2006
@@ -0,0 +1,15 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.deprecated("dojo.text.String", "replaced by dojo.string", "0.4");
+dojo.require("dojo.string");
+
+dojo.text = dojo.string;
+dojo.provide("dojo.text.String");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Text.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Text.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Text.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/Text.js Sat May 13 09:36:25 2006
@@ -0,0 +1,15 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.deprecated("dojo.text.Text", "replaced by dojo.string", "0.4");
+dojo.require("dojo.string");
+
+dojo.text = dojo.string;
+dojo.provide("dojo.text.Text");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/__package__.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/__package__.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/__package__.js Sat May 13 09:36:25 2006
@@ -0,0 +1,17 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+ common: [
+ "dojo.text.String",
+ "dojo.text.Builder"
+ ]
+});
+dojo.provide("dojo.text.*");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/textDirectory.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/textDirectory.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/textDirectory.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/text/textDirectory.js Sat May 13 09:36:25 2006
@@ -0,0 +1,81 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.text.textDirectory");
+dojo.provide("dojo.text.textDirectory.Property");
+dojo.provide("dojo.text.textDirectory.tokenise");
+dojo.require("dojo.string");
+
+/* adapted from Paul Sowden's iCalendar work */
+
+dojo.textDirectoryTokeniser = function () {}
+
+/*
+ * This class parses a single line from a text/directory file
+ * and returns an object with four named values; name, group, params
+ * and value. name, group and value are strings containing the original
+ * tokens unaltered and values is an array containing name/value pairs
+ * or a single name token packed into arrays.
+ */
+dojo.textDirectoryTokeniser.Property = function (line) {
+ // split into name/value pair
+ var left = dojo.string.trim(line.substring(0, line.indexOf(':')));
+ var right = dojo.string.trim(line.substr(line.indexOf(':') + 1));
+
+ // seperate name and paramters
+ var parameters = dojo.string.splitEscaped(left,';');
+ this.name = parameters[0]
+ parameters.splice(0, 1);
+
+ // parse paramters
+ this.params = [];
+ for (var i = 0; i < parameters.length; i++) {
+ var arr = parameters[i].split("=");
+ var key = dojo.string.trim(arr[0].toUpperCase());
+
+ if (arr.length == 1) { this.params.push([key]); continue; }
+
+ var values = dojo.string.splitEscaped(arr[1],',');
+ for (var j = 0; j < values.length; j++) {
+ if (dojo.string.trim(values[j]) != '') {
+ this.params.push([key, dojo.string.trim(values[j])]);
+ }
+ }
+ }
+
+ // seperate group
+ if (this.name.indexOf('.') > 0) {
+ var arr = this.name.split('.');
+ this.group = arr[0];
+ this.name = arr[1];
+ }
+
+ // don't do any parsing, leave to implementation
+ this.value = right;
+}
+
+
+// tokeniser, parses into an array of properties.
+dojo.textDirectoryTokeniser.tokenise = function (text) {
+ // normlize to one propterty per line and parse
+ nText = dojo.string.normalizeNewlines(text,"\n");
+ nText = nText.replace(/\n[ \t]/g, '');
+ nText = nText.replace(/\x00/g, '');
+
+ var lines = nText.split("\n");
+ var properties = []
+
+ for (var i = 0; i < lines.length; i++) {
+ if (dojo.string.trim(lines[i]) == '') { continue; }
+ var prop = new dojo.textDirectoryTokeniser.Property(lines[i]);
+ properties.push(prop);
+ }
+ return properties;
+}
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/Manager.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/Manager.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/Manager.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/Manager.js Sat May 13 09:36:25 2006
@@ -0,0 +1,196 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.undo.Manager");
+dojo.require("dojo.lang");
+
+dojo.undo.Manager = function(parent) {
+ this.clear();
+ this._parent = parent;
+};
+dojo.lang.extend(dojo.undo.Manager, {
+ _parent: null,
+ _undoStack: null,
+ _redoStack: null,
+ _currentManager: null,
+
+ canUndo: false,
+ canRedo: false,
+
+ isUndoing: false,
+ isRedoing: false,
+
+ // these events allow you to hook in and update your code (UI?) as necessary
+ onUndo: function(manager, item) {},
+ onRedo: function(manager, item) {},
+
+ // fired when you do *any* undo action, which means you'll have one for every item
+ // in a transaction. this is usually only useful for debugging
+ onUndoAny: function(manager, item) {},
+ onRedoAny: function(manager, item) {},
+
+ _updateStatus: function() {
+ this.canUndo = this._undoStack.length > 0;
+ this.canRedo = this._redoStack.length > 0;
+ },
+
+ clear: function() {
+ this._undoStack = [];
+ this._redoStack = [];
+ this._currentManager = this;
+
+ this.isUndoing = false;
+ this.isRedoing = false;
+
+ this._updateStatus();
+ },
+
+ undo: function() {
+ if(!this.canUndo) { return false; }
+
+ this.endAllTransactions();
+
+ this.isUndoing = true;
+ var top = this._undoStack.pop();
+ if(top instanceof this.constructor) {
+ top.undoAll();
+ } else {
+ top.undo();
+ }
+ if(top.redo) {
+ this._redoStack.push(top);
+ }
+ this.isUndoing = false;
+
+ this._updateStatus();
+ this.onUndo(this, top);
+ if(!(top instanceof this.constructor)) {
+ this.getTop().onUndoAny(this, top);
+ }
+ return true;
+ },
+
+ redo: function() {
+ if(!this.canRedo) { return false; }
+
+ this.isRedoing = true;
+ var top = this._redoStack.pop();
+ if(top instanceof this.constructor) {
+ top.redoAll();
+ } else {
+ top.redo();
+ }
+ this._undoStack.push(top);
+ this.isRedoing = false;
+
+ this._updateStatus();
+ this.onRedo(this, top);
+ if(!(top instanceof this.constructor)) {
+ this.getTop().onRedoAny(this, top);
+ }
+ return true;
+ },
+
+ undoAll: function() {
+ while(this._undoStack.length > 0) {
+ this.undo();
+ }
+ },
+
+ redoAll: function() {
+ while(this._redoStack.length > 0) {
+ this.redo();
+ }
+ },
+
+ push: function(undo, redo /* optional */, description /* optional */) {
+ if(!undo) { return; }
+
+ if(this._currentManager == this) {
+ this._undoStack.push({
+ undo: undo,
+ redo: redo,
+ description: description
+ });
+ } else {
+ this._currentManager.push.apply(this._currentManager, arguments);
+ }
+ // adding a new undo-able item clears out the redo stack
+ this._redoStack = [];
+ this._updateStatus();
+ },
+
+ concat: function(manager) {
+ if ( !manager ) { return; }
+
+ if (this._currentManager == this ) {
+ for(var x=0; x < manager._undoStack.length; x++) {
+ this._undoStack.push(manager._undoStack[x]);
+ }
+ this._updateStatus();
+ } else {
+ this._currentManager.concat.apply(this._currentManager, arguments);
+ }
+ },
+
+ beginTransaction: function(description /* optional */) {
+ if(this._currentManager == this) {
+ var mgr = new dojo.undo.Manager(this);
+ mgr.description = description ? description : "";
+ this._undoStack.push(mgr);
+ this._currentManager = mgr;
+ return mgr;
+ } else {
+ //for nested transactions need to make sure the top level _currentManager is set
+ this._currentManager = this._currentManager.beginTransaction.apply(this._currentManager, arguments);
+ }
+ },
+
+ endTransaction: function(flatten /* optional */) {
+ if(this._currentManager == this) {
+ if(this._parent) {
+ this._parent._currentManager = this._parent;
+ // don't leave empty transactions hangin' around
+ if(this._undoStack.length == 0 || flatten) {
+ var idx = dojo.lang.find(this._parent._undoStack, this);
+ if (idx >= 0) {
+ this._parent._undoStack.splice(idx, 1);
+ //add the current transaction to parents undo stack
+ if (flatten) {
+ for(var x=0; x < this._undoStack.length; x++){
+ this._parent._undoStack.splice(idx++, 0, this._undoStack[x]);
+ }
+ this._updateStatus();
+ }
+ }
+ }
+ return this._parent;
+ }
+ } else {
+ //for nested transactions need to make sure the top level _currentManager is set
+ this._currentManager = this._currentManager.endTransaction.apply(this._currentManager, arguments);
+ }
+ },
+
+ endAllTransactions: function() {
+ while(this._currentManager != this) {
+ this.endTransaction();
+ }
+ },
+
+ // find the top parent of an undo manager
+ getTop: function() {
+ if(this._parent) {
+ return this._parent.getTop();
+ } else {
+ return this;
+ }
+ }
+});
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/__package__.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/__package__.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/__package__.js Sat May 13 09:36:25 2006
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.undo.Manager");
+dojo.provide("dojo.undo.*");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/browser.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/browser.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/browser.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/undo/browser.js Sat May 13 09:36:25 2006
@@ -0,0 +1,273 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.undo.browser");
+dojo.require("dojo.io");
+
+try{
+ if((!djConfig["preventBackButtonFix"])&&(!dojo.hostenv.post_load_)){
+ document.write("<iframe style='border: 0px; width: 1px; height: 1px; position: absolute; bottom: 0px; right: 0px; visibility: visible;' name='djhistory' id='djhistory' src='"+(dojo.hostenv.getBaseScriptUri()+'iframe_history.html')+"'></iframe>");
+ }
+}catch(e){/* squelch */}
+
+/* NOTES:
+ * Safari 1.2:
+ * back button "works" fine, however it's not possible to actually
+ * DETECT that you've moved backwards by inspecting window.location.
+ * Unless there is some other means of locating.
+ * FIXME: perhaps we can poll on history.length?
+ * Safari 2.0.3+ (and probably 1.3.2+):
+ * works fine, except when changeUrl is used. When changeUrl is used,
+ * Safari jumps all the way back to whatever page was shown before
+ * the page that uses dojo.undo.browser support.
+ * IE 5.5 SP2:
+ * back button behavior is macro. It does not move back to the
+ * previous hash value, but to the last full page load. This suggests
+ * that the iframe is the correct way to capture the back button in
+ * these cases.
+ * Don't test this page using local disk for MSIE. MSIE will not create
+ * a history list for iframe_history.html if served from a file: URL.
+ * The XML served back from the XHR tests will also not be properly
+ * created if served from local disk. Serve the test pages from a web
+ * server to test in that browser.
+ * IE 6.0:
+ * same behavior as IE 5.5 SP2
+ * Firefox 1.0:
+ * the back button will return us to the previous hash on the same
+ * page, thereby not requiring an iframe hack, although we do then
+ * need to run a timer to detect inter-page movement.
+ */
+dojo.undo.browser = {
+ initialHref: window.location.href,
+ initialHash: window.location.hash,
+
+ moveForward: false,
+ historyStack: [],
+ forwardStack: [],
+ historyIframe: null,
+ bookmarkAnchor: null,
+ locationTimer: null,
+
+ /**
+ * setInitialState sets the state object and back callback for the very first page that is loaded.
+ * It is recommended that you call this method as part of an event listener that is registered via
+ * dojo.addOnLoad().
+ */
+ setInitialState: function(args){
+ this.initialState = {"url": this.initialHref, "kwArgs": args, "urlHash": this.initialHash};
+ },
+
+ //FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things.
+ //FIXME: is there a slight race condition in moz using change URL with the timer check and when
+ // the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent.
+ /**
+ * addToHistory takes one argument, and it is an object that defines the following functions:
+ * - To support getting back button notifications, the object argument should implement a
+ * function called either "back", "backButton", or "handle". The string "back" will be
+ * passed as the first and only argument to this callback.
+ * - To support getting forward button notifications, the object argument should implement a
+ * function called either "forward", "forwardButton", or "handle". The string "forward" will be
+ * passed as the first and only argument to this callback.
+ * - If you want the browser location string to change, define "changeUrl" on the object. If the
+ * value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment
+ * identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does
+ * not evaluate to false, that value will be used as the fragment identifier. For example,
+ * if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1
+ *
+ * Full example:
+ *
+ * dojo.undo.browser.addToHistory({
+ * back: function() { alert('back pressed'); },
+ * forward: function() { alert('forward pressed'); },
+ * changeUrl: true
+ * });
+ */
+ addToHistory: function(args){
+ var hash = null;
+ if(!this.historyIframe){
+ this.historyIframe = window.frames["djhistory"];
+ }
+ if(!this.bookmarkAnchor){
+ this.bookmarkAnchor = document.createElement("a");
+ (document.body||document.getElementsByTagName("body")[0]).appendChild(this.bookmarkAnchor);
+ this.bookmarkAnchor.style.display = "none";
+ }
+ if((!args["changeUrl"])||(dojo.render.html.ie)){
+ var url = dojo.hostenv.getBaseScriptUri()+"iframe_history.html?"+(new Date()).getTime();
+ this.moveForward = true;
+ dojo.io.setIFrameSrc(this.historyIframe, url, false);
+ }
+ if(args["changeUrl"]){
+ this.changingUrl = true;
+ hash = "#"+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());
+ setTimeout("window.location.href = '"+hash+"'; dojo.undo.browser.changingUrl = false;", 1);
+ this.bookmarkAnchor.href = hash;
+
+ if(dojo.render.html.ie){
+ var oldCB = args["back"]||args["backButton"]||args["handle"];
+
+ //The function takes handleName as a parameter, in case the
+ //callback we are overriding was "handle". In that case,
+ //we will need to pass the handle name to handle.
+ var tcb = function(handleName){
+ if(window.location.hash != ""){
+ setTimeout("window.location.href = '"+hash+"';", 1);
+ }
+ //Use apply to set "this" to args, and to try to avoid memory leaks.
+ oldCB.apply(this, [handleName]);
+ }
+
+ //Set interceptor function in the right place.
+ if(args["back"]){
+ args.back = tcb;
+ }else if(args["backButton"]){
+ args.backButton = tcb;
+ }else if(args["handle"]){
+ args.handle = tcb;
+ }
+
+ //If addToHistory is called, then that means we prune the
+ //forward stack -- the user went back, then wanted to
+ //start a new forward path.
+ this.forwardStack = [];
+ var oldFW = args["forward"]||args["forwardButton"]||args["handle"];
+
+ //The function takes handleName as a parameter, in case the
+ //callback we are overriding was "handle". In that case,
+ //we will need to pass the handle name to handle.
+ var tfw = function(handleName){
+ if(window.location.hash != ""){
+ window.location.href = hash;
+ }
+ if(oldFW){ // we might not actually have one
+ //Use apply to set "this" to args, and to try to avoid memory leaks.
+ oldFW.apply(this, [handleName]);
+ }
+ }
+
+ //Set interceptor function in the right place.
+ if(args["forward"]){
+ args.forward = tfw;
+ }else if(args["forwardButton"]){
+ args.forwardButton = tfw;
+ }else if(args["handle"]){
+ args.handle = tfw;
+ }
+
+ }else if(dojo.render.html.moz){
+ // start the timer
+ if(!this.locationTimer){
+ this.locationTimer = setInterval("dojo.undo.browser.checkLocation();", 200);
+ }
+ }
+ }
+
+ this.historyStack.push({"url": url, "kwArgs": args, "urlHash": hash});
+ },
+
+ checkLocation: function(){
+ if (!this.changingUrl){
+ var hsl = this.historyStack.length;
+
+ if((window.location.hash == this.initialHash)||(window.location.href == this.initialHref)&&(hsl == 1)){
+ // FIXME: could this ever be a forward button?
+ // we can't clear it because we still need to check for forwards. Ugg.
+ // clearInterval(this.locationTimer);
+ this.handleBackButton();
+ return;
+ }
+ // first check to see if we could have gone forward. We always halt on
+ // a no-hash item.
+ if(this.forwardStack.length > 0){
+ if(this.forwardStack[this.forwardStack.length-1].urlHash == window.location.hash){
+ this.handleForwardButton();
+ return;
+ }
+ }
+
+ // ok, that didn't work, try someplace back in the history stack
+ if((hsl >= 2)&&(this.historyStack[hsl-2])){
+ if(this.historyStack[hsl-2].urlHash==window.location.hash){
+ this.handleBackButton();
+ return;
+ }
+ }
+ }
+ },
+
+ iframeLoaded: function(evt, ifrLoc){
+ var query = this._getUrlQuery(ifrLoc.href);
+ if(query == null){
+ // alert("iframeLoaded");
+ // we hit the end of the history, so we should go back
+ if(this.historyStack.length == 1){
+ this.handleBackButton();
+ }
+ return;
+ }
+ if(this.moveForward){
+ // we were expecting it, so it's not either a forward or backward movement
+ this.moveForward = false;
+ return;
+ }
+
+ //Check the back stack first, since it is more likely.
+ //Note that only one step back or forward is supported.
+ if(this.historyStack.length >= 2 && query == this._getUrlQuery(this.historyStack[this.historyStack.length-2].url)){
+ this.handleBackButton();
+ }
+ else if(this.forwardStack.length > 0 && query == this._getUrlQuery(this.forwardStack[this.forwardStack.length-1].url)){
+ this.handleForwardButton();
+ }
+ },
+
+ handleBackButton: function(){
+ //The "current" page is always at the top of the history stack.
+ var current = this.historyStack.pop();
+ if(!current){ return; }
+ var last = this.historyStack[this.historyStack.length-1];
+ if(!last && this.historyStack.length == 0){
+ last = this.initialState;
+ }
+ if (last){
+ if(last.kwArgs["back"]){
+ last.kwArgs["back"]();
+ }else if(last.kwArgs["backButton"]){
+ last.kwArgs["backButton"]();
+ }else if(last.kwArgs["handle"]){
+ last.kwArgs.handle("back");
+ }
+ }
+ this.forwardStack.push(current);
+ },
+
+ handleForwardButton: function(){
+ var last = this.forwardStack.pop();
+ if(!last){ return; }
+ if(last.kwArgs["forward"]){
+ last.kwArgs.forward();
+ }else if(last.kwArgs["forwardButton"]){
+ last.kwArgs.forwardButton();
+ }else if(last.kwArgs["handle"]){
+ last.kwArgs.handle("forward");
+ }
+ this.historyStack.push(last);
+ },
+
+ _getUrlQuery: function(url){
+ var segments = url.split("?");
+ if (segments.length < 2){
+ return null;
+ }
+ else{
+ return segments[1];
+ }
+ }
+}
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/Uri.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/Uri.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/Uri.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/Uri.js Sat May 13 09:36:25 2006
@@ -0,0 +1,84 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.uri.Uri");
+
+dojo.uri = new function() {
+ this.joinPath = function() {
+ // DEPRECATED: use the dojo.uri.Uri object instead
+ var arr = [];
+ for(var i = 0; i < arguments.length; i++) { arr.push(arguments[i]); }
+ return arr.join("/").replace(/\/{2,}/g, "/").replace(/((https*|ftps*):)/i, "$1/");
+ }
+
+ this.dojoUri = function (uri) {
+ // returns a Uri object resolved relative to the dojo root
+ return new dojo.uri.Uri(dojo.hostenv.getBaseScriptUri(), uri);
+ }
+
+ this.Uri = function (/*uri1, uri2, [...]*/) {
+ // An object representing a Uri.
+ // Each argument is evaluated in order relative to the next until
+ // a conanical uri is producued. To get an absolute Uri relative
+ // to the current document use
+ // new dojo.uri.Uri(document.baseURI, uri)
+
+ // TODO: support for IPv6, see RFC 2732
+
+ // resolve uri components relative to each other
+ var uri = arguments[0];
+ for (var i = 1; i < arguments.length; i++) {
+ if(!arguments[i]) { continue; }
+
+ // Safari doesn't support this.constructor so we have to be explicit
+ var relobj = new dojo.uri.Uri(arguments[i].toString());
+ var uriobj = new dojo.uri.Uri(uri.toString());
+
+ if (relobj.path == "" && relobj.scheme == null &&
+ relobj.authority == null && relobj.query == null) {
+ if (relobj.fragment != null) { uriobj.fragment = relobj.fragment; }
+ relobj = uriobj;
+ }
+
+ if (relobj.scheme != null && relobj.authority != null)
+ uri = "";
+ if (relobj.scheme != null) { uri += relobj.scheme + ":"; }
+ if (relobj.authority != null) { uri += "//" + relobj.authority; }
+ uri += relobj.path;
+ if (relobj.query != null) { uri += "?" + relobj.query; }
+ if (relobj.fragment != null) { uri += "#" + relobj.fragment; }
+ }
+
+ this.uri = uri.toString();
+
+ // break the uri into its main components
+ var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
+ var r = this.uri.match(new RegExp(regexp));
+
+ this.scheme = r[2] || (r[1] ? "" : null);
+ this.authority = r[4] || (r[3] ? "" : null);
+ this.path = r[5]; // can never be undefined
+ this.query = r[7] || (r[6] ? "" : null);
+ this.fragment = r[9] || (r[8] ? "" : null);
+
+ if (this.authority != null) {
+ // server based naming authority
+ regexp = "^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$";
+ r = this.authority.match(new RegExp(regexp));
+
+ this.user = r[3] || null;
+ this.password = r[4] || null;
+ this.host = r[5];
+ this.port = r[7] || null;
+ }
+
+ this.toString = function(){ return this.uri; }
+ }
+};
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/__package__.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/__package__.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/__package__.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uri/__package__.js Sat May 13 09:36:25 2006
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+ common: ["dojo.uri.Uri", false, false]
+});
+dojo.provide("dojo.uri.*");
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/LightweightGenerator.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/LightweightGenerator.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/LightweightGenerator.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/LightweightGenerator.js Sat May 13 09:36:25 2006
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.uuid.LightweightGenerator");
+
+/**
+ * The LightweightGenerator is intended to be small and fast,
+ * but not necessarily good.
+ *
+ * Small: The LightweightGenerator has a small footprint.
+ * Once comments are stripped, it's only about 25 lines of
+ * code, and it doesn't dojo.require() any other packages.
+ *
+ * Fast: The LightweightGenerator can generate lots of new
+ * UUIDs fairly quickly (at least, more quickly than the other
+ * dojo UUID generators).
+ *
+ * Not necessarily good: We use Math.random() as our source
+ * of randomness, which may or may not provide much randomness.
+ */
+dojo.uuid.LightweightGenerator = new function() {
+
+ var HEX_RADIX = 16;
+
+// --------------------------------------------------
+// Private functions
+// --------------------------------------------------
+ function _generateRandomEightCharacterHexString() {
+ // Make random32bitNumber be a randomly generated floating point number
+ // between 0 and (4,294,967,296 - 1), inclusive.
+ var random32bitNumber = Math.floor( (Math.random() % 1) * Math.pow(2, 32) );
+ var eightCharacterHexString = random32bitNumber.toString(HEX_RADIX);
+ while (eightCharacterHexString.length < 8) {
+ eightCharacterHexString = "0" + eightCharacterHexString;
+ }
+ return eightCharacterHexString; // for example: "3B12F1DF"
+ }
+
+// --------------------------------------------------
+// Public functions
+// --------------------------------------------------
+
+/**
+ * This function generates random UUIDs, meaning "version 4" UUIDs.
+ * For example, a typical generated value would be something like
+ * "3b12f1df-5232-4804-897e-917bf397618a".
+ *
+ * Examples:
+ * <pre>
+ * var string = dojo.uuid.LightweightGenerator.generate();
+ * var string = dojo.uuid.LightweightGenerator.generate(String);
+ * var uuid = dojo.uuid.LightweightGenerator.generate(dojo.uuid.Uuid);
+ * </pre>
+ *
+ * @param returnType Optional. The type of instance to return.
+ * @return A newly generated version 4 UUID.
+ */
+ this.generate = function(returnType) {
+ var hyphen = "-";
+ var versionCodeForRandomlyGeneratedUuids = "4"; // 8 == binary2hex("0100")
+ var variantCodeForDCEUuids = "8"; // 8 == binary2hex("1000")
+ var a = _generateRandomEightCharacterHexString();
+ var b = _generateRandomEightCharacterHexString();
+ b = b.substring(0, 4) + hyphen + versionCodeForRandomlyGeneratedUuids + b.substring(5, 8);
+ var c = _generateRandomEightCharacterHexString();
+ c = variantCodeForDCEUuids + c.substring(1, 4) + hyphen + c.substring(4, 8);
+ var d = _generateRandomEightCharacterHexString();
+ var returnValue = a + hyphen + b + hyphen + c + d;
+ returnValue = returnValue.toLowerCase();
+ if (returnType && (returnType != String)) {
+ returnValue = new returnType(returnValue);
+ }
+ return returnValue;
+ };
+}();
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NameBasedGenerator.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NameBasedGenerator.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NameBasedGenerator.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NameBasedGenerator.js Sat May 13 09:36:25 2006
@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.uuid.NameBasedGenerator");
+
+dojo.uuid.NameBasedGenerator = new function() {
+
+/**
+ * This function generates name-based UUIDs, meaning "version 3"
+ * and "version 5" UUIDs.
+ *
+ * Examples:
+ * <pre>
+ * var string = dojo.uuid.NameBasedGenerator.generate();
+ * var string = dojo.uuid.NameBasedGenerator.generate(String);
+ * var uuid = dojo.uuid.NameBasedGenerator.generate(dojo.uuid.Uuid);
+ * </pre>
+ *
+ * @param returnType Optional. The type of instance to return.
+ * @return A newly generated version 3 or version 5 UUID.
+ */
+ this.generate = function(returnType) {
+ dojo.unimplemented('dojo.uuid.NameBasedGenerator.generate');
+
+ // FIXME:
+ // For an algorithm to generate name-based UUIDs,
+ // see sections 4.3 of RFC 4122:
+ // http://www.ietf.org/rfc/rfc4122.txt
+
+ var returnValue = "00000000-0000-0000-0000-000000000000"; // FIXME
+ if (returnType && (returnType != String)) {
+ returnValue = new returnType(returnValue);
+ }
+ return returnValue;
+ };
+}();
\ No newline at end of file
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NilGenerator.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NilGenerator.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NilGenerator.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/NilGenerator.js Sat May 13 09:36:25 2006
@@ -0,0 +1,38 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.uuid.NilGenerator");
+
+dojo.uuid.NilGenerator = new function() {
+
+/**
+ * This function returns the Nil UUID:
+ * "00000000-0000-0000-0000-000000000000".
+ * The Nil UUID is described in section 4.1.7 of
+ * RFC 4122: http://www.ietf.org/rfc/rfc4122.txt
+ *
+ * Examples:
+ * <pre>
+ * var string = dojo.uuid.NilGenerator.generate();
+ * var string = dojo.uuid.NilGenerator.generate(String);
+ * var uuid = dojo.uuid.NilGenerator.generate(dojo.uuid.Uuid);
+ * </pre>
+ *
+ * @param returnType Optional. The type of instance to return.
+ * @return The nil UUID.
+ */
+ this.generate = function(returnType) {
+ var returnValue = "00000000-0000-0000-0000-000000000000";
+ if (returnType && (returnType != String)) {
+ returnValue = new returnType(returnValue);
+ }
+ return returnValue;
+ };
+}();
\ No newline at end of file
Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/RandomGenerator.js
URL: http://svn.apache.org/viewcvs/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/RandomGenerator.js?rev=406128&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/RandomGenerator.js (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/dojo/src/uuid/RandomGenerator.js Sat May 13 09:36:25 2006
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.uuid.RandomGenerator");
+
+dojo.uuid.RandomGenerator = new function() {
+
+/**
+ * This function generates random UUIDs, meaning "version 4" UUIDs.
+ * For example, a typical generated value would be something like
+ * "3b12f1df-5232-4804-897e-917bf397618a".
+ *
+ * Examples:
+ * <pre>
+ * var string = dojo.uuid.RandomGenerator.generate();
+ * var string = dojo.uuid.RandomGenerator.generate(String);
+ * var uuid = dojo.uuid.RandomGenerator.generate(dojo.uuid.Uuid);
+ * </pre>
+ *
+ * @param returnType Optional. The type of instance to return.
+ * @return A newly generated version 4 UUID.
+ */
+ this.generate = function(returnType) {
+ dojo.unimplemented('dojo.uuid.RandomGenerator.generate');
+
+ // FIXME:
+ // For an algorithm to generate a random UUID, see
+ // sections 4.4 and 4.5 of RFC 4122:
+ // http://www.ietf.org/rfc/rfc4122.txt
+
+ var returnValue = "00000000-0000-0000-0000-000000000000"; // FIXME
+ if (returnType && (returnType != String)) {
+ returnValue = new returnType(returnValue);
+ }
+ return returnValue;
+ };
+}();