diff options
Diffstat (limited to 'js/lib')
-rw-r--r-- | js/lib/ajax.js | 462 | ||||
-rw-r--r-- | js/lib/elgglib.js | 638 | ||||
-rw-r--r-- | js/lib/languages.js | 176 | ||||
-rw-r--r-- | js/lib/security.js | 150 | ||||
-rw-r--r-- | js/lib/session.js | 230 | ||||
-rw-r--r-- | js/lib/ui.js | 156 | ||||
-rw-r--r-- | js/lib/ui.widgets.js | 394 |
7 files changed, 1103 insertions, 1103 deletions
diff --git a/js/lib/ajax.js b/js/lib/ajax.js index 447d0c634..c84698a22 100644 --- a/js/lib/ajax.js +++ b/js/lib/ajax.js @@ -1,231 +1,231 @@ -/*globals elgg, $*/
-elgg.provide('elgg.ajax');
-
-/**
- * @author Evan Winslow
- * Provides a bunch of useful shortcut functions for making ajax calls
- */
-
-/**
- * Wrapper function for jQuery.ajax which ensures that the url being called
- * is relative to the elgg site root.
- *
- * You would most likely use elgg.get or elgg.post, rather than this function
- *
- * @param {string} url Optionally specify the url as the first argument
- * @param {Object} options Optional. {@see jQuery#ajax}
- * @return {XmlHttpRequest}
- */
-elgg.ajax = function(url, options) {
- options = elgg.ajax.handleOptions(url, options);
-
- options.url = elgg.normalize_url(options.url);
- return $.ajax(options);
-};
-/**
- * @const
- */
-elgg.ajax.SUCCESS = 0;
-
-/**
- * @const
- */
-elgg.ajax.ERROR = -1;
-
-/**
- * Handle optional arguments and return the resulting options object
- *
- * @param url
- * @param options
- * @return {Object}
- * @private
- */
-elgg.ajax.handleOptions = function(url, options) {
- var data_only = true,
- data,
- member;
-
- //elgg.ajax('example/file.php', {...});
- if (elgg.isString(url)) {
- options = options || {};
-
- //elgg.ajax({...});
- } else {
- options = url || {};
- url = options.url;
- }
-
- //elgg.ajax('example/file.php', function() {...});
- if (elgg.isFunction(options)) {
- data_only = false;
- options = {success: options};
- }
-
- //elgg.ajax('example/file.php', {data:{...}});
- if (options.data) {
- data_only = false;
- } else {
- for (member in options) {
- //elgg.ajax('example/file.php', {callback:function(){...}});
- if (elgg.isFunction(options[member])) {
- data_only = false;
- }
- }
- }
-
- //elgg.ajax('example/file.php', {notdata:notfunc});
- if (data_only) {
- data = options;
- options = {data: data};
- }
-
- if (url) {
- options.url = url;
- }
-
- return options;
-};
-
-/**
- * Wrapper function for elgg.ajax which forces the request type to 'get.'
- *
- * @param {string} url Optionally specify the url as the first argument
- * @param {Object} options {@see jQuery#ajax}
- * @return {XmlHttpRequest}
- */
-elgg.get = function(url, options) {
- options = elgg.ajax.handleOptions(url, options);
-
- options.type = 'get';
- return elgg.ajax(options);
-};
-
-/**
- * Wrapper function for elgg.get which forces the dataType to 'json.'
- *
- * @param {string} url Optionally specify the url as the first argument
- * @param {Object} options {@see jQuery#ajax}
- * @return {XmlHttpRequest}
- */
-elgg.getJSON = function(url, options) {
- options = elgg.ajax.handleOptions(url, options);
-
- options.dataType = 'json';
- return elgg.get(options);
-};
-
-/**
- * Wrapper function for elgg.ajax which forces the request type to 'post.'
- *
- * @param {string} url Optionally specify the url as the first argument
- * @param {Object} options {@see jQuery#ajax}
- * @return {XmlHttpRequest}
- */
-elgg.post = function(url, options) {
- options = elgg.ajax.handleOptions(url, options);
-
- options.type = 'post';
- return elgg.ajax(options);
-};
-
-/**
- * Perform an action via ajax
- *
- * @example Usage 1:
- * At its simplest, only the action name is required (and anything more than the
- * action name will be invalid).
- * <pre>
- * elgg.action('name/of/action');
- * </pre>
- * Note that it will *not* love you if you specify the full url as the action
- * (i.e. elgg.yoursite.com/action/name/of/action), but why would you want to do
- * that anyway, when you can just specify the action name?
- *
- * @example Usage 2:
- * If you want to pass some data along with it, use the second parameter
- * <pre>
- * elgg.action('friend/add', { friend: some_guid });
- * </pre>
- *
- * @example Usage 3:
- * Of course, you will have no control over what happens when the request
- * completes if you do it like that, so there's also the most verbose method
- * <pre>
- * elgg.action('friend/add', {
- * data: {
- * friend: some_guid
- * },
- * success: function(json) {
- * //do something
- * },
- * }
- * </pre>
- * You can pass any of your favorite $.ajax arguments into this second parameter.
- *
- * @note If you intend to use the second field in the "verbose" way, you must
- * specify a callback method or the data parameter. If you do not, elgg.action
- * will think you mean to send the second parameter as data.
- *
- * @note You do not have to add security tokens to this request. Elgg does that
- * for you automatically.
- *
- * @see jQuery.ajax
- *
- * @param {String} action The action to call.
- * @param {Object} options
- * @return {XMLHttpRequest}
- */
-elgg.action = function(action, options) {
- elgg.assertTypeOf('string', action);
-
- options = elgg.ajax.handleOptions('action/' + action, options);
-
- options.data = elgg.security.addToken(options.data);
- options.dataType = 'json';
-
- //Always display system messages after actions
- var custom_success = options.success || elgg.nullFunction;
- options.success = function(json, two, three, four) {
- if (json.system_messages) {
- elgg.register_error(json.system_messages.errors);
- elgg.system_message(json.system_messages.messages);
- }
-
- custom_success(json, two, three, four);
- };
-
- return elgg.post(options);
-};
-
-/**
- * Make an API call
- *
- * @example Usage:
- * <pre>
- * elgg.api('system.api.list', {
- * success: function(data) {
- * console.log(data);
- * }
- * });
- * </pre>
- *
- * @param {String} method The API method to be called
- * @param {Object} options {@see jQuery#ajax}
- * @return {XmlHttpRequest}
- */
-elgg.api = function (method, options) {
- elgg.assertTypeOf('string', method);
-
- var defaults = {
- dataType: 'json',
- data: {}
- };
-
- options = elgg.ajax.handleOptions(method, options);
- options = $.extend(defaults, options);
-
- options.url = 'services/api/rest/' + options.dataType + '/';
- options.data.method = method;
-
- return elgg.ajax(options);
-};
+/*globals elgg, $*/ +elgg.provide('elgg.ajax'); + +/** + * @author Evan Winslow + * Provides a bunch of useful shortcut functions for making ajax calls + */ + +/** + * Wrapper function for jQuery.ajax which ensures that the url being called + * is relative to the elgg site root. + * + * You would most likely use elgg.get or elgg.post, rather than this function + * + * @param {string} url Optionally specify the url as the first argument + * @param {Object} options Optional. {@see jQuery#ajax} + * @return {XmlHttpRequest} + */ +elgg.ajax = function(url, options) { + options = elgg.ajax.handleOptions(url, options); + + options.url = elgg.normalize_url(options.url); + return $.ajax(options); +}; +/** + * @const + */ +elgg.ajax.SUCCESS = 0; + +/** + * @const + */ +elgg.ajax.ERROR = -1; + +/** + * Handle optional arguments and return the resulting options object + * + * @param url + * @param options + * @return {Object} + * @private + */ +elgg.ajax.handleOptions = function(url, options) { + var data_only = true, + data, + member; + + //elgg.ajax('example/file.php', {...}); + if (elgg.isString(url)) { + options = options || {}; + + //elgg.ajax({...}); + } else { + options = url || {}; + url = options.url; + } + + //elgg.ajax('example/file.php', function() {...}); + if (elgg.isFunction(options)) { + data_only = false; + options = {success: options}; + } + + //elgg.ajax('example/file.php', {data:{...}}); + if (options.data) { + data_only = false; + } else { + for (member in options) { + //elgg.ajax('example/file.php', {callback:function(){...}}); + if (elgg.isFunction(options[member])) { + data_only = false; + } + } + } + + //elgg.ajax('example/file.php', {notdata:notfunc}); + if (data_only) { + data = options; + options = {data: data}; + } + + if (url) { + options.url = url; + } + + return options; +}; + +/** + * Wrapper function for elgg.ajax which forces the request type to 'get.' + * + * @param {string} url Optionally specify the url as the first argument + * @param {Object} options {@see jQuery#ajax} + * @return {XmlHttpRequest} + */ +elgg.get = function(url, options) { + options = elgg.ajax.handleOptions(url, options); + + options.type = 'get'; + return elgg.ajax(options); +}; + +/** + * Wrapper function for elgg.get which forces the dataType to 'json.' + * + * @param {string} url Optionally specify the url as the first argument + * @param {Object} options {@see jQuery#ajax} + * @return {XmlHttpRequest} + */ +elgg.getJSON = function(url, options) { + options = elgg.ajax.handleOptions(url, options); + + options.dataType = 'json'; + return elgg.get(options); +}; + +/** + * Wrapper function for elgg.ajax which forces the request type to 'post.' + * + * @param {string} url Optionally specify the url as the first argument + * @param {Object} options {@see jQuery#ajax} + * @return {XmlHttpRequest} + */ +elgg.post = function(url, options) { + options = elgg.ajax.handleOptions(url, options); + + options.type = 'post'; + return elgg.ajax(options); +}; + +/** + * Perform an action via ajax + * + * @example Usage 1: + * At its simplest, only the action name is required (and anything more than the + * action name will be invalid). + * <pre> + * elgg.action('name/of/action'); + * </pre> + * Note that it will *not* love you if you specify the full url as the action + * (i.e. elgg.yoursite.com/action/name/of/action), but why would you want to do + * that anyway, when you can just specify the action name? + * + * @example Usage 2: + * If you want to pass some data along with it, use the second parameter + * <pre> + * elgg.action('friend/add', { friend: some_guid }); + * </pre> + * + * @example Usage 3: + * Of course, you will have no control over what happens when the request + * completes if you do it like that, so there's also the most verbose method + * <pre> + * elgg.action('friend/add', { + * data: { + * friend: some_guid + * }, + * success: function(json) { + * //do something + * }, + * } + * </pre> + * You can pass any of your favorite $.ajax arguments into this second parameter. + * + * @note If you intend to use the second field in the "verbose" way, you must + * specify a callback method or the data parameter. If you do not, elgg.action + * will think you mean to send the second parameter as data. + * + * @note You do not have to add security tokens to this request. Elgg does that + * for you automatically. + * + * @see jQuery.ajax + * + * @param {String} action The action to call. + * @param {Object} options + * @return {XMLHttpRequest} + */ +elgg.action = function(action, options) { + elgg.assertTypeOf('string', action); + + options = elgg.ajax.handleOptions('action/' + action, options); + + options.data = elgg.security.addToken(options.data); + options.dataType = 'json'; + + //Always display system messages after actions + var custom_success = options.success || elgg.nullFunction; + options.success = function(json, two, three, four) { + if (json.system_messages) { + elgg.register_error(json.system_messages.errors); + elgg.system_message(json.system_messages.messages); + } + + custom_success(json, two, three, four); + }; + + return elgg.post(options); +}; + +/** + * Make an API call + * + * @example Usage: + * <pre> + * elgg.api('system.api.list', { + * success: function(data) { + * console.log(data); + * } + * }); + * </pre> + * + * @param {String} method The API method to be called + * @param {Object} options {@see jQuery#ajax} + * @return {XmlHttpRequest} + */ +elgg.api = function (method, options) { + elgg.assertTypeOf('string', method); + + var defaults = { + dataType: 'json', + data: {} + }; + + options = elgg.ajax.handleOptions(method, options); + options = $.extend(defaults, options); + + options.url = 'services/api/rest/' + options.dataType + '/'; + options.data.method = method; + + return elgg.ajax(options); +}; diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js index bed2db39d..0a627dc70 100644 --- a/js/lib/elgglib.js +++ b/js/lib/elgglib.js @@ -1,320 +1,320 @@ -/**
- * @namespace Singleton object for holding the Elgg javascript library
- */
-var elgg = elgg || {};
-
-/**
- * Pointer to the global context
- *
- * @see elgg.require
- * @see elgg.provide
- */
-elgg.global = this;
-
-/**
- * Convenience reference to an empty function.
- *
- * Save memory by not generating multiple empty functions.
- */
-elgg.nullFunction = function() {};
-
-/**
- * This forces an inheriting class to implement the method or
- * it will throw an error.
- *
- * @example
- * AbstractClass.prototype.toBeImplemented = elgg.abstractMethod;
- */
-elgg.abstractMethod = function() {
- throw new Error("Oops... you forgot to implement an abstract method!");
-};
-
-/**
- * Merges two or more objects together and returns the result.
- */
-elgg.extend = jQuery.extend;
-
-/**
- * Check if the value is an array.
- *
- * No sense in reinventing the wheel!
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isArray = jQuery.isArray;
-
-/**
- * Check if the value is a function.
- *
- * No sense in reinventing the wheel!
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isFunction = jQuery.isFunction;
-
-/**
- * Check if the value is a "plain" object (i.e., created by {} or new Object())
- *
- * No sense in reinventing the wheel!
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isPlainObject = jQuery.isPlainObject;
-
-/**
- * Check if the value is a string
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isString = function(val) {
- return typeof val === 'string';
-};
-
-/**
- * Check if the value is a number
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isNumber = function(val) {
- return typeof val === 'number';
-};
-
-/**
- * Check if the value is an object
- *
- * @note This returns true for functions and arrays! If you want to return true only
- * for "plain" objects (created using {} or new Object()) use elgg.isPlainObject.
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isObject = function(val) {
- return typeof val === 'object';
-};
-
-/**
- * Check if the value is undefined
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isUndefined = function(val) {
- return val === undefined;
-};
-
-/**
- * Check if the value is null
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isNull = function(val) {
- return val === null;
-};
-
-/**
- * Check if the value is either null or undefined
- *
- * @param {*} val
- *
- * @return boolean
- */
-elgg.isNullOrUndefined = function(val) {
- return val == null;
-};
-
-/**
- * Throw an exception of the type doesn't match
- *
- * @todo Might be more appropriate for debug mode only?
- */
-elgg.assertTypeOf = function(type, val) {
- if (typeof val !== type) {
- throw new TypeError("Expecting param of " +
- arguments.caller + "to be a(n) " + type + "." +
- " Was actually a(n) " + typeof val + ".");
- }
-};
-
-/**
- * Throw an error if the required package isn't present
- *
- * @param {String} pkg The required package (e.g., 'elgg.package')
- */
-elgg.require = function(pkg) {
- elgg.assertTypeOf('string', pkg);
-
- var parts = pkg.split('.'),
- cur = elgg.global,
- part, i;
-
- for (i = 0; i < parts.length; i += 1) {
- part = parts[i];
- cur = cur[part];
- if (elgg.isUndefined(cur)) {
- throw new Error("Missing package: " + pkg);
- }
- }
-};
-
-/**
- * Generate the skeleton for a package.
- *
- * <pre>
- * elgg.provide('elgg.package.subpackage');
- * </pre>
- *
- * is equivalent to
- *
- * <pre>
- * elgg = elgg || {};
- * elgg.package = elgg.package || {};
- * elgg.package.subpackage = elgg.package.subpackage || {};
- * </pre>
- *
- * @example elgg.provide('elgg.config.translations')
- *
- * @param {string} pkg The package name.
- */
-elgg.provide = function(pkg, opt_context) {
- elgg.assertTypeOf('string', pkg);
-
- var parts = pkg.split('.'),
- context = opt_context || elgg.global,
- part, i;
-
-
- for (i = 0; i < parts.length; i += 1) {
- part = parts[i];
- context[part] = context[part] || {};
- context = context[part];
- }
-};
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * @example
- * <pre>
- * function ParentClass(a, b) { }
- *
- * ParentClass.prototype.foo = function(a) { alert(a); }
- *
- * function ChildClass(a, b, c) {
- * //equivalent of parent::__construct(a, b); in PHP
- * ParentClass.call(this, a, b);
- * }
- *
- * elgg.inherit(ChildClass, ParentClass);
- *
- * var child = new ChildClass('a', 'b', 'see');
- * child.foo('boo!'); // alert('boo!');
- * </pre>
- *
- * @param {Function} childCtor Child class.
- * @param {Function} parentCtor Parent class.
- */
-elgg.inherit = function(Child, Parent) {
- Child.prototype = new Parent();
- Child.prototype.constructor = Child;
-};
-
-/**
- * Prepend elgg.config.wwwroot to a url if the url doesn't already have it.
- *
- * @param {String} url The url to extend
- * @return {String} The extended url
- * @private
- */
-elgg.normalize_url = function(url) {
- url = url || '';
- elgg.assertTypeOf('string', url);
-
- // jslint complains if you use /regexp/ shorthand here... ?!?!
- if ((new RegExp("^(https?:)?//")).test(url)) {
- return url;
- }
-
- return elgg.config.wwwroot + url.ltrim('/');
-};
-
-/**
- * Displays system messages via javascript rather than php.
- *
- * @param {String} msgs The message we want to display
- * @param {Number} delay The amount of time to display the message in milliseconds. Defaults to 6 seconds.
- * @param {String} type The type of message (typically 'error' or 'message')
- * @private
- */
-elgg.system_messages = function(msgs, delay, type) {
- if (elgg.isUndefined(msgs)) {
- return;
- }
-
- var classes = ['elgg_system_message', 'radius8'],
- messages_html = [],
- appendMessage = function(msg) {
- messages_html.push('<div class="' + classes.join(' ') + '"><p>' + msg + '</p></div>');
- }, i;
-
- //validate delay. Must be a positive integer.
- delay = parseInt(delay || 6000, 10);
- if (isNaN(delay) || delay <= 0) {
- delay = 6000;
- }
-
- if (type === 'error') {
- classes.push('messages_error');
- }
-
- //Handle non-arrays
- if (!elgg.isArray(msgs)) {
- msgs = [msgs];
- }
-
- msgs.forEach(appendMessage);
-
- $(messages_html.join('')).appendTo('#elgg_system_messages')
- .animate({opacity: '1.0'}, delay).fadeOut('slow');
-};
-
-/**
- * Wrapper function for system_messages. Specifies "messages" as the type of message
- * @param {String} msg The message to display
- * @param {Number} delay How long to display the message (milliseconds)
- */
-elgg.system_message = function(msgs, delay) {
- elgg.system_messages(msgs, delay, "message");
-};
-
-/**
- * Wrapper function for system_messages. Specifies "errors" as the type of message
- * @param {String} error The error message to display
- * @param {Number} delay How long to dispaly the error message (milliseconds)
- */
-elgg.register_error = function(errors, delay) {
- elgg.system_messages(errors, delay, "error");
-};
-
-/**
- * Meant to mimic the php forward() function by simply redirecting the
- * user to another page.
- *
- * @param {String} url The url to forward to
- */
-elgg.forward = function(url) {
- location.href = elgg.normalize_url(url);
+/** + * @namespace Singleton object for holding the Elgg javascript library + */ +var elgg = elgg || {}; + +/** + * Pointer to the global context + * + * @see elgg.require + * @see elgg.provide + */ +elgg.global = this; + +/** + * Convenience reference to an empty function. + * + * Save memory by not generating multiple empty functions. + */ +elgg.nullFunction = function() {}; + +/** + * This forces an inheriting class to implement the method or + * it will throw an error. + * + * @example + * AbstractClass.prototype.toBeImplemented = elgg.abstractMethod; + */ +elgg.abstractMethod = function() { + throw new Error("Oops... you forgot to implement an abstract method!"); +}; + +/** + * Merges two or more objects together and returns the result. + */ +elgg.extend = jQuery.extend; + +/** + * Check if the value is an array. + * + * No sense in reinventing the wheel! + * + * @param {*} val + * + * @return boolean + */ +elgg.isArray = jQuery.isArray; + +/** + * Check if the value is a function. + * + * No sense in reinventing the wheel! + * + * @param {*} val + * + * @return boolean + */ +elgg.isFunction = jQuery.isFunction; + +/** + * Check if the value is a "plain" object (i.e., created by {} or new Object()) + * + * No sense in reinventing the wheel! + * + * @param {*} val + * + * @return boolean + */ +elgg.isPlainObject = jQuery.isPlainObject; + +/** + * Check if the value is a string + * + * @param {*} val + * + * @return boolean + */ +elgg.isString = function(val) { + return typeof val === 'string'; +}; + +/** + * Check if the value is a number + * + * @param {*} val + * + * @return boolean + */ +elgg.isNumber = function(val) { + return typeof val === 'number'; +}; + +/** + * Check if the value is an object + * + * @note This returns true for functions and arrays! If you want to return true only + * for "plain" objects (created using {} or new Object()) use elgg.isPlainObject. + * + * @param {*} val + * + * @return boolean + */ +elgg.isObject = function(val) { + return typeof val === 'object'; +}; + +/** + * Check if the value is undefined + * + * @param {*} val + * + * @return boolean + */ +elgg.isUndefined = function(val) { + return val === undefined; +}; + +/** + * Check if the value is null + * + * @param {*} val + * + * @return boolean + */ +elgg.isNull = function(val) { + return val === null; +}; + +/** + * Check if the value is either null or undefined + * + * @param {*} val + * + * @return boolean + */ +elgg.isNullOrUndefined = function(val) { + return val == null; +}; + +/** + * Throw an exception of the type doesn't match + * + * @todo Might be more appropriate for debug mode only? + */ +elgg.assertTypeOf = function(type, val) { + if (typeof val !== type) { + throw new TypeError("Expecting param of " + + arguments.caller + "to be a(n) " + type + "." + + " Was actually a(n) " + typeof val + "."); + } +}; + +/** + * Throw an error if the required package isn't present + * + * @param {String} pkg The required package (e.g., 'elgg.package') + */ +elgg.require = function(pkg) { + elgg.assertTypeOf('string', pkg); + + var parts = pkg.split('.'), + cur = elgg.global, + part, i; + + for (i = 0; i < parts.length; i += 1) { + part = parts[i]; + cur = cur[part]; + if (elgg.isUndefined(cur)) { + throw new Error("Missing package: " + pkg); + } + } +}; + +/** + * Generate the skeleton for a package. + * + * <pre> + * elgg.provide('elgg.package.subpackage'); + * </pre> + * + * is equivalent to + * + * <pre> + * elgg = elgg || {}; + * elgg.package = elgg.package || {}; + * elgg.package.subpackage = elgg.package.subpackage || {}; + * </pre> + * + * @example elgg.provide('elgg.config.translations') + * + * @param {string} pkg The package name. + */ +elgg.provide = function(pkg, opt_context) { + elgg.assertTypeOf('string', pkg); + + var parts = pkg.split('.'), + context = opt_context || elgg.global, + part, i; + + + for (i = 0; i < parts.length; i += 1) { + part = parts[i]; + context[part] = context[part] || {}; + context = context[part]; + } +}; + +/** + * Inherit the prototype methods from one constructor into another. + * + * @example + * <pre> + * function ParentClass(a, b) { } + * + * ParentClass.prototype.foo = function(a) { alert(a); } + * + * function ChildClass(a, b, c) { + * //equivalent of parent::__construct(a, b); in PHP + * ParentClass.call(this, a, b); + * } + * + * elgg.inherit(ChildClass, ParentClass); + * + * var child = new ChildClass('a', 'b', 'see'); + * child.foo('boo!'); // alert('boo!'); + * </pre> + * + * @param {Function} childCtor Child class. + * @param {Function} parentCtor Parent class. + */ +elgg.inherit = function(Child, Parent) { + Child.prototype = new Parent(); + Child.prototype.constructor = Child; +}; + +/** + * Prepend elgg.config.wwwroot to a url if the url doesn't already have it. + * + * @param {String} url The url to extend + * @return {String} The extended url + * @private + */ +elgg.normalize_url = function(url) { + url = url || ''; + elgg.assertTypeOf('string', url); + + // jslint complains if you use /regexp/ shorthand here... ?!?! + if ((new RegExp("^(https?:)?//")).test(url)) { + return url; + } + + return elgg.config.wwwroot + url.ltrim('/'); +}; + +/** + * Displays system messages via javascript rather than php. + * + * @param {String} msgs The message we want to display + * @param {Number} delay The amount of time to display the message in milliseconds. Defaults to 6 seconds. + * @param {String} type The type of message (typically 'error' or 'message') + * @private + */ +elgg.system_messages = function(msgs, delay, type) { + if (elgg.isUndefined(msgs)) { + return; + } + + var classes = ['elgg_system_message', 'radius8'], + messages_html = [], + appendMessage = function(msg) { + messages_html.push('<div class="' + classes.join(' ') + '"><p>' + msg + '</p></div>'); + }, i; + + //validate delay. Must be a positive integer. + delay = parseInt(delay || 6000, 10); + if (isNaN(delay) || delay <= 0) { + delay = 6000; + } + + if (type === 'error') { + classes.push('messages_error'); + } + + //Handle non-arrays + if (!elgg.isArray(msgs)) { + msgs = [msgs]; + } + + msgs.forEach(appendMessage); + + $(messages_html.join('')).appendTo('#elgg_system_messages') + .animate({opacity: '1.0'}, delay).fadeOut('slow'); +}; + +/** + * Wrapper function for system_messages. Specifies "messages" as the type of message + * @param {String} msg The message to display + * @param {Number} delay How long to display the message (milliseconds) + */ +elgg.system_message = function(msgs, delay) { + elgg.system_messages(msgs, delay, "message"); +}; + +/** + * Wrapper function for system_messages. Specifies "errors" as the type of message + * @param {String} error The error message to display + * @param {Number} delay How long to dispaly the error message (milliseconds) + */ +elgg.register_error = function(errors, delay) { + elgg.system_messages(errors, delay, "error"); +}; + +/** + * Meant to mimic the php forward() function by simply redirecting the + * user to another page. + * + * @param {String} url The url to forward to + */ +elgg.forward = function(url) { + location.href = elgg.normalize_url(url); };
\ No newline at end of file diff --git a/js/lib/languages.js b/js/lib/languages.js index 03ff4b817..727e939c0 100644 --- a/js/lib/languages.js +++ b/js/lib/languages.js @@ -1,89 +1,89 @@ -/*globals vsprintf*/
-/**
- * Provides language-related functionality
- */
-elgg.provide('elgg.config.translations');
-
-elgg.config.language = 'en';
-
-/**
- * Analagous to the php version. Merges translations for a
- * given language into the current translations map.
- */
-elgg.add_translation = function(lang, translations) {
- elgg.provide('elgg.config.translations.' + lang);
-
- elgg.extend(elgg.config.translations[lang], translations);
-};
-
-/**
- * Load the translations for the given language.
- *
- * If no language is specified, the default language is used.
- * @param {string} language
- * @return {XMLHttpRequest}
- */
-elgg.reload_all_translations = function(language) {
- var lang = language || elgg.get_language();
- elgg.getJSON('pg/js/languages%252f' + lang + '.js', {
- data: {
- 'viewtype': 'default',
- 'lastcache': elgg.config.lastcache
- },
- success: function(json) {
- elgg.add_translation(lang, json);
- }
- });
-};
-
-/**
- * Get the current language
- * @return {String}
- */
-elgg.get_language = function() {
- var user = elgg.get_loggedin_user();
-
- if (user && user.language) {
- return user.language;
- }
-
- return elgg.config.language;
-};
-
-/**
- * Translates a string
- *
- * @param {String} key The string to translate
- * @param {Array} argv vsprintf support
- * @param {String} language The language to display it in
- *
- * @return {String} The translation
- */
-elgg.echo = function(key, argv, language) {
- //elgg.echo('str', 'en')
- if (elgg.isString(argv)) {
- language = argv;
- argv = [];
- }
-
- //elgg.echo('str', [...], 'en')
- var translations = elgg.config.translations,
- dlang = elgg.get_language(),
- map;
-
- language = language || dlang;
- argv = argv || [];
-
- map = translations[language] || translations[dlang];
- if (map && map[key]) {
- return vsprintf(map[key], argv);
- }
-
- return undefined;
-};
-
-elgg.config.translations.init = function() {
- elgg.reload_all_translations();
-};
-
+/*globals vsprintf*/ +/** + * Provides language-related functionality + */ +elgg.provide('elgg.config.translations'); + +elgg.config.language = 'en'; + +/** + * Analagous to the php version. Merges translations for a + * given language into the current translations map. + */ +elgg.add_translation = function(lang, translations) { + elgg.provide('elgg.config.translations.' + lang); + + elgg.extend(elgg.config.translations[lang], translations); +}; + +/** + * Load the translations for the given language. + * + * If no language is specified, the default language is used. + * @param {string} language + * @return {XMLHttpRequest} + */ +elgg.reload_all_translations = function(language) { + var lang = language || elgg.get_language(); + elgg.getJSON('pg/js/languages%252f' + lang + '.js', { + data: { + 'viewtype': 'default', + 'lastcache': elgg.config.lastcache + }, + success: function(json) { + elgg.add_translation(lang, json); + } + }); +}; + +/** + * Get the current language + * @return {String} + */ +elgg.get_language = function() { + var user = elgg.get_loggedin_user(); + + if (user && user.language) { + return user.language; + } + + return elgg.config.language; +}; + +/** + * Translates a string + * + * @param {String} key The string to translate + * @param {Array} argv vsprintf support + * @param {String} language The language to display it in + * + * @return {String} The translation + */ +elgg.echo = function(key, argv, language) { + //elgg.echo('str', 'en') + if (elgg.isString(argv)) { + language = argv; + argv = []; + } + + //elgg.echo('str', [...], 'en') + var translations = elgg.config.translations, + dlang = elgg.get_language(), + map; + + language = language || dlang; + argv = argv || []; + + map = translations[language] || translations[dlang]; + if (map && map[key]) { + return vsprintf(map[key], argv); + } + + return undefined; +}; + +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 diff --git a/js/lib/security.js b/js/lib/security.js index b9d1be3a3..def775c05 100644 --- a/js/lib/security.js +++ b/js/lib/security.js @@ -1,76 +1,76 @@ -/**
- * Hold security-related data here
- */
-elgg.provide('elgg.security');
-
-elgg.security.token = {};
-
-elgg.security.setToken = function(json) {
- //update the convenience object
- elgg.security.token = json;
-
- //also update all forms
- $('[name=__elgg_ts]').val(json.__elgg_ts);
- $('[name=__elgg_token]').val(json.__elgg_token);
-
- //also update all links
- $('[href]').each(function() {
- this.href = this.href
- .replace(/__elgg_ts=\d*/, '__elgg_ts=' + json.__elgg_ts)
- .replace(/__elgg_token=[0-9a-f]*/, '__elgg_token=' + json.__elgg_token);
- });
-};
-
-/**
- * Security tokens time out, so lets refresh those every so often
- *
- * @todo handle error and bad return data
- */
-elgg.security.refreshToken = function() {
- elgg.action('security/refreshtoken', function(data) {
- elgg.security.setToken(data.output);
- });
-};
-
-
-/**
- * Add elgg action tokens to an object or string (assumed to be url data)
- *
- * @param {Object|string} data
- * @return {Object} The new data object including action tokens
- * @private
- */
-elgg.security.addToken = function(data) {
-
- // 'http://example.com?data=sofar'
- if (elgg.isString(data)) {
- var args = [];
- if (data) {
- args.push(data);
- }
- args.push("__elgg_ts=" + elgg.security.token.__elgg_ts);
- args.push("__elgg_token=" + elgg.security.token.__elgg_token);
-
- return args.join('&');
- }
-
- // no input! acts like a getter
- if (elgg.isUndefined(data)) {
- return elgg.security.token;
- }
-
- // {...}
- if (elgg.isPlainObject(data)) {
- return elgg.extend(data, elgg.security.token);
- }
-
- // oops, don't recognize that!
- throw new TypeError("elgg.security.addToken not implemented for " + (typeof data) + "s");
-};
-
-elgg.security.init = function() {
- //refresh security token every 5 minutes
- setInterval(elgg.security.refreshToken, elgg.security.interval);
-};
-
+/** + * Hold security-related data here + */ +elgg.provide('elgg.security'); + +elgg.security.token = {}; + +elgg.security.setToken = function(json) { + //update the convenience object + elgg.security.token = json; + + //also update all forms + $('[name=__elgg_ts]').val(json.__elgg_ts); + $('[name=__elgg_token]').val(json.__elgg_token); + + //also update all links + $('[href]').each(function() { + this.href = this.href + .replace(/__elgg_ts=\d*/, '__elgg_ts=' + json.__elgg_ts) + .replace(/__elgg_token=[0-9a-f]*/, '__elgg_token=' + json.__elgg_token); + }); +}; + +/** + * Security tokens time out, so lets refresh those every so often + * + * @todo handle error and bad return data + */ +elgg.security.refreshToken = function() { + elgg.action('security/refreshtoken', function(data) { + elgg.security.setToken(data.output); + }); +}; + + +/** + * Add elgg action tokens to an object or string (assumed to be url data) + * + * @param {Object|string} data + * @return {Object} The new data object including action tokens + * @private + */ +elgg.security.addToken = function(data) { + + // 'http://example.com?data=sofar' + if (elgg.isString(data)) { + var args = []; + if (data) { + args.push(data); + } + args.push("__elgg_ts=" + elgg.security.token.__elgg_ts); + args.push("__elgg_token=" + elgg.security.token.__elgg_token); + + return args.join('&'); + } + + // no input! acts like a getter + if (elgg.isUndefined(data)) { + return elgg.security.token; + } + + // {...} + if (elgg.isPlainObject(data)) { + return elgg.extend(data, elgg.security.token); + } + + // oops, don't recognize that! + throw new TypeError("elgg.security.addToken not implemented for " + (typeof data) + "s"); +}; + +elgg.security.init = function() { + //refresh security token every 5 minutes + setInterval(elgg.security.refreshToken, elgg.security.interval); +}; + elgg.register_event_handler('boot', 'system', elgg.security.init);
\ No newline at end of file diff --git a/js/lib/session.js b/js/lib/session.js index fc61144be..613910412 100644 --- a/js/lib/session.js +++ b/js/lib/session.js @@ -1,116 +1,116 @@ -/**
- * @todo comment
- */
-elgg.provide('elgg.session');
-
-/**
- * Helper function for setting cookies
- * @param {string} name
- * @param {string} value
- * @param {Object} options
- * {number|Date} options[expires]
- * {string} options[path]
- * {string} options[domain]
- * {boolean} options[secure]
- *
- * @return {string} The value of the cookie, if only name is specified
- */
-elgg.session.cookie = function (name, value, options) {
- var cookies = [], cookie = [], i = 0, date, valid = true;
-
- //elgg.session.cookie()
- if (elgg.isUndefined(name)) {
- return document.cookie;
- }
-
- //elgg.session.cookie(name)
- if (elgg.isUndefined(value)) {
- if (document.cookie && document.cookie !== '') {
- cookies = document.cookie.split(';');
- for (i = 0; i < cookies.length; i += 1) {
- cookie = jQuery.trim(cookies[i]).split('=');
- if (cookie[0] === name) {
- return decodeURIComponent(cookie[1]);
- }
- }
- }
- return undefined;
- }
-
- // elgg.session.cookie(name, value[, opts])
- options = options || {};
-
- if (elgg.isNull(value)) {
- value = '';
- options.expires = -1;
- }
-
- cookies.push(name + '=' + value);
-
- if (elgg.isNumber(options.expires)) {
- if (elgg.isNumber(options.expires)) {
- date = new Date();
- date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
- } else if (options.expires.toUTCString) {
- date = options.expires;
- } else {
- valid = false;
- }
-
- if (valid) {
- cookies.push('expires=' + date.toUTCString());
- }
- }
-
- // CAUTION: Needed to parenthesize options.path and options.domain
- // in the following expressions, otherwise they evaluate to undefined
- // in the packed version for some reason.
- if (options.path) {
- cookies.push('path=' + (options.path));
- }
-
- if (options.domain) {
- cookies.push('domain=' + (options.domain));
- }
-
- if (options.secure) {
- cookies.push('secure');
- }
-
- document.cookie = cookies.join('; ');
-};
-
-/**
- * @return {ElggUser} The logged in user
- */
-elgg.get_loggedin_user = function() {
- return elgg.session.user;
-};
-
-/**
- * @return {number} The GUID of the logged in user
- */
-elgg.get_loggedin_userid = function() {
- var user = elgg.get_loggedin_user();
- return user ? user.guid : 0;
-};
-
-/**
- * @return {boolean} Whether there is a user logged in
- */
-elgg.isloggedin = function() {
- return (elgg.get_loggedin_user() instanceof elgg.ElggUser);
-};
-
-/**
- * @return {boolean} Whether there is an admin logged in
- */
-elgg.isadminloggedin = function() {
- var user = elgg.get_loggedin_user();
- return (user instanceof elgg.ElggUser) && user.isAdmin();
-};
-
-/**
- * @deprecated Use elgg.session.cookie instead
- */
+/** + * @todo comment + */ +elgg.provide('elgg.session'); + +/** + * Helper function for setting cookies + * @param {string} name + * @param {string} value + * @param {Object} options + * {number|Date} options[expires] + * {string} options[path] + * {string} options[domain] + * {boolean} options[secure] + * + * @return {string} The value of the cookie, if only name is specified + */ +elgg.session.cookie = function (name, value, options) { + var cookies = [], cookie = [], i = 0, date, valid = true; + + //elgg.session.cookie() + if (elgg.isUndefined(name)) { + return document.cookie; + } + + //elgg.session.cookie(name) + if (elgg.isUndefined(value)) { + if (document.cookie && document.cookie !== '') { + cookies = document.cookie.split(';'); + for (i = 0; i < cookies.length; i += 1) { + cookie = jQuery.trim(cookies[i]).split('='); + if (cookie[0] === name) { + return decodeURIComponent(cookie[1]); + } + } + } + return undefined; + } + + // elgg.session.cookie(name, value[, opts]) + options = options || {}; + + if (elgg.isNull(value)) { + value = ''; + options.expires = -1; + } + + cookies.push(name + '=' + value); + + if (elgg.isNumber(options.expires)) { + if (elgg.isNumber(options.expires)) { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else if (options.expires.toUTCString) { + date = options.expires; + } else { + valid = false; + } + + if (valid) { + cookies.push('expires=' + date.toUTCString()); + } + } + + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason. + if (options.path) { + cookies.push('path=' + (options.path)); + } + + if (options.domain) { + cookies.push('domain=' + (options.domain)); + } + + if (options.secure) { + cookies.push('secure'); + } + + document.cookie = cookies.join('; '); +}; + +/** + * @return {ElggUser} The logged in user + */ +elgg.get_loggedin_user = function() { + return elgg.session.user; +}; + +/** + * @return {number} The GUID of the logged in user + */ +elgg.get_loggedin_userid = function() { + var user = elgg.get_loggedin_user(); + return user ? user.guid : 0; +}; + +/** + * @return {boolean} Whether there is a user logged in + */ +elgg.isloggedin = function() { + return (elgg.get_loggedin_user() instanceof elgg.ElggUser); +}; + +/** + * @return {boolean} Whether there is an admin logged in + */ +elgg.isadminloggedin = function() { + var user = elgg.get_loggedin_user(); + return (user instanceof elgg.ElggUser) && user.isAdmin(); +}; + +/** + * @deprecated Use elgg.session.cookie instead + */ jQuery.cookie = elgg.session.cookie;
\ No newline at end of file diff --git a/js/lib/ui.js b/js/lib/ui.js index a1d852e5a..56f2d5eb0 100644 --- a/js/lib/ui.js +++ b/js/lib/ui.js @@ -1,79 +1,79 @@ -elgg.provide('elgg.ui');
-
-elgg.ui.init = function () {
- //if the user clicks a system message, make it disappear
- $('.elgg-system-messages li').live('click', function() {
- $(this).stop().fadeOut('fast');
- });
-
- $('.elgg-toggle').live('click', elgg.ui.toggle);
-
- $('.elgg-menu-parent').live('click', elgg.ui.toggleMenu);
-
- $('.elgg-like-toggle').live('click', elgg.ui.toggleLikes);
-
- $('a.collapsibleboxlink').click(elgg.ui.toggleCollapsibleBox);
-};
-
-/**
- * Toggles an element based on clicking a separate element
- *
- * Use .elgg-toggle on the toggler element
- * The id of the toggler is elgg-toggler-<id>
- * The id of the element being toggled is elgg-togglee-<id>
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.toggle = function(event) {
- var id = $(this).attr('id').replace('toggler', 'togglee');
- $('#' + id).slideToggle('medium');
- event.preventDefault();
-}
-
-/**
- * Toggles a child menu when the parent is clicked
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.toggleMenu = function(event) {
- $(this).siblings().slideToggle('medium');
- $(this).toggleClass('elgg-menu-closed elgg-menu-opened');
- event.preventDefault();
-}
-
-// reusable generic hidden panel
-elgg.ui.toggleCollapsibleBox = function () {
- //$(this.parentNode.parentNode).children(".collapsible_box").slideToggle("fast");
- return false;
-};
-
-/**
- * Toggles the likes list
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.toggleLikes = function(event) {
- var $list = $(this).next(".elgg-likes-list");
- var position = $(this).position();
- var startTop = position.top;
- var stopTop = position.top - $list.height();
- if ($list.css('display') == 'none') {
- $('.elgg-likes-list').fadeOut();
-
- $list.css('top', startTop);
- $list.css('left', position.left - $list.width());
- $list.animate({opacity: "toggle", top: stopTop}, 500);
-
- $list.click(function(event) {
- $list.fadeOut();
- });
- } else {
- $list.animate({opacity: "toggle", top: startTop}, 500);
- }
- event.preventDefault();
-}
-
+elgg.provide('elgg.ui'); + +elgg.ui.init = function () { + //if the user clicks a system message, make it disappear + $('.elgg-system-messages li').live('click', function() { + $(this).stop().fadeOut('fast'); + }); + + $('.elgg-toggle').live('click', elgg.ui.toggle); + + $('.elgg-menu-parent').live('click', elgg.ui.toggleMenu); + + $('.elgg-like-toggle').live('click', elgg.ui.toggleLikes); + + $('a.collapsibleboxlink').click(elgg.ui.toggleCollapsibleBox); +}; + +/** + * Toggles an element based on clicking a separate element + * + * Use .elgg-toggle on the toggler element + * The id of the toggler is elgg-toggler-<id> + * The id of the element being toggled is elgg-togglee-<id> + * + * @param {Object} event + * @return void + */ +elgg.ui.toggle = function(event) { + var id = $(this).attr('id').replace('toggler', 'togglee'); + $('#' + id).slideToggle('medium'); + event.preventDefault(); +} + +/** + * Toggles a child menu when the parent is clicked + * + * @param {Object} event + * @return void + */ +elgg.ui.toggleMenu = function(event) { + $(this).siblings().slideToggle('medium'); + $(this).toggleClass('elgg-menu-closed elgg-menu-opened'); + event.preventDefault(); +} + +// reusable generic hidden panel +elgg.ui.toggleCollapsibleBox = function () { + //$(this.parentNode.parentNode).children(".collapsible_box").slideToggle("fast"); + return false; +}; + +/** + * Toggles the likes list + * + * @param {Object} event + * @return void + */ +elgg.ui.toggleLikes = function(event) { + var $list = $(this).next(".elgg-likes-list"); + var position = $(this).position(); + var startTop = position.top; + var stopTop = position.top - $list.height(); + if ($list.css('display') == 'none') { + $('.elgg-likes-list').fadeOut(); + + $list.css('top', startTop); + $list.css('left', position.left - $list.width()); + $list.animate({opacity: "toggle", top: stopTop}, 500); + + $list.click(function(event) { + $list.fadeOut(); + }); + } else { + $list.animate({opacity: "toggle", top: startTop}, 500); + } + event.preventDefault(); +} + elgg.register_event_handler('init', 'system', elgg.ui.init);
\ No newline at end of file diff --git a/js/lib/ui.widgets.js b/js/lib/ui.widgets.js index 87f552d50..bcace608f 100644 --- a/js/lib/ui.widgets.js +++ b/js/lib/ui.widgets.js @@ -1,197 +1,197 @@ -elgg.provide('elgg.ui.widgets');
-
-/**
- * Widgets initialization
- *
- * @return void
- */
-elgg.ui.widgets.init = function() {
-
- // widget layout?
- if ($(".elgg-widgets").length == 0) {
- return;
- }
-
- $(".elgg-widgets").sortable({
- items: 'div.elgg-widget',
- connectWith: '.elgg-widgets',
- handle: 'div.drag-handle',
- forcePlaceholderSize: true,
- placeholder: 'elgg-widget-placeholder',
- opacity: 0.8,
- revert: 500,
- stop: elgg.ui.widgets.move
- });
-
- $('.elgg-widgets-add-panel li.elgg-widget-available').click(elgg.ui.widgets.add);
-
- $('a.elgg-widget-delete-button').live('click', elgg.ui.widgets.remove);
- $('.elgg-widget-edit > form ').live('submit', elgg.ui.widgets.saveSettings);
- $('a.elgg-widget-collapse-button').live('click', elgg.ui.widgets.collapseToggle);
-
- elgg.ui.widgets.equalHeight(".elgg-widgets");
-};
-
-/**
- * Adds a new widget
- *
- * Makes Ajax call to persist new widget and inserts the widget html
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.widgets.add = function(event) {
- // elgg-widget-type-<type>
- var type = $(this).attr('id');
- type = type.substr(type.indexOf('elgg-widget-type-') + "elgg-widget-type-".length);
-
- // if multiple instances not allow, disable this widget type add button
- var multiple = $(this).attr('class').indexOf('elgg-widget-multiple') != -1;
- if (multiple == false) {
- $(this).addClass('elgg-widget-unavailable');
- $(this).removeClass('elgg-widget-available');
- $(this).unbind('click', elgg.ui.widgets.add);
- }
-
- elgg.action('widgets/add', {
- data: {
- handler: type,
- user_guid: elgg.get_loggedin_userid(),
- context: $("input[name='widget_context']").val()
- },
- success: function(json) {
- $('#elgg-widget-col-1').prepend(json.output);
- var $widget = $('#elgg-widget-col-1').children(":first");
- }
- });
- event.preventDefault();
-}
-
-/**
- * Persist the widget's new position
- *
- * @param {Object} event
- * @param {Object} ui
- *
- * @return void
- */
-elgg.ui.widgets.move = function(event, ui) {
-
- // elgg-widget-<guid>
- var guidString = ui.item.attr('id');
- guidString = guidString.substr(guidString.indexOf('elgg-widget-') + "elgg-widget-".length);
-
- // elgg-widget-col-<column>
- var col = ui.item.parent().attr('id');
- col = col.substr(col.indexOf('elgg-widget-col-') + "elgg-widget-col-".length);
-
- elgg.action('widgets/move', {
- data: {
- guid: guidString,
- column: col,
- position: ui.item.index()
- }
- });
-
- // @hack fixes jquery-ui/opera bug where draggable elements jump
- ui.item.css('top', 0);
- ui.item.css('left', 0);
-}
-
-/**
- * Removes a widget from the layout
- *
- * Event callback the uses Ajax to delete the widget and removes its HTML
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.widgets.remove = function(event) {
- var $widget = $(this).parent().parent();
-
- // if widget type is single instance type, enable the add buton
- var type = $widget.attr('class');
- // elgg-widget-instance-<type>
- type = type.substr(type.indexOf('elgg-widget-instance-') + "elgg-widget-instance-".length);
- $button = $('#elgg-widget-type-' + type);
- var multiple = $button.attr('class').indexOf('elgg-widget-multiple') != -1;
- if (multiple == false) {
- $button.addClass('elgg-widget-available');
- $button.removeClass('elgg-widget-unavailable');
- $button.unbind('click', elgg.ui.widgets.add); // make sure we don't bind twice
- $button.click(elgg.ui.widgets.add);
- }
-
- $widget.remove();
-
- // elgg-widget-delete-button-<guid>
- var id = $(this).attr('id');
- id = id.substr(id.indexOf('elgg-widget-delete-button-') + "elgg-widget-delete-button-".length);
-
- elgg.action('widgets/delete', {
- data: {
- guid: id
- }
- });
- event.preventDefault();
-}
-
-/**
- * Toggle the collapse state of the widget
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.widgets.collapseToggle = function(event) {
- $(this).toggleClass('elgg-widget-collapsed');
- $(this).parent().parent().find('.elgg-widget-container').slideToggle('medium');
- event.preventDefault();
-}
-
-/**
- * Save a widget's settings
- *
- * Uses Ajax to save the settings and updates the HTML.
- *
- * @param {Object} event
- * @return void
- */
-elgg.ui.widgets.saveSettings = function(event) {
- $(this).parent().slideToggle('medium');
- var $widgetContent = $(this).parent().parent().children('.elgg-widget-content');
-
- // stick the ajaxk loader in there
- var $loader = $('#elgg-widget-loader').clone();
- $loader.attr('id', '#elgg-widget-active-loader');
- $loader.removeClass('hidden');
- $widgetContent.html($loader);
-
- elgg.action('widgets/save', {
- data: $(this).serialize(),
- success: function(json) {
- $widgetContent.html(json.output);
- }
- });
- event.preventDefault();
-}
-
-/**
- * Make all elements have the same min-height
- *
- * This addresses the issue of trying to drag a widget into a column that does
- * not have any widgets.
- *
- * @param {String} selector
- * @return void
- */
-elgg.ui.widgets.equalHeight = function(selector) {
- var maxHeight = 0;
- $(selector).each(function() {
- if ($(this).height() > maxHeight) {
- maxHeight = $(this).height();
- }
- })
- $(selector).css('min-height', maxHeight);
-}
-
-elgg.register_event_handler('init', 'system', elgg.ui.widgets.init);
+elgg.provide('elgg.ui.widgets'); + +/** + * Widgets initialization + * + * @return void + */ +elgg.ui.widgets.init = function() { + + // widget layout? + if ($(".elgg-widgets").length == 0) { + return; + } + + $(".elgg-widgets").sortable({ + items: 'div.elgg-widget', + connectWith: '.elgg-widgets', + handle: 'div.drag-handle', + forcePlaceholderSize: true, + placeholder: 'elgg-widget-placeholder', + opacity: 0.8, + revert: 500, + stop: elgg.ui.widgets.move + }); + + $('.elgg-widgets-add-panel li.elgg-widget-available').click(elgg.ui.widgets.add); + + $('a.elgg-widget-delete-button').live('click', elgg.ui.widgets.remove); + $('.elgg-widget-edit > form ').live('submit', elgg.ui.widgets.saveSettings); + $('a.elgg-widget-collapse-button').live('click', elgg.ui.widgets.collapseToggle); + + elgg.ui.widgets.equalHeight(".elgg-widgets"); +}; + +/** + * Adds a new widget + * + * Makes Ajax call to persist new widget and inserts the widget html + * + * @param {Object} event + * @return void + */ +elgg.ui.widgets.add = function(event) { + // elgg-widget-type-<type> + var type = $(this).attr('id'); + type = type.substr(type.indexOf('elgg-widget-type-') + "elgg-widget-type-".length); + + // if multiple instances not allow, disable this widget type add button + var multiple = $(this).attr('class').indexOf('elgg-widget-multiple') != -1; + if (multiple == false) { + $(this).addClass('elgg-widget-unavailable'); + $(this).removeClass('elgg-widget-available'); + $(this).unbind('click', elgg.ui.widgets.add); + } + + elgg.action('widgets/add', { + data: { + handler: type, + user_guid: elgg.get_loggedin_userid(), + context: $("input[name='widget_context']").val() + }, + success: function(json) { + $('#elgg-widget-col-1').prepend(json.output); + var $widget = $('#elgg-widget-col-1').children(":first"); + } + }); + event.preventDefault(); +} + +/** + * Persist the widget's new position + * + * @param {Object} event + * @param {Object} ui + * + * @return void + */ +elgg.ui.widgets.move = function(event, ui) { + + // elgg-widget-<guid> + var guidString = ui.item.attr('id'); + guidString = guidString.substr(guidString.indexOf('elgg-widget-') + "elgg-widget-".length); + + // elgg-widget-col-<column> + var col = ui.item.parent().attr('id'); + col = col.substr(col.indexOf('elgg-widget-col-') + "elgg-widget-col-".length); + + elgg.action('widgets/move', { + data: { + guid: guidString, + column: col, + position: ui.item.index() + } + }); + + // @hack fixes jquery-ui/opera bug where draggable elements jump + ui.item.css('top', 0); + ui.item.css('left', 0); +} + +/** + * Removes a widget from the layout + * + * Event callback the uses Ajax to delete the widget and removes its HTML + * + * @param {Object} event + * @return void + */ +elgg.ui.widgets.remove = function(event) { + var $widget = $(this).parent().parent(); + + // if widget type is single instance type, enable the add buton + var type = $widget.attr('class'); + // elgg-widget-instance-<type> + type = type.substr(type.indexOf('elgg-widget-instance-') + "elgg-widget-instance-".length); + $button = $('#elgg-widget-type-' + type); + var multiple = $button.attr('class').indexOf('elgg-widget-multiple') != -1; + if (multiple == false) { + $button.addClass('elgg-widget-available'); + $button.removeClass('elgg-widget-unavailable'); + $button.unbind('click', elgg.ui.widgets.add); // make sure we don't bind twice + $button.click(elgg.ui.widgets.add); + } + + $widget.remove(); + + // elgg-widget-delete-button-<guid> + var id = $(this).attr('id'); + id = id.substr(id.indexOf('elgg-widget-delete-button-') + "elgg-widget-delete-button-".length); + + elgg.action('widgets/delete', { + data: { + guid: id + } + }); + event.preventDefault(); +} + +/** + * Toggle the collapse state of the widget + * + * @param {Object} event + * @return void + */ +elgg.ui.widgets.collapseToggle = function(event) { + $(this).toggleClass('elgg-widget-collapsed'); + $(this).parent().parent().find('.elgg-widget-container').slideToggle('medium'); + event.preventDefault(); +} + +/** + * Save a widget's settings + * + * Uses Ajax to save the settings and updates the HTML. + * + * @param {Object} event + * @return void + */ +elgg.ui.widgets.saveSettings = function(event) { + $(this).parent().slideToggle('medium'); + var $widgetContent = $(this).parent().parent().children('.elgg-widget-content'); + + // stick the ajaxk loader in there + var $loader = $('#elgg-widget-loader').clone(); + $loader.attr('id', '#elgg-widget-active-loader'); + $loader.removeClass('hidden'); + $widgetContent.html($loader); + + elgg.action('widgets/save', { + data: $(this).serialize(), + success: function(json) { + $widgetContent.html(json.output); + } + }); + event.preventDefault(); +} + +/** + * Make all elements have the same min-height + * + * This addresses the issue of trying to drag a widget into a column that does + * not have any widgets. + * + * @param {String} selector + * @return void + */ +elgg.ui.widgets.equalHeight = function(selector) { + var maxHeight = 0; + $(selector).each(function() { + if ($(this).height() > maxHeight) { + maxHeight = $(this).height(); + } + }) + $(selector).css('min-height', maxHeight); +} + +elgg.register_event_handler('init', 'system', elgg.ui.widgets.init); |