You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by hn...@apache.org on 2010/10/04 18:21:18 UTC
svn commit: r1004309 [2/2] - in
/shindig/trunk/extras/src/main/javascript/features-extras: ./
org.openajax.hub-2.0.3/ org.openajax.hub-2.0.4/ org.openajax.hub-2.0.5/
pubsub-2/
Added: shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/iframe.js
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/iframe.js?rev=1004309&view=auto
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/iframe.js (added)
+++ shindig/trunk/extras/src/main/javascript/features-extras/org.openajax.hub-2.0.5/iframe.js Mon Oct 4 16:21:18 2010
@@ -0,0 +1,873 @@
+/*
+
+ 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.
+*/
+
+var OpenAjax = OpenAjax || {};
+OpenAjax.hub = OpenAjax.hub || {};
+OpenAjax.gadgets = typeof OpenAjax.gadgets === 'object' ? OpenAjax.gadgets :
+ typeof gadgets === 'object' ? gadgets :
+ {};
+OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
+
+(function() {
+ // For now, we only use "oaaConfig" for the global "gadgets" object. If the "gadgets" global
+ // already exists, then there is no reason to check for "oaaConfig". In the future, if we use
+ // "oaaConfig" for other purposes, we'll need to remove the check for "!window.gadgets".
+ if (typeof gadgets === 'undefined') {
+ // "oaaConfig" can be specified as a global object. If not found, then look for it as an
+ // attribute on the script line for the OpenAjax Hub JS file.
+ if (typeof oaaConfig === 'undefined') {
+ var scripts = document.getElementsByTagName("script");
+ // match "OpenAjax-mashup.js", "OpenAjaxManagedHub-all*.js", "OpenAjaxManagedHub-core*.js"
+ var reHub = /openajax(?:managedhub-(?:all|core).*|-mashup)\.js$/i;
+ for ( var i = scripts.length - 1; i >= 0; i-- ) {
+ var src = scripts[i].getAttribute( "src" );
+ if ( !src ) {
+ continue;
+ }
+
+ var m = src.match( reHub );
+ if ( m ) {
+ var config = scripts[i].getAttribute( "oaaConfig" );
+ if ( config ) {
+ try {
+ oaaConfig = eval( "({ " + config + " })" );
+ } catch (e) {}
+ }
+ break;
+ }
+ }
+ }
+
+ if (typeof oaaConfig !== 'undefined' && oaaConfig.gadgetsGlobal) {
+ gadgets = OpenAjax.gadgets;
+ }
+ }
+})();
+
+
+if (!OpenAjax.hub.IframeContainer) {
+
+(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.
+ *
+ * SECURITY
+ *
+ * In order for the connection between the IframeContainer and IframeHubClient
+ * to be fully secure, you must specify a valid 'tunnelURI'. Note that if you
+ * do specify a 'tunnelURI', then only the WPM and NIX transports are used,
+ * covering the following browsers:
+ * IE 6+, Firefox 3+, Safari 4+, Chrome 2+, Opera 9+.
+ *
+ * If no 'tunnelURI' is specified, then some security features are disabled:
+ * the IframeContainer will not report FramePhish errors, and on some browsers
+ * IframeContainer and IframeHubClient will not be able to validate the
+ * identity of their partner (i.e. getPartnerOrigin() will return 'null').
+ * However, not providing 'tunnelURI' allows the additional use of the RMR
+ * and FE transports -- in addition to the above browsers, the Hub code will
+ * also work on:
+ * Firefox 1 & 2, Safari 2 & 3, Chrome 1.
+ *
+ * @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. If not specified, connection will not
+ * be fully secure (see SECURITY section).
+ * @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 )
+{
+ assertValidParams( arguments );
+
+ var container = this;
+ var scope = params.Container.scope || window;
+ var connected = false;
+ var subs = {};
+ var securityToken;
+ var internalID;
+ 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 );
+
+ // Create an "internal" ID, which is guaranteed to be unique within the
+ // window, not just within the hub.
+ internalID = OpenAjax.hub.IframeContainer._rpcRouter.add( clientID, this );
+ securityToken = generateSecurityToken( params, scope, log );
+
+ var relay = null;
+ var transportName = OpenAjax.gadgets.rpc.getRelayChannel();
+ if ( params.IframeContainer.tunnelURI ) {
+ if ( transportName !== "wpm" && transportName !== "nix" ) {
+ throw new Error( OpenAjax.hub.Error.IncompatBrowser );
+ }
+ } else {
+ log( "WARNING: Parameter 'IframeContaienr.tunnelURI' not specified. Connection will not be fully secure." );
+ if ( transportName === "rmr" ) {
+ relay = OpenAjax.gadgets.rpc.getOrigin( params.IframeContainer.uri ) + "/robots.txt";
+ }
+ }
+
+ // Create IFRAME to hold the client
+ createIframe();
+
+ OpenAjax.gadgets.rpc.setupReceiver( internalID, relay );
+
+ startLoadTimer();
+ };
+
+
+ /*** OpenAjax.hub.Container interface ***/
+
+ this.sendToClient = function( topic, data, subscriptionID ) {
+ OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", null, "pub", topic, data,
+ subscriptionID );
+ };
+
+ this.remove = function() {
+ finishDisconnect();
+ clearTimeout( loadTimer );
+ OpenAjax.gadgets.rpc.removeReceiver( internalID );
+ var iframe = document.getElementById( internalID );
+ iframe.parentNode.removeChild( iframe );
+ OpenAjax.hub.IframeContainer._rpcRouter.remove( internalID );
+ };
+
+ this.isConnected = function() {
+ return connected;
+ };
+
+ this.getClientID = function() {
+ return clientID;
+ };
+
+ this.getPartnerOrigin = function() {
+ if ( connected ) {
+ var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( internalID );
+ if ( origin ) {
+ // remove port if present
+ return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
+ }
+ }
+ 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 );
+ };
+
+
+ /*** private functions ***/
+
+ function assertValidParams( args ) {
+ var hub = args[0],
+ clientID = args[1],
+ params = args[2];
+ if ( ! hub || ! clientID || ! params || ! params.Container ||
+ ! params.Container.onSecurityAlert || ! params.IframeContainer ||
+ ! params.IframeContainer.parent || ! params.IframeContainer.uri ) {
+ throw new Error( OpenAjax.hub.Error.BadParameters );
+ }
+ }
+
+ this._handleIncomingRPC = function( command, topic, data ) {
+ switch ( command ) {
+ // publish
+ // 'data' is topic message
+ case "pub":
+ hub.publishForClient( container, topic, data );
+ break;
+
+ // subscribe
+ // 'data' is subscription ID
+ case "sub":
+ var errCode = ""; // empty string is success
+ try {
+ subs[ data ] = hub.subscribeForClient( container, topic, data );
+ } catch( e ) {
+ errCode = e.message;
+ }
+ return errCode;
+
+ // unsubscribe
+ // 'data' is subscription ID
+ case "uns":
+ var handle = subs[ data ];
+ hub.unsubscribeForClient( container, handle );
+ delete subs[ data ];
+ return data;
+
+ // connect
+ case "con":
+ finishConnect();
+ return true;
+
+ // disconnect
+ case "dis":
+ startLoadTimer();
+ finishDisconnect();
+ if ( params.Container.onDisconnect ) {
+ try {
+ params.Container.onDisconnect.call( scope, container );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onDisconnect callback to constructor: " + e.message );
+ }
+ }
+ return true;
+ }
+ };
+
+ this._onSecurityAlert = function( error ) {
+ invokeSecurityAlert( rpcErrorsToOAA[ error ] );
+ };
+
+ // The RPC code requires that the 'name' attribute be properly set on the
+ // iframe. However, setting the 'name' property on the iframe object
+ // returned from 'createElement("iframe")' doesn't work on IE --
+ // 'window.name' returns null for the code within the iframe. The
+ // workaround is to set the 'innerHTML' of a span to the iframe's HTML code,
+ // with 'name' and other attributes properly set.
+ function createIframe() {
+ var span = document.createElement( "span" );
+ params.IframeContainer.parent.appendChild( span );
+
+ var iframeText = '<iframe id="' + internalID + '" name="' + internalID +
+ '" src="javascript:\'<html></html>\'"';
+
+ // Add iframe attributes
+ var styleText = '';
+ var attrs = params.IframeContainer.iframeAttrs;
+ if ( attrs ) {
+ for ( var attr in attrs ) {
+ switch ( attr ) {
+ case "style":
+ for ( var style in attrs.style ) {
+ styleText += style + ':' + attrs.style[ style ] + ';';
+ }
+ break;
+ case "className":
+ iframeText += ' class="' + attrs[ attr ] + '"';
+ break;
+ default:
+ iframeText += ' ' + attr + '="' + attrs[ attr ] + '"';
+ }
+ }
+ }
+
+ // initially hide IFRAME content, in order to lessen frame phishing impact
+ styleText += 'visibility:hidden;';
+ iframeText += ' style="' + styleText + '"></iframe>';
+
+ span.innerHTML = iframeText;
+
+ var tunnelText;
+ if ( params.IframeContainer.tunnelURI ) {
+ tunnelText = "&parent=" + encodeURIComponent( params.IframeContainer.tunnelURI ) +
+ "&forcesecure=true";
+ } else {
+ tunnelText = "&oahParent=" +
+ encodeURIComponent( OpenAjax.gadgets.rpc.getOrigin( window.location.href ));
+ }
+ var idText = "";
+ if ( internalID !== clientID ) {
+ idText = "&oahId=" + internalID.substring( internalID.lastIndexOf('_') + 1 );
+ }
+ document.getElementById( internalID ).src = params.IframeContainer.uri +
+ "#rpctoken=" + securityToken + tunnelText + idText;
+ }
+
+ // If the relay iframe used by RPC has not been loaded yet, then we won't have unload protection
+ // at this point. Since we can't detect when the relay iframe has loaded, we use a two stage
+ // connection process. First, the child sends a connection msg and the container sends an ack.
+ // Then the container sends a connection msg and the child replies with an ack. Since the
+ // container can only send a message if the relay iframe has loaded, then we know if we get an
+ // ack here that the relay iframe is ready. And we are fully connected.
+ function finishConnect() {
+ // connect acknowledgement
+ function callback( result ) {
+ if ( result ) {
+ connected = true;
+ clearTimeout( loadTimer );
+ document.getElementById( internalID ).style.visibility = "visible";
+ 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 );
+ }
+ }
+ }
+ }
+ OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", callback, "cmd", "con" );
+ }
+
+ 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 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._handleIncomingRPC = 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 {Boolean} [params.IframeHubClient.requireParentVerifiable]
+ * Set to true in order to require that this IframeHubClient use a
+ * transport that can verify the parent Container's identity.
+ * @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 connected = false;
+ var subs = {};
+ var subIndex = 0;
+ var clientID;
+// var securityToken; // XXX still need "securityToken"?
+
+ 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() {};
+ }
+
+ this._init = function() {
+ var urlParams = OpenAjax.gadgets.util.getUrlParameters();
+ if ( ! urlParams.parent ) {
+ // The RMR transport does not require a valid relay file, but does need a URL
+ // in the parent's domain. The URL does not need to point to valid file, so just
+ // point to 'robots.txt' file. See RMR transport code for more info.
+ var parent = urlParams.oahParent + "/robots.txt";
+ OpenAjax.gadgets.rpc.setupReceiver( "..", parent );
+ }
+
+ if ( params.IframeHubClient && params.IframeHubClient.requireParentVerifiable &&
+ OpenAjax.gadgets.rpc.getReceiverOrigin( ".." ) === null ) {
+ // If user set 'requireParentVerifiable' to true but RPC transport does not
+ // support this, throw error.
+ OpenAjax.gadgets.rpc.removeReceiver( ".." );
+ throw new Error( OpenAjax.hub.Error.IncompatBrowser );
+ }
+
+ OpenAjax.hub.IframeContainer._rpcRouter.add( "..", this );
+// XXX The RPC layer initializes immediately on load, in the child (IframeHubClient). So it is too
+// late here to specify a security token for the RPC layer. At the moment, only the NIX
+// transport requires a child token (IFPC [aka FIM] is not supported).
+// securityToken = generateSecurityToken( params, scope, log );
+
+ clientID = OpenAjax.gadgets.rpc.RPC_ID;
+ if ( urlParams.oahId ) {
+ clientID = clientID.substring( 0, clientID.lastIndexOf('_') );
+ }
+ };
+
+ /*** HubClient interface ***/
+
+ this.connect = function( onComplete, scope ) {
+ if ( connected ) {
+ throw new Error( OpenAjax.hub.Error.Duplicate );
+ }
+
+ // connect acknowledgement
+ function callback( result ) {
+ if ( result ) {
+ connected = true;
+ if ( onComplete ) {
+ try {
+ onComplete.call( scope || window, client, true );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onComplete callback to connect(): " + e.message );
+ }
+ }
+ }
+ }
+ OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "con" );
+ };
+
+ this.disconnect = function( onComplete, scope ) {
+ if ( !connected ) {
+ throw new Error( OpenAjax.hub.Error.Disconnected );
+ }
+
+ connected = false;
+
+ // disconnect acknowledgement
+ var callback = null;
+ if ( onComplete ) {
+ callback = function( result ) {
+ try {
+ onComplete.call( scope || window, client, true );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onComplete callback to disconnect(): " + e.message );
+ }
+ };
+ }
+ OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "dis" );
+ };
+
+ this.getPartnerOrigin = function() {
+ if ( connected ) {
+ var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( ".." );
+ if ( origin ) {
+ // remove port if present
+ return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
+ }
+ }
+ 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 };
+
+ // subscribe acknowledgement
+ function callback( result ) {
+ if ( result !== '' ) { // error
+ delete subs[ subID ];
+ }
+ if ( onComplete ) {
+ try {
+ onComplete.call( scope, subID, result === "", result );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onComplete callback to subscribe(): " + e.message );
+ }
+ }
+ }
+ OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "sub", topic, subID );
+
+ return subID;
+ };
+
+ this.publish = function( topic, data ) {
+ assertConn();
+ assertPubTopic( topic );
+ OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", null, "pub", topic, 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 );
+ }
+
+ // unsubscribe in progress
+ subs[ subscriptionID ].uns = true;
+
+ // unsubscribe acknowledgement
+ function callback( result ) {
+ delete subs[ subscriptionID ];
+ if ( onComplete ) {
+ try {
+ onComplete.call( scope || window, subscriptionID, true );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onComplete callback to unsubscribe(): " + e.message );
+ }
+ }
+ }
+ OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "uns", null, 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;
+ };
+
+ /*** private functions ***/
+
+ this._handleIncomingRPC = function( command, topic, data, subscriptionID ) {
+ if ( command === "pub" ) {
+ // if subscription exists and we are not in process of unsubscribing...
+ if ( subs[ subscriptionID ] && ! subs[ subscriptionID ].uns ) {
+ try {
+ subs[ subscriptionID ].cb.call( subs[ subscriptionID ].sc, topic,
+ data, subs[ subscriptionID ].d );
+ } catch( e ) {
+ OpenAjax.hub._debugger();
+ log( "caught error from onData callback to subscribe(): " + e.message );
+ }
+ }
+ }
+ // else if command === "cmd"...
+
+ // First time this function is called, topic should be "con". This is the 2nd stage of the
+ // connection process. Simply need to return "true" in order to send an acknowledgement
+ // back to container. See finishConnect() in the container object.
+ if ( topic === "con" ) {
+ return true;
+ }
+ return false;
+ };
+
+ 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 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();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+ // RPC object contents:
+ // s: Service Name
+ // f: From
+ // c: The callback ID or 0 if none.
+ // a: The arguments for this RPC call.
+ // t: The authentication token.
+OpenAjax.hub.IframeContainer._rpcRouter = function() {
+ var receivers = {};
+
+ function router() {
+ var r = receivers[ this.f ];
+ if ( r ) {
+ return r._handleIncomingRPC.apply( r, arguments );
+ }
+ }
+
+ function onSecurityAlert( receiverId, error ) {
+ var r = receivers[ receiverId ];
+ if ( r ) {
+ r._onSecurityAlert.call( r, error );
+ }
+ }
+
+ return {
+ add: function( id, receiver ) {
+ function _add( id, receiver ) {
+ if ( id === ".." ) {
+ if ( ! receivers[ ".." ] ) {
+ receivers[ ".." ] = receiver;
+ }
+ return;
+ }
+
+ var newId = id;
+ while ( document.getElementById(newId) ) {
+ // a client with the specified ID already exists on this page;
+ // create a unique ID
+ newId = id + '_' + ((0x7fff * Math.random()) | 0).toString(16);
+ };
+ receivers[ newId ] = receiver;
+ return newId;
+ }
+
+ // when this function is first called, register the RPC service
+ OpenAjax.gadgets.rpc.register( "openajax.pubsub", router );
+ OpenAjax.gadgets.rpc.config({
+ securityCallback: onSecurityAlert
+ });
+
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_LOAD_TIMEOUT ] = OpenAjax.hub.SecurityAlert.LoadTimeout;
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FRAME_PHISH ] = OpenAjax.hub.SecurityAlert.FramePhish;
+ rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FORGED_MSG ] = OpenAjax.hub.SecurityAlert.ForgedMsg;
+
+ this.add = _add;
+ return _add( id, receiver );
+ },
+
+ remove: function( id ) {
+ delete receivers[ id ];
+ }
+ };
+}();
+
+var rpcErrorsToOAA = {};
+
+////////////////////////////////////////////////////////////////////////////////
+
+function generateSecurityToken( params, scope, log ) {
+ 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 = (p && p.tokenLength) || 6;
+ return OpenAjax.hub.IframeContainer._prng.nextRandomB64Str( tokenLength );
+}
+
+})();
+}
Modified: shindig/trunk/extras/src/main/javascript/features-extras/pubsub-2/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/extras/src/main/javascript/features-extras/pubsub-2/feature.xml?rev=1004309&r1=1004308&r2=1004309&view=diff
==============================================================================
--- shindig/trunk/extras/src/main/javascript/features-extras/pubsub-2/feature.xml (original)
+++ shindig/trunk/extras/src/main/javascript/features-extras/pubsub-2/feature.xml Mon Oct 4 16:21:18 2010
@@ -19,7 +19,7 @@ specific language governing permissions
<feature>
<name>pubsub-2</name>
<dependency>globals</dependency>
- <dependency>org.openajax.hub-2.0.4</dependency>
+ <dependency>org.openajax.hub-2.0.5</dependency>
<gadget>
<script src="pubsub-2.js"/>
<script src="taming.js"/>