From ef68436ac04da078ffdcacd7e1f785473a303d45 Mon Sep 17 00:00:00 2001 From: Giulio Cesare Solaroli Date: Sun, 02 Oct 2011 23:56:18 +0000 Subject: First version of the newly restructured repository --- (limited to 'frontend/beta/js/YUI-extensions/yutil.js') diff --git a/frontend/beta/js/YUI-extensions/yutil.js b/frontend/beta/js/YUI-extensions/yutil.js new file mode 100644 index 0000000..a815397 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/yutil.js @@ -0,0 +1,637 @@ +YAHOO.namespace('ext', 'ext.util', 'ext.grid', 'ext.dd', 'ext.tree', 'ext.data', 'ext.form'); +if(typeof Ext == 'undefined'){ + Ext = YAHOO.ext; +} +YAHOO.ext.Strict = (document.compatMode == 'CSS1Compat'); +YAHOO.ext.SSL_SECURE_URL = 'javascript:false'; +YAHOO.ext.BLANK_IMAGE_URL = 'http:/'+'/www.yui-ext.com/blog/images/s.gif'; + +// for old browsers +window.undefined = undefined; +/** + * @class Function + * These functions are available on every Function object (any javascript function). + */ + // + /** + * Creates a callback that passes arguments[0], arguments[1], arguments[2], ... + * Call directly on any function. Example: myFunction.createCallback(myarg, myarg2) + * Will create a function that is bound to those 2 args. + * @return {Function} The new function +*/ +Function.prototype.createCallback = function(/*args...*/){ + // make args available, in function below + var args = arguments; + var method = this; + return function() { + return method.apply(window, args); + }; +}; + +/** + * Creates a delegate (callback) that sets the scope to obj. + * Call directly on any function. Example: this.myFunction.createDelegate(this) + * Will create a function that is automatically scoped to this. + * @param {Object} obj (optional) The object for which the scope is set + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Function} The new function + */ +Function.prototype.createDelegate = function(obj, args, appendArgs){ + var method = this; + return function() { + var callArgs = args || arguments; + if(appendArgs === true){ + callArgs = Array.prototype.slice.call(arguments, 0); + callArgs = callArgs.concat(args); + }else if(typeof appendArgs == 'number'){ + callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first + var applyArgs = [appendArgs, 0].concat(args); // create method call params + Array.prototype.splice.apply(callArgs, applyArgs); // splice them in + } + return method.apply(obj || window, callArgs); + }; +}; + +/** + * Calls this function after the number of millseconds specified. + * @param {Number} millis The number of milliseconds for the setTimeout call + * @param {Object} obj (optional) The object for which the scope is set + * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) + * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, + * if a number the args are inserted at the specified position + * @return {Number} The timeout id that can be used with clearTimeout + */ +Function.prototype.defer = function(millis, obj, args, appendArgs){ + return setTimeout(this.createDelegate(obj, args, appendArgs), millis); +}; +/** + * Create a combined function call sequence of the original function + the passed function. + * The resulting function returns the results of the original function. + * The passed fcn is called with the parameters of the original function + * @param {Function} fcn The function to sequence + * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window) + * @return {Function} The new function + */ +Function.prototype.createSequence = function(fcn, scope){ + if(typeof fcn != 'function'){ + return this; + } + var method = this; + return function() { + var retval = method.apply(this || window, arguments); + fcn.apply(scope || this || window, arguments); + return retval; + }; +}; + +/* + * IE will leak if this isn't here + */ +YAHOO.util.Event.on(window, 'unload', function(){ + var p = Function.prototype; + delete p.createSequence; + delete p.defer; + delete p.createDelegate; + delete p.createCallback; + delete p.createInterceptor; +}); + +/** + * Creates an interceptor function. The passed fcn is called before the original one. If it returns false, the original one is not called. + * The resulting function returns the results of the original function. + * The passed fcn is called with the parameters of the original function. + * @addon + * @param {Function} fcn The function to call before the original + * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window) + * @return {Function} The new function + */ +Function.prototype.createInterceptor = function(fcn, scope){ + if(typeof fcn != 'function'){ + return this; + } + var method = this; + return function() { + fcn.target = this; + fcn.method = method; + if(fcn.apply(scope || this || window, arguments) === false){ + return; + } + return method.apply(this || window, arguments);; + }; +}; + +/** + * @class YAHOO.ext.util.Browser + * @singleton + */ +YAHOO.ext.util.Browser = new function(){ + var ua = navigator.userAgent.toLowerCase(); + /** @type Boolean */ + this.isOpera = (ua.indexOf('opera') > -1); + /** @type Boolean */ + this.isSafari = (ua.indexOf('webkit') > -1); + /** @type Boolean */ + this.isIE = (window.ActiveXObject); + /** @type Boolean */ + this.isIE7 = (ua.indexOf('msie 7') > -1); + /** @type Boolean */ + this.isGecko = !this.isSafari && (ua.indexOf('gecko') > -1); + + if(ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1){ + /** @type Boolean */ + this.isWindows = true; + }else if(ua.indexOf("macintosh") != -1){ + /** @type Boolean */ + this.isMac = true; + } + if(this.isIE && !this.isIE7){ + try{ + document.execCommand("BackgroundImageCache", false, true); + }catch(e){} + } +}(); + + /** + * Enable custom handler signature and event cancelling. Using fireDirect() instead of fire() calls the subscribed event handlers + * with the exact parameters passed to fireDirect, instead of the usual (eventType, args[], obj). IMO this is more intuitive + * and promotes cleaner code. Also, if an event handler returns false, it is returned by fireDirect and no other handlers will be called.
+ * Example:


+ * if(beforeUpdateEvent.fireDirect(myArg, myArg2) !== false){
+ *     // do update
+ * }
+ */ +YAHOO.util.CustomEvent.prototype.fireDirect = function(){ + var len=this.subscribers.length; + for (var i=0; iFunction} fn (optional) The default function to timeout + * @param {Object} scope (optional) The default scope of that timeout + * @param {Array} args (optional) The default Array of arguments + */ +YAHOO.ext.util.DelayedTask = function(fn, scope, args){ + var timeoutId = null; + + /** + * Cancels any pending timeout and queues a new one + * @param {Number} delay The milliseconds to delay + * @param {Function} newFn (optional) Overrides function passed to constructor + * @param {Object} newScope (optional) Overrides scope passed to constructor + * @param {Array} newArgs (optional) Overrides args passed to constructor + */ + this.delay = function(delay, newFn, newScope, newArgs){ + if(timeoutId){ + clearTimeout(timeoutId); + } + fn = newFn || fn; + scope = newScope || scope; + args = newArgs || args; + timeoutId = setTimeout(fn.createDelegate(scope, args), delay); + }; + + /** + * Cancel the last queued timeout + */ + this.cancel = function(){ + if(timeoutId){ + clearTimeout(timeoutId); + timeoutId = null; + } + }; +}; + +/** + * @class YAHOO.ext.util.Observable + * Abstract base class that provides a common interface for publishing events. Subclasses are expected to + * to have a property "events" with all the events defined.
+ * For example: + *

+ var Employee = function(name){
+    this.name = name;
+    this.events = {
+        'fired' : new YAHOO.util.CustomEvent('fired'),
+        'quit' : true // lazy initialize the CustomEvent
+    }
+ }
+ YAHOO.extend(Employee, YAHOO.ext.util.Observable);
+
+ */ +YAHOO.ext.util.Observable = function(){}; +YAHOO.ext.util.Observable.prototype = { + /** + * Fires the specified event with the passed parameters (minus the event name). + * @param {String} eventName + * @param {Object...} args Variable number of parameters are passed to handlers + * @return {Boolean} returns false if any of the handlers return false otherwise it returns true + */ + fireEvent : function(){ + var ce = this.events[arguments[0].toLowerCase()]; + if(typeof ce == 'object'){ + return ce.fireDirect.apply(ce, Array.prototype.slice.call(arguments, 1)); + }else{ + return true; + } + }, + /** + * Appends an event handler to this component + * @param {String} eventName The type of event to listen for + * @param {Function} handler The method the event invokes + * @param {Object} scope (optional) The scope (this object) for the handler + * @param {boolean} override (optional) If true, scope becomes the scope + */ + addListener : function(eventName, fn, scope, override){ + eventName = eventName.toLowerCase(); + var ce = this.events[eventName]; + if(!ce){ + // added for a better message when subscribing to wrong event + throw 'You are trying to listen for an event that does not exist: "' + eventName + '".'; + } + if(typeof ce == 'boolean'){ + ce = new YAHOO.util.CustomEvent(eventName); + this.events[eventName] = ce; + } + ce.subscribe(fn, scope, override); + }, + + /** + * Appends an event handler to this component that is delayed the specified number of milliseconds. This + * is useful for events that modify the DOM and need to wait for the browser to catch up. + * @param {String} eventName The type of event to listen for + * @param {Function} handler The method the event invokes + * @param {Object} scope (optional) The scope (this object) for the handler + * @param {Number} delay (optional) The number of milliseconds to delay (defaults to 1 millisecond) + * @return {Function} The wrapped function that was created (can be used to remove the listener) + */ + delayedListener : function(eventName, fn, scope, delay){ + var newFn = function(){ + setTimeout(fn.createDelegate(scope, arguments), delay || 1); + } + this.addListener(eventName, newFn); + return newFn; + }, + + /** + * Appends an event handler to this component that is buffered. If the event is triggered more than once + * in the specified time-frame, only the last one actually fires. + * @param {String} eventName The type of event to listen for + * @param {Function} handler The method the event invokes + * @param {Object} scope (optional) The scope (this object) for the handler + * @param {Number} millis (optional) The number of milliseconds to buffer (defaults to 250) + * @return {Function} The wrapped function that was created (can be used to remove the listener) + */ + bufferedListener : function(eventName, fn, scope, millis){ + var task = new YAHOO.ext.util.DelayedTask(); + var newFn = function(){ + task.delay(millis || 250, fn, scope, Array.prototype.slice.call(arguments, 0)); + } + this.addListener(eventName, newFn); + return newFn; + }, + + /** + * Removes a listener + * @param {String} eventName The type of event to listen for + * @param {Function} handler The handler to remove + * @param {Object} scope (optional) The scope (this object) for the handler + */ + removeListener : function(eventName, fn, scope){ + var ce = this.events[eventName.toLowerCase()]; + if(typeof ce == 'object'){ + ce.unsubscribe(fn, scope); + } + }, + + /** + * Removes all listeners for this object + */ + purgeListeners : function(){ + for(var evt in this.events){ + if(typeof this.events[evt] == 'object'){ + this.events[evt].unsubscribeAll(); + } + } + } +}; +/** + * Appends an event handler to this element (shorthand for addListener) + * @param {String} eventName The type of event to listen for + * @param {Function} handler The method the event invokes + * @param {Object} scope (optional) The scope (this object) for the handler + * @param {boolean} override (optional) If true, scope becomes the scope + * @method + */ +YAHOO.ext.util.Observable.prototype.on = YAHOO.ext.util.Observable.prototype.addListener; + +/** + * Starts capture on the specified Observable. All events will be passed + * to the supplied function with the event name + standard signature of the event + * before the event is fired. If the supplied function returns false, + * the event will not fire. + * @param {Observable} o The Observable to capture + * @param {Function} fn The function to call + * @param {Object} scope (optional) The scope (this object) for the fn + * @static + */ +YAHOO.ext.util.Observable.capture = function(o, fn, scope){ + o.fireEvent = o.fireEvent.createInterceptor(fn, scope); +}; + +/** + * Removes all added captures from the Observable. + * @param {Observable} o The Observable to release + * @static + */ +YAHOO.ext.util.Observable.releaseCapture = function(o){ + o.fireEvent = YAHOO.ext.util.Observable.prototype.fireEvent; +}; + +/** + * @class YAHOO.ext.util.Config + * Class with one useful method + * @singleton + */ +YAHOO.ext.util.Config = { + /** + * Copies all the properties of config to obj. + * @param {Object} obj The receiver of the properties + * @param {Object} config The source of the properties + * @param {Object} defaults A different object that will also be applied for default values + * @return {Object} returns obj + */ + apply : function(obj, config, defaults){ + if(defaults){ + this.apply(obj, defaults); + } + if(config){ + for(var prop in config){ + obj[prop] = config[prop]; + } + } + return obj; + } +}; + +if(!String.escape){ + String.escape = function(string) { + return string.replace(/('|\\)/g, "\\$1"); + }; +}; + +String.leftPad = function (val, size, ch) { + var result = new String(val); + if (ch == null) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result; +}; + +// workaround for Safari anim duration speed problems +if(YAHOO.util.AnimMgr && YAHOO.ext.util.Browser.isSafari){ + YAHOO.util.AnimMgr.fps = 500; +} + +// add ability for callbacks instead of events for animations +if(YAHOO.util.Anim){ + YAHOO.util.Anim.prototype.animateX = function(callback, scope){ + var f = function(){ + this.onComplete.unsubscribe(f); + if(typeof callback == 'function'){ + callback.call(scope || this, this); + } + }; + this.onComplete.subscribe(f, this, true); + this.animate(); + }; +} + +// workaround for Safari 1.3 not supporting hasOwnProperty +if(YAHOO.util.Connect && YAHOO.ext.util.Browser.isSafari){ + YAHOO.util.Connect.setHeader = function(o){ + for(var prop in this._http_header){ + // if(this._http_header.hasOwnProperty(prop)){ + if(typeof this._http_header[prop] != 'function'){ + o.conn.setRequestHeader(prop, this._http_header[prop]); + } + } + delete this._http_header; + this._http_header = {}; + this._has_http_headers = false; + }; +} +/** + * A simple enhancement to drag drop that allows you to constrain the movement of the + * DD or DDProxy object to a particular element.

+ * + * Usage: +

+ var dd = new YAHOO.util.DDProxy("dragDiv1", "proxytest",  
+                { dragElId: "existingProxyDiv" });
+ dd.startDrag = function(){
+     this.constrainTo('parent-id');
+ }; 
+ 
+ * Or you can initalize it using the {@link YAHOO.ext.Element} object: +

+ getEl('dragDiv1').initDDProxy('proxytest', {dragElId: "existingProxyDiv"}, {
+     startDrag : function(){
+         this.constrainTo('parent-id');
+     }
+ });
+ 
+ */ +if(YAHOO.util.DragDrop){ + /** + * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}). + * @type Object + */ + YAHOO.util.DragDrop.prototype.defaultPadding = {left:0, right:0, top:0, bottom:0}; + + /** + * Initializes the drag drop object's constraints to restrict movement to a certain element. + * @param {String/HTMLElement/Element} constrainTo The element to constrain to. + * @param {Object/Number} pad (optional) Pad provides a way to specify "padding" of the constraints, + * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or + * an object containing the sides to pad. For example: {right:10, bottom:10} + * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders) + */ + YAHOO.util.DragDrop.prototype.constrainTo = function(constrainTo, pad, inContent){ + if(typeof pad == 'number'){ + pad = {left: pad, right:pad, top:pad, bottom:pad}; + } + pad = pad || this.defaultPadding; + var b = getEl(this.getEl()).getBox(); + var ce = getEl(constrainTo); + var c = ce.dom == document.body ? { x: 0, y: 0, + width: YAHOO.util.Dom.getViewportWidth(), + height: YAHOO.util.Dom.getViewportHeight()} : ce.getBox(inContent || false); + var topSpace = b.y - c.y; + var leftSpace = b.x - c.x; + + this.resetConstraints(); + this.setXConstraint(leftSpace - (pad.left||0), // left + c.width - leftSpace - b.width - (pad.right||0) //right + ); + this.setYConstraint(topSpace - (pad.top||0), //top + c.height - topSpace - b.height - (pad.bottom||0) //bottom + ); + } +} -- cgit v0.9.0.2