diff options
| -rw-r--r-- | js/lib/autocomplete.js | 2 | ||||
| -rw-r--r-- | js/lib/elgglib.js | 16 | ||||
| -rw-r--r-- | js/lib/events.js | 52 | ||||
| -rw-r--r-- | js/lib/hooks.js | 94 | ||||
| -rw-r--r-- | js/lib/languages.js | 2 | ||||
| -rw-r--r-- | js/lib/security.js | 2 | ||||
| -rw-r--r-- | js/lib/ui.js | 84 | ||||
| -rw-r--r-- | js/lib/ui.widgets.js | 2 | ||||
| -rw-r--r-- | js/lib/userpicker.js | 2 | ||||
| -rw-r--r-- | js/tests/ElggEventsTest.js | 28 | ||||
| -rw-r--r-- | js/tests/ElggHooksTest.js | 28 | ||||
| -rw-r--r-- | mod/blog/views/default/js/blog/save_draft.php | 2 | ||||
| -rw-r--r-- | mod/bookmarks/views/default/bookmarks/js.php | 2 | ||||
| -rw-r--r-- | mod/messageboard/views/default/messageboard/js.php | 2 | ||||
| -rw-r--r-- | mod/tinymce/views/default/js/tinymce.php | 2 | ||||
| -rw-r--r-- | mod/uservalidationbyemail/views/default/uservalidationbyemail/js.php | 2 | ||||
| -rw-r--r-- | views/default/core/account/login_box.php | 2 | ||||
| -rw-r--r-- | views/default/core/account/login_dropdown.php | 11 | ||||
| -rw-r--r-- | views/default/core/river/filter.php | 2 | ||||
| -rw-r--r-- | views/default/js/admin.php | 2 | ||||
| -rw-r--r-- | views/default/js/elgg.php | 7 | 
21 files changed, 202 insertions, 144 deletions
diff --git a/js/lib/autocomplete.js b/js/lib/autocomplete.js index eb59f51aa..917326d4f 100644 --- a/js/lib/autocomplete.js +++ b/js/lib/autocomplete.js @@ -36,4 +36,4 @@ elgg.autocomplete.init = function() {  	};  }; -elgg.register_event_handler('init', 'system', elgg.autocomplete.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.autocomplete.init);
\ No newline at end of file diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js index 3b409d134..4137c4a7a 100644 --- a/js/lib/elgglib.js +++ b/js/lib/elgglib.js @@ -350,4 +350,18 @@ elgg.register_error = function(errors, delay) {   */  elgg.forward = function(url) {  	location.href = elgg.normalize_url(url); -};
\ No newline at end of file +}; + +/** + * Returns the fragment part of the URL, including the #. Returns '' if no fragment. + * + * @param {String} url The URL. + */ +elgg.getUrlFragment = function(url) { +	var fragment = url.split('#')[1]; +	 +	if (fragment) { +		return '#' + fragment; +	} +	return ''; +}
\ No newline at end of file diff --git a/js/lib/events.js b/js/lib/events.js deleted file mode 100644 index c1aa6fd9a..000000000 --- a/js/lib/events.js +++ /dev/null @@ -1,52 +0,0 @@ -elgg.provide('elgg.config.events'); - -/** - * - */ -elgg.register_event_handler = function(event_name, event_type, handler, priority) { -	elgg.assertTypeOf('string', event_name); -	elgg.assertTypeOf('string', event_type); -	elgg.assertTypeOf('function', handler); - -	if (!event_name || !event_type) { -		return false; -	} - -	var events = elgg.config.events; - -	elgg.provide(event_name + '.' + event_type, events); - - -	if (!(events[event_name][event_type] instanceof elgg.ElggPriorityList)) { -		events[event_name][event_type] = new elgg.ElggPriorityList(); -	} - -	return events[event_name][event_type].insert(handler, priority); -}; - -/** - * - */ -elgg.trigger_event = function(event_name, event_type, opt_object) { -	elgg.assertTypeOf('string', event_name); -	elgg.assertTypeOf('string', event_type); - -	var events = elgg.config.events, -		callEventHandler = function(handler) { -			return handler(event_name, event_type, opt_object) !== false; -		}; - -	elgg.provide(event_name + '.' + event_type, events); -	elgg.provide('all.' + event_type, events); -	elgg.provide(event_name + '.all', events); -	elgg.provide('all.all', events); - -	return [ -	    events[event_name][event_type], -	    events['all'][event_type], -	    events[event_name]['all'], -	    events['all']['all'] -	].every(function(handlers) { -		return !(handlers instanceof elgg.ElggPriorityList) || handlers.every(callEventHandler); -	}); -};
\ No newline at end of file diff --git a/js/lib/hooks.js b/js/lib/hooks.js new file mode 100644 index 000000000..9c86a1fec --- /dev/null +++ b/js/lib/hooks.js @@ -0,0 +1,94 @@ +/* + * Javascript hook interface + */ + +elgg.provide('elgg.config.hooks'); + +/** + * Registers an hook handler with the event system. + * + * The special keyword "all" can be used for either the name or the type or both + * and means to call that handler for all of those hooks. + * + * @param {String}   name     Name of the plugin hook to register for + * @param {String}   type     Type of the event to register for + * @param {Function} handler  Handle to call + * @param {Number}   priority Priority to call the event handler + * @return {Bool} + */ +elgg.register_hook_handler = function(name, type, handler, priority) { +	elgg.assertTypeOf('string', name); +	elgg.assertTypeOf('string', type); +	elgg.assertTypeOf('function', handler); + +	if (!name || !type) { +		return false; +	} + +	var priorities =  elgg.config.hooks; + +	elgg.provide(name + '.' + type, priorities); + +	if (!(priorities[name][type] instanceof elgg.ElggPriorityList)) { +		priorities[name][type] = new elgg.ElggPriorityList(); +	} + +	return priorities[name][type].insert(handler, priority); +}; + +/** + * Emits a hook. + * + * Loops through all registered hooks and calls the handler functions in order. + * Every handler function will always be called, regardless of the return value. + * + * @warning Handlers take the same 4 arguments in the same order as when calling this function. + * This is different to the PHP version! + * + * Hooks are called in this order: + *	specifically registered (event_name and event_type match) + *	all names, specific type + *	specific name, all types + *	all names, all types + * + * @param {String} name   Name of the hook to emit + * @param {String} type   Type of the hook to emit + * @param {Object} params Optional parameters to pass to the handlers + * @param {Object} value  Initial value of the return. Can be mangled by handlers + * + * @return {Bool} + */ +elgg.trigger_hook = function(name, type, params, value) { +	elgg.assertTypeOf('string', name); +	elgg.assertTypeOf('string', type); + +	// default to true if unpassed +	value = value || true; + +	var hooks = elgg.config.hooks, +		tempReturnValue = null, +		returnValue = value, +		callHookHandler = function(handler) { +			tempReturnValue = handler(name, type, params, value); +			// always continue through all the handlers +			return true; +		}; + +	elgg.provide(name + '.' + type, hooks); +	elgg.provide('all.' + type, hooks); +	elgg.provide(name + '.all', hooks); +	elgg.provide('all.all', hooks); + +	[	hooks[name][type], +		hooks['all'][type], +		hooks[name]['all'], +		hooks['all']['all'] +	].every(function(handlers) { +		if (handlers instanceof elgg.ElggPriorityList) { +			handlers.every(callHookHandler); +		} +		return true; +	}); + +	return tempReturnValue || returnValue; +};
\ No newline at end of file diff --git a/js/lib/languages.js b/js/lib/languages.js index 10afa24b0..79768c471 100644 --- a/js/lib/languages.js +++ b/js/lib/languages.js @@ -86,4 +86,4 @@ elgg.config.translations.init = function() {  	elgg.reload_all_translations();  }; -elgg.register_event_handler('boot', 'system', elgg.config.translations.init);
\ No newline at end of file +elgg.register_hook_handler('boot', 'system', elgg.config.translations.init);
\ No newline at end of file diff --git a/js/lib/security.js b/js/lib/security.js index def775c05..d449d8887 100644 --- a/js/lib/security.js +++ b/js/lib/security.js @@ -73,4 +73,4 @@ elgg.security.init = function() {  	setInterval(elgg.security.refreshToken, elgg.security.interval);  }; -elgg.register_event_handler('boot', 'system', elgg.security.init);
\ No newline at end of file +elgg.register_hook_handler('boot', 'system', elgg.security.init);
\ No newline at end of file diff --git a/js/lib/ui.js b/js/lib/ui.js index c77c85aed..8d519a995 100644 --- a/js/lib/ui.js +++ b/js/lib/ui.js @@ -1,7 +1,6 @@  elgg.provide('elgg.ui');  elgg.ui.init = function () { -  	elgg.ui.initHoverMenu();  	//if the user clicks a system message, make it disappear @@ -46,13 +45,14 @@ elgg.ui.toggles = function(event) {   * Set the rel="popup" on the popper and set the href to target the   * item you want to toggle (<a rel="popup" href="#id-of-target">)   * - * This function emits the popup, ui event that plugins can register for to provide custom - * positioning for elements.  The handler is passed an object with the values: - *	popupSelector: The selector used to find the popup - *	popup:         The popup jQuery element as found by the selector - *	popper:        The jquery element whose click event initiated a popup. - * - * The handler function must return false to tell this function to abort automatic placement. + * This function emits the getOptions, ui.popup hook that plugins can register for to provide custom + * positioning for elements.  The handler is passed the following params: + *	targetSelector: The selector used to find the popup + *	target:         The popup jQuery element as found by the selector + *	source:         The jquery element whose click event initiated a popup. + *	 + * The return value of the function is used as the options object to .position(). + * Handles can also return false to abort the default behvior and override it with their own.   *   * @param {Object} event   * @return void @@ -60,17 +60,26 @@ elgg.ui.toggles = function(event) {  elgg.ui.popsUp = function(event) {  	event.preventDefault(); -	var target = $(this).toggleClass('elgg-state-active').attr('href'); +	var target = elgg.getUrlFragment($(this).toggleClass('elgg-state-active').attr('href'));  	var $target = $(target);  	// emit a hook to allow plugins to position and control popups -	var obj = { -		popupSelector: target, -		popup: $target, -		popper: $(this) +	var params = { +		targetSelector: target, +		target: $target, +		source: $(this)  	}; -	 -	if (!elgg.trigger_event('popup', 'ui', obj)) { + +	var options = { +		my: 'center top', +		at: 'center bottom', +		of: $(this) +	} + +	options = elgg.trigger_hook('getOptions', 'ui.popup', params, options); + +	// allow plugins to cancel event +	if (!options) {  		return;  	} @@ -82,11 +91,7 @@ elgg.ui.popsUp = function(event) {  	$target.appendTo('body')  		.fadeIn() -		.position({ -			'my': 'left top', -			'at': 'right bottom', -			'of': $(this) -		}); +		.position(options);  }  /** @@ -164,7 +169,7 @@ elgg.ui.initHoverMenu = function(parent) {  /**   * Calls a confirm() and prevents default if denied.   * - * @param {Object} event + * @param {Object} e   * @return void   */  elgg.ui.requiresConfirmation = function(e) { @@ -175,25 +180,24 @@ elgg.ui.requiresConfirmation = function(e) {  };  /** - * Repositions the likes popup. + * Repositions the likes popup + * + * @param {String} hook    'getOptions' + * @param {String} type    'ui.popup' + * @param {Object} params  An array of info about the target and source. + * @param {Object} options Options to pass to + * + * @return {Object}   */ -elgg.ui.likesPopupHandler = function(event, type, object) { -	if (object.popup.hasClass('elgg-likes-list')) { -		if (object.popup.is(':visible')) { -			object.popup.fadeOut(); -			return false; -		} -		 -		object.popup.appendTo('body') -			.fadeIn() -			.position({ -				'my': 'right bottom', -				'at': 'left top', -				'of': object.popper -			}); +elgg.ui.likesPopupHandler = function(hook, type, params, options) { +	if (params.target.hasClass('elgg-likes-list')) { +		options.my = 'right bottom'; +		options.at = 'left top'; +		return options;  	} -	return false; -} +	return null; +}; -elgg.register_event_handler('init', 'system', elgg.ui.init); -elgg.register_event_handler('popup', 'ui', elgg.ui.likesPopupHandler);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.ui.init); +//elgg.register_hook_handler('popup', 'ui', elgg.ui.likesPopupHandler); +elgg.register_hook_handler('getOptions', 'ui.popup', elgg.ui.likesPopupHandler);
\ No newline at end of file diff --git a/js/lib/ui.widgets.js b/js/lib/ui.widgets.js index 1acc22928..fb256672a 100644 --- a/js/lib/ui.widgets.js +++ b/js/lib/ui.widgets.js @@ -199,4 +199,4 @@ elgg.ui.widgets.equalHeight = function(selector) {  	$(selector).css('min-height', maxHeight);  } -elgg.register_event_handler('init', 'system', elgg.ui.widgets.init); +elgg.register_hook_handler('init', 'system', elgg.ui.widgets.init); diff --git a/js/lib/userpicker.js b/js/lib/userpicker.js index 5fc39bce3..b551ea830 100644 --- a/js/lib/userpicker.js +++ b/js/lib/userpicker.js @@ -81,4 +81,4 @@ elgg.userpicker.getSearchParams = function(e) {  	}  } -elgg.register_event_handler('init', 'system', elgg.userpicker.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.userpicker.init);
\ No newline at end of file diff --git a/js/tests/ElggEventsTest.js b/js/tests/ElggEventsTest.js deleted file mode 100644 index 4765878cf..000000000 --- a/js/tests/ElggEventsTest.js +++ /dev/null @@ -1,28 +0,0 @@ -ElggEventsTest = TestCase("ElggEventsTest"); - -ElggEventsTest.prototype.setUp = function() { -	elgg.config.events = {}; -	elgg.provide('elgg.config.events.all.all'); -}; - -ElggEventsTest.prototype.testEventHandlersMustBeFunctions = function () { -	assertException(function() { elgg.register_event_handler('str', 'str', 'oops'); }); -}; - -ElggEventsTest.prototype.testReturnValueDefaultsToTrue = function () { -	assertTrue(elgg.trigger_event('fee', 'fum')); - -	elgg.register_event_handler('fee', 'fum', elgg.nullFunction); -	assertTrue(elgg.trigger_event('fee', 'fum')); -}; - -ElggEventsTest.prototype.testCanGlomEventsWithAll = function () { -	elgg.register_event_handler('all', 'bar', elgg.abstractMethod); -	assertException("all,bar", function() { elgg.trigger_event('foo', 'bar'); }); - -	elgg.register_event_handler('foo', 'all', elgg.abstractMethod); -	assertException("foo,all", function() { elgg.trigger_event('foo', 'baz'); }); - -	elgg.register_event_handler('all', 'all', elgg.abstractMethod); -	assertException("all,all", function() { elgg.trigger_event('pinky', 'winky'); }); -};
\ No newline at end of file diff --git a/js/tests/ElggHooksTest.js b/js/tests/ElggHooksTest.js new file mode 100644 index 000000000..e7a2440e7 --- /dev/null +++ b/js/tests/ElggHooksTest.js @@ -0,0 +1,28 @@ +ElggHooksTest = TestCase("ElggHooksTest"); + +ElggHooksTest.prototype.setUp = function() { +	elgg.config.hooks = {}; +	elgg.provide('elgg.config.hooks.all.all'); +}; + +ElggHooksTest.prototype.testHookHandlersMustBeFunctions = function () { +	assertException(function() { elgg.register_hook_handler('str', 'str', 'oops'); }); +}; + +ElggHooksTest.prototype.testReturnValueDefaultsToTrue = function () { +	assertTrue(elgg.trigger_hook('fee', 'fum')); + +	elgg.register_hook_handler('fee', 'fum', elgg.nullFunction); +	assertTrue(elgg.trigger_hook('fee', 'fum')); +}; + +ElggHooksTest.prototype.testCanGlomHooksWithAll = function () { +	elgg.register_hook_handler('all', 'bar', elgg.abstractMethod); +	assertException("all,bar", function() { elgg.trigger_hook('foo', 'bar'); }); + +	elgg.register_hook_handler('foo', 'all', elgg.abstractMethod); +	assertException("foo,all", function() { elgg.trigger_hook('foo', 'baz'); }); + +	elgg.register_hook_handler('all', 'all', elgg.abstractMethod); +	assertException("all,all", function() { elgg.trigger_hook('pinky', 'winky'); }); +};
\ No newline at end of file diff --git a/mod/blog/views/default/js/blog/save_draft.php b/mod/blog/views/default/js/blog/save_draft.php index 1d5ae5c39..fd76c870c 100644 --- a/mod/blog/views/default/js/blog/save_draft.php +++ b/mod/blog/views/default/js/blog/save_draft.php @@ -64,4 +64,4 @@ elgg.blog.init = function() {  	setInterval(elgg.blog.saveDraft, 60000);  }; -elgg.register_event_handler('init', 'system', elgg.blog.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.blog.init);
\ No newline at end of file diff --git a/mod/bookmarks/views/default/bookmarks/js.php b/mod/bookmarks/views/default/bookmarks/js.php index 35dc82f70..b2fcd88bd 100644 --- a/mod/bookmarks/views/default/bookmarks/js.php +++ b/mod/bookmarks/views/default/bookmarks/js.php @@ -8,4 +8,4 @@ elgg.bookmarks.init = function() {  	e.attr('href', link);  } -elgg.register_event_handler('init', 'system', elgg.bookmarks.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.bookmarks.init);
\ No newline at end of file diff --git a/mod/messageboard/views/default/messageboard/js.php b/mod/messageboard/views/default/messageboard/js.php index 22aad10b7..b7da18a56 100644 --- a/mod/messageboard/views/default/messageboard/js.php +++ b/mod/messageboard/views/default/messageboard/js.php @@ -50,4 +50,4 @@ elgg.messageboard.deletePost = function(e) {  } -elgg.register_event_handler('init', 'system', elgg.messageboard.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.messageboard.init);
\ No newline at end of file diff --git a/mod/tinymce/views/default/js/tinymce.php b/mod/tinymce/views/default/js/tinymce.php index 4697e33a7..9809aa841 100644 --- a/mod/tinymce/views/default/js/tinymce.php +++ b/mod/tinymce/views/default/js/tinymce.php @@ -70,4 +70,4 @@ elgg.tinymce.init = function() {  } -elgg.register_event_handler('init', 'system', elgg.tinymce.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.tinymce.init);
\ No newline at end of file diff --git a/mod/uservalidationbyemail/views/default/uservalidationbyemail/js.php b/mod/uservalidationbyemail/views/default/uservalidationbyemail/js.php index c1ca58559..66cfcd6f6 100644 --- a/mod/uservalidationbyemail/views/default/uservalidationbyemail/js.php +++ b/mod/uservalidationbyemail/views/default/uservalidationbyemail/js.php @@ -24,4 +24,4 @@ elgg.uservalidationbyemail.init = function() {  	});  }; -elgg.register_event_handler('init', 'system', elgg.uservalidationbyemail.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.uservalidationbyemail.init);
\ No newline at end of file diff --git a/views/default/core/account/login_box.php b/views/default/core/account/login_box.php index 40b5f5637..274172bdb 100644 --- a/views/default/core/account/login_box.php +++ b/views/default/core/account/login_box.php @@ -20,7 +20,7 @@ echo elgg_view_module('aside', $title, $body);  <script type="text/javascript"> -	elgg.register_event_handler('init', 'system', function() {  +	elgg.register_hook_handler('init', 'system', function() {  		$('input[name=username]').focus();   	});  </script> diff --git a/views/default/core/account/login_dropdown.php b/views/default/core/account/login_dropdown.php index f3f105be1..a1d64a768 100644 --- a/views/default/core/account/login_dropdown.php +++ b/views/default/core/account/login_dropdown.php @@ -1,8 +1,6 @@  <?php  /**   * Elgg drop-down login form - * - * @todo Forms 1.8: Convert to use elgg_view_form()   */  if (elgg_is_logged_in()) { @@ -19,12 +17,11 @@ $body = elgg_view_form('login', array('action' => "{$login_url}action/login"), a  <div id="login-dropdown">  	<?php   		echo elgg_view('output/url', array( -			'href' => 'login', +			'href' => 'login#login-dropdown-box', +			'rel' => 'popup', +			'class' => 'elgg-button elgg-button-dropdown',  			'text' => elgg_echo('login'),  		));   		echo elgg_view_module('dropdown', '', $body, array('id' => 'login-dropdown-box'));   	?> -</div> -<script> -	$('#login-dropdown > a').attr('href', '#login-dropdown-box').addClass('elgg-toggler elgg-button elgg-button-dropdown'); -</script>
\ No newline at end of file +</div>
\ No newline at end of file diff --git a/views/default/core/river/filter.php b/views/default/core/river/filter.php index 0df10675c..87380b561 100644 --- a/views/default/core/river/filter.php +++ b/views/default/core/river/filter.php @@ -37,7 +37,7 @@ echo elgg_view('input/dropdown', $params);  ?>  <?php //@todo JS 1.8: no ?>  <script type="text/javascript"> -elgg.register_event_handler('init', 'system', function() { +elgg.register_hook_handler('init', 'system', function() {  	$('#elgg-river-selector').change(function() {  		var url = window.location.href;  		if (window.location.search.length) { diff --git a/views/default/js/admin.php b/views/default/js/admin.php index 15c74d4de..afffe95f0 100644 --- a/views/default/js/admin.php +++ b/views/default/js/admin.php @@ -146,4 +146,4 @@ elgg.admin.moveProfileField = function(e, ui) {  	});  } -elgg.register_event_handler('init', 'system', elgg.admin.init, 1000);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.admin.init, 1000);
\ No newline at end of file diff --git a/views/default/js/elgg.php b/views/default/js/elgg.php index 9ddd6907a..018db7967 100644 --- a/views/default/js/elgg.php +++ b/views/default/js/elgg.php @@ -28,7 +28,7 @@ foreach ($model_files as $file) {  $libs = array(  	//libraries  	'prototypes', -	'events', +	'hooks',  	'security',  	'languages',  	'ajax', @@ -59,11 +59,12 @@ elgg.security.interval = 5 * 60 * 1000; <?php //@todo make this configurable ?>  //Mimic PHP engine boot process  //Before the DOM is ready -- note that plugins aren't loaded yet -elgg.trigger_event('boot', 'system'); +elgg.trigger_hook('boot', 'system');  //After the DOM is ready  $(function() { -	elgg.trigger_event('init', 'system'); +	elgg.trigger_hook('init', 'system'); +	elgg.trigger_hook('ready', 'system');  });  <?php  | 
