All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tapestry5.t5-pubsub.js Maven / Gradle / Ivy

/* Copyright 2011 The Apache Software Foundation
 *
 * 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.
 */

T5.extend(T5, function() {

	var map = T5.map;
	var mapcat = T5.mapcat;

	var subscribersVersion = 0;

	var subscribers = {};
	var publishers = {};

	/**
	 * Expands a selector into a array of strings representing the containers of
	 * the selector (by stripping off successive terms, breaking at slashes).
	 */
	function expandSelector(selector) {
		var result = [];
		var current = selector;

		while (true) {
			result.push(current);
			var slashx = current.lastIndexOf('/');

			if (slashx < 0)
				break;

			current = current.substring(0, slashx);
		}

		return result;
	}

	function doPublish(listeners, message) {

		return map(function(fn) {
			fn(message);
		}, listeners);
	}

	/**
	 * Creates a publisher for a selector. The selector is a string consisting
	 * of individual terms separated by slashes. A publisher sends a message to
	 * listener functions. Publishers are cached internally.
	 * 
	 * 

* The returned publisher function is used to publish a message. It takes a * single argument, the message object. The message object is passed to all * listener functions matching the selector. The return value from the * publisher function is all the return values from the listener functions. * * @return publisher function */ function createPublisher(selector) { var publisher = publishers[selector]; if (publisher === undefined) { var selectors = expandSelector(selector); var listeners = null; var subscribersVersionSnapshot = -1; var publisher = function(message) { // Recalculate the listeners whenever the subscribers map // has changed. if (subscribersVersionSnapshot !== subscribersVersion) { listeners = mapcat(function(selector) { return subscribers[selector] || []; }, selectors); subscribersVersionSnapshot = subscribersVersion; } return doPublish(listeners, message); }; publishers[selector] = publisher; } return publisher; } /** * Creates a publisher for the selector (or uses a previously cached * publisher) and publishes the message, returning the combined results of * all the listener functions. */ function publish(selector, message) { return createPublisher(selector)(message); } function unsubscribe(selector, listenerfn) { var listeners = subscribers[selector]; var editted = T5.without(listenerfn, listeners); if (editted !== listeners) { subscribers[selector] = editted; subscribersVersion++; } } /** * Subscribes a listener function to a selector. The selector is a string * consisting of individual terms separated by slashes. A publisher will * send a message object to a selector; matching listener functions are * invoked, and are passed the message object. *

* The return value is a function, of no parameters, used to unsubscribe the * listener function. * */ function subscribe(selector, listenerfn) { var listeners = subscribers[selector]; if (listeners === undefined) { listeners = []; subscribers[selector] = listeners; } listeners.push(listenerfn); // Indicate that subscribers has changed, so publishers need to // recalculate their listeners. subscribersVersion++; return function() { unsubscribe(selector, listenerfn); } } return { createPublisher : createPublisher, pub : publish, sub : subscribe }; });





© 2015 - 2025 Weber Informatics LLC | Privacy Policy