From ca32f08966f1b51fcb19460f0996bb0c4048e6fe Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 3 Dec 2011 13:29:22 +0100 Subject: Update to MediaWiki 1.18.0 * also update ArchLinux skin to chagnes in MonoBook * Use only css to hide our menu bar when printing --- resources/jquery/images/sort_both.gif | Bin 0 -> 1184 bytes resources/jquery/images/sort_down.gif | Bin 0 -> 1174 bytes resources/jquery/images/sort_none.gif | Bin 0 -> 462 bytes resources/jquery/images/sort_up.gif | Bin 0 -> 1174 bytes resources/jquery/jquery.appear.js | 138 + resources/jquery/jquery.async.js | 33 +- resources/jquery/jquery.autoEllipsis.js | 78 +- resources/jquery/jquery.byteLength.js | 19 + resources/jquery/jquery.byteLimit.js | 56 + resources/jquery/jquery.checkboxShiftClick.js | 14 +- resources/jquery/jquery.client.js | 390 +- resources/jquery/jquery.color.js | 125 +- resources/jquery/jquery.colorUtil.js | 193 + resources/jquery/jquery.cookie.js | 87 +- resources/jquery/jquery.form.js | 791 +++ resources/jquery/jquery.getAttrs.js | 24 + resources/jquery/jquery.hoverIntent.js | 111 + resources/jquery/jquery.js | 7082 ++++++++++++++------- resources/jquery/jquery.json.js | 180 + resources/jquery/jquery.localize.js | 105 +- resources/jquery/jquery.makeCollapsible.css | 14 + resources/jquery/jquery.makeCollapsible.js | 339 + resources/jquery/jquery.messageBox.css | 15 + resources/jquery/jquery.messageBox.js | 98 + resources/jquery/jquery.mwPrototypes.js | 120 + resources/jquery/jquery.placeholder.js | 32 +- resources/jquery/jquery.qunit.completenessTest.js | 267 + resources/jquery/jquery.qunit.css | 225 + resources/jquery/jquery.qunit.js | 1442 +++++ resources/jquery/jquery.suggestions.css | 2 +- resources/jquery/jquery.suggestions.js | 18 +- resources/jquery/jquery.tabIndex.js | 45 +- resources/jquery/jquery.tablesorter.css | 17 + resources/jquery/jquery.tablesorter.js | 910 +++ resources/jquery/jquery.textSelection.js | 183 +- 35 files changed, 10502 insertions(+), 2651 deletions(-) create mode 100644 resources/jquery/images/sort_both.gif create mode 100644 resources/jquery/images/sort_down.gif create mode 100644 resources/jquery/images/sort_none.gif create mode 100644 resources/jquery/images/sort_up.gif create mode 100644 resources/jquery/jquery.appear.js create mode 100644 resources/jquery/jquery.byteLength.js create mode 100644 resources/jquery/jquery.byteLimit.js create mode 100644 resources/jquery/jquery.colorUtil.js create mode 100644 resources/jquery/jquery.form.js create mode 100644 resources/jquery/jquery.getAttrs.js create mode 100644 resources/jquery/jquery.hoverIntent.js create mode 100644 resources/jquery/jquery.json.js create mode 100644 resources/jquery/jquery.makeCollapsible.css create mode 100644 resources/jquery/jquery.makeCollapsible.js create mode 100644 resources/jquery/jquery.messageBox.css create mode 100644 resources/jquery/jquery.messageBox.js create mode 100644 resources/jquery/jquery.mwPrototypes.js create mode 100644 resources/jquery/jquery.qunit.completenessTest.js create mode 100644 resources/jquery/jquery.qunit.css create mode 100644 resources/jquery/jquery.qunit.js create mode 100644 resources/jquery/jquery.tablesorter.css create mode 100644 resources/jquery/jquery.tablesorter.js (limited to 'resources/jquery') diff --git a/resources/jquery/images/sort_both.gif b/resources/jquery/images/sort_both.gif new file mode 100644 index 00000000..50ad15a0 Binary files /dev/null and b/resources/jquery/images/sort_both.gif differ diff --git a/resources/jquery/images/sort_down.gif b/resources/jquery/images/sort_down.gif new file mode 100644 index 00000000..ec4f41b0 Binary files /dev/null and b/resources/jquery/images/sort_down.gif differ diff --git a/resources/jquery/images/sort_none.gif b/resources/jquery/images/sort_none.gif new file mode 100644 index 00000000..edd07e58 Binary files /dev/null and b/resources/jquery/images/sort_none.gif differ diff --git a/resources/jquery/images/sort_up.gif b/resources/jquery/images/sort_up.gif new file mode 100644 index 00000000..80189185 Binary files /dev/null and b/resources/jquery/images/sort_up.gif differ diff --git a/resources/jquery/jquery.appear.js b/resources/jquery/jquery.appear.js new file mode 100644 index 00000000..4f77886c --- /dev/null +++ b/resources/jquery/jquery.appear.js @@ -0,0 +1,138 @@ +/* + * jQuery.appear + * http://code.google.com/p/jquery-appear/ + * + * Copyright (c) 2009 Michael Hixson + * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) +*/ +(function($) { + + $.fn.appear = function(fn, options) { + + var settings = $.extend({ + + //arbitrary data to pass to fn + data: undefined, + + //call fn only on the first appear? + one: true + + }, options); + + return this.each(function() { + + var t = $(this); + + //whether the element is currently visible + t.appeared = false; + + if (!fn) { + + //trigger the custom event + t.trigger('appear', settings.data); + return; + } + + var w = $(window); + + //fires the appear event when appropriate + var check = function() { + + //is the element hidden? + if (!t.is(':visible')) { + + //it became hidden + t.appeared = false; + return; + } + + //is the element inside the visible window? + var a = w.scrollLeft(); + var b = w.scrollTop(); + var o = t.offset(); + var x = o.left; + var y = o.top; + + if (y + t.height() >= b && + y <= b + w.height() && + x + t.width() >= a && + x <= a + w.width()) { + + //trigger the custom event + if (!t.appeared) t.trigger('appear', settings.data); + + } else { + + //it scrolled out of view + t.appeared = false; + } + }; + + //create a modified fn with some additional logic + var modifiedFn = function() { + + //mark the element as visible + t.appeared = true; + + //is this supposed to happen only once? + if (settings.one) { + + //remove the check + w.unbind('scroll', check); + var i = $.inArray(check, $.fn.appear.checks); + if (i >= 0) $.fn.appear.checks.splice(i, 1); + } + + //trigger the original fn + fn.apply(this, arguments); + }; + + //bind the modified fn to the element + if (settings.one) t.one('appear', settings.data, modifiedFn); + else t.bind('appear', settings.data, modifiedFn); + + //check whenever the window scrolls + w.scroll(check); + + //check whenever the dom changes + $.fn.appear.checks.push(check); + + //check now + (check)(); + }); + }; + + //keep a queue of appearance checks + $.extend($.fn.appear, { + + checks: [], + timeout: null, + + //process the queue + checkAll: function() { + var length = $.fn.appear.checks.length; + if (length > 0) while (length--) ($.fn.appear.checks[length])(); + }, + + //check the queue asynchronously + run: function() { + if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout); + $.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20); + } + }); + + //run checks when these methods are called + $.each(['append', 'prepend', 'after', 'before', 'attr', + 'removeAttr', 'addClass', 'removeClass', 'toggleClass', + 'remove', 'css', 'show', 'hide'], function(i, n) { + var old = $.fn[n]; + if (old) { + $.fn[n] = function() { + var r = old.apply(this, arguments); + $.fn.appear.run(); + return r; + } + } + }); + +})(jQuery); \ No newline at end of file diff --git a/resources/jquery/jquery.async.js b/resources/jquery/jquery.async.js index 61493f71..2161f6b9 100644 --- a/resources/jquery/jquery.async.js +++ b/resources/jquery/jquery.async.js @@ -13,33 +13,28 @@ // opts.test : (default true) function to test in the while test part // opts.loop : (default empty) function to call in the while loop part // opts.end : (default empty) function to call at the end of the while loop -$.whileAsync = function(opts) -{ +$.whileAsync = function(opts) { var delay = Math.abs(opts.delay) || 10, bulk = isNaN(opts.bulk) ? 500 : Math.abs(opts.bulk), test = opts.test || function(){ return true; }, loop = opts.loop || function(){}, - end = opts.end || function(){}; + end = opts.end || function(){}; (function(){ var t = false, begin = new Date(); - while( t = test() ) - { + while( t = test() ) { loop(); - if( bulk === 0 || (new Date() - begin) > bulk ) - { + if( bulk === 0 || (new Date() - begin) > bulk ) { break; } } - if( t ) - { + if( t ) { setTimeout(arguments.callee, delay); } - else - { + else { end(); } @@ -50,17 +45,15 @@ $.whileAsync = function(opts) // opts.bulk : (default 500) delay during which the loop can continue synchronously without yielding the CPU // opts.loop : (default empty) function to call in the each loop part, signature: function(index, value) this = value // opts.end : (default empty) function to call at the end of the each loop -$.eachAsync = function(array, opts) -{ - var i = 0, +$.eachAsync = function(array, opts) { + var i = 0, l = array.length, loop = opts.loop || function(){}; $.whileAsync( $.extend(opts, { - test: function(){ return i < l; }, - loop: function() - { + test: function() { return i < l; }, + loop: function() { var val = array[i]; return loop.call(val, i++, val); } @@ -68,11 +61,9 @@ $.eachAsync = function(array, opts) ); }; -$.fn.eachAsync = function(opts) -{ +$.fn.eachAsync = function(opts) { $.eachAsync(this, opts); return this; } -})(jQuery); - +})(jQuery); \ No newline at end of file diff --git a/resources/jquery/jquery.autoEllipsis.js b/resources/jquery/jquery.autoEllipsis.js index 4993118d..7d726894 100644 --- a/resources/jquery/jquery.autoEllipsis.js +++ b/resources/jquery/jquery.autoEllipsis.js @@ -3,9 +3,9 @@ */ ( function( $ ) { -// Cache ellipsed substrings for every string-width combination +// Cache ellipsed substrings for every string-width-position combination var cache = { }; -// Use a seperate cache when match highlighting is enabled +// Use a separate cache when match highlighting is enabled var matchTextCache = { }; $.fn.autoEllipsis = function( options ) { @@ -17,29 +17,29 @@ $.fn.autoEllipsis = function( options ) { 'matchText': null }, options ); $(this).each( function() { - var $this = $(this); + var $el = $(this); if ( options.restoreText ) { - if ( ! $this.data( 'autoEllipsis.originalText' ) ) { - $this.data( 'autoEllipsis.originalText', $this.text() ); + if ( !$el.data( 'autoEllipsis.originalText' ) ) { + $el.data( 'autoEllipsis.originalText', $el.text() ); } else { - $this.text( $this.data( 'autoEllipsis.originalText' ) ); + $el.text( $el.data( 'autoEllipsis.originalText' ) ); } } // container element - used for measuring against - var $container = $this; + var $container = $el; // trimmable text element - only the text within this element will be trimmed var $trimmableText = null; // protected text element - the width of this element is counted, but next is never trimmed from it var $protectedText = null; if ( options.hasSpan ) { - $trimmableText = $this.children( options.selector ); + $trimmableText = $el.children( options.selector ); } else { $trimmableText = $( '' ) .css( 'whiteSpace', 'nowrap' ) - .text( $this.text() ); - $this + .text( $el.text() ); + $el .empty() .append( $trimmableText ); } @@ -49,27 +49,39 @@ $.fn.autoEllipsis = function( options ) { var w = $container.width(); var pw = $protectedText ? $protectedText.width() : 0; // Try cache - if ( !( text in cache ) ) { - cache[text] = {}; - } - if ( options.matchText && !( text in matchTextCache ) ) { - matchTextCache[text] = {}; - } - if ( options.matchText && !( options.matchText in matchTextCache[text] ) ) { - matchTextCache[text][options.matchText] = {}; - } - if ( !options.matchText && w in cache[text] ) { - $container.html( cache[text][w] ); - if ( options.tooltip ) - $container.attr( 'title', text ); - return; - } - if( options.matchText && options.matchText in matchTextCache[text] && w in matchTextCache[text][options.matchText] ) { - $container.html( matchTextCache[text][options.matchText][w] ); - if ( options.tooltip ) - $container.attr( 'title', text ); - return; + if ( options.matchText ) { + if ( !( text in matchTextCache ) ) { + matchTextCache[text] = {}; + } + if ( !( options.matchText in matchTextCache[text] ) ) { + matchTextCache[text][options.matchText] = {}; + } + if ( !( w in matchTextCache[text][options.matchText] ) ) { + matchTextCache[text][options.matchText][w] = {}; + } + if ( options.position in matchTextCache[text][options.matchText][w] ) { + $container.html( matchTextCache[text][options.matchText][w][options.position] ); + if ( options.tooltip ) { + $container.attr( 'title', text ); + } + return; + } + } else { + if ( !( text in cache ) ) { + cache[text] = {}; + } + if ( !( w in cache[text] ) ) { + cache[text][w] = {}; + } + if ( options.position in cache[text][w] ) { + $container.html( cache[text][w][options.position] ); + if ( options.tooltip ) { + $container.attr( 'title', text ); + } + return; + } } + if ( $trimmableText.width() + pw > w ) { switch ( options.position ) { case 'right': @@ -94,7 +106,7 @@ $.fn.autoEllipsis = function( options ) { while ( $trimmableText.outerWidth() + pw > w && i[0] > 0 ) { $trimmableText.text( trimmableText.substr( 0, i[0] ) + '...' + trimmableText.substr( i[1] ) ); // Alternate between trimming the end and begining - if ( side == 0 ) { + if ( side === 0 ) { // Make the begining shorter i[0]--; side = 1; @@ -120,9 +132,9 @@ $.fn.autoEllipsis = function( options ) { } if ( options.matchText ) { $container.highlightText( options.matchText ); - matchTextCache[text][options.matchText][w] = $container.html(); + matchTextCache[text][options.matchText][w][options.position] = $container.html(); } else { - cache[text][w] = $container.html(); + cache[text][w][options.position] = $container.html(); } } ); diff --git a/resources/jquery/jquery.byteLength.js b/resources/jquery/jquery.byteLength.js new file mode 100644 index 00000000..20fa5c8e --- /dev/null +++ b/resources/jquery/jquery.byteLength.js @@ -0,0 +1,19 @@ +/** + * jQuery.byteLength + * + * Calculate the byte length of a string (accounting for UTF-8). + * + * @author Jan Paul Posma + */ +jQuery.byteLength = function( str ) { + + // This basically figures out how many bytes a UTF-16 string (which is what js sees) + // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that. + // Note, surrogate (\uD800-\uDFFF) characters are counted as 2 bytes, since there's two of them + // and the actual character takes 4 bytes in UTF-8 (2*2=4). Might not work perfectly in + // edge cases such as illegal sequences, but that should never happen. + return str + .replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' ) + .replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' ) + .length; +} diff --git a/resources/jquery/jquery.byteLimit.js b/resources/jquery/jquery.byteLimit.js new file mode 100644 index 00000000..c1d26fc4 --- /dev/null +++ b/resources/jquery/jquery.byteLimit.js @@ -0,0 +1,56 @@ +/** + * jQuery byteLimit + * + * @author Jan Paul Posma + */ +( function( $ ) { + + /** + * Enforces a byte limit to a textbox, so that UTF-8 entries are not arbitrarily truncated. + */ + $.fn.byteLimit = function( limit ) { + + // Default to current attribute value + if ( limit == null ) { + limit = this.attr( 'maxLength' ); + + // If passed, update/set attribute value instead + } else { + this.attr( 'maxLength', limit ); + } + + // Nothing passed and/or empty attribute, return without binding an event. + if ( limit == null ) { + return this; + } + + // We've got something, go for it: + return this.keypress( function( e ) { + // First check to see if this is actually a character key + // being pressed. + // Based on key-event info from http://unixpapa.com/js/key.html + // jQuery should also normalize e.which to be consistent cross-browser, + // however the same check is still needed regardless of jQuery. + + // Note: At the moment, for some older opera versions (~< 10.5) + // some special keys won't be recognized (aka left arrow key). + // Backspace will be, so not big issue. + + if ( e.which === 0 || e.charCode === 0 || e.which === 8 || + e.ctrlKey || e.altKey || e.metaKey ) + { + return true; //a special key (backspace, etc) so don't interfere. + } + + var len = $.byteLength( this.value ); + // Note that keypress returns a character code point, not a keycode. + // However, this may not be super reliable depending on how keys come in... + var charLen = $.byteLength( String.fromCharCode( e.which ) ); + + if ( ( len + charLen ) > limit ) { + e.preventDefault(); + } + }); + }; + +} )( jQuery ); diff --git a/resources/jquery/jquery.checkboxShiftClick.js b/resources/jquery/jquery.checkboxShiftClick.js index b2fcb6ef..cfa696d4 100644 --- a/resources/jquery/jquery.checkboxShiftClick.js +++ b/resources/jquery/jquery.checkboxShiftClick.js @@ -7,22 +7,22 @@ * @license GPL v2 */ ( function( $ ) { -jQuery.fn.checkboxShiftClick = function( text ) { +$.fn.checkboxShiftClick = function( text ) { var prevCheckbox = null; var $box = this; // When our boxes are clicked.. - $box.click(function (e) { + $box.click( function( e ) { // And one has been clicked before... - if (prevCheckbox !== null && e.shiftKey) { + if ( prevCheckbox !== null && e.shiftKey ) { // Check or uncheck this one and all in-between checkboxes $box.slice( - Math.min($box.index(prevCheckbox), $box.index(e.target)), - Math.max($box.index(prevCheckbox), $box.index(e.target)) + 1 - ).attr({checked: e.target.checked ? 'checked' : ''}); + Math.min( $box.index( prevCheckbox ), $box.index( e.target ) ), + Math.max( $box.index( prevCheckbox ), $box.index( e.target ) ) + 1 + ).attr( {checked: e.target.checked ? 'checked' : ''} ); } // Either way, update the prevCheckbox variable to the one clicked now prevCheckbox = e.target; - }); + } ); return $box; }; } )( jQuery ); \ No newline at end of file diff --git a/resources/jquery/jquery.client.js b/resources/jquery/jquery.client.js index 4b9f580f..8082fa7d 100644 --- a/resources/jquery/jquery.client.js +++ b/resources/jquery/jquery.client.js @@ -1,206 +1,216 @@ -/* +/** * User-agent detection */ ( function( $ ) { -$.client = new ( function() { /* Private Members */ - var profile; - - /* Public Functions */ - /** - * Returns an object containing information about the browser - * - * The resulting client object will be in the following format: - * { - * 'name': 'firefox', - * 'layout': 'gecko', - * 'layoutVersion': '20101026', - * 'platform': 'linux' - * 'version': '3.5.1', - * 'versionBase': '3', - * 'versionNumber': 3.5, - * } + * @var profileCache {Object} Keyed by userAgent string, + * value is the parsed $.client.profile object for that user agent. */ - this.profile = function() { - // Use the cached version if possible - if ( typeof profile === 'undefined' ) { - - /* Configuration */ - - // Name of browsers or layout engines we don't recognize - var uk = 'unknown'; - // Generic version digit - var x = 'x'; - // Strings found in user agent strings that need to be conformed - var wildUserAgents = [ 'Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3']; - // Translations for conforming user agent strings - var userAgentTranslations = [ - // Tons of browsers lie about being something they are not - [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''], - // Chrome lives in the shadow of Safari still - ['Chrome Safari', 'Chrome'], - // KHTML is the layout engine not the browser - LIES! - ['KHTML', 'Konqueror'], - // Firefox nightly builds - ['Minefield', 'Firefox'], - // This helps keep differnt versions consistent - ['Navigator', 'Netscape'], - // This prevents version extraction issues, otherwise translation would happen later - ['PLAYSTATION 3', 'PS3'], - ]; - // Strings which precede a version number in a user agent string - combined and used as match 1 in - // version detectection - var versionPrefixes = [ - 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror', 'lynx', - 'msie', 'safari', 'ps3' - ]; - // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number - var versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)'; - // Names of known browsers - var names = [ - 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera', 'safari', 'ipod', - 'iphone', 'blackberry', 'ps3' - ]; - // Tanslations for conforming browser names - var nameTranslations = []; - // Names of known layout engines - var layouts = ['gecko', 'konqueror', 'msie', 'opera', 'webkit']; - // Translations for conforming layout names - var layoutTranslations = [['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto']]; - // Names of supported layout engines for version number - var layoutVersions = ['applewebkit', 'gecko']; - // Names of known operating systems - var platforms = ['win', 'mac', 'linux', 'sunos', 'solaris', 'iphone']; - // Translations for conforming operating system names - var platformTranslations = [['sunos', 'solaris']]; - - /* Methods */ - - // Performs multiple replacements on a string - function translate( source, translations ) { - for ( var i = 0; i < translations.length; i++ ) { - source = source.replace( translations[i][0], translations[i][1] ); - } - return source; - }; - - /* Pre-processing */ - - var userAgent = navigator.userAgent, match, name = uk, layout = uk, layoutversion = uk, platform = uk, version = x; - if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( userAgent ) ) { - // Takes a userAgent string and translates given text into something we can more easily work with - userAgent = translate( userAgent, userAgentTranslations ); + var profileCache = {}; + + /* Public Methods */ + + $.client = { + + /** + * Get an object containing information about the client. + * + * @param nav {Object} An object with atleast a 'userAgent' and 'platform' key.= + * Defaults to the global Navigator object. + * @return {Object} The resulting client object will be in the following format: + * { + * 'name': 'firefox', + * 'layout': 'gecko', + * 'layoutVersion': 20101026, + * 'platform': 'linux' + * 'version': '3.5.1', + * 'versionBase': '3', + * 'versionNumber': 3.5, + * } + */ + profile: function( nav ) { + if ( nav === undefined ) { + nav = window.navigator; } - // Everything will be in lowercase from now on - userAgent = userAgent.toLowerCase(); - - /* Extraction */ - - if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( userAgent ) ) { - name = translate( match[1], nameTranslations ); - } - if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( userAgent ) ) { - layout = translate( match[1], layoutTranslations ); - } - if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( navigator.userAgent.toLowerCase() ) ) { - layoutversion = parseInt(match[2]); - } - if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( navigator.platform.toLowerCase() ) ) { - platform = translate( match[1], platformTranslations ); - } - if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( userAgent ) ) { - version = match[3]; - } - - /* Edge Cases -- did I mention about how user agent string lie? */ - - // Decode Safari's crazy 400+ version numbers - if ( name.match( /safari/ ) && version > 400 ) { - version = '2.0'; + // Use the cached version if possible + if ( profileCache[nav.userAgent] === undefined ) { + + /* Configuration */ + + // Name of browsers or layout engines we don't recognize + var uk = 'unknown'; + // Generic version digit + var x = 'x'; + // Strings found in user agent strings that need to be conformed + var wildUserAgents = [ 'Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3']; + // Translations for conforming user agent strings + var userAgentTranslations = [ + // Tons of browsers lie about being something they are not + [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''], + // Chrome lives in the shadow of Safari still + ['Chrome Safari', 'Chrome'], + // KHTML is the layout engine not the browser - LIES! + ['KHTML', 'Konqueror'], + // Firefox nightly builds + ['Minefield', 'Firefox'], + // This helps keep differnt versions consistent + ['Navigator', 'Netscape'], + // This prevents version extraction issues, otherwise translation would happen later + ['PLAYSTATION 3', 'PS3'] + ]; + // Strings which precede a version number in a user agent string - combined and used as match 1 in + // version detectection + var versionPrefixes = [ + 'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror', 'lynx', + 'msie', 'safari', 'ps3' + ]; + // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number + var versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)'; + // Names of known browsers + var names = [ + 'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera', 'safari', 'ipod', + 'iphone', 'blackberry', 'ps3' + ]; + // Tanslations for conforming browser names + var nameTranslations = []; + // Names of known layout engines + var layouts = ['gecko', 'konqueror', 'msie', 'opera', 'webkit']; + // Translations for conforming layout names + var layoutTranslations = [['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto']]; + // Names of supported layout engines for version number + var layoutVersions = ['applewebkit', 'gecko']; + // Names of known operating systems + var platforms = ['win', 'mac', 'linux', 'sunos', 'solaris', 'iphone']; + // Translations for conforming operating system names + var platformTranslations = [['sunos', 'solaris']]; + + /* Methods */ + + // Performs multiple replacements on a string + var translate = function( source, translations ) { + for ( var i = 0; i < translations.length; i++ ) { + source = source.replace( translations[i][0], translations[i][1] ); + } + return source; + }; + + /* Pre-processing */ + + var ua = nav.userAgent, + match, + name = uk, + layout = uk, + layoutversion = uk, + platform = uk, + version = x; + + if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) { + // Takes a userAgent string and translates given text into something we can more easily work with + ua = translate( ua, userAgentTranslations ); + } + // Everything will be in lowercase from now on + ua = ua.toLowerCase(); + + /* Extraction */ + + if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) { + name = translate( match[1], nameTranslations ); + } + if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) { + layout = translate( match[1], layoutTranslations ); + } + if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) { + layoutversion = parseInt( match[2], 10 ); + } + if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) { + platform = translate( match[1], platformTranslations ); + } + if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) { + version = match[3]; + } + + /* Edge Cases -- did I mention about how user agent string lie? */ + + // Decode Safari's crazy 400+ version numbers + if ( name.match( /safari/ ) && version > 400 ) { + version = '2.0'; + } + // Expose Opera 10's lies about being Opera 9.8 + if ( name === 'opera' && version >= 9.8) { + version = ua.match( /version\/([0-9\.]*)/i )[1] || 10; + } + var versionNumber = parseFloat( version, 10 ) || 0.0; + + /* Caching */ + + profileCache[nav.userAgent] = { + 'name': name, + 'layout': layout, + 'layoutVersion': layoutversion, + 'platform': platform, + 'version': version, + 'versionBase': ( version !== x ? Math.floor( versionNumber ).toString() : x ), + 'versionNumber': versionNumber + }; } - // Expose Opera 10's lies about being Opera 9.8 - if ( name === 'opera' && version >= 9.8) { - version = userAgent.match( /version\/([0-9\.]*)/i )[1] || 10; + return profileCache[nav.userAgent]; + }, + + /** + * Checks the current browser against a support map object to determine if the browser has been black-listed or + * not. If the browser was not configured specifically it is assumed to work. It is assumed that the body + * element is classified as either "ltr" or "rtl". If neither is set, "ltr" is assumed. + * + * A browser map is in the following format: + * { + * 'ltr': { + * // Multiple rules with configurable operators + * 'msie': [['>=', 7], ['!=', 9]], + * // Blocked entirely + * 'iphone': false + * }, + * 'rtl': { + * // Test against a string + * 'msie': [['!==', '8.1.2.3']], + * // RTL rules do not fall through to LTR rules, you must explicity set each of them + * 'iphone': false + * } + * } + * + * @param map {Object} Browser support map + * @param profile {Object} (optional) a client-profile object. + * + * @return Boolean true if browser known or assumed to be supported, false if blacklisted + */ + test: function( map, profile ) { + profile = $.isPlainObject( profile ) ? profile : $.client.profile(); + + var dir = $( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'; + // Check over each browser condition to determine if we are running in a compatible client + if ( typeof map[dir] !== 'object' || typeof map[dir][profile.name] === 'undefined' ) { + // Unknown, so we assume it's working + return true; } - - /* Caching */ - - profile = { - 'name': name, - 'layout': layout, - 'layoutVersion': layoutversion, - 'platform': platform, - 'version': version, - 'versionBase': ( version !== x ? new String( version ).substr( 0, 1 ) : x ), - 'versionNumber': ( parseFloat( version, 10 ) || 0.0 ) - }; - } - return profile; - }; - - /** - * Checks the current browser against a support map object to determine if the browser has been black-listed or - * not. If the browser was not configured specifically it is assumed to work. It is assumed that the body - * element is classified as either "ltr" or "rtl". If neither is set, "ltr" is assumed. - * - * A browser map is in the following format: - * { - * 'ltr': { - * // Multiple rules with configurable operators - * 'msie': [['>=', 7], ['!=', 9]], - * // Blocked entirely - * 'iphone': false - * }, - * 'rtl': { - * // Test against a string - * 'msie': [['!==', '8.1.2.3']], - * // RTL rules do not fall through to LTR rules, you must explicity set each of them - * 'iphone': false - * } - * } - * - * @param map Object of browser support map - * - * @return Boolean true if browser known or assumed to be supported, false if blacklisted - */ - this.test = function( map ) { - var profile = jQuery.client.profile(); - var dir = jQuery( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'; - // Check over each browser condition to determine if we are running in a compatible client - if ( typeof map[dir] !== 'object' || typeof map[dir][profile.name] === 'undefined' ) { - // Unknown, so we assume it's working - return true; - } - var name = map[dir][profile.name]; - for ( var condition in name ) { - var op = name[condition][0]; - var val = name[condition][1]; - if ( val === false ) { - return false; - } else if ( typeof val == 'string' ) { - if ( !( eval( 'profile.version' + op + '"' + val + '"' ) ) ) { - return false; - } - } else if ( typeof val == 'number' ) { - if ( !( eval( 'profile.versionNumber' + op + val ) ) ) { + var conditions = map[dir][profile.name]; + for ( var i = 0; i < conditions.length; i++ ) { + var op = conditions[i][0]; + var val = conditions[i][1]; + if ( val === false ) { return false; + } else if ( typeof val == 'string' ) { + if ( !( eval( 'profile.version' + op + '"' + val + '"' ) ) ) { + return false; + } + } else if ( typeof val == 'number' ) { + if ( !( eval( 'profile.versionNumber' + op + val ) ) ) { + return false; + } } } + return true; } - return true; - } -} )(); - -$( document ).ready( function() { - var profile = $.client.profile(); - $( 'html' ) - .addClass( 'client-' + profile.name ) - .addClass( 'client-' + profile.name + '-' + profile.versionBase ) - .addClass( 'client-' + profile.layout ) - .addClass( 'client-' + profile.platform ); -} ); - + }; } )( jQuery ); diff --git a/resources/jquery/jquery.color.js b/resources/jquery/jquery.color.js index e1b0d0dd..b0419428 100644 --- a/resources/jquery/jquery.color.js +++ b/resources/jquery/jquery.color.js @@ -1,123 +1,44 @@ -/* +/** * jQuery Color Animations * Copyright 2007 John Resig * Released under the MIT and GPL licenses. + * + * - 2011-01-05: Modified by Krinkle to use the jQuery.colorUtil plugin (which has to be loaded first!) */ - -(function(jQuery){ +(function( $ ) { // We override the animation for all of these color styles - jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){ - jQuery.fx.step[attr] = function(fx){ - if ( fx.state == 0 ) { - fx.start = getColor( fx.elem, attr ); - fx.end = getRGB( fx.end ); + $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], + function( i, attr ) { + $.fx.step[attr] = function( fx ) { + if ( fx.state == 0 ) { + fx.start = getColor( fx.elem, attr ); + fx.end = $.colorUtil.getRGB( fx.end ); + } + + fx.elem.style[attr] = 'rgb(' + [ + Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), + Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), + Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0) + ].join( ',' ) + ')'; } - - fx.elem.style[attr] = "rgb(" + [ - Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), - Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), - Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0) - ].join(",") + ")"; } - }); - - // Color Conversion functions from highlightFade - // By Blair Mitchelmore - // http://jquery.offput.ca/highlightFade/ - - // Parse strings looking for color tuples [255,255,255] - function getRGB(color) { - var result; - - // Check if we're already dealing with an array of colors - if ( color && color.constructor == Array && color.length == 3 ) - return color; - - // Look for rgb(num,num,num) - if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) - return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])]; - - // Look for rgb(num%,num%,num%) - if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec(color)) - return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; - - // Look for #a0b1c2 - if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) - return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; - - // Look for #fff - if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) - return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; - - // Otherwise, we're most likely dealing with a named color - return colors[jQuery.trim(color).toLowerCase()]; - } + ); function getColor(elem, attr) { var color; do { - color = jQuery.curCSS(elem, attr); + color = $.curCSS(elem, attr); // Keep going until we find an element that has color, or we hit the body - if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") ) + if ( color != '' && color != 'transparent' || $.nodeName(elem, 'body') ) break; - attr = "backgroundColor"; + attr = 'backgroundColor'; } while ( elem = elem.parentNode ); - return getRGB(color); - }; - - // Some named colors to work with - // From Interface by Stefan Petre - // http://interface.eyecon.ro/ - - var colors = { - aqua:[0,255,255], - azure:[240,255,255], - beige:[245,245,220], - black:[0,0,0], - blue:[0,0,255], - brown:[165,42,42], - cyan:[0,255,255], - darkblue:[0,0,139], - darkcyan:[0,139,139], - darkgrey:[169,169,169], - darkgreen:[0,100,0], - darkkhaki:[189,183,107], - darkmagenta:[139,0,139], - darkolivegreen:[85,107,47], - darkorange:[255,140,0], - darkorchid:[153,50,204], - darkred:[139,0,0], - darksalmon:[233,150,122], - darkviolet:[148,0,211], - fuchsia:[255,0,255], - gold:[255,215,0], - green:[0,128,0], - indigo:[75,0,130], - khaki:[240,230,140], - lightblue:[173,216,230], - lightcyan:[224,255,255], - lightgreen:[144,238,144], - lightgrey:[211,211,211], - lightpink:[255,182,193], - lightyellow:[255,255,224], - lime:[0,255,0], - magenta:[255,0,255], - maroon:[128,0,0], - navy:[0,0,128], - olive:[128,128,0], - orange:[255,165,0], - pink:[255,192,203], - purple:[128,0,128], - violet:[128,0,128], - red:[255,0,0], - silver:[192,192,192], - white:[255,255,255], - yellow:[255,255,0] + return $.colorUtil.getRGB(color); }; -})(jQuery); +} )( jQuery ); diff --git a/resources/jquery/jquery.colorUtil.js b/resources/jquery/jquery.colorUtil.js new file mode 100644 index 00000000..1116aec6 --- /dev/null +++ b/resources/jquery/jquery.colorUtil.js @@ -0,0 +1,193 @@ +/** + * jQuery Color Utilities + * Written by Krinkle in 2011 + * Released under the MIT and GPL licenses. + * Mostly based on other plugins and functions (taken through JSLint and optimized a little). + * Sources cited locally. + */ +( function( $ ) { +$.colorUtil = { + + // Color Conversion function from highlightFade + // By Blair Mitchelmore + // http://jquery.offput.ca/highlightFade/ + // Parse strings looking for color tuples [255,255,255] + getRGB : function( color ) { + var result; + + // Check if we're already dealing with an array of colors + if ( color && color.constructor == Array && color.length == 3 ){ + return color; + } + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) { + return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; + } + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) { + return [parseFloat(result[1],10)*2.55, parseFloat(result[2],10)*2.55, parseFloat(result[3])*2.55]; + } + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) { + return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; + } + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) { + return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; + } + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) { + return $.colorUtil.colors.transparent; + } + + // Otherwise, we're most likely dealing with a named color + return $.colorUtil.colors[$.trim(color).toLowerCase()]; + }, + + // Some named colors to work with + // From Interface by Stefan Petre + // http://interface.eyecon.ro/ + colors: { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0], + transparent: [255,255,255] + }, + /** + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + * Converts an RGB color value to HSL. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes r, g, and b are contained in the set [0, 255] and + * returns h, s, and l in the set [0, 1]. + * + * @param Number R The red color value + * @param Number G The green color value + * @param Number B The blue color value + * @return Array The HSL representation + */ + rgbToHsl: function( R, G, B ) { + var r = R / 255, + g = G / 255, + b = B / 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min){ + h = s = 0; // achromatic + }else{ + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return [h, s, l]; + }, + /** + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ + hslToRgb: function( h, s, l ) { + var r, g, b; + + if(s === 0){ + r = g = b = l; // achromatic + }else{ + var hue2rgb = function(p, q, t){ + if(t < 0){ t += 1; } + if(t > 1){ t -= 1; } + if(t < 1/6){ return p + (q - p) * 6 * t; } + if(t < 1/2){ return q; } + if(t < 2/3){ return p + (q - p) * (2/3 - t) * 6; } + return p; + }; + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return [r * 255, g * 255, b * 255]; + }, + /** + * Get's a brighter or darker rgb() value string. + * + * @author Krinkle + * + * @example getCSSColorMod( 'red', +0.1 ) + * @example getCSSColorMod( 'rgb(200,50,50)', -0.2 ) + * + * @param Mixed currentColor current value in css + * @param Number mod wanted brightness modification between -1 and 1 + * @return String 'rgb(r,g,b)' + */ + getColorBrightness: function( currentColor, mod ) { + var rgbArr = $.colorUtil.getRGB( currentColor ), + hslArr = $.colorUtil.rgbToHsl(rgbArr[0], rgbArr[1], rgbArr[2] ); + rgbArr = $.colorUtil.hslToRgb(hslArr[0], hslArr[1], hslArr[2]+mod); + return 'rgb(' + + [parseInt( rgbArr[0], 10), parseInt( rgbArr[1], 10 ), parseInt( rgbArr[2], 10 )].join( ',' ) + + ')'; + } + +}; +} )( jQuery ); \ No newline at end of file diff --git a/resources/jquery/jquery.cookie.js b/resources/jquery/jquery.cookie.js index eaa254e5..79317f74 100644 --- a/resources/jquery/jquery.cookie.js +++ b/resources/jquery/jquery.cookie.js @@ -1,19 +1,15 @@ -/*jslint browser: true */ /*global jQuery: true */ - /** - * jQuery Cookie plugin + * Cookie plugin * - * Copyright (c) 2010 Klaus Hartl (stilbuero.de) + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ -// TODO JsDoc - /** - * Create a cookie with the given key and value and other optional parameters. + * Create a cookie with the given name and value and other optional parameters. * * @example $.cookie('the_cookie', 'the_value'); * @desc Set the value of a cookie. @@ -25,16 +21,16 @@ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain * used when the cookie was set. * - * @param key String The key of the cookie. - * @param value String The value of the cookie. - * @param options Object An object literal containing key/value pairs to provide optional cookie attributes. - * @option expires Number|Date Either an integer specifying the expiration date from now on in days or a Date object. + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. * If set to null or omitted, the cookie will be a session cookie and will not be retained * when the the browser exits. - * @option path String The value of the path atribute of the cookie (default: path of page that created the cookie). - * @option domain String The value of the domain attribute of the cookie (default: domain of page that created the cookie). - * @option secure Boolean If true, the secure attribute of the cookie will be set and the cookie transmission will + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will * require a secure protocol (like HTTPS). * @type undefined * @@ -44,12 +40,12 @@ */ /** - * Get the value of a cookie with the given key. + * Get the value of a cookie with the given name. * * @example $.cookie('the_cookie'); * @desc Get the value of a cookie. * - * @param key String The key of the cookie. + * @param String name The name of the cookie. * @return The value of the cookie. * @type String * @@ -57,33 +53,44 @@ * @cat Plugins/Cookie * @author Klaus Hartl/klaus.hartl@stilbuero.de */ -jQuery.cookie = function (key, value, options) { - - // key and value given, set cookie... - if (arguments.length > 1 && (value === null || typeof value !== "object")) { - options = jQuery.extend({}, options); - +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; if (value === null) { + value = ''; options.expires = -1; } - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE } - - return (document.cookie = [ - encodeURIComponent(key), '=', - options.raw ? String(value) : encodeURIComponent(String(value)), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); + // 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... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; } - - // key and possibly options given, get cookie... - options = value || {}; - var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; - return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; }; diff --git a/resources/jquery/jquery.form.js b/resources/jquery/jquery.form.js new file mode 100644 index 00000000..53c078f9 --- /dev/null +++ b/resources/jquery/jquery.form.js @@ -0,0 +1,791 @@ +/*! + * jQuery Form Plugin + * version: 2.52 (07-DEC-2010) + * @requires jQuery v1.3.2 or later + * + * Examples and documentation at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function($) { + +/* + Usage Note: + ----------- + Do not use both ajaxSubmit and ajaxForm on the same form. These + functions are intended to be exclusive. Use ajaxSubmit if you want + to bind your own submit handler to the form. For example, + + $(document).ready(function() { + $('#myForm').bind('submit', function(e) { + e.preventDefault(); // <-- important + $(this).ajaxSubmit({ + target: '#output' + }); + }); + }); + + Use ajaxForm when you want the plugin to manage all the event binding + for you. For example, + + $(document).ready(function() { + $('#myForm').ajaxForm({ + target: '#output' + }); + }); + + When using ajaxForm, the ajaxSubmit function will be invoked for you + at the appropriate time. +*/ + +/** + * ajaxSubmit() provides a mechanism for immediately submitting + * an HTML form using AJAX. + */ +$.fn.ajaxSubmit = function(options) { + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + if (typeof options == 'function') { + options = { success: options }; + } + + var action = this.attr('action'); + var url = (typeof action === 'string') ? $.trim(action) : ''; + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + url = url || window.location.href || ''; + + options = $.extend(true, { + url: url, + type: this.attr('method') || 'GET', + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var n,v,a = this.formToArray(options.semantic); + if (options.data) { + options.extraData = options.data; + for (n in options.data) { + if(options.data[n] instanceof Array) { + for (var k in options.data[n]) { + a.push( { name: n, value: options.data[n][k] } ); + } + } + else { + v = options.data[n]; + v = $.isFunction(v) ? v() : v; // if value is fn, invoke it + a.push( { name: n, value: v } ); + } + } + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a); + + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else { + options.data = q; // data is the query string for 'post' + } + + var $form = this, callbacks = []; + if (options.resetForm) { + callbacks.push(function() { $form.resetForm(); }); + } + if (options.clearForm) { + callbacks.push(function() { $form.clearForm(); }); + } + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + var fn = options.replaceTarget ? 'replaceWith' : 'html'; + $(options.target)[fn](data).each(oldSuccess, arguments); + }); + } + else if (options.success) { + callbacks.push(options.success); + } + + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg + var context = options.context || options; // jQuery 1.4+ supports scope context + for (var i=0, max=callbacks.length; i < max; i++) { + callbacks[i].apply(context, [data, status, xhr || $form, $form]); + } + }; + + // are there files to upload? + var fileInputs = $('input:file', this).length > 0; + var mp = 'multipart/form-data'; + var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) { + $.get(options.closeKeepAlive, fileUpload); + } + else { + fileUpload(); + } + } + else { + $.ajax(options); + } + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUpload() { + var form = $form[0]; + + if ($(':input[name=submit],:input[id=submit]', form).length) { + // if there is an input with a name or id of 'submit' then we won't be + // able to invoke the submit fn on the form (at least not x-browser) + alert('Error: Form elements must not have name or id of "submit".'); + return; + } + + var s = $.extend(true, {}, $.ajaxSettings, options); + s.context = s.context || s; + var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id; + window[fn] = function() { + var f = $io.data('form-plugin-onload'); + if (f) { + f(); + window[fn] = undefined; + try { delete window[fn]; } catch(e){} + } + }; + var $io = $('