PageRenderTime 61ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/errai-bus/src/main/java/org/jboss/errai/bus/public/js/pagebus_2.0.js

https://github.com/bpmc/errai
JavaScript | 6701 lines | 3952 code | 540 blank | 2209 comment | 561 complexity | 2712716bc6bad39a2d961a61505ccfb5 MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright 2010 JBoss, a divison Red Hat, Inc
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. // prevent re-definition of the OpenAjax object
  17. if (!window["OpenAjax"]) {
  18. OpenAjax = new function() {
  19. this.hub = {};
  20. h = this.hub;
  21. h.implementer = "http://openajax.org";
  22. h.implVersion = "2.0";
  23. h.specVersion = "2.0";
  24. h.implExtraData = {};
  25. var libs = {};
  26. h.libraries = libs;
  27. var ooh = "org.openajax.hub.";
  28. h.registerLibrary = function(prefix, nsURL, version, extra) {
  29. libs[prefix] = {
  30. prefix: prefix,
  31. namespaceURI: nsURL,
  32. version: version,
  33. extraData: extra
  34. };
  35. this.publish(ooh + "registerLibrary", libs[prefix]);
  36. }
  37. h.unregisterLibrary = function(prefix) {
  38. this.publish(ooh + "unregisterLibrary", libs[prefix]);
  39. delete libs[prefix];
  40. }
  41. }
  42. /**
  43. * Error
  44. *
  45. * Standard Error names used when the standard functions need to throw Errors.
  46. */
  47. OpenAjax.hub.Error = {
  48. // Either a required argument is missing or an invalid argument was provided
  49. BadParameters: "OpenAjax.hub.Error.BadParameters",
  50. // The specified hub has been disconnected and cannot perform the requested
  51. // operation:
  52. Disconnected: "OpenAjax.hub.Error.Disconnected",
  53. // Container with specified ID already exists:
  54. Duplicate: "OpenAjax.hub.Error.Duplicate",
  55. // The specified ManagedHub has no such Container (or it has been removed)
  56. NoContainer: "OpenAjax.hub.Error.NoContainer",
  57. // The specified ManagedHub or Container has no such subscription
  58. NoSubscription: "OpenAjax.hub.Error.NoSubscription",
  59. // Permission denied by manager's security policy
  60. NotAllowed: "OpenAjax.hub.Error.NotAllowed",
  61. // Wrong communications protocol identifier provided by Container or HubClient
  62. WrongProtocol: "OpenAjax.hub.Error.WrongProtocol"
  63. };
  64. /**
  65. * SecurityAlert
  66. *
  67. * Standard codes used when attempted security violations are detected. Unlike
  68. * Errors, these codes are not thrown as exceptions but rather passed into the
  69. * SecurityAlertHandler function registered with the Hub instance.
  70. */
  71. OpenAjax.hub.SecurityAlert = {
  72. // Container did not load (possible frame phishing attack)
  73. LoadTimeout: "OpenAjax.hub.SecurityAlert.LoadTimeout",
  74. // Hub suspects a frame phishing attack against the specified container
  75. FramePhish: "OpenAjax.hub.SecurityAlert.FramePhish",
  76. // Hub detected a message forgery that purports to come to a specifed
  77. // container
  78. ForgedMsg: "OpenAjax.hub.SecurityAlert.ForgedMsg"
  79. };
  80. /**
  81. * Debugging Help
  82. *
  83. * OpenAjax.hub.enableDebug
  84. *
  85. * If OpenAjax.hub.enableDebug is set to true, then the "debugger" keyword
  86. * will get hit whenever a user callback throws an exception, thereby
  87. * bringing up the JavaScript debugger.
  88. */
  89. OpenAjax.hub._debugger = function() {
  90. if (OpenAjax.hub.enableDebug) debugger; // REMOVE ON BUILD
  91. }
  92. ////////////////////////////////////////////////////////////////////////////////
  93. /**
  94. * Hub interface
  95. *
  96. * Hub is implemented on the manager side by ManagedHub and on the client side
  97. * by ClientHub.
  98. */
  99. //OpenAjax.hub.Hub = function() {}
  100. /**
  101. * Subscribe to a topic.
  102. *
  103. * @param {String} topic
  104. * A valid topic string. MAY include wildcards.
  105. * @param {Function} onData
  106. * Callback function that is invoked whenever an event is
  107. * published on the topic
  108. * @param {Object} [scope]
  109. * When onData callback or onComplete callback is invoked,
  110. * the JavaScript "this" keyword refers to this scope object.
  111. * If no scope is provided, default is window.
  112. * @param {Function} [onComplete]
  113. * Invoked to tell the client application whether the
  114. * subscribe operation succeeded or failed.
  115. * @param {*} [subscriberData]
  116. * Client application provides this data, which is handed
  117. * back to the client application in the subscriberData
  118. * parameter of the onData callback function.
  119. *
  120. * @returns subscriptionID
  121. * Identifier representing the subscription. This identifier is an
  122. * arbitrary ID string that is unique within this Hub instance
  123. * @type {String}
  124. *
  125. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  126. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
  127. */
  128. //OpenAjax.hub.Hub.prototype.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {}
  129. /**
  130. * Publish an event on a topic
  131. *
  132. * @param {String} topic
  133. * A valid topic string. MUST NOT include wildcards.
  134. * @param {*} data
  135. * Valid publishable data. To be portable across different
  136. * Container implementations, this value SHOULD be serializable
  137. * as JSON.
  138. *
  139. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  140. * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
  141. * wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
  142. */
  143. //OpenAjax.hub.Hub.prototype.publish = function( topic, data ) {}
  144. /**
  145. * Unsubscribe from a subscription
  146. *
  147. * @param {String} subscriptionID
  148. * A subscriptionID returned by Hub.subscribe()
  149. * @param {Function} [onComplete]
  150. * Callback function invoked when unsubscribe completes
  151. * @param {Object} [scope]
  152. * When onComplete callback function is invoked, the JavaScript "this"
  153. * keyword refers to this scope object.
  154. * If no scope is provided, default is window.
  155. *
  156. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  157. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  158. */
  159. //OpenAjax.hub.Hub.prototype.unsubscribe = function( subscriptionID, onComplete, scope ) {}
  160. /**
  161. * Return true if this Hub instance is in the Connected state.
  162. * Else returns false.
  163. *
  164. * This function can be called even if the Hub is not in a CONNECTED state.
  165. *
  166. * @returns Boolean
  167. * @type {Boolean}
  168. */
  169. //OpenAjax.hub.Hub.prototype.isConnected = function() {}
  170. /**
  171. * Returns the scope associated with this Hub instance and which will be used
  172. * with callback functions.
  173. *
  174. * This function can be called even if the Hub is not in a CONNECTED state.
  175. *
  176. * @returns scope object
  177. * @type {Object}
  178. */
  179. //OpenAjax.hub.Hub.prototype.getScope = function() {}
  180. /**
  181. * Returns the subscriberData parameter that was provided when
  182. * Hub.subscribe was called.
  183. *
  184. * @param {String} subscriberID
  185. * The subscriberID of a subscription
  186. *
  187. * @returns subscriberData
  188. * @type {*}
  189. *
  190. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  191. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  192. */
  193. //OpenAjax.hub.Hub.prototype.getSubscriberData = function(subscriberID) {}
  194. /**
  195. * Returns the scope associated with a specified subscription. This scope will
  196. * be used when invoking the 'onData' callback supplied to Hub.subscribe().
  197. *
  198. * @param {String} subscriberID
  199. * The subscriberID of a subscription
  200. *
  201. * @returns scope
  202. * @type {*}
  203. *
  204. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  205. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  206. */
  207. //OpenAjax.hub.Hub.prototype.getSubscriberScope = function(subscriberID) {}
  208. /**
  209. * Returns the params object associated with this Hub instance.
  210. * Allows mix-in code to access parameters passed into constructor that created
  211. * this Hub instance.
  212. *
  213. * @returns params the params object associated with this Hub instance
  214. * @type {Object}
  215. */
  216. //OpenAjax.hub.Hub.prototype.getParameters = function() {}
  217. ////////////////////////////////////////////////////////////////////////////////
  218. /**
  219. * HubClient interface
  220. *
  221. * Extends Hub interface.
  222. *
  223. * A HubClient implementation is typically specific to a particular
  224. * implementation of Container.
  225. */
  226. /**
  227. * Create a new HubClient. All HubClient constructors MUST have this
  228. * signature.
  229. * @constructor
  230. *
  231. * @param {Object} params
  232. * Parameters used to instantiate the HubClient.
  233. * Once the constructor is called, the params object belongs to the
  234. * HubClient. The caller MUST not modify it.
  235. * Implementations of HubClient may specify additional properties
  236. * for the params object, besides those identified below.
  237. *
  238. * @param {Function} params.HubClient.onSecurityAlert
  239. * Called when an attempted security breach is thwarted
  240. * @param {Object} [params.HubClient.scope]
  241. * Whenever one of the HubClient's callback functions is called,
  242. * references to "this" in the callback will refer to the scope object.
  243. * If not provided, the default is window.
  244. *
  245. * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
  246. * parameters is missing, or if a parameter value is invalid in
  247. * some way.
  248. */
  249. //OpenAjax.hub.HubClient = function( params ) {}
  250. /**
  251. * Requests a connection to the ManagedHub, via the Container
  252. * associated with this HubClient.
  253. *
  254. * If the Container accepts the connection request, the HubClient's
  255. * state is set to CONNECTED and the HubClient invokes the
  256. * onComplete callback function.
  257. *
  258. * If the Container refuses the connection request, the HubClient
  259. * invokes the onComplete callback function with an error code.
  260. * The error code might, for example, indicate that the Container
  261. * is being destroyed.
  262. *
  263. * In most implementations, this function operates asynchronously,
  264. * so the onComplete callback function is the only reliable way to
  265. * determine when this function completes and whether it has succeeded
  266. * or failed.
  267. *
  268. * A client application may call HubClient.disconnect and then call
  269. * HubClient.connect.
  270. *
  271. * @param {Function} [onComplete]
  272. * Callback function to call when this operation completes.
  273. * @param {Object} [scope]
  274. * When the onComplete function is invoked, the JavaScript "this"
  275. * keyword refers to this scope object.
  276. * If no scope is provided, default is window.
  277. *
  278. * @throws {OpenAjax.hub.Error.Duplicate} if the HubClient is already connected
  279. */
  280. //OpenAjax.hub.HubClient.prototype.connect = function( onComplete, scope ) {}
  281. /**
  282. * Disconnect from the ManagedHub
  283. *
  284. * Disconnect immediately:
  285. *
  286. * 1. Sets the HubClient's state to DISCONNECTED.
  287. * 2. Causes the HubClient to send a Disconnect request to the
  288. * associated Container.
  289. * 3. Ensures that the client application will receive no more
  290. * onData or onComplete callbacks associated with this
  291. * connection, except for the disconnect function's own
  292. * onComplete callback.
  293. * 4. Automatically destroys all of the HubClient's subscriptions.
  294. *
  295. * In most implementations, this function operates asynchronously,
  296. * so the onComplete callback function is the only reliable way to
  297. * determine when this function completes and whether it has succeeded
  298. * or failed.
  299. *
  300. * A client application is allowed to call HubClient.disconnect and
  301. * then call HubClient.connect.
  302. *
  303. * @param {Function} [onComplete]
  304. * Callback function to call when this operation completes.
  305. * @param {Object} [scope]
  306. * When the onComplete function is invoked, the JavaScript "this"
  307. * keyword refers to the scope object.
  308. * If no scope is provided, default is window.
  309. *
  310. * @throws {OpenAjax.hub.Error.Disconnected} if the HubClient is already
  311. * disconnected
  312. */
  313. //OpenAjax.hub.HubClient.prototype.disconnect = function( onComplete, scope ) {}
  314. /**
  315. * If DISCONNECTED: Returns null
  316. * If CONNECTED: Returns the origin associated with the window containing the
  317. * Container associated with this HubClient instance. The origin has the format
  318. *
  319. * [protocol]://[host]
  320. *
  321. * where:
  322. *
  323. * [protocol] is "http" or "https"
  324. * [host] is the hostname of the partner page.
  325. *
  326. * @returns Partner's origin
  327. * @type {String}
  328. */
  329. //OpenAjax.hub.HubClient.prototype.getPartnerOrigin = function() {}
  330. /**
  331. * Returns the client ID of this HubClient
  332. *
  333. * @returns clientID
  334. * @type {String}
  335. */
  336. //OpenAjax.hub.HubClient.prototype.getClientID = function() {}
  337. ////////////////////////////////////////////////////////////////////////////////
  338. /**
  339. * OpenAjax.hub.ManagedHub
  340. *
  341. * Managed hub API for the manager application and for Containers.
  342. *
  343. * Implements OpenAjax.hub.Hub.
  344. */
  345. /**
  346. * Create a new ManagedHub instance
  347. * @constructor
  348. *
  349. * This constructor automatically sets the ManagedHub's state to
  350. * CONNECTED.
  351. *
  352. * @param {Object} params
  353. * Parameters used to instantiate the ManagedHub.
  354. * Once the constructor is called, the params object belongs exclusively to
  355. * the ManagedHub. The caller MUST not modify it.
  356. *
  357. * The params object may contain the following properties:
  358. *
  359. * @param {Function} params.onPublish
  360. * Callback function that is invoked whenever a
  361. * data value published by a Container is about
  362. * to be delivered to some (possibly the same) Container.
  363. * This callback function implements a security policy;
  364. * it returns true if the delivery of the data is
  365. * permitted and false if permission is denied.
  366. * @param {Function} params.onSubscribe
  367. * Called whenever a Container tries to subscribe
  368. * on behalf of its client.
  369. * This callback function implements a security policy;
  370. * it returns true if the subscription is permitted
  371. * and false if permission is denied.
  372. * @param {Function} [params.onUnsubscribe]
  373. * Called whenever a Container unsubscribes on behalf of its client.
  374. * Unlike the other callbacks, onUnsubscribe is intended only for
  375. * informative purposes, and is not used to implement a security
  376. * policy.
  377. * @param {Object} [params.scope]
  378. * Whenever one of the ManagedHub's callback functions is called,
  379. * references to the JavaScript "this" keyword in the callback
  380. * function refer to this scope object
  381. * If no scope is provided, default is window.
  382. * @param {Function} [params.log] Optional logger function. Would
  383. * be used to log to console.log or equivalent.
  384. *
  385. * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
  386. * parameters are missing
  387. */
  388. OpenAjax.hub.ManagedHub = function(params) {
  389. if (! params || ! params.onPublish || ! params.onSubscribe)
  390. throw new Error(OpenAjax.hub.Error.BadParameters);
  391. this._p = params;
  392. this._onUnsubscribe = params.onUnsubscribe ? params.onUnsubscribe : null;
  393. this._scope = params.scope || window;
  394. if (params.log) {
  395. var scope = this._scope;
  396. var logfunc = params.log;
  397. this._log = function(msg) {
  398. logfunc.call(scope, "ManagedHub: " + msg);
  399. };
  400. } else {
  401. this._log = function() {
  402. };
  403. }
  404. this._subscriptions = { c:{}, s:null };
  405. this._containers = {};
  406. // Sequence # used to create IDs that are unique within this hub
  407. this._seq = 0;
  408. this._active = true;
  409. this._isPublishing = false;
  410. this._pubQ = [];
  411. }
  412. /**
  413. * Subscribe to a topic on behalf of a Container. Called only by
  414. * Container implementations, NOT by manager applications.
  415. *
  416. * This function:
  417. * 1. Checks with the ManagedHub's onSubscribe security policy
  418. * to determine whether this Container is allowed to subscribe
  419. * to this topic.
  420. * 2. If the subscribe operation is permitted, subscribes to the
  421. * topic and returns the ManagedHub's subscription ID for this
  422. * subscription.
  423. * 3. If the subscribe operation is not permitted, throws
  424. * OpenAjax.hub.Error.NotAllowed.
  425. *
  426. * When data is published on the topic, the ManagedHub's
  427. * onPublish security policy will be invoked to ensure that
  428. * this Container is permitted to receive the published data.
  429. * If the Container is allowed to receive the data, then the
  430. * Container's sendToClient function will be invoked.
  431. *
  432. * When a Container needs to create a subscription on behalf of
  433. * its client, the Container MUST use this function to create
  434. * the subscription.
  435. *
  436. * @param {OpenAjax.hub.Container} container
  437. * A Container
  438. * @param {String} topic
  439. * A valid topic
  440. * @param {String} containerSubID
  441. * Arbitrary string ID that the Container uses to
  442. * represent the subscription. Must be unique within the
  443. * context of the Container
  444. *
  445. * @returns managerSubID
  446. * Arbitrary string ID that this ManagedHub uses to
  447. * represent the subscription. Will be unique within the
  448. * context of this ManagedHub
  449. * @type {String}
  450. *
  451. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  452. * @throws {OpenAjax.hub.Error.NotAllowed} if subscription request is denied by the onSubscribe security policy
  453. * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
  454. */
  455. OpenAjax.hub.ManagedHub.prototype.subscribeForClient = function(container, topic, containerSubID) {
  456. this._assertConn();
  457. // check subscribe permission
  458. if (this._invokeOnSubscribe(topic, container)) {
  459. // return ManagedHub's subscriptionID for this subscription
  460. return this._subscribe(topic, this._sendToClient, this, { c: container, sid: containerSubID });
  461. }
  462. throw new Error(OpenAjax.hub.Error.NotAllowed);
  463. }
  464. /**
  465. * Unsubscribe from a subscription on behalf of a Container. Called only by
  466. * Container implementations, NOT by manager application code.
  467. *
  468. * This function:
  469. * 1. Destroys the specified subscription
  470. * 2. Calls the ManagedHub's onUnsubscribe callback function
  471. *
  472. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  473. *
  474. * @param {OpenAjax.hub.Container} container
  475. * container instance that is unsubscribing
  476. * @param {String} managerSubID
  477. * opaque ID of a subscription, returned by previous call to subscribeForClient()
  478. *
  479. * @throws {OpenAjax.hub.Error.NoSubscription} if subscriptionID does not refer to a valid subscription
  480. */
  481. OpenAjax.hub.ManagedHub.prototype.unsubscribeForClient = function(container, managerSubID) {
  482. this._unsubscribe(managerSubID);
  483. this._invokeOnUnsubscribe(container, managerSubID);
  484. }
  485. /**
  486. * Publish data on a topic on behalf of a Container. Called only by
  487. * Container implementations, NOT by manager application code.
  488. *
  489. * @param {OpenAjax.hub.Container} container
  490. * Container on whose behalf data should be published
  491. * @param {String} topic
  492. * Valid topic string. Must NOT contain wildcards.
  493. * @param {*} data
  494. * Valid publishable data. To be portable across different
  495. * Container implementations, this value SHOULD be serializable
  496. * as JSON.
  497. *
  498. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  499. * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
  500. */
  501. OpenAjax.hub.ManagedHub.prototype.publishForClient = function(container, topic, data) {
  502. this._assertConn();
  503. this._publish(topic, data, container);
  504. }
  505. /**
  506. * Destroy this ManagedHub
  507. *
  508. * 1. Sets state to DISCONNECTED. All subsequent attempts to add containers,
  509. * publish or subscribe will throw the Disconnected error. We will
  510. * continue to allow "cleanup" operations such as removeContainer
  511. * and unsubscribe, as well as read-only operations such as
  512. * isConnected
  513. * 2. Remove all Containers associated with this ManagedHub
  514. */
  515. OpenAjax.hub.ManagedHub.prototype.disconnect = function() {
  516. this._active = false;
  517. for (var c in this._containers) {
  518. this.removeContainer(this._containers[c]);
  519. }
  520. }
  521. /**
  522. * Get a container belonging to this ManagedHub by its clientID, or null
  523. * if this ManagedHub has no such container
  524. *
  525. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  526. *
  527. * @param {String} containerId
  528. * Arbitrary string ID associated with the container
  529. *
  530. * @returns container associated with given ID
  531. * @type {OpenAjax.hub.Container}
  532. */
  533. OpenAjax.hub.ManagedHub.prototype.getContainer = function(containerId) {
  534. var container = this._containers[containerId];
  535. return container ? container : null;
  536. }
  537. /**
  538. * Returns an array listing all containers belonging to this ManagedHub.
  539. * The order of the Containers in this array is arbitrary.
  540. *
  541. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  542. *
  543. * @returns container array
  544. * @type {OpenAjax.hub.Container[]}
  545. */
  546. OpenAjax.hub.ManagedHub.prototype.listContainers = function() {
  547. var res = [];
  548. for (var c in this._containers) {
  549. res.push(this._containers[c]);
  550. }
  551. return res;
  552. }
  553. /**
  554. * Add a container to this ManagedHub.
  555. *
  556. * This function should only be called by a Container constructor.
  557. *
  558. * @param {OpenAjax.hub.Container} container
  559. * A Container to be added to this ManagedHub
  560. *
  561. * @throws {OpenAjax.hub.Error.Duplicate} if there is already a Container
  562. * in this ManagedHub whose clientId is the same as that of container
  563. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  564. */
  565. OpenAjax.hub.ManagedHub.prototype.addContainer = function(container) {
  566. this._assertConn();
  567. var containerId = container.getClientID();
  568. if (this._containers[containerId]) {
  569. throw new Error(OpenAjax.hub.Error.Duplicate);
  570. }
  571. this._containers[containerId] = container;
  572. }
  573. /**
  574. * Remove a container from this ManagedHub immediately
  575. *
  576. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  577. *
  578. * @param {OpenAjax.hub.Container} container
  579. * A Container to be removed from this ManagedHub
  580. *
  581. * @throws {OpenAjax.hub.Error.NoContainer} if no such container is found
  582. */
  583. OpenAjax.hub.ManagedHub.prototype.removeContainer = function(container) {
  584. var containerId = container.getClientID();
  585. if (! this._containers[ containerId ]) {
  586. throw new Error(OpenAjax.hub.Error.NoContainer);
  587. }
  588. container.remove();
  589. delete this._containers[ containerId ];
  590. }
  591. /*** OpenAjax.hub.Hub interface implementation ***/
  592. /**
  593. * Subscribe to a topic.
  594. *
  595. * This implementation of Hub.subscribe is synchronous. When subscribe
  596. * is called:
  597. *
  598. * 1. The ManagedHub's onSubscribe callback is invoked. The
  599. * container parameter is null, because the manager application,
  600. * rather than a container, is subscribing.
  601. * 2. If onSubscribe returns true, then the subscription is created.
  602. * 3. The onComplete callback is invoked.
  603. * 4. Then this function returns.
  604. *
  605. * @param {String} topic
  606. * A valid topic string. MAY include wildcards.
  607. * @param {Function} onData
  608. * Callback function that is invoked whenever an event is
  609. * published on the topic
  610. * @param {Object} [scope]
  611. * When onData callback or onComplete callback is invoked,
  612. * the JavaScript "this" keyword refers to this scope object.
  613. * If no scope is provided, default is window.
  614. * @param {Function} [onComplete]
  615. * Invoked to tell the client application whether the
  616. * subscribe operation succeeded or failed.
  617. * @param {*} [subscriberData]
  618. * Client application provides this data, which is handed
  619. * back to the client application in the subscriberData
  620. * parameter of the onData and onComplete callback functions.
  621. *
  622. * @returns subscriptionID
  623. * Identifier representing the subscription. This identifier is an
  624. * arbitrary ID string that is unique within this Hub instance
  625. * @type {String}
  626. *
  627. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  628. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
  629. */
  630. OpenAjax.hub.ManagedHub.prototype.subscribe = function(topic, onData, scope, onComplete, subscriberData) {
  631. this._assertConn();
  632. this._assertSubTopic(topic);
  633. if (! onData) {
  634. throw new Error(OpenAjax.hub.Error.BadParameters);
  635. }
  636. // check subscribe permission
  637. if (! this._invokeOnSubscribe(topic, null)) {
  638. this._invokeOnComplete(onComplete, scope, null, false, OpenAjax.hub.Error.NotAllowed);
  639. return;
  640. }
  641. // on publish event, check publish permissions
  642. scope = scope || window;
  643. var that = this;
  644. function publishCB(topic, data, sd, pcont) {
  645. if (that._invokeOnPublish(topic, data, pcont, null)) {
  646. try {
  647. onData.call(scope, topic, data, subscriberData);
  648. } catch(e) {
  649. OpenAjax.hub._debugger();
  650. that._log("caught error from onData callback to Hub.subscribe(): " + e.message);
  651. }
  652. }
  653. }
  654. var subID = this._subscribe(topic, publishCB, scope, subscriberData);
  655. this._invokeOnComplete(onComplete, scope, subID, true);
  656. return subID;
  657. }
  658. /**
  659. * Publish an event on a topic
  660. *
  661. * This implementation of Hub.publish is synchronous. When publish
  662. * is called:
  663. *
  664. * 1. The target subscriptions are identified.
  665. * 2. For each target subscription, the ManagedHub's onPublish
  666. * callback is invoked. Data is only delivered to a target
  667. * subscription if the onPublish callback returns true.
  668. * The pcont parameter of the onPublish callback is null.
  669. * This is because the ManagedHub, rather than a container,
  670. * is publishing the data.
  671. *
  672. * @param {String} topic
  673. * A valid topic string. MUST NOT include wildcards.
  674. * @param {*} data
  675. * Valid publishable data. To be portable across different
  676. * Container implementations, this value SHOULD be serializable
  677. * as JSON.
  678. *
  679. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  680. * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
  681. * wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
  682. */
  683. OpenAjax.hub.ManagedHub.prototype.publish = function(topic, data) {
  684. this._assertConn();
  685. this._assertPubTopic(topic);
  686. this._publish(topic, data, null);
  687. }
  688. /**
  689. * Unsubscribe from a subscription
  690. *
  691. * This implementation of Hub.unsubscribe is synchronous. When unsubscribe
  692. * is called:
  693. *
  694. * 1. The subscription is destroyed.
  695. * 2. The ManagedHub's onUnsubscribe callback is invoked, if there is one.
  696. * 3. The onComplete callback is invoked.
  697. * 4. Then this function returns.
  698. *
  699. * @param {String} subscriptionID
  700. * A subscriptionID returned by Hub.subscribe()
  701. * @param {Function} [onComplete]
  702. * Callback function invoked when unsubscribe completes
  703. * @param {Object} [scope]
  704. * When onComplete callback function is invoked, the JavaScript "this"
  705. * keyword refers to this scope object.
  706. * If no scope is provided, default is window.
  707. *
  708. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  709. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  710. */
  711. OpenAjax.hub.ManagedHub.prototype.unsubscribe = function(subscriptionID, onComplete, scope) {
  712. this._assertConn();
  713. if (typeof subscriptionID === "undefined" || subscriptionID == null) {
  714. throw new Error(OpenAjax.hub.Error.BadParameters);
  715. }
  716. this._unsubscribe(subscriptionID);
  717. this._invokeOnUnsubscribe(null, subscriptionID);
  718. this._invokeOnComplete(onComplete, scope, subscriptionID, true);
  719. }
  720. /**
  721. * Returns true if disconnect() has NOT been called on this ManagedHub,
  722. * else returns false
  723. *
  724. * @returns Boolean
  725. * @type {Boolean}
  726. */
  727. OpenAjax.hub.ManagedHub.prototype.isConnected = function() {
  728. return this._active;
  729. }
  730. /**
  731. * Returns the scope associated with this Hub instance and which will be used
  732. * with callback functions.
  733. *
  734. * This function can be called even if the Hub is not in a CONNECTED state.
  735. *
  736. * @returns scope object
  737. * @type {Object}
  738. */
  739. OpenAjax.hub.ManagedHub.prototype.getScope = function() {
  740. return this._scope;
  741. }
  742. /**
  743. * Returns the subscriberData parameter that was provided when
  744. * Hub.subscribe was called.
  745. *
  746. * @param subscriberID
  747. * The subscriberID of a subscription
  748. *
  749. * @returns subscriberData
  750. * @type {*}
  751. *
  752. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  753. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  754. */
  755. OpenAjax.hub.ManagedHub.prototype.getSubscriberData = function(subscriberID) {
  756. this._assertConn();
  757. var path = subscriberID.split(".");
  758. var sid = path.pop();
  759. var sub = this._getSubscriptionObject(this._subscriptions, path, 0, sid);
  760. if (sub)
  761. return sub.data;
  762. throw new Error(OpenAjax.hub.Error.NoSubscription);
  763. }
  764. /**
  765. * Returns the scope associated with a specified subscription. This scope will
  766. * be used when invoking the 'onData' callback supplied to Hub.subscribe().
  767. *
  768. * @param subscriberID
  769. * The subscriberID of a subscription
  770. *
  771. * @returns scope
  772. * @type {*}
  773. *
  774. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  775. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  776. */
  777. OpenAjax.hub.ManagedHub.prototype.getSubscriberScope = function(subscriberID) {
  778. this._assertConn();
  779. var path = subscriberID.split(".");
  780. var sid = path.pop();
  781. var sub = this._getSubscriptionObject(this._subscriptions, path, 0, sid);
  782. if (sub)
  783. return sub.scope;
  784. throw new Error(OpenAjax.hub.Error.NoSubscription);
  785. }
  786. /**
  787. * Returns the params object associated with this Hub instance.
  788. * Allows mix-in code to access parameters passed into constructor that created
  789. * this Hub instance.
  790. *
  791. * @returns params the params object associated with this Hub instance
  792. * @type {Object}
  793. */
  794. OpenAjax.hub.ManagedHub.prototype.getParameters = function() {
  795. return this._p;
  796. }
  797. /* PRIVATE FUNCTIONS */
  798. /**
  799. * Send a message to a container's client.
  800. * This is an OAH subscriber's data callback. It is private to ManagedHub
  801. * and serves as an adapter between the OAH 1.0 API and Container.sendToClient.
  802. *
  803. * @param {String} topic Topic on which data was published
  804. * @param {Object} data Data to be delivered to the client
  805. * @param {Object} sd Object containing properties
  806. * c: container to which data must be sent
  807. * sid: subscription ID within that container
  808. * @param {Object} pcont Publishing container, or null if this data was
  809. * published by the manager
  810. */
  811. OpenAjax.hub.ManagedHub.prototype._sendToClient = function(topic, data, sd, pcont) {
  812. if (!this.isConnected()) {
  813. return;
  814. }
  815. if (this._invokeOnPublish(topic, data, pcont, sd.c)) {
  816. sd.c.sendToClient(topic, data, sd.sid);
  817. }
  818. }
  819. OpenAjax.hub.ManagedHub.prototype._assertConn = function() {
  820. if (!this.isConnected()) {
  821. throw new Error(OpenAjax.hub.Error.Disconnected);
  822. }
  823. }
  824. OpenAjax.hub.ManagedHub.prototype._assertPubTopic = function(topic) {
  825. if ((topic == null) || (topic == "") || (topic.indexOf("*") != -1) ||
  826. (topic.indexOf("..") != -1) || (topic.charAt(0) == ".") ||
  827. (topic.charAt(topic.length - 1) == ".")) {
  828. throw new Error(OpenAjax.hub.Error.BadParameters);
  829. }
  830. }
  831. OpenAjax.hub.ManagedHub.prototype._assertSubTopic = function(topic) {
  832. if (! topic) {
  833. throw new Error(OpenAjax.hub.Error.BadParameters);
  834. }
  835. var path = topic.split(".");
  836. var len = path.length;
  837. for (var i = 0; i < len; i++) {
  838. var p = path[i];
  839. if ((p == "") ||
  840. ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
  841. throw new Error(OpenAjax.hub.Error.BadParameters);
  842. }
  843. if ((p == "**") && (i < len - 1)) {
  844. throw new Error(OpenAjax.hub.Error.BadParameters);
  845. }
  846. }
  847. }
  848. OpenAjax.hub.ManagedHub.prototype._invokeOnComplete = function(func, scope, item, success, errorCode) {
  849. if (func) { // onComplete is optional
  850. try {
  851. scope = scope || window;
  852. func.call(scope, item, success, errorCode);
  853. } catch(e) {
  854. OpenAjax.hub._debugger();
  855. this._log("caught error from onComplete callback: " + e.message);
  856. }
  857. }
  858. }
  859. OpenAjax.hub.ManagedHub.prototype._invokeOnPublish = function(topic, data, pcont, scont) {
  860. try {
  861. return this._p.onPublish.call(this._scope, topic, data, pcont, scont);
  862. } catch(e) {
  863. OpenAjax.hub._debugger();
  864. this._log("caught error from onPublish callback to constructor: " + e.message);
  865. }
  866. return false;
  867. }
  868. OpenAjax.hub.ManagedHub.prototype._invokeOnSubscribe = function(topic, container) {
  869. try {
  870. return this._p.onSubscribe.call(this._scope, topic, container);
  871. } catch(e) {
  872. OpenAjax.hub._debugger();
  873. this._log("caught error from onSubscribe callback to constructor: " + e.message);
  874. }
  875. return false;
  876. }
  877. OpenAjax.hub.ManagedHub.prototype._invokeOnUnsubscribe = function(container, managerSubID) {
  878. if (this._onUnsubscribe) {
  879. var topic = managerSubID.slice(0, managerSubID.lastIndexOf("."));
  880. try {
  881. this._onUnsubscribe.call(this._scope, topic, container);
  882. } catch(e) {
  883. OpenAjax.hub._debugger();
  884. this._log("caught error from onUnsubscribe callback to constructor: " + e.message);
  885. }
  886. }
  887. }
  888. OpenAjax.hub.ManagedHub.prototype._subscribe = function(topic, onData, scope, subscriberData) {
  889. var handle = topic + "." + this._seq;
  890. var sub = { scope: scope, cb: onData, data: subscriberData, sid: this._seq++ };
  891. var path = topic.split(".");
  892. this._recursiveSubscribe(this._subscriptions, path, 0, sub);
  893. return handle;
  894. }
  895. OpenAjax.hub.ManagedHub.prototype._recursiveSubscribe = function(tree, path, index, sub) {
  896. var token = path[index];
  897. if (index == path.length) {
  898. sub.next = tree.s;
  899. tree.s = sub;
  900. } else {
  901. if (typeof tree.c == "undefined") {
  902. tree.c = {};
  903. }
  904. if (typeof tree.c[token] == "undefined") {
  905. tree.c[token] = { c: {}, s: null };
  906. this._recursiveSubscribe(tree.c[token], path, index + 1, sub);
  907. } else {
  908. this._recursiveSubscribe(tree.c[token], path, index + 1, sub);
  909. }
  910. }
  911. }
  912. OpenAjax.hub.ManagedHub.prototype._publish = function(topic, data, pcont) {
  913. // if we are currently handling a publish event, then queue this request
  914. // and handle later, one by one
  915. if (this._isPublishing) {
  916. this._pubQ.push({ t: topic, d: data, p: pcont });
  917. return;
  918. }
  919. this._safePublish(topic, data, pcont);
  920. while (this._pubQ.length > 0) {
  921. var pub = this._pubQ.shift();
  922. this._safePublish(pub.t, pub.d, pub.p);
  923. }
  924. }
  925. OpenAjax.hub.ManagedHub.prototype._safePublish = function(topic, data, pcont) {
  926. this._isPublishing = true;
  927. var path = topic.split(".");
  928. this._recursivePublish(this._subscriptions, path, 0, topic, data, pcont);
  929. this._isPublishing = false;
  930. }
  931. OpenAjax.hub.ManagedHub.prototype._recursivePublish = function(tree, path, index, name, msg, pcont) {
  932. if (typeof tree != "undefined") {
  933. var node;
  934. if (index == path.length) {
  935. node = tree;
  936. } else {
  937. this._recursivePublish(tree.c[path[index]], path, index + 1, name, msg, pcont);
  938. this._recursivePublish(tree.c["*"], path, index + 1, name, msg, pcont);
  939. node = tree.c["**"];
  940. }
  941. if (typeof node != "undefined") {
  942. var sub = node.s;
  943. while (sub) {
  944. var sc = sub.scope;
  945. var cb = sub.cb;
  946. var d = sub.data;
  947. var sid = sub.sid;
  948. if (typeof cb == "string") {
  949. // get a function object
  950. cb = sc[cb];
  951. }
  952. cb.call(sc, name, msg, d, pcont);
  953. sub = sub.next;
  954. }
  955. }
  956. }
  957. }
  958. OpenAjax.hub.ManagedHub.prototype._unsubscribe = function(subscriptionID) {
  959. var path = subscriptionID.split(".");
  960. var sid = path.pop();
  961. if (! this._recursiveUnsubscribe(this._subscriptions, path, 0, sid)) {
  962. throw new Error(OpenAjax.hub.Error.NoSubscription);
  963. }
  964. }
  965. /**
  966. * @returns 'true' if properly unsubscribed; 'false' otherwise
  967. */
  968. OpenAjax.hub.ManagedHub.prototype._recursiveUnsubscribe = function(tree, path, index, sid) {
  969. if (typeof tree == "undefined") {
  970. return false;
  971. }
  972. if (index < path.length) {
  973. var childNode = tree.c[path[index]];
  974. if (! childNode) {
  975. return false;
  976. }
  977. this._recursiveUnsubscribe(childNode, path, index + 1, sid);
  978. if (childNode.s == null) {
  979. for (var x in childNode.c) {
  980. return true;
  981. }
  982. delete tree.c[path[index]];
  983. }
  984. } else {
  985. var sub = tree.s;
  986. var sub_prev = null;
  987. var found = false;
  988. while (sub) {
  989. if (sid == sub.sid) {
  990. found = true;
  991. if (sub == tree.s) {
  992. tree.s = sub.next;
  993. } else {
  994. sub_prev.next = sub.next;
  995. }
  996. break;
  997. }
  998. sub_prev = sub;
  999. sub = sub.next;
  1000. }
  1001. if (! found) {
  1002. return false;
  1003. }
  1004. }
  1005. return true;
  1006. }
  1007. OpenAjax.hub.ManagedHub.prototype._getSubscriptionObject = function(tree, path, index, sid) {
  1008. if (typeof tree != "undefined") {
  1009. if (index < path.length) {
  1010. var childNode = tree.c[path[index]];
  1011. return this._getSubscriptionObject(childNode, path, index + 1, sid);
  1012. }
  1013. var sub = tree.s;
  1014. while (sub) {
  1015. if (sid == sub.sid) {
  1016. return sub;
  1017. }
  1018. sub = sub.next;
  1019. }
  1020. }
  1021. return null;
  1022. }
  1023. ////////////////////////////////////////////////////////////////////////////////
  1024. /**
  1025. * Container
  1026. * @constructor
  1027. *
  1028. * Container represents an instance of a manager-side object that contains and
  1029. * communicates with a single client of the hub. The container might be an inline
  1030. * container, an iframe FIM container, or an iframe PostMessage container, or
  1031. * it might be an instance of some other implementation.
  1032. *
  1033. * @param {OpenAjax.hub.ManagedHub} hub
  1034. * Managed Hub instance
  1035. * @param {String} clientID
  1036. * A string ID that identifies a particular client of a Managed Hub. Unique
  1037. * within the context of the ManagedHub.
  1038. * @param {Object} params
  1039. * Parameters used to instantiate the Container.
  1040. * Once the constructor is called, the params object belongs exclusively to
  1041. * the Container. The caller MUST not modify it.
  1042. * Implementations of Container may specify additional properties
  1043. * for the params object, besides those identified below.
  1044. * The following params properties MUST be supported by all Container
  1045. * implementations:
  1046. * @param {Function} params.Container.onSecurityAlert
  1047. * Called when an attempted security breach is thwarted. Function is defined
  1048. * as follows: function(container, securityAlert)
  1049. * @param {Function} [params.Container.onConnect]
  1050. * Called when the client connects to the Managed Hub. Function is defined
  1051. * as follows: function(container)
  1052. * @param {Function} [params.Container.onDisconnect]
  1053. * Called when the client disconnects from the Managed Hub. Function is
  1054. * defined as follows: function(container)
  1055. * @param {Object} [params.Container.scope]
  1056. * Whenever one of the Container's callback functions is called, references
  1057. * to "this" in the callback will refer to the scope object. If no scope is
  1058. * provided, default is window.
  1059. * @param {Function} [params.Container.log]
  1060. * Optional logger function. Would be used to log to console.log or
  1061. * equivalent.
  1062. *
  1063. * @throws {OpenAjax.hub.Error.BadParameters} if required params are not
  1064. * present or null
  1065. * @throws {OpenAjax.hub.Error.Duplicate} if a Container with this clientID
  1066. * already exists in the given Managed Hub
  1067. * @throws {OpenAjax.hub.Error.Disconnected} if ManagedHub is not connected
  1068. */
  1069. //OpenAjax.hub.Container = function( hub, clientID, params ) {}
  1070. /**
  1071. * Send a message to the client inside this container. This function MUST only
  1072. * be called by ManagedHub.
  1073. *
  1074. * @param {String} topic
  1075. * The topic name for the published message
  1076. * @param {*} data
  1077. * The payload. Can be any JSON-serializable value.
  1078. * @param {String} containerSubscriptionId
  1079. * Container's ID for a subscription, from previous call to
  1080. * subscribeForClient()
  1081. */
  1082. //OpenAjax.hub.Container.prototype.sendToClient = function( topic, data, containerSubscriptionId ) {}
  1083. /**
  1084. * Shut down a container. remove does all of the following:
  1085. * - disconnects container from HubClient
  1086. * - unsubscribes from all of its existing subscriptions in the ManagedHub
  1087. *
  1088. * This function is only called by ManagedHub.removeContainer
  1089. * Calling this function does NOT cause the container's onDisconnect callback to
  1090. * be invoked.
  1091. */
  1092. //OpenAjax.hub.Container.prototype.remove = function() {}
  1093. /**
  1094. * Returns true if the given client is connected to the managed hub.
  1095. * Else returns false.
  1096. *
  1097. * @returns true if the client is connected to the managed hub
  1098. * @type boolean
  1099. */
  1100. //OpenAjax.hub.Container.prototype.isConnected = function() {}
  1101. /**
  1102. * Returns the clientID passed in when this Container was instantiated.
  1103. *
  1104. * @returns The clientID
  1105. * @type {String}
  1106. */
  1107. //OpenAjax.hub.Container.prototype.getClientID = function() {}
  1108. /**
  1109. * If DISCONNECTED:
  1110. * Returns null
  1111. * If CONNECTED:
  1112. * Returns the origin associated with the window containing the HubClient
  1113. * associated with this Container instance. The origin has the format
  1114. *
  1115. * [protocol]://[host]
  1116. *
  1117. * where:
  1118. *
  1119. * [protocol] is "http" or "https"
  1120. * [host] is the hostname of the partner page.
  1121. *
  1122. * @returns Partner's origin
  1123. * @type {String}
  1124. */
  1125. //OpenAjax.hub.Container.prototype.getPartnerOrigin = function() {}
  1126. /**
  1127. * Returns the params object associated with this Container instance.
  1128. * Allows mix-in code to access parameters passed into constructor that created
  1129. * this Container instance.
  1130. *
  1131. * @returns params
  1132. * The params object associated with this Container instance
  1133. * @type {Object}
  1134. */
  1135. //OpenAjax.hub.Container.prototype.getParameters = function() {}
  1136. /**
  1137. * Returns the ManagedHub to which this Container belongs.
  1138. *
  1139. * @returns ManagedHub
  1140. * The ManagedHub object associated with this Container instance
  1141. * @type {OpenAjax.hub.ManagedHub}
  1142. */
  1143. //OpenAjax.hub.Container.prototype.getHub = function() {}
  1144. ////////////////////////////////////////////////////////////////////////////////
  1145. /*
  1146. * Unmanaged Hub
  1147. */
  1148. /**
  1149. * OpenAjax.hub._hub is the default ManagedHub instance that we use to
  1150. * provide OAH 1.0 behavior.
  1151. */
  1152. OpenAjax.hub._hub = new OpenAjax.hub.ManagedHub({
  1153. onSubscribe: function(topic, ctnr) {
  1154. return true;
  1155. },
  1156. onPublish: function(topic, data, pcont, scont) {
  1157. return true;
  1158. }
  1159. });
  1160. /**
  1161. * Subscribe to a topic.
  1162. *
  1163. * @param {String} topic
  1164. * A valid topic string. MAY include wildcards.
  1165. * @param {Function|String} onData
  1166. * Callback function that is invoked whenever an event is published on the
  1167. * topic. If 'onData' is a string, then it represents the name of a
  1168. * function on the 'scope' object.
  1169. * @param {Object} [scope]
  1170. * When onData callback is invoked,
  1171. * the JavaScript "this" keyword refers to this scope object.
  1172. * If no scope is provided, default is window.
  1173. * @param {*} [subscriberData]
  1174. * Client application provides this data, which is handed
  1175. * back to the client application in the subscriberData
  1176. * parameter of the onData callback function.
  1177. *
  1178. * @returns {String} Identifier representing the subscription.
  1179. *
  1180. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid
  1181. * (e.g.contains an empty token)
  1182. */
  1183. OpenAjax.hub.subscribe = function(topic, onData, scope, subscriberData) {
  1184. // resolve the 'onData' function if it is a string
  1185. if (typeof onData === "string") {
  1186. scope = scope || window;
  1187. onData = scope[ onData ] || null;
  1188. }
  1189. return OpenAjax.hub._hub.subscribe(topic, onData, scope, null, subscriberData);
  1190. }
  1191. /**
  1192. * Unsubscribe from a subscription.
  1193. *
  1194. * @param {String} subscriptionID
  1195. * Subscription identifier returned by subscribe()
  1196. *
  1197. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  1198. */
  1199. OpenAjax.hub.unsubscribe = function(subscriptionID) {
  1200. return OpenAjax.hub._hub.unsubscribe(subscriptionID);
  1201. }
  1202. /**
  1203. * Publish an event on a topic.
  1204. *
  1205. * @param {String} topic
  1206. * A valid topic string. MUST NOT include wildcards.
  1207. * @param {*} data
  1208. * Valid publishable data.
  1209. *
  1210. * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published
  1211. * (e.g. contains wildcards or empty tokens)
  1212. */
  1213. OpenAjax.hub.publish = function(topic, data) {
  1214. OpenAjax.

Large files files are truncated, but you can click here to view the full file