]> git.mxchange.org Git - friendica.git/blob - view/theme/frio/frameworks/jquery-color/jquery.color.js
Merge remote-tracking branch 'upstream/develop' into develop
[friendica.git] / view / theme / frio / frameworks / jquery-color / jquery.color.js
1 /*!
2  * jQuery Color Animations v@VERSION
3  * https://github.com/jquery/jquery-color
4  *
5  * Copyright jQuery Foundation and other contributors
6  * Released under the MIT license.
7  * http://jquery.org/license
8  *
9  * Date: @DATE
10  */
11
12 (function( root, factory ) {
13         if ( typeof define === "function" && define.amd) {
14
15                 // AMD. Register as an anonymous module.
16                 define( [ "jquery" ], factory);
17         } else if ( typeof exports === "object" ) {
18                 module.exports = factory( require( "jquery" ) );
19         } else {
20                 factory( root.jQuery );
21         }
22 })( this, function( jQuery, undefined ) {
23
24         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
25
26         // plusequals test for += 100 -= 100
27         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
28         // a set of RE's that can match strings and generate color tuples.
29         stringParsers = [{
30                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
31                         parse: function( execResult ) {
32                                 return [
33                                         execResult[ 1 ],
34                                         execResult[ 2 ],
35                                         execResult[ 3 ],
36                                         execResult[ 4 ]
37                                 ];
38                         }
39                 }, {
40                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
41                         parse: function( execResult ) {
42                                 return [
43                                         execResult[ 1 ] * 2.55,
44                                         execResult[ 2 ] * 2.55,
45                                         execResult[ 3 ] * 2.55,
46                                         execResult[ 4 ]
47                                 ];
48                         }
49                 }, {
50                         // this regex ignores A-F because it's compared against an already lowercased string
51                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
52                         parse: function( execResult ) {
53                                 return [
54                                         parseInt( execResult[ 1 ], 16 ),
55                                         parseInt( execResult[ 2 ], 16 ),
56                                         parseInt( execResult[ 3 ], 16 )
57                                 ];
58                         }
59                 }, {
60                         // this regex ignores A-F because it's compared against an already lowercased string
61                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
62                         parse: function( execResult ) {
63                                 return [
64                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
65                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
66                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
67                                 ];
68                         }
69                 }, {
70                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
71                         space: "hsla",
72                         parse: function( execResult ) {
73                                 return [
74                                         execResult[ 1 ],
75                                         execResult[ 2 ] / 100,
76                                         execResult[ 3 ] / 100,
77                                         execResult[ 4 ]
78                                 ];
79                         }
80                 }],
81
82         // jQuery.Color( )
83         color = jQuery.Color = function( color, green, blue, alpha ) {
84                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
85         },
86         spaces = {
87                 rgba: {
88                         props: {
89                                 red: {
90                                         idx: 0,
91                                         type: "byte"
92                                 },
93                                 green: {
94                                         idx: 1,
95                                         type: "byte"
96                                 },
97                                 blue: {
98                                         idx: 2,
99                                         type: "byte"
100                                 }
101                         }
102                 },
103
104                 hsla: {
105                         props: {
106                                 hue: {
107                                         idx: 0,
108                                         type: "degrees"
109                                 },
110                                 saturation: {
111                                         idx: 1,
112                                         type: "percent"
113                                 },
114                                 lightness: {
115                                         idx: 2,
116                                         type: "percent"
117                                 }
118                         }
119                 }
120         },
121         propTypes = {
122                 "byte": {
123                         floor: true,
124                         max: 255
125                 },
126                 "percent": {
127                         max: 1
128                 },
129                 "degrees": {
130                         mod: 360,
131                         floor: true
132                 }
133         },
134         support = color.support = {},
135
136         // element for support tests
137         supportElem = jQuery( "<p>" )[ 0 ],
138
139         // colors = jQuery.Color.names
140         colors,
141
142         // local aliases of functions called often
143         each = jQuery.each;
144
145 // determine rgba support immediately
146 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
147 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
148
149 // define cache name and alpha properties
150 // for rgba and hsla spaces
151 each( spaces, function( spaceName, space ) {
152         space.cache = "_" + spaceName;
153         space.props.alpha = {
154                 idx: 3,
155                 type: "percent",
156                 def: 1
157         };
158 });
159
160 function clamp( value, prop, allowEmpty ) {
161         var type = propTypes[ prop.type ] || {};
162
163         if ( value == null ) {
164                 return (allowEmpty || !prop.def) ? null : prop.def;
165         }
166
167         // ~~ is an short way of doing floor for positive numbers
168         value = type.floor ? ~~value : parseFloat( value );
169
170         // IE will pass in empty strings as value for alpha,
171         // which will hit this case
172         if ( isNaN( value ) ) {
173                 return prop.def;
174         }
175
176         if ( type.mod ) {
177                 // we add mod before modding to make sure that negatives values
178                 // get converted properly: -10 -> 350
179                 return (value + type.mod) % type.mod;
180         }
181
182         // for now all property types without mod have min and max
183         return 0 > value ? 0 : type.max < value ? type.max : value;
184 }
185
186 function stringParse( string ) {
187         var inst = color(),
188                 rgba = inst._rgba = [];
189
190         string = string.toLowerCase();
191
192         each( stringParsers, function( i, parser ) {
193                 var parsed,
194                         match = parser.re.exec( string ),
195                         values = match && parser.parse( match ),
196                         spaceName = parser.space || "rgba";
197
198                 if ( values ) {
199                         parsed = inst[ spaceName ]( values );
200
201                         // if this was an rgba parse the assignment might happen twice
202                         // oh well....
203                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
204                         rgba = inst._rgba = parsed._rgba;
205
206                         // exit each( stringParsers ) here because we matched
207                         return false;
208                 }
209         });
210
211         // Found a stringParser that handled it
212         if ( rgba.length ) {
213
214                 // if this came from a parsed string, force "transparent" when alpha is 0
215                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
216                 if ( rgba.join() === "0,0,0,0" ) {
217                         jQuery.extend( rgba, colors.transparent );
218                 }
219                 return inst;
220         }
221
222         // named colors
223         return colors[ string ];
224 }
225
226 color.fn = jQuery.extend( color.prototype, {
227         parse: function( red, green, blue, alpha ) {
228                 if ( red === undefined ) {
229                         this._rgba = [ null, null, null, null ];
230                         return this;
231                 }
232                 if ( red.jquery || red.nodeType ) {
233                         red = jQuery( red ).css( green );
234                         green = undefined;
235                 }
236
237                 var inst = this,
238                         type = jQuery.type( red ),
239                         rgba = this._rgba = [];
240
241                 // more than 1 argument specified - assume ( red, green, blue, alpha )
242                 if ( green !== undefined ) {
243                         red = [ red, green, blue, alpha ];
244                         type = "array";
245                 }
246
247                 if ( type === "string" ) {
248                         return this.parse( stringParse( red ) || colors._default );
249                 }
250
251                 if ( type === "array" ) {
252                         each( spaces.rgba.props, function( key, prop ) {
253                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
254                         });
255                         return this;
256                 }
257
258                 if ( type === "object" ) {
259                         if ( red instanceof color ) {
260                                 each( spaces, function( spaceName, space ) {
261                                         if ( red[ space.cache ] ) {
262                                                 inst[ space.cache ] = red[ space.cache ].slice();
263                                         }
264                                 });
265                         } else {
266                                 each( spaces, function( spaceName, space ) {
267                                         var cache = space.cache;
268                                         each( space.props, function( key, prop ) {
269
270                                                 // if the cache doesn't exist, and we know how to convert
271                                                 if ( !inst[ cache ] && space.to ) {
272
273                                                         // if the value was null, we don't need to copy it
274                                                         // if the key was alpha, we don't need to copy it either
275                                                         if ( key === "alpha" || red[ key ] == null ) {
276                                                                 return;
277                                                         }
278                                                         inst[ cache ] = space.to( inst._rgba );
279                                                 }
280
281                                                 // this is the only case where we allow nulls for ALL properties.
282                                                 // call clamp with alwaysAllowEmpty
283                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
284                                         });
285
286                                         // everything defined but alpha?
287                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
288                                                 // use the default of 1
289                                                 inst[ cache ][ 3 ] = 1;
290                                                 if ( space.from ) {
291                                                         inst._rgba = space.from( inst[ cache ] );
292                                                 }
293                                         }
294                                 });
295                         }
296                         return this;
297                 }
298         },
299         is: function( compare ) {
300                 var is = color( compare ),
301                         same = true,
302                         inst = this;
303
304                 each( spaces, function( _, space ) {
305                         var localCache,
306                                 isCache = is[ space.cache ];
307                         if (isCache) {
308                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
309                                 each( space.props, function( _, prop ) {
310                                         if ( isCache[ prop.idx ] != null ) {
311                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
312                                                 return same;
313                                         }
314                                 });
315                         }
316                         return same;
317                 });
318                 return same;
319         },
320         _space: function() {
321                 var used = [],
322                         inst = this;
323                 each( spaces, function( spaceName, space ) {
324                         if ( inst[ space.cache ] ) {
325                                 used.push( spaceName );
326                         }
327                 });
328                 return used.pop();
329         },
330         transition: function( other, distance ) {
331                 var end = color( other ),
332                         spaceName = end._space(),
333                         space = spaces[ spaceName ],
334                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
335                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
336                         result = start.slice();
337
338                 end = end[ space.cache ];
339                 each( space.props, function( key, prop ) {
340                         var index = prop.idx,
341                                 startValue = start[ index ],
342                                 endValue = end[ index ],
343                                 type = propTypes[ prop.type ] || {};
344
345                         // if null, don't override start value
346                         if ( endValue === null ) {
347                                 return;
348                         }
349                         // if null - use end
350                         if ( startValue === null ) {
351                                 result[ index ] = endValue;
352                         } else {
353                                 if ( type.mod ) {
354                                         if ( endValue - startValue > type.mod / 2 ) {
355                                                 startValue += type.mod;
356                                         } else if ( startValue - endValue > type.mod / 2 ) {
357                                                 startValue -= type.mod;
358                                         }
359                                 }
360                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
361                         }
362                 });
363                 return this[ spaceName ]( result );
364         },
365         blend: function( opaque ) {
366                 // if we are already opaque - return ourself
367                 if ( this._rgba[ 3 ] === 1 ) {
368                         return this;
369                 }
370
371                 var rgb = this._rgba.slice(),
372                         a = rgb.pop(),
373                         blend = color( opaque )._rgba;
374
375                 return color( jQuery.map( rgb, function( v, i ) {
376                         return ( 1 - a ) * blend[ i ] + a * v;
377                 }));
378         },
379         toRgbaString: function() {
380                 var prefix = "rgba(",
381                         rgba = jQuery.map( this._rgba, function( v, i ) {
382                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
383                         });
384
385                 if ( rgba[ 3 ] === 1 ) {
386                         rgba.pop();
387                         prefix = "rgb(";
388                 }
389
390                 return prefix + rgba.join() + ")";
391         },
392         toHslaString: function() {
393                 var prefix = "hsla(",
394                         hsla = jQuery.map( this.hsla(), function( v, i ) {
395                                 if ( v == null ) {
396                                         v = i > 2 ? 1 : 0;
397                                 }
398
399                                 // catch 1 and 2
400                                 if ( i && i < 3 ) {
401                                         v = Math.round( v * 100 ) + "%";
402                                 }
403                                 return v;
404                         });
405
406                 if ( hsla[ 3 ] === 1 ) {
407                         hsla.pop();
408                         prefix = "hsl(";
409                 }
410                 return prefix + hsla.join() + ")";
411         },
412         toHexString: function( includeAlpha ) {
413                 var rgba = this._rgba.slice(),
414                         alpha = rgba.pop();
415
416                 if ( includeAlpha ) {
417                         rgba.push( ~~( alpha * 255 ) );
418                 }
419
420                 return "#" + jQuery.map( rgba, function( v ) {
421
422                         // default to 0 when nulls exist
423                         v = ( v || 0 ).toString( 16 );
424                         return v.length === 1 ? "0" + v : v;
425                 }).join("");
426         },
427         toString: function() {
428                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
429         }
430 });
431 color.fn.parse.prototype = color.fn;
432
433 // hsla conversions adapted from:
434 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
435
436 function hue2rgb( p, q, h ) {
437         h = ( h + 1 ) % 1;
438         if ( h * 6 < 1 ) {
439                 return p + (q - p) * h * 6;
440         }
441         if ( h * 2 < 1) {
442                 return q;
443         }
444         if ( h * 3 < 2 ) {
445                 return p + (q - p) * ((2/3) - h) * 6;
446         }
447         return p;
448 }
449
450 spaces.hsla.to = function ( rgba ) {
451         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
452                 return [ null, null, null, rgba[ 3 ] ];
453         }
454         var r = rgba[ 0 ] / 255,
455                 g = rgba[ 1 ] / 255,
456                 b = rgba[ 2 ] / 255,
457                 a = rgba[ 3 ],
458                 max = Math.max( r, g, b ),
459                 min = Math.min( r, g, b ),
460                 diff = max - min,
461                 add = max + min,
462                 l = add * 0.5,
463                 h, s;
464
465         if ( min === max ) {
466                 h = 0;
467         } else if ( r === max ) {
468                 h = ( 60 * ( g - b ) / diff ) + 360;
469         } else if ( g === max ) {
470                 h = ( 60 * ( b - r ) / diff ) + 120;
471         } else {
472                 h = ( 60 * ( r - g ) / diff ) + 240;
473         }
474
475         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
476         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
477         if ( diff === 0 ) {
478                 s = 0;
479         } else if ( l <= 0.5 ) {
480                 s = diff / add;
481         } else {
482                 s = diff / ( 2 - add );
483         }
484         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
485 };
486
487 spaces.hsla.from = function ( hsla ) {
488         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
489                 return [ null, null, null, hsla[ 3 ] ];
490         }
491         var h = hsla[ 0 ] / 360,
492                 s = hsla[ 1 ],
493                 l = hsla[ 2 ],
494                 a = hsla[ 3 ],
495                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
496                 p = 2 * l - q;
497
498         return [
499                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
500                 Math.round( hue2rgb( p, q, h ) * 255 ),
501                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
502                 a
503         ];
504 };
505
506
507 each( spaces, function( spaceName, space ) {
508         var props = space.props,
509                 cache = space.cache,
510                 to = space.to,
511                 from = space.from;
512
513         // makes rgba() and hsla()
514         color.fn[ spaceName ] = function( value ) {
515
516                 // generate a cache for this space if it doesn't exist
517                 if ( to && !this[ cache ] ) {
518                         this[ cache ] = to( this._rgba );
519                 }
520                 if ( value === undefined ) {
521                         return this[ cache ].slice();
522                 }
523
524                 var ret,
525                         type = jQuery.type( value ),
526                         arr = ( type === "array" || type === "object" ) ? value : arguments,
527                         local = this[ cache ].slice();
528
529                 each( props, function( key, prop ) {
530                         var val = arr[ type === "object" ? key : prop.idx ];
531                         if ( val == null ) {
532                                 val = local[ prop.idx ];
533                         }
534                         local[ prop.idx ] = clamp( val, prop );
535                 });
536
537                 if ( from ) {
538                         ret = color( from( local ) );
539                         ret[ cache ] = local;
540                         return ret;
541                 } else {
542                         return color( local );
543                 }
544         };
545
546         // makes red() green() blue() alpha() hue() saturation() lightness()
547         each( props, function( key, prop ) {
548                 // alpha is included in more than one space
549                 if ( color.fn[ key ] ) {
550                         return;
551                 }
552                 color.fn[ key ] = function( value ) {
553                         var vtype = jQuery.type( value ),
554                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
555                                 local = this[ fn ](),
556                                 cur = local[ prop.idx ],
557                                 match;
558
559                         if ( vtype === "undefined" ) {
560                                 return cur;
561                         }
562
563                         if ( vtype === "function" ) {
564                                 value = value.call( this, cur );
565                                 vtype = jQuery.type( value );
566                         }
567                         if ( value == null && prop.empty ) {
568                                 return this;
569                         }
570                         if ( vtype === "string" ) {
571                                 match = rplusequals.exec( value );
572                                 if ( match ) {
573                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
574                                 }
575                         }
576                         local[ prop.idx ] = value;
577                         return this[ fn ]( local );
578                 };
579         });
580 });
581
582 // add cssHook and .fx.step function for each named hook.
583 // accept a space separated string of properties
584 color.hook = function( hook ) {
585         var hooks = hook.split( " " );
586         each( hooks, function( i, hook ) {
587                 jQuery.cssHooks[ hook ] = {
588                         set: function( elem, value ) {
589                                 var parsed, curElem,
590                                         backgroundColor = "";
591
592                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
593                                         value = color( parsed || value );
594                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
595                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
596                                                 while (
597                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
598                                                         curElem && curElem.style
599                                                 ) {
600                                                         try {
601                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
602                                                                 curElem = curElem.parentNode;
603                                                         } catch ( e ) {
604                                                         }
605                                                 }
606
607                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
608                                                         backgroundColor :
609                                                         "_default" );
610                                         }
611
612                                         value = value.toRgbaString();
613                                 }
614                                 try {
615                                         elem.style[ hook ] = value;
616                                 } catch( e ) {
617                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
618                                 }
619                         }
620                 };
621                 jQuery.fx.step[ hook ] = function( fx ) {
622                         if ( !fx.colorInit ) {
623                                 fx.start = color( fx.elem, hook );
624                                 fx.end = color( fx.end );
625                                 fx.colorInit = true;
626                         }
627                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
628                 };
629         });
630
631 };
632
633 color.hook( stepHooks );
634
635 jQuery.cssHooks.borderColor = {
636         expand: function( value ) {
637                 var expanded = {};
638
639                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
640                         expanded[ "border" + part + "Color" ] = value;
641                 });
642                 return expanded;
643         }
644 };
645
646 // Basic color names only.
647 // Usage of any of the other color names requires adding yourself or including
648 // jquery.color.svg-names.js.
649 colors = jQuery.Color.names = {
650         // 4.1. Basic color keywords
651         aqua: "#00ffff",
652         black: "#000000",
653         blue: "#0000ff",
654         fuchsia: "#ff00ff",
655         gray: "#808080",
656         green: "#008000",
657         lime: "#00ff00",
658         maroon: "#800000",
659         navy: "#000080",
660         olive: "#808000",
661         purple: "#800080",
662         red: "#ff0000",
663         silver: "#c0c0c0",
664         teal: "#008080",
665         white: "#ffffff",
666         yellow: "#ffff00",
667
668         // 4.2.3. "transparent" color keyword
669         transparent: [ null, null, null, 0 ],
670
671         _default: "#ffffff"
672 };
673
674 });