You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by zh...@apache.org on 2011/04/01 02:29:38 UTC

svn commit: r1087520 [20/35] - in /incubator/rave/donations/ogce-gadget-container: ./ config/ config/shindig-1.1-BETA5/ config/shindig-2.0.0/ db-cleaner/ examples/ examples/src/ examples/src/main/ examples/src/main/java/ examples/src/main/java/cgl/ exa...

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/iframe.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/iframe.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/iframe.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/iframe.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,1277 @@
+/*
+
+        Copyright 2006-2009 OpenAjax Alliance
+
+        Licensed under the Apache License, Version 2.0 (the "License"); 
+        you may not use this file except in compliance with the License. 
+        You may obtain a copy of the License at
+        
+                http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software 
+        distributed under the License is distributed on an "AS IS" BASIS, 
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+        See the License for the specific language governing permissions and 
+        limitations under the License.
+*/
+
+if ( typeof OpenAjax === "undefined" ) {
+    window.OpenAjax = {};
+}
+if ( typeof OpenAjax.hub === "undefined" ) {
+    window.OpenAjax.hub = {};
+}
+
+(function(){
+
+/**
+ * Create a new Iframe Container.
+ * @constructor
+ * @extends OpenAjax.hub.Container
+ * 
+ * IframeContainer implements the Container interface to provide a container
+ * that isolates client components into secure sandboxes by leveraging the
+ * isolation features provided by browser iframes.
+ * 
+ * IframeContainer makes use of several different transport layers to provide
+ * secure messaging across the iframe boundary.  Each transport layer implements
+ * the Transport API as outlined below.  In addition, IframeContainer implements
+ * the Transport Callback API, which the transport layers use for notification
+ * purposes.
+ * 
+ * TRANSPORT API
+ * 
+ * + addReceiver( args )
+ *     Add an object that wishes to receive messages using the transport.
+ *         args {Object}:
+ *             receiver {Object}  Object which receives messages.  Must
+ *                     implement Transport Callback API.
+ *             receiverId {String}  ID for given 'receiver'.  Must be unique
+ *                     within page, not just ManagedHub instance.
+ *             [name] {String}  ID for given 'receiver', as specified by user.
+ *                     May not be unique within page. May be identical to
+ *                     'receiverId'. If not specified, defaults to value of
+ *                     'receiverId'. 
+ *             securityToken {String}
+ *             uri {String}  Location to load in child iframe (PARENT ONLY)
+ *             tunnelURI {String}  URI of the tunnel iframe. Must be from the
+ *                     same origin as the parent. (PARENT ONLY)
+ *             [log] {Function}  Logger function. Can be used to log to
+ *                     console.log or equivalent.
+ *     Returns the receiver ID (this is only really necessary for the child).
+ *     NOTE: This function should return before tranport calls 'transportReady'
+ * + getURI()
+ *     Returns the updated URI for the child iframe.  The tranport layer may
+ *     choose to add URL params.  This function is called before the iframe is
+ *     created. (PARENT ONLY)
+ * + postAdd( receiverId, frame )
+ *     This function is called after the iframe has been created.  The tranport
+ *     layer may need to modify the provided iframe element. (PARENT ONLY)
+ * + sendMsg( targetId, msg )
+ *     The message is a JSON representation of the following object:
+ *          {
+ *              m: message type,
+ *              i: client id,
+ *              t: security token,
+ *              p: payload (depends on message type)
+ *          }
+ *     
+ *     The payload for each message type is as follows:
+ *          TYPE        DESCRIPTION                     PAYLOAD
+ *          "con"        connect                         N/A
+ *          "con_ack"    connect acknowledgment          N/A
+ *          "dis"        disconnect                      N/A
+ *          "dis_ack"    disconnect acknowledgment       N/A
+ *          "sub"        subscribe                       { t: topic, s: subscription id }
+ *          "sub_ack"    subscribe acknowledgment        { s: subscription id, e: error code (empty string if no error) }
+ *          "uns"        unsubscribe                     { s: subscription id }
+ *          "uns_ack"    unsubscribe acknowledgment      { s: subscription id }
+ *          "pub"        publish                         { t: topic, d: data }
+ *          "pub"        publish (i.e. sendToClient())   { t: topic, d: data, s: subscription id }
+ * + tunnelLoaded()
+ *     Called when the tunnel iframe has loaded.  The "window" object refers to
+ *     the tunnel iframe window.
+ * + removeReceiver( receiverId )
+ * 
+ * TRANSPORT CALLBACK API
+ * 
+ * + transportReady( receiverId, receiverName, success, args )
+ *     Called when the transport layer has fully initialized, or if there is an
+ *     error.
+ * + receiveMsg( msg )
+ *     Called when tranport layer has received a message.
+ * + securityAlert( alert )
+ *     Called when the transport layer has encountered a security condition.
+ * 
+ * 
+ * @param {OpenAjax.hub.ManagedHub} hub
+ *    Managed Hub instance to which this Container belongs
+ * @param {String} clientID
+ *    A string ID that identifies a particular client of a Managed Hub. Unique
+ *    within the context of the ManagedHub.
+ * @param {Object} params  
+ *    Parameters used to instantiate the IframeContainer.
+ *    Once the constructor is called, the params object belongs exclusively to
+ *    the IframeContainer. The caller MUST not modify it.
+ *    The following are the pre-defined properties on params:
+ * @param {Function} params.Container.onSecurityAlert
+ *    Called when an attempted security breach is thwarted.  Function is defined
+ *    as follows:  function(container, securityAlert)
+ * @param {Function} [params.Container.onConnect]
+ *    Called when the client connects to the Managed Hub.  Function is defined
+ *    as follows:  function(container)
+ * @param {Function} [params.Container.onDisconnect]
+ *    Called when the client disconnects from the Managed Hub.  Function is
+ *    defined as follows:  function(container)
+ * @param {Object} [params.Container.scope]
+ *    Whenever one of the Container's callback functions is called, references
+ *    to "this" in the callback will refer to the scope object. If no scope is
+ *    provided, default is window.
+ * @param {Function} [params.Container.log]
+ *    Optional logger function. Would be used to log to console.log or
+ *    equivalent. 
+ * @param {Object} params.IframeContainer.parent
+ *    DOM element that is to be parent of iframe
+ * @param {String} params.IframeContainer.uri
+ *    Initial Iframe URI (Container will add parameters to this URI)
+ * @param {String} params.IframeContainer.tunnelURI
+ *    URI of the tunnel iframe. Must be from the same origin as the page which
+ *    instantiates the IframeContainer.
+ * @param {Object} [params.IframeContainer.iframeAttrs]
+ *    Attributes to add to IFRAME DOM entity.  For example:
+ *              { style: { width: "100%",
+ *                         height: "100%" },
+ *                className: "some_class" }
+ * @param {Number} [params.IframeContainer.timeout]
+ *    Load timeout in milliseconds.  If not specified, defaults to 15000.  If
+ *    the client at params.IframeContainer.uri does not establish a connection
+ *    with this container in the given time, the onSecurityAlert callback is
+ *    called with a LoadTimeout error code.
+ * @param {Function} [params.IframeContainer.seed]
+ *    A function that returns a string that will be used to seed the
+ *    pseudo-random number generator, which is used to create the security
+ *    tokens.  An implementation of IframeContainer may choose to ignore this
+ *    value.
+ * @param {Number} [params.IframeContainer.tokenLength]
+ *    Length of the security tokens used when transmitting messages.  If not
+ *    specified, defaults to 6.  An implementation of IframeContainer may choose
+ *    to ignore this value.
+ *
+ * @throws {OpenAjax.hub.Error.BadParameters}   if required params are not
+ *          present or null
+ * @throws {OpenAjax.hub.Error.Duplicate}   if a Container with this clientID
+ *          already exists in the given Managed Hub
+ * @throws {OpenAjax.hub.Error.Disconnected}   if hub is not connected
+ */
+OpenAjax.hub.IframeContainer = function( hub, clientID, params )
+{
+    if ( ! hub || ! clientID || ! params ||
+            ! params.Container || ! params.Container.onSecurityAlert ||
+            ! params.IframeContainer || ! params.IframeContainer.parent ||
+            ! params.IframeContainer.uri || ! params.IframeContainer.tunnelURI ) {
+        throw new Error( OpenAjax.hub.Error.BadParameters );
+    }
+    
+    var container = this;
+    var scope = params.Container.scope || window;
+    var connected = false, doConnect = false, tunnelLoaded = false;
+    var subs = {};
+    var partnerOrigin;
+    var securityToken;
+    var internalID;
+    var transport;
+    var timeout = params.IframeContainer.timeout || 15000;
+    var loadTimer;
+
+    if ( params.Container.log ) {
+        var log = function( msg ) {
+            try {
+                params.Container.log.call( scope, "IframeContainer::" + clientID + ": " + msg );
+            } catch( e ) {
+                OpenAjax.hub._debugger();
+            }
+        };
+    } else {
+        log = function() {};
+    }
+    
+    
+    this._init = function() {
+        // add to ManagedHub first, to see if clientID is a duplicate
+        hub.addContainer( this );
+        
+        // initialize transport layer for this container
+        transport = getTransportLayer();
+
+        // Create an "internal" ID, which is guaranteed to be unique within the
+        // window, not just within the hub (internalID may be the same as
+        // clientID).
+        internalID = addContainer( clientID, this );
+        // Our FIM impl requires a security token length of 6
+        securityToken = generateSecurityToken( params, scope, log,
+                transport.type === "FIM" ? 6 : null );
+        
+        var args = {
+                receiver: this,
+                receiverId: internalID,
+                securityToken: securityToken,
+                uri: params.IframeContainer.uri,
+                tunnelURI: params.IframeContainer.tunnelURI,
+                log: log
+        };
+        if ( clientID !== internalID ) {
+            args.name = clientID;
+        }
+        transport.addReceiver( args );
+        
+        // Create IFRAME to hold the client
+        createIframe();
+        
+        transport.postAdd( internalID, document.getElementById( internalID ) );
+        
+        startLoadTimer();
+    };
+
+        
+  /*** OpenAjax.hub.Container interface ***/
+   
+    this.sendToClient = function( topic, data, subscriptionID ) {
+        sendMessage( "pub", { t: topic, d: data, s: subscriptionID } );
+    };
+
+    this.remove = function() {
+        finishDisconnect();
+        transport.removeReceiver( internalID );
+        clearTimeout( loadTimer );
+        removeIframe( internalID );
+    };
+
+    this.isConnected = function() {
+        return connected;
+    };
+    
+    this.getClientID = function() {
+        return clientID;
+    };
+
+    this.getPartnerOrigin = function() {
+        if ( connected ) {
+            return partnerOrigin;
+        }
+        return null;
+    };
+    
+    this.getParameters = function() {
+        return params;
+    };
+    
+    this.getHub = function() {
+        return hub;
+    };
+    
+    
+  /*** OpenAjax.hub.IframeContainer interface ***/
+    
+    /**
+     * Get the iframe associated with this iframe container
+     * 
+     * This function returns the iframe associated with an IframeContainer,
+     * allowing the Manager Application to change its size, styles, scrollbars, etc.
+     * 
+     * CAUTION: The iframe is owned exclusively by the IframeContainer. The Manager
+     * Application MUST NOT destroy the iframe directly. Also, if the iframe is
+     * hidden and disconnected, the Manager Application SHOULD NOT attempt to make
+     * it visible. The Container SHOULD automatically hide the iframe when it is
+     * disconnected; to make it visible would introduce security risks. 
+     * 
+     * @returns iframeElement
+     * @type {Object}
+     */
+    this.getIframe = function() {
+        return document.getElementById( internalID );
+    };
+    
+    
+  /*** transport interface ***/
+    
+    this.transportReady = function( receiverId, receiverName, success, args ) {
+        if ( ! success ) {
+            if ( args.securityAlert ) {
+                invokeSecurityAlert( args.securityAlert );
+            }
+            return;
+        }
+        partnerOrigin = args.partnerOrigin;
+    };
+    
+    this.receiveMsg = function( msg ) {
+        switch ( msg.m ) {
+            // publish
+            case "pub":
+                hub.publishForClient( this, msg.p.t, msg.p.d );
+                break;
+            
+            // subscribe
+            case "sub":
+                var errCode = "";  // empty string is success
+                try {
+                    subs[ msg.p.s ] = hub.subscribeForClient( this, msg.p.t, msg.p.s );
+                } catch( e ) {
+                    errCode = e.message;
+                }
+                sendMessage( "sub_ack", { s: msg.p.s, e: errCode } );
+                break;
+            
+            // unsubscribe
+            case "uns":
+                var handle = subs[ msg.p.s ];
+                hub.unsubscribeForClient( this, handle );
+                delete subs[ msg.p.s ];
+                sendMessage( "uns_ack", { s: msg.p.s } );
+                break;
+            
+            // connect
+            case "con":
+                doConnect = true;
+                finishConnect();
+                break;
+            
+            // disconnect
+            case "dis":
+                startLoadTimer();
+                finishDisconnect();
+                sendMessage( "dis_ack", null );
+                if ( params.Container.onDisconnect ) {
+                    try {
+                        params.Container.onDisconnect.call( scope, this );
+                    } catch( e ) {
+                        OpenAjax.hub._debugger();
+                        log( "caught error from onDisconnect callback to constructor: " + e.message );
+                    }
+                }
+                break;
+        }
+    };
+    
+    this.securityAlert = function( alert ) {
+        invokeSecurityAlert( alert );
+    };
+    
+    
+  /*** private functions ***/
+
+    function createIframe() {
+        var iframe = document.createElement( "iframe" );
+        iframe.id = internalID;
+        iframe.name = internalID;
+        
+        // Add iframe attributes
+        var attrs = params.IframeContainer.iframeAttrs;
+        if ( attrs ) {
+            for ( var attr in attrs ) {
+                switch ( attr ) {
+                    case "id":
+                    case "name":
+                        // Since we make use of these internally, we ignore
+                        // these two attributes.
+                        log( "Ignoring 'id' or 'name' property in 'iframeAttrs' -- " +
+                                "these attributes on the iframe are used for " +
+                                "internal purposes.");
+                        break;
+                    
+                    case "style":
+                        for ( var style in attrs.style ) {
+                            iframe.style[ style ] = attrs.style[ style ];
+                        }
+                        break;
+                    
+                    default:
+                        iframe[ attr ] = attrs[ attr ];
+                }
+            }
+        }
+    
+        // initially hide IFRAME content, in order to lessen frame phishing impact
+        iframe.style.visibility = "hidden";
+        
+        // (1) Setting the iframe src after it has been added to the DOM can cause
+        // problems in IE6/7.  Specifically, if the code is being executed on a page
+        // that was served through HTTPS, then IE6/7 will see an iframe with a blank
+        // src as a non-secure item and display a dialog warning the user that "this
+        // page contains both secure and nonsecure items."  To prevent that, we
+        // first set the src to a dummy value, then add the iframe to the DOM, then
+        // set the real src value.
+        // (2) Trying to fix the above issue by setting the real src before adding
+        // the iframe to the DOM breaks Firefox 3.x.  For some reason, when
+        // reloading a page that has instantiated an IframeContainer, Firefox will
+        // load a previously cached version of the iframe content, whose source
+        // contains stale URL query params or hash.  This results in errors in the
+        // Hub code, which is expected different values.
+        iframe.src = 'javascript:"<html></html>"';
+        params.IframeContainer.parent.appendChild( iframe );
+        iframe.src = transport.getURI();
+
+        // To prevent leak in IE, null out the parent node now that we no
+        // longer need it.
+        params.IframeContainer.parent = null;
+    }
+    
+    var removeIframe = function() {
+        if ( navigator.appName === 'Microsoft Internet Explorer' ) {
+            return function( id ) {
+                // IE doesn't seem to properly clean up the iframe content if we
+                // simply remove it. Instead, navigate away, forcing clean up, then
+                // remove the iframe.
+                var iframe = document.getElementById( id );
+                iframe.onreadystatechange = function() {
+                    if ( iframe.readyState == 'complete' ) {
+                        iframe.onreadystatechange = null;
+                        iframe.outerHTML = "";
+                        iframe = null;
+                    }
+                };
+                iframe.src = "";
+            };
+        } else {
+            return function( id ) {
+                var iframe = document.getElementById( id );
+                iframe.parentNode.removeChild( iframe );
+                iframe = null;
+            };
+        }
+    }();
+    
+    function sendMessage( type, payload ) {
+        var data = {
+            m: type,
+            i: internalID,
+            r: "..",
+            t: securityToken,
+            p: payload
+        };
+        transport.sendMsg( internalID, data );
+    }
+    
+    function finishConnect() {
+        // don't finish connection if tunnel has yet to load
+        if ( ! tunnelLoaded || ! doConnect ) {
+            return;
+        }
+        
+        connected = true;
+        clearTimeout( loadTimer );
+        document.getElementById( internalID ).style.visibility = "visible";
+        sendMessage( "con_ack", null );
+        if ( params.Container.onConnect ) {
+            try {
+                params.Container.onConnect.call( scope, container );
+            } catch( e ) {
+                OpenAjax.hub._debugger();
+                log( "caught error from onConnect callback to constructor: " + e.message );
+            }
+        }
+    }
+    
+    function finishDisconnect() {
+        if ( connected ) {
+            connected = false;
+            document.getElementById( internalID ).style.visibility = "hidden";
+        
+            // unsubscribe from all subs
+            for ( var s in subs ) {
+                hub.unsubscribeForClient( container, subs[s] );
+            }
+            subs = {};
+        }
+    }
+    
+    function addContainer( id, container ) {
+        while ( OpenAjax.hub.IframeContainer._containers[ id ] ) {
+            // a client with the specified ID already exists on this page;
+            // create a unique ID
+            id += "_" + ((0x7fff * Math.random()) | 0).toString(16);
+        }
+        OpenAjax.hub.IframeContainer._containers[ id ] = container;
+        return id;
+    }
+    
+    this._tunnelLoaded = function( tunnelWindow ) {
+        // set unload handler on tunnel window
+        tunnelWindow.onunload = tunnelUnloadHandler;
+        tunnelLoaded = true;
+        hookMainPageUnload();
+        finishConnect();
+    };
+
+    function tunnelUnloadHandler() {
+        // The tunnel's unload handler can be called in two instances: (1) when
+        // the source for the tunnel's parent iframe is changed, or (2) when the
+        // mashup page itself is closed or navigated to a different location.
+        // We don't want to throw an error in case (2).
+        if ( connected && ! _mainPageUnloading ) {
+            invokeSecurityAlert( OpenAjax.hub.SecurityAlert.FramePhish );
+        }
+    }
+    
+    function invokeSecurityAlert( errorMsg ) {
+        try {
+            params.Container.onSecurityAlert.call( scope, container, errorMsg );
+        } catch( e ) {
+            OpenAjax.hub._debugger();
+            log( "caught error from onSecurityAlert callback to constructor: " + e.message );
+        }
+    }
+    
+    function startLoadTimer() {
+        loadTimer = setTimeout(
+            function() {
+                // alert the security alert callback
+                invokeSecurityAlert( OpenAjax.hub.SecurityAlert.LoadTimeout );
+                // don't receive any more messages from HubClient
+                container.receiveMsg = function() {};
+            },
+            timeout
+        );
+    }
+    
+    
+    this._init();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Create a new IframeHubClient.
+ * @constructor
+ * @extends OpenAjax.hub.HubClient
+ * 
+ * @param {Object} params
+ *    Once the constructor is called, the params object belongs to the
+ *    HubClient. The caller MUST not modify it.
+ *    The following are the pre-defined properties on params:
+ * @param {Function} params.HubClient.onSecurityAlert
+ *     Called when an attempted security breach is thwarted
+ * @param {Object} [params.HubClient.scope]
+ *     Whenever one of the HubClient's callback functions is called,
+ *     references to "this" in the callback will refer to the scope object.
+ *     If not provided, the default is window.
+ * @param {Function} [params.HubClient.log]
+ *     Optional logger function. Would be used to log to console.log or
+ *     equivalent. 
+ * @param {Function} [params.IframeHubClient.seed]
+ *     A function that returns a string that will be used to seed the
+ *     pseudo-random number generator, which is used to create the security
+ *     tokens.  An implementation of IframeHubClient may choose to ignore
+ *     this value.
+ * @param {Number} [params.IframeHubClient.tokenLength]
+ *     Length of the security tokens used when transmitting messages.  If
+ *     not specified, defaults to 6.  An implementation of IframeHubClient
+ *     may choose to ignore this value.
+ *     
+ * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
+ *          parameters is missing, or if a parameter value is invalid in 
+ *          some way.
+ */
+OpenAjax.hub.IframeHubClient = function( params )
+{
+    if ( ! params || ! params.HubClient || ! params.HubClient.onSecurityAlert ) {
+        throw new Error( OpenAjax.hub.Error.BadParameters );
+    }
+    
+    var client = this;
+    var scope = params.HubClient.scope || window;
+    var ready = false;
+    var connected = false;
+    var subs = {};
+    var subIndex = 0;
+    var clientID, internalID, securityToken;
+    var partnerOrigin;
+    
+    if ( params.HubClient.log ) {
+        var log = function( msg ) {
+            try {
+                params.HubClient.log.call( scope, "IframeHubClient::" + clientID + ": " + msg );
+            } catch( e ) {
+                OpenAjax.hub._debugger();
+            }
+        };
+    } else {
+        log = function() {};
+    }
+    
+    var transport;
+    
+    this._init = function() {
+        // init transport layer
+        transport = getTransportLayer();
+        
+        // Our FIM impl requires a security token length of 6
+        securityToken = generateSecurityToken( params, scope, log,
+                transport.type === "FIM" ? 6 : null );
+        
+        clientID = transport.addReceiver({
+                receiver: this,
+                receiverId: "..",
+                securityToken: securityToken,
+                log: log
+        });
+        
+        if ( ! clientID ) {
+            throw new Error( OpenAjax.hub.Error.WrongProtocol );
+        }
+    };
+    
+  /*** HubClient interface ***/
+
+    this.connect = function( onComplete, scope ) {
+        scope = scope || window;
+        if ( connected ) {
+            throw new Error( OpenAjax.hub.Error.Duplicate );
+        }
+        
+        if ( onComplete ) {
+            this._connectCallback = {
+                func: onComplete,
+                scope: scope
+            };
+        }
+        
+        if ( ready ) {
+            sendMessage( "con", null );
+        } else {
+            // connect() may get called before the transport is ready.  If so,
+            // we send the "con" message in transportReady().
+            this._connectPending = true;
+        }
+    };
+    
+    this.disconnect = function( onComplete, scope ) {
+        scope = scope || window;
+        if ( !connected ) {
+            throw new Error( OpenAjax.hub.Error.Disconnected );
+        }
+        
+        connected = false;
+        
+        if ( onComplete ) {
+            this._disconnectCallback = {
+                func: onComplete,
+                scope: scope
+            };
+        }
+        sendMessage( "dis", null );
+    };
+    
+    this.getPartnerOrigin = function() {
+        if ( connected ) {
+            return partnerOrigin;
+        }
+        return null;
+    };
+    
+    this.getClientID = function() {
+        return clientID;
+    };
+    
+  /*** Hub interface ***/
+    
+    this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
+        assertConn();
+        assertSubTopic( topic );
+        if ( ! onData ) {
+            throw new Error( OpenAjax.hub.Error.BadParameters );
+        }
+    
+        scope = scope || window;
+        var subID = "" + subIndex++;
+        subs[ subID ] = { cb: onData, sc: scope, d: subscriberData, oc: onComplete };
+        sendMessage( "sub", { t: topic, s: subID } );
+        return subID;
+    };
+    
+    this.publish = function( topic, data ) {
+        assertConn();
+        assertPubTopic( topic );
+        sendMessage( "pub", { t: topic, d: data } );
+    };
+    
+    this.unsubscribe = function( subscriptionID, onComplete, scope ) {
+        assertConn();
+        if ( ! subscriptionID ) {
+            throw new Error( OpenAjax.hub.Error.BadParameters );
+        }
+        
+        // if no such subscriptionID, or in process of unsubscribing given ID, throw error
+        if ( ! subs[ subscriptionID ] || subs[ subscriptionID ].uns ) {
+            throw new Error( OpenAjax.hub.Error.NoSubscription );
+        }
+        
+        scope = scope || window;
+        subs[ subscriptionID ].uns = { cb: onComplete, sc: scope };
+        sendMessage( "uns", { s: subscriptionID } );
+    };
+    
+    this.isConnected = function() {
+        return connected;
+    };
+    
+    this.getScope = function() {
+        return scope;
+    };
+    
+    this.getSubscriberData = function( subscriptionID ) {
+        assertConn();
+        if ( subs[ subscriptionID ] ) {
+            return subs[ subscriptionID ].d;
+        }
+        throw new Error( OpenAjax.hub.Error.NoSubscription );
+    };
+    
+    this.getSubscriberScope = function( subscriptionID ) {
+        assertConn();
+        if ( subs[ subscriptionID ] ) {
+            return subs[ subscriptionID ].sc;
+        }
+        throw new Error( OpenAjax.hub.Error.NoSubscription );
+    };
+    
+    this.getParameters = function() {
+        return params;
+    };
+    
+  /*** transport interface ***/
+    
+    this.transportReady = function( receiverId, receiverName, success, args ) {
+        if ( ! success ) {
+            if ( args.securityAlert ) {
+                invokeSecurityAlert( args.securityAlert );
+            }
+            return;
+        }
+        
+        internalID = receiverId;
+        partnerOrigin = args.partnerOrigin;
+        
+        if ( args.debug ) { OpenAjax.hub.enableDebug = true; } // REMOVE ON BUILD
+        
+        ready = true;
+        if ( this._connectPending ) {
+            delete this._connectPending;
+            sendMessage( "con", null );
+        }
+    };
+    
+    this.receiveMsg = function( msg ) {
+        var subID, onComplete;
+        
+        switch ( msg.m ) {
+            // publish
+            case "pub":
+                subID = msg.p.s;
+                // if subscription exists and we are not in process of unsubscribing...
+                if ( subs[ subID ] && ! subs[ subID ].uns ) {
+                    try {
+                        subs[ subID ].cb.call( subs[ subID ].sc, msg.p.t, msg.p.d, subs[ subID ].d );
+                    } catch( e ) {
+                        OpenAjax.hub._debugger();
+                        log( "caught error from onData callback to subscribe(): " + e.message );
+                    }
+                }
+                break;
+            
+            // subscribe acknowledgement
+            case "sub_ack":
+                subID = msg.p.s;
+                onComplete = subs[ subID ].oc;
+                if ( onComplete ) {
+                    try {
+                        delete subs[ subID ].oc;
+                        onComplete.call( subs[ subID ].sc, subID, msg.p.e === "", msg.p.e );
+                    } catch( e ) {
+                        OpenAjax.hub._debugger();
+                        log( "caught error from onComplete callback to subscribe(): " + e.message );
+                    }
+                }
+                break;
+            
+            // unsubscribe acknowledgement
+            case "uns_ack":
+                subID = msg.p.s;
+                if ( subs[ subID ] ) {
+                    onComplete = subs[ subID ].uns.cb;
+                    if ( onComplete ) {
+                        try {
+                            onComplete.call( subs[ subID ].uns.sc, subID, true );
+                        } catch( e ) {
+                            OpenAjax.hub._debugger();
+                            log( "caught error from onComplete callback to unsubscribe(): " + e.message );
+                        }
+                    }
+                    delete subs[ subID ];
+                }
+                break;
+            
+            // connect acknowledgement
+            case "con_ack":
+                connected = true;
+                if ( this._connectCallback ) {
+                    try {
+                        this._connectCallback.func.call( this._connectCallback.scope,
+                                this, true );
+                    } catch( e ) {
+                        OpenAjax.hub._debugger();
+                        log( "caught error from onComplete callback to connect(): " + e.message );
+                    }
+                    delete this._connectCallback;
+                }
+                break;
+                        
+            // disconnect acknowledgement
+            case "dis_ack":
+                if ( this._disconnectCallback ) {
+                    try {
+                        this._disconnectCallback.func.call( this._disconnectCallback.scope,
+                                this, true );
+                    } catch( e ) {
+                        OpenAjax.hub._debugger();
+                        log( "caught error from onComplete callback to disconnect(): " + e.message );
+                    }
+                    delete this._disconnectCallback;
+                }
+                break;
+        }
+    };
+    
+    this.securityAlert = function( alert ) {
+        invokeSecurityAlert( alert );
+    };
+    
+  /*** private functions ***/
+    
+    function assertConn() {
+        if ( ! connected ) {
+            throw new Error( OpenAjax.hub.Error.Disconnected );
+        }
+    }
+    
+    function assertSubTopic( topic )
+    {
+        if ( ! topic ) {
+            throw new Error( OpenAjax.hub.Error.BadParameters );
+        }
+        var path = topic.split(".");
+        var len = path.length;
+        for (var i = 0; i < len; i++) {
+            var p = path[i];
+            if ((p === "") ||
+               ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
+                throw new Error( OpenAjax.hub.Error.BadParameters );
+            }
+            if ((p == "**") && (i < len - 1)) {
+                throw new Error( OpenAjax.hub.Error.BadParameters );
+            }
+        }
+    }
+    
+    function assertPubTopic( topic ) {
+        if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
+            (topic.indexOf("..") != -1) ||  (topic.charAt(0) == ".") ||
+            (topic.charAt(topic.length-1) == "."))
+        {
+            throw new Error( OpenAjax.hub.Error.BadParameters );
+        }
+    }
+    
+    function sendMessage( type, payload ) {
+        var data = {
+            m: type,
+            i: internalID,
+            t: securityToken,
+            p: payload
+        };
+        transport.sendMsg( "..", data );
+    }
+    
+    function invokeSecurityAlert( errorMsg ) {
+        try {
+            params.HubClient.onSecurityAlert.call( scope, client, errorMsg );
+        } catch( e ) {
+            OpenAjax.hub._debugger();
+            log( "caught error from onSecurityAlert callback to constructor: " + e.message );
+        }
+    }
+
+    
+    this._init();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+OpenAjax.hub.IframeContainer._containers = {};
+
+/**
+ * Called by the tunnel iframe, once it has loaded.  Note that this function is
+ * executed in the window context of the tunnel, not the IframeContainer.
+ */
+OpenAjax.hub.IframeContainer._tunnelLoaded = function() {
+    var transport = getTransportLayer();
+    var id = transport.tunnelLoaded();
+    
+    window.parent.parent.OpenAjax.hub.IframeContainer._containers[ id ]
+            ._tunnelLoaded( window );
+};
+
+OpenAjax.hub.IframeContainer._queryURLParam = function( param ) {
+    var result = new RegExp( "[\\?&]" + param + "=([^&#]*)" ).exec( window.location.search );
+    if ( result ) {
+        return decodeURIComponent( result[1].replace( /\+/g, "%20" ) );
+    }
+    return null;
+};
+
+OpenAjax.hub.IframeContainer._createTunnelIframe = function( uri ) {
+    var iframe = document.createElement( "iframe" );
+    iframe.src = uri;
+	document.body.appendChild(iframe);
+	iframe.style.position = "absolute";
+	iframe.style.left = iframe.style.top = "-10px";
+	iframe.style.height = iframe.style.width = "1px";
+	iframe.style.visibility = "hidden";
+};
+
+OpenAjax.hub.IframeContainer._getTargetWin = function( id ) {
+    if (typeof id === "undefined" || id === "..") {
+        return window.parent;
+    }
+    
+    // Cast to a String to avoid an index lookup.
+    id = String(id);
+    
+    // Try window.frames first
+    var target = window.frames[id];
+    if (target) {
+        return target;
+    }
+    
+    // Fall back to getElementById()
+    target = document.getElementById(id);
+    if (target && target.contentWindow) {
+        return target.contentWindow;
+    }
+    
+    return null;
+};
+
+//  Track when this main page is closed or navigated to a different location
+// ("unload" event).
+//  NOTE: The use of the "unload" handler here and for the tunnel iframe
+// prevents the use of the in-memory page cache in modern browsers.
+var _mainPageUnloading = false,
+    _hookedUnload = false;
+
+function hookMainPageUnload() {
+    if ( _hookedUnload ) {
+        return;
+    }
+    addEventListener( "unload",
+            function() {
+                _mainPageUnloading = true;
+            },
+            false
+    );
+    _hookedUnload = true;
+}
+
+function addEventListener( eventName, callback, useCapture ) {
+    if ( window.addEventListener ) {
+        window.addEventListener( eventName, callback, useCapture );
+    } else if ( window.attachEvent ) {
+        window.attachEvent( "on" + eventName, callback );
+    }
+}
+
+function removeEventListener( eventName, callback, useCapture ) {
+    if ( window.removeEventListener ) {
+        window.removeEventListener( eventName, callback, useCapture );
+    } else {
+        window.detachEvent( "on" + eventName, callback );
+    }
+}
+
+var _transport;
+
+function getTransportLayer() {
+    if ( ! _transport ) {
+        var t = window.postMessage ? "PM" :
+                window.ActiveXObject ? "NIX" :
+                "FIM";
+/** Added by Gerald Guo. PM does not work when window is moved.  */
+        t = "FIM";
+        _transport = new OpenAjax.hub.IframeContainer[ "_" + t ]();
+        _transport.type = t;
+    }
+    return _transport;
+}
+
+function generateSecurityToken( params, scope, log, overrideTokenLength ) {
+    if ( ! OpenAjax.hub.IframeContainer._prng ) {
+        // create pseudo-random number generator with a default seed
+        var seed = new Date().getTime() + Math.random() + document.cookie;
+        OpenAjax.hub.IframeContainer._prng = OpenAjax._smash.crypto.newPRNG( seed );
+    }
+    
+    var p = params.IframeContainer || params.IframeHubClient;
+    if ( p && p.seed ) {
+        try {
+            var extraSeed = p.seed.call( scope );
+            OpenAjax.hub.IframeContainer._prng.addSeed( extraSeed );
+        } catch( e ) {
+            OpenAjax.hub._debugger();
+            log( "caught error from 'seed' callback: " + e.message );
+        }
+    }
+    
+    var tokenLength = overrideTokenLength || (p && p.tokenLength) || 6;
+    return OpenAjax.hub.IframeContainer._prng.nextRandomB64Str( tokenLength );
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+OpenAjax.hub.IframeContainer._PM = function() {
+    // communications protocol identifier
+    var protocolID = "openajax-2.0.2";
+    
+    var receivers = {};
+    var pmCapabilities, postMessage;
+    var uri;
+    
+    // start listening for messages
+    addEventListener( "message", receiveMsg, false);
+
+  /*** Transport Layer API ***/
+    
+    this.addReceiver = function( args ) {
+        var params;
+        receivers[ args.receiverId ] = { r: args.receiver };
+        
+        // complete a connection with parent...
+        if ( args.receiverId === ".." ) {
+            // make sure provided protocol version is the same
+            var pv = OpenAjax.hub.IframeContainer._queryURLParam( "oahpv" );
+            if ( ! pv || pv !== protocolID ) {
+                return null;
+            }
+            
+            var tunnelURI = OpenAjax.hub.IframeContainer._queryURLParam( "oahu" );
+            var uniqueId = OpenAjax.hub.IframeContainer._queryURLParam( "oahi" );
+            var name = OpenAjax.hub.IframeContainer._queryURLParam( "oahn" );
+            var authToken = OpenAjax.hub.IframeContainer._queryURLParam( "oaht" );
+            
+            // if any of the URL params are missing, return null
+            if ( ! uniqueId || ! authToken || ! tunnelURI ) {
+                return null;
+            }
+            
+            // handle postMessage
+            pmCapabilities = OpenAjax.hub.IframeContainer._queryURLParam( "oahpm" );
+            setPostMessageFunction();
+            
+            var origin = /^([a-zA-Z]+:\/\/[^\/?#]+).*/.exec( tunnelURI )[1];
+            receivers[ ".." ].o = origin;
+            receivers[ ".." ].m = setOriginMatch( origin );
+            
+            // add params to tunnel URI
+            var paramStr =
+                    "oahi=" + encodeURIComponent( uniqueId ) +
+                    "&oaht=" + authToken;
+            var parts = tunnelURI.split("#");
+            parts[0] = parts[0] + ((parts[0].indexOf( "?" ) != -1) ? "&" : "?") + paramStr;
+            tunnelURI = parts.length === 1 ? parts[0] : parts[0] + "#" + parts[1];
+            
+            // create hidden tunnel iframe
+            OpenAjax.hub.IframeContainer._createTunnelIframe( tunnelURI );
+            
+            params = {
+                // remove port, if it is present
+                partnerOrigin: /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1],
+                securityToken: authToken
+            };
+            if ( OpenAjax.hub.IframeContainer._queryURLParam("oahd") ) { params.debug = true; } // REMOVE ON BUILD
+            
+            setTimeout( function() {
+                args.receiver.transportReady( uniqueId, name, true, params );
+            }, 0 );
+            return name || uniqueId;    // 'name' may be null -- default to 'uniqueId'
+        }
+        
+        // create connection to a child frame...
+        
+        // test if the postMessage impl of this browser is synchronous
+        if ( typeof pmCapabilities === "undefined" ) {
+            testPostMessage();
+            setPostMessageFunction();
+        }
+        
+        origin = /^([a-zA-Z]+:\/\/[^\/?#]+).*/.exec( args.uri )[1];
+        receivers[ args.receiverId ].o = origin;
+        receivers[ args.receiverId ].m = setOriginMatch( origin );
+        
+        params = {
+            // remove port, if it is present
+            partnerOrigin: /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1]
+        };
+        setTimeout( function() {
+            args.receiver.transportReady( args.receiverId, args.name, true, params );
+        }, 0 );
+        
+        // add the client ID and a security token as URL query params when loading
+        // the client iframe
+        paramStr =
+                "oahpv=" + encodeURIComponent( protocolID ) +
+                "&oahi=" + encodeURIComponent( args.receiverId ) +
+                (args.name ? "&oahn=" + encodeURIComponent( args.name ) : "") +
+                "&oaht=" + args.securityToken +
+                "&oahu=" + encodeURIComponent( args.tunnelURI ) +
+                "&oahpm=" + pmCapabilities;
+        paramStr += OpenAjax.hub.enableDebug ? "&oahd=true" : ""; // REMOVE ON BUILD
+        
+        parts = args.uri.split("#");
+        parts[0] = parts[0] + ((parts[0].indexOf( "?" ) != -1) ? "&" : "?") + paramStr;
+        uri = parts.length === 1 ? parts[0] : parts[0] + "#" + parts[1];
+        
+        return null;
+    };
+    
+    this.getURI = function() {
+        return uri;
+    };
+    
+    this.postAdd = function( receiverId, frame ) {};
+    
+    this.sendMsg = function( targetId, data ) {
+        if ( receivers[ targetId ] ) {
+            var targetWin = OpenAjax.hub.IframeContainer._getTargetWin( targetId );
+            postMessage( targetWin, JSON.stringify(data),
+                    receivers[ targetId ].o );
+        }
+        return true;
+    };
+    
+    this.tunnelLoaded = function() {
+        return OpenAjax.hub.IframeContainer._queryURLParam( "oahi" );
+    };
+    
+    this.removeReceiver = function( receiverId ) {
+        delete receivers[ receiverId ];
+    };
+    
+  /*** private functions ***/
+    
+    /**
+     * Some browsers (IE, Opera) have an implementation of postMessage that is
+     * synchronous, although HTML5 specifies that it should be asynchronous.  In
+     * order to make all browsers behave consistently, we run a small test to detect
+     * if postMessage is asynchronous or not.  If not, we wrap calls to postMessage
+     * in a setTimeout with a timeout of 0.
+     * Also, Opera's "message" event does not have an "origin" property (at least,
+     * it doesn't in version 9.64;  presumably, it will in version 10).  If
+     * event.origin does not exist, use event.domain.  The other difference is that
+     * while event.origin looks like <scheme>://<hostname>:<port>, event.domain
+     * consists only of <hostname>.
+     */
+    function testPostMessage() {
+        // String identifier that specifies whether this browser's postMessage
+        // implementation differs from the spec:
+        //      contains "s" - postMessage is synchronous
+        //      contains "d" - "message" event does not have an "origin" property;
+        //                     the code looks for the "domain" property instead
+        pmCapabilities = "";
+    
+        var hit = false;
+        
+        function receiveMsg(event) {
+            if ( event.data == "postmessage.test" ) {
+                hit = true;
+                if ( typeof event.origin === "undefined" ) {
+                    pmCapabilities += "d";
+                }
+            }
+        }
+        
+        addEventListener( "message", receiveMsg, false );
+        window.postMessage( "postmessage.test", "*" );
+        
+        // if 'hit' is true here, then postMessage is synchronous
+        if ( hit ) {
+            pmCapabilities += "s";
+        }
+    
+        removeEventListener( "message", receiveMsg, false );
+    }
+    
+    /**
+     * if postMessage is synchronous, wrap in a setTimeout
+     */
+    function setPostMessageFunction() {
+        if ( pmCapabilities.indexOf("s") === -1 ) {
+            postMessage = function( win, msg, origin ) {
+                win.postMessage( msg, origin );
+            };
+        } else {
+            postMessage = function( win, msg, origin ) {
+                setTimeout(
+                    function() {
+                        win.postMessage( msg, origin );
+                    },
+                    0
+                );
+            };
+        }
+    }
+    
+    // See testPostMessage comment for explanation.
+    function setOriginMatch( origin ) {
+        if ( pmCapabilities.indexOf("d") !== -1 ) {
+            return ( /^.+:\/\/([^:]+).*/.exec( origin )[1] );
+        }
+        return origin;
+    }
+    
+    function receiveMsg( event ) {
+        // If the received message isn't JSON parseable or if the resulting
+        // object doesn't have the structure we expect, then just return.  This
+        // message might belong to some other code on the page that is also using
+        // postMessage for communication.
+        try {
+            var data = JSON.parse( event.data );
+            
+            var id = data.r || data.i;
+            if ( typeof id === "undefined" ) {
+                return;
+            }
+            if ( ! receivers[ id ] ) {
+                if ( typeof data.m !== "undefined" && typeof data.p !== "undefined" ) {
+                    // this looks like a forged message, with an invalid ID
+                    receivers[ ".." ].r.securityAlert( OpenAjax.hub.SecurityAlert.ForgedMsg );
+                }
+                return;
+            }
+            
+            // Older versions of Opera did not have "event.origin", so we have
+            // to use "event.domain" instead. See testPostMessage comment for
+            // full explanation.
+            if ( receivers[ id ].m !== (event.origin || event.domain) ) {
+                receivers[ id ].r.securityAlert( OpenAjax.hub.SecurityAlert.ForgedMsg );
+                return;
+            }
+            
+            receivers[ id ].r.receiveMsg( data );
+        } catch( e ) {
+            return;
+        }
+    }
+};
+
+})();

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/json2.js
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/json2.js?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/json2.js (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/iframe/json2.js Fri Apr  1 00:29:22 2011
@@ -0,0 +1,499 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*
+    http://www.JSON.org/json2.js
+    2008-11-19
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the object holding the key.
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+*/
+
+/*jslint evil: true */
+
+/*global JSON */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON) {
+    JSON = {};
+}
+(function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z';
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+})();

Added: incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/index.html
URL: http://svn.apache.org/viewvc/incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/index.html?rev=1087520&view=auto
==============================================================================
--- incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/index.html (added)
+++ incubator/rave/donations/ogce-gadget-container/ishindig-webapp/src/main/webapp/www/js/OpenAjax_Hub/src/containers/index.html Fri Apr  1 00:29:22 2011
@@ -0,0 +1,35 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<html><head><title>openajaxallianc - Revision 1339: /hub20/tags/Hub_2.0.3_release/src/containers/iframe</title></head>
+<body>
+ <h2>openajaxallianc - Revision 1339: /hub20/tags/Hub_2.0.3_release/src/containers/iframe</h2>
+ <ul>
+  <li><a href="../">..</a></li>
+  <li><a href="FIM.js">FIM.js</a></li>
+  <li><a href="NIX.js">NIX.js</a></li>
+  <li><a href="crypto.js">crypto.js</a></li>
+  <li><a href="iframe.js">iframe.js</a></li>
+  <li><a href="json2.js">json2.js</a></li>
+  <li><a href="tunnel.html">tunnel.html</a></li>
+ </ul>
+ <hr noshade><em>Powered by <a href="http://subversion.tigris.org/">Subversion</a> version 1.6.9 (r901367).</em>
+</body></html>