]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Fixes #3540. Added "instant hooks" to JS hooks engine. elgg.register_instant_hook...
authorBrett Profitt <brett.profitt@gmail.com>
Sat, 15 Oct 2011 08:02:01 +0000 (01:02 -0700)
committerBrett Profitt <brett.profitt@gmail.com>
Sat, 15 Oct 2011 08:02:01 +0000 (01:02 -0700)
js/lib/elgglib.js
js/lib/hooks.js

index 96bd04d7c9bad8e15c9e3ffe6576cf2d9f34360e..0f17eecedbba4b03e81d59662f490ab3c36a7982 100644 (file)
@@ -520,6 +520,42 @@ elgg.getSelectorFromUrlFragment = function(url) {
        return '';
 };
 
+/**
+ * Adds child to object[parent] array.
+ *
+ * @param {Object} object The object to add to
+ * @param {String} parent The parent array to add to.
+ * @param {Mixed}  value  The value
+ */
+elgg.push_to_object_array = function(object, parent, value) {
+       elgg.assertTypeOf('object', object);
+       elgg.assertTypeOf('string', parent);
+
+       if (!(object[parent] instanceof Array)) {
+               object[parent] = []
+       }
+
+       if (object[parent].indexOf(value) < 0) {
+               return object[parent].push(value);
+       }
+
+       return false;
+}
+
+/**
+ * Tests if object[parent] contains child
+ *
+ * @param {Object} object The object to add to
+ * @param {String} parent The parent array to add to.
+ * @param {Mixed}  value  The value
+ */
+elgg.is_in_object_array = function(object, parent, value) {
+       elgg.assertTypeOf('object', object);
+       elgg.assertTypeOf('string', parent);
+
+       return typeof(object[parent]) != 'undefined' && object[parent].indexOf(value) >= 0;
+}
+
 /**
  * Triggers the init hook when the library is ready
  *
index ab3a8a224036c6bfbcc48b9cd02760d72a878984..edfd28f2468f066964a21cd7991047c430d4f60c 100644 (file)
@@ -3,13 +3,18 @@
  */
 
 elgg.provide('elgg.config.hooks');
+elgg.provide('elgg.config.instant_hooks');
+elgg.provide('elgg.config.triggered_hooks');
 
 /**
- * Registers an hook handler with the event system.
+ * Registers a 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.
  *
+ * Note that handlers registering for instant hooks will be executed immediately if the instant
+ * hook has been previously triggered.
+ *
  * @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
@@ -33,6 +38,11 @@ elgg.register_hook_handler = function(name, type, handler, priority) {
                priorities[name][type] = new elgg.ElggPriorityList();
        }
 
+       // call if instant and already triggered.
+       if (elgg.is_instant_hook(name, type) && elgg.is_triggered_hook(name, type)) {
+               handler(name, type, null, null);
+       }
+
        return priorities[name][type].insert(handler, priority);
 };
 
@@ -43,7 +53,9 @@ elgg.register_hook_handler = function(name, type, handler, priority) {
  * 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!
+ * This is different from the PHP version!
+ *
+ * @note Instant hooks do not support params or values.
  *
  * Hooks are called in this order:
  *     specifically registered (event_name and event_type match)
@@ -62,6 +74,9 @@ elgg.trigger_hook = function(name, type, params, value) {
        elgg.assertTypeOf('string', name);
        elgg.assertTypeOf('string', type);
 
+       // mark as triggered
+       elgg.set_triggered_hook(name, type);
+
        // default to true if unpassed
        value = value || true;
 
@@ -101,4 +116,58 @@ elgg.trigger_hook = function(name, type, params, value) {
        });
 
        return (tempReturnValue !== null) ? tempReturnValue : returnValue;
-};
\ No newline at end of file
+};
+
+/**
+ * Registers a hook as an instant hook.
+ *
+ * After being trigger once, registration of a handler to an instant hook will cause the
+ * handle to be executed immediately.
+ *
+ * @note Instant hooks must be triggered without params or defaults. Any params or default
+ * passed will *not* be passed to handlers executed upon registration.
+ *
+ * @param {String} name The hook name.
+ * @param {String} type The hook type.
+ * @return {Int}
+ */
+elgg.register_instant_hook = function(name, type) {
+       elgg.assertTypeOf('string', name);
+       elgg.assertTypeOf('string', type);
+
+       return elgg.push_to_object_array(elgg.config.instant_hooks, name, type);
+}
+
+/**
+ * Is this hook registered as an instant hook?
+ *
+ * @param {String} name The hook name.
+ * @param {String} type The hook type.
+ */
+elgg.is_instant_hook = function(name, type) {
+       return elgg.is_in_object_array(elgg.config.instant_hooks, name, type);
+}
+
+/**
+ * Records that a hook has been triggered.
+ *
+ * @param {String} name The hook name.
+ * @param {String} type The hook type.
+ */
+elgg.set_triggered_hook = function(name, type) {
+       return elgg.push_to_object_array(elgg.config.triggered_hooks, name, type);
+}
+
+/**
+ * Has this hook been triggered yet?
+ *
+ * @param {String} name The hook name.
+ * @param {String} type The hook type.
+ */
+elgg.is_triggered_hook = function(name, type) {
+       return elgg.is_in_object_array(elgg.config.triggered_hooks, name, type);
+}
+
+elgg.register_instant_hook('init', 'system');
+elgg.register_instant_hook('ready', 'system');
+elgg.register_instant_hook('boot', 'system');