├── .gitattributes
├── .gitignore
├── tests
├── unit
│ ├── boxsizing.js
│ ├── columns.js
│ ├── boxreflect.js
│ ├── borderimage.js
│ ├── transform.js
│ ├── color.js
│ ├── transition.js
│ ├── bgpos.js
│ ├── gradients.js
│ ├── marginpadding.js
│ ├── borderradius.js
│ ├── userinterface.js
│ ├── borderradiusalt.js
│ ├── boxshadow.js
│ └── textshadow.js
├── qunit
│ ├── qunit.css
│ └── qunit.js
└── index.html
├── boxsizing.js
├── boxreflect.js
├── borderimage.js
├── marginpadding.js
├── LICENSE.txt
├── columns.js
├── transition.js
├── userinterface.js
├── textshadow.js
├── README.md
├── bgpos.js
├── borderradius.js
├── gradients.js
├── boxshadow.js
├── skeleton.js
├── border-radius.htc
├── borderradiusalt.js
├── color.js
└── transform.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | * crlf=input
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.diff
3 | *.patch
4 |
--------------------------------------------------------------------------------
/tests/unit/boxsizing.js:
--------------------------------------------------------------------------------
1 | module("boxSizing");
2 |
3 | test("boxSizing", 2, function() {
4 | equals( jQuery("#test").css("boxSizing"), "border-box", "returns correct value" );
5 | equals( jQuery("#test").css("boxSizing","content-box").css("boxSizing"), "content-box", "sets and gets correct value" );
6 | });
--------------------------------------------------------------------------------
/tests/unit/columns.js:
--------------------------------------------------------------------------------
1 | module("Multiplecolumns");
2 |
3 | test("columnCount", 2, function() {
4 | equals( jQuery("#test").css("columnCount"), "2", "returns correct value" );
5 | equals( jQuery("#test").css("columnCount", "4").css("columnCount"), "4", "sets and retrieves new property" );
6 | });
7 |
--------------------------------------------------------------------------------
/tests/unit/boxreflect.js:
--------------------------------------------------------------------------------
1 | module("boxreflect");
2 |
3 | test("boxReflect", 2, function() {
4 | equals( jQuery("#test").css("boxReflect"), "below 3px none", "returns correct value" );
5 | equals( jQuery("#test").css('boxReflect', 'above 3px').css("boxReflect"), "above 3px none", "sets and retrieves new property" );
6 | });
--------------------------------------------------------------------------------
/tests/unit/borderimage.js:
--------------------------------------------------------------------------------
1 | module("borderImage");
2 |
3 | test("borderImage", 2, function() {
4 | ok( /^url(.*) 27 27 27 27 round round$/i.test( jQuery("#test").css("borderImage") ) , "returns correct value" );
5 | ok( /^url(.*) 30 27 30 27 round round$/i.test( jQuery("#test").css("borderImage", "url(border.png) 30 27 30 27 round round").css("borderImage") ) , "sets and returns correct value" );
6 | });
--------------------------------------------------------------------------------
/tests/unit/transform.js:
--------------------------------------------------------------------------------
1 | module("transform");
2 |
3 | test("transform", 1, function() {
4 | var $test = jQuery("#test");
5 | // clear transforms in IE
6 | $test[0].style.filter = "";
7 | // clear transforms in other browsers
8 | $test[0].setAttribute('style', '');
9 | $test.css('transform', 'rotate(90deg) scale(2) translateX(100px)');
10 | ok( ~jQuery("#test").css("transform").indexOf('matrix'), "computed matrix is not 'none'" );
11 | });
12 |
--------------------------------------------------------------------------------
/boxsizing.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Box Sizing cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | * Licensed under the MIT License (LICENSE.txt).
7 | */
8 | (function($) {
9 |
10 | var div = document.createElement("div"),
11 | divStyle = div.style;
12 |
13 | $.support.boxSizing =
14 | divStyle.boxSizing === ''? 'boxSizing' :
15 | (divStyle.MozBoxSizing === ''? 'MozBoxSizing' :
16 | (divStyle.WebkitBoxSizing === ''? 'WebkitBoxSizing' :
17 | (divStyle.MsBoxSizing === ''? 'msBoxSizing' : false)));
18 |
19 | if ( $.support.boxSizing && $.support.boxSizing !== "boxSizing" ){
20 |
21 | $.cssHooks.boxSizing = {
22 | get: function( elem, computed, extra ) {
23 | return $.css(elem, $.support.boxSizing);
24 | },
25 | set: function( elem, value ) {
26 | elem.style[ $.support.boxSizing ] = value;
27 | }
28 | };
29 | }
30 |
31 | div = divStyle = null;
32 |
33 | })(jQuery);
--------------------------------------------------------------------------------
/boxreflect.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Box Reflect cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | - Doesn't currently support gradients
7 | * Licensed under the MIT License (LICENSE.txt).
8 | */
9 | (function($) {
10 | var div = document.createElement('div'),
11 | divStyle = div.style;
12 |
13 | $.support.boxReflect =
14 | divStyle.boxReflect === '' ? 'boxReflect' :
15 | (divStyle.MozBoxReflect === '' ? 'MozBoxReflect' :
16 | (divStyle.WebkitBoxReflect === '' ? 'WebkitBoxReflect' :
17 | (divStyle.OBoxReflect === '' ? 'OBoxReflect' : false)));
18 |
19 | if ( $.support.boxReflect && $.support.boxReflect !== 'boxReflect' ) {
20 |
21 | $.cssHooks.boxReflect = {
22 | get: function( elem, computed, extra ) {
23 | return $.css( elem, $.support.boxReflect );
24 | },
25 | set: function( elem, value ) {
26 | elem.style[$.support.boxReflect] = value;
27 | }
28 | };
29 | }
30 | div = divStyle = null;
31 |
32 | })(jQuery);
--------------------------------------------------------------------------------
/borderimage.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Border Image cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | - Doesn't work in all CSS3 browers (currently)
7 | * Licensed under the MIT License (LICENSE.txt).
8 | */
9 | (function($) {
10 |
11 | var div = document.createElement( "div" ),
12 | divStyle = div.style;
13 |
14 | $.support.borderImage =
15 | divStyle.borderImage === '' ? 'borderImage' :
16 | (divStyle.MozBorderImage === '' ? 'MozBorderImage' :
17 | (divStyle.WebkitBorderImage === '' ? 'WebkitBorderImage' : false));
18 |
19 | if ( $.support.borderImage && $.support.borderImage !== "borderImage" ) {
20 | $.cssHooks.borderImage = {
21 | get: function( elem, computed, extra ) {
22 | return $.css(elem, $.support.borderImage);
23 | },
24 | set: function( elem, value ) {
25 | elem.style[$.support.borderImage] = value;
26 | }
27 | };
28 | }
29 |
30 | div = divStyle = null;
31 |
32 | })(jQuery)
--------------------------------------------------------------------------------
/marginpadding.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | */
4 | (function($) {
5 | // padding and margin get hooks
6 | var dirs = "Top Right Bottom Left".split(" ");
7 | $.each(["margin", "padding"], function( i, hook ) {
8 | $.cssHooks[ hook ] = {
9 | get: function( elem, computed, extra ) {
10 | return $.map(dirs, function( dir ) {
11 | return $.css( elem, hook + dir );
12 | }).join(" ");
13 | },
14 | set: function( elem, value ) {
15 | var parts = value.split(/\s/),
16 | values = {
17 | "Top": parts[0],
18 | "Right": parts[1] || parts[0],
19 | "Bottom": parts[2] || parts[0],
20 | "Left": parts[3] || parts[1] || parts[0]
21 | };
22 | $.each(dirs, function( i, dir ) {
23 | elem.style[ hook + dir ] = values[ dir ];
24 | });
25 | }
26 | };
27 | });
28 | })(jQuery);
29 |
--------------------------------------------------------------------------------
/tests/unit/color.js:
--------------------------------------------------------------------------------
1 | module("color");
2 |
3 | test("Basic getting & setting", 10, function() {
4 | equals( jQuery("#test").css("color"), "rgb(0, 0, 0)", "returns just the color" );
5 | equals( jQuery("#test").css("color", "rgb(100, 150, 200)").css("color"), "rgb(100, 150, 200)", "sets the color properly" );
6 | equals( jQuery("#test").css("color", "#bada55").css("color"), "rgb(186, 218, 85)", "sets the color properly" );
7 | equals( jQuery("#test").css("color", "red").css("color"), "rgb(255, 0, 0)", "sets the color properly" );
8 | equals( jQuery("#test").css("color", "lawngreen").css("color"), "rgb(124, 252, 0)", "sets the color properly" );
9 | equals( jQuery("#test").css("color", "rgba(0, 0, 0, 0.3)").css("color"), "rgba(0, 0, 0, 0.3)", "sets the color properly" );
10 | equals( jQuery("#test").css("color", "rgba(0, 255, 0, 0.5)").css("color"), "rgba(0, 255, 0, 0.5)", "sets the color properly" );
11 | equals( jQuery("#test").css("color", "rgb(33%, 66%, 99%)").css("color"), "rgb(84, 168, 252)", "sets the color properly" );
12 | equals( jQuery("#test").css("color", "hsl(75%, 50%, 25%)").css("color"), "rgb(63, 31, 95)", "sets the color properly" );
13 | equals( jQuery("#test").css("color", "hsla(10%, 20%, 30%, 0.4)").css("color"), "rgba(91, 79, 61, 0.4)", "sets the color properly" );
14 | });
--------------------------------------------------------------------------------
/tests/unit/transition.js:
--------------------------------------------------------------------------------
1 | module("transition");
2 |
3 | test("transition", 2, function() {
4 | equals( jQuery("#test").css("transition"), "border 1s cubic-bezier(0, 0, 1, 1)", "returns values in the correct order" );
5 | equals( jQuery("#test").css("transition", "color 2s ease-in").css("transition"), "color 2s cubic-bezier(0.42, 0, 1, 1)", "sets the values properly" );
6 | });
7 |
8 | test("transitionProperty", 2, function() {
9 | equals( jQuery("#test").css("transitionProperty"), "border", "returns proper value" );
10 | equals( jQuery("#test").css("transitionProperty", "color").css("transitionProperty"), "color", "sets the values properly" );
11 | });
12 |
13 | test("transitionDuration", 2, function() {
14 | equals( jQuery("#test").css("transitionDuration"), "1s", "returns proper value" );
15 | equals( jQuery("#test").css("transitionDuration", "2s").css("transitionDuration"), "2s", "sets the values properly" );
16 | });
17 |
18 | test("transitionTimingFunction", 2, function() {
19 | equals( jQuery("#test").css("transitionTimingFunction"), "cubic-bezier(0, 0, 1, 1)", "returns proper value" );
20 | equals( jQuery("#test").css("transitionTimingFunction", "ease-in").css("transitionTimingFunction"), "cubic-bezier(0.42, 0, 1, 1)", "sets the values properly" );
21 | });
22 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2011 Brandon Aaron (http://brandonaaron.net), Burin Asavesna (http://helloburin.com), Tom Ellis (http://www.webmuse.co.uk),
2 | Phil Dokas (http://jetless.org) and Louis-Rémi Babé (http://twitter.com/louis_remi).
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/unit/bgpos.js:
--------------------------------------------------------------------------------
1 | module("backgroundPosition");
2 |
3 | test("backgroundPosition", 2, function() {
4 | equals( jQuery("#test").css("backgroundPosition"), "3px 5px", "returns values in the correct order" );
5 | equals( jQuery("#test").css("backgroundPosition", "1px 2px").css("backgroundPosition"), "1px 2px", "sets the values properly" );
6 | });
7 |
8 | test("backgroundPositionX", 3, function() {
9 | equals( jQuery("#test").css("backgroundPositionX"), "3px", "returns proper value" );
10 | equals( jQuery("#test").css("backgroundPositionX", "1px").css("backgroundPositionX"), "1px", "sets the value properly" );
11 | stop();
12 | jQuery("#test").animate({ backgroundPositionX: 10 }, 100, function() {
13 | equals( jQuery("#test").css("backgroundPositionX"), "10px", "animates the value properly" );
14 | start();
15 | });
16 | });
17 |
18 | test("backgroundPositionY", 3, function() {
19 | equals( jQuery("#test").css("backgroundPositionY"), "5px", "returns proper value" );
20 | equals( jQuery("#test").css("backgroundPositionY", "1px").css("backgroundPositionY"), "1px", "sets the value properly" );
21 | stop();
22 | jQuery("#test").animate({ backgroundPositionY: 10 }, 100, function() {
23 | equals( jQuery("#test").css("backgroundPositionY"), "10px", "animates the value properly" );
24 | start();
25 | });
26 | });
27 |
28 |
--------------------------------------------------------------------------------
/tests/unit/gradients.js:
--------------------------------------------------------------------------------
1 | module("gradient");
2 |
3 | test("linearGradient", 3, function() {
4 | ok( /linear-gradient/i.test( jQuery("#test2").css("backgroundImage", "linear-gradient(top, blue, red)").css("backgroundImage") ) , "returns correct value using colour names" );
5 | ok( /linear-gradient/i.test( jQuery("#test2").css("backgroundImage", "linear-gradient(top, rgb(0,0,225), rgb(255,0,0))").css("backgroundImage") ) , "returns correct value using rgb values" );
6 | ok( /linear-gradient/i.test( jQuery("#test2").css("backgroundImage", "linear-gradient(top, hsl(240,100%, 50%), hsl(0,100%, 50%))").css("backgroundImage") ) , "returns correct value using hsl values" );
7 | });
8 |
9 | test("radialGradient", 3, function() {
10 | jQuery("#test").css("backgroundImage", "radial-gradient(50% 50%, circle, red, blue)");
11 | ok( /radial-gradient/i.test( jQuery("#test2").css("backgroundImage","radial-gradient(50% 50%, circle, grey, blue)").css("backgroundImage") ) , "returns correct value using colour names" );
12 | ok( /radial-gradient/i.test( jQuery("#test2").css("backgroundImage", "radial-gradient(50% 50%, circle, top, rgb(0,0,225), rgb(255,0,0))").css("backgroundImage") ) , "returns correct value using rgb colours" );
13 | ok( /radial-gradient/i.test( jQuery("#test2").css("backgroundImage", "radial-gradient(50% 50%, circle, top, hsl(240,100%, 50%), hsl(0,100%, 50%))").css("backgroundImage") ) , "returns correct value using rgb colours" );
14 | });
--------------------------------------------------------------------------------
/tests/unit/marginpadding.js:
--------------------------------------------------------------------------------
1 | module("marginpadding");
2 |
3 | test("margin", 5, function() {
4 | equals( jQuery("#test").css("margin"), "1px 2px 3px 4px", "returns values in the correct order" );
5 | equals( jQuery("#test").css("margin", "4px 3px 2px 1px").css("margin"), "4px 3px 2px 1px", "sets the top, right, bottom, left values properly" );
6 | equals( jQuery("#test").css("margin", "5px 6px 7px").css("margin"), "5px 6px 7px 6px", "sets the top, right & left, bottom values properly" );
7 | equals( jQuery("#test").css("margin", "8px 9px").css("margin"), "8px 9px 8px 9px", "sets the top & bottom, left & right values properly" );
8 | equals( jQuery("#test").css("margin", "1px").css("margin"), "1px 1px 1px 1px", "sets all the values properly" );
9 | });
10 |
11 | test("padding", 5, function() {
12 | equals( jQuery("#test").css("padding"), "1px 2px 3px 4px", "returns values in the correct order" );
13 | equals( jQuery("#test").css("padding", "4px 3px 2px 1px").css("padding"), "4px 3px 2px 1px", "sets the top, right, bottom, left values properly" );
14 | equals( jQuery("#test").css("padding", "5px 6px 7px").css("padding"), "5px 6px 7px 6px", "sets the top, right & left, bottom values properly" );
15 | equals( jQuery("#test").css("padding", "8px 9px").css("padding"), "8px 9px 8px 9px", "sets the top & bottom, left & right values properly" );
16 | equals( jQuery("#test").css("padding", "1px").css("padding"), "1px 1px 1px 1px", "sets all the values properly" );
17 | });
18 |
19 |
--------------------------------------------------------------------------------
/columns.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Columns cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | * Licensed under the MIT License (LICENSE.txt).
7 | */
8 | (function($) {
9 |
10 | var div = document.createElement("div"),
11 | divStyle = div.style,
12 | rWhitespace = /\s/,
13 | column = "Column",
14 | props = "Span Count Gap Width RuleColor RuleStyle RuleWidth".split(rWhitespace),
15 | prefix = divStyle.WebkitColumnGap === ''? 'Webkit' : (divStyle.MozColumnGap === '' ? 'Moz' : ''),
16 | getCssProperty = function( prefix, prop ) {
17 | return prefix + ( (prefix === '') ? column.toLowerCase() : column ) + prop;
18 | };
19 |
20 | $.support.columnCount =
21 | divStyle.columnCount === '' ? 'columnCount' :
22 | (divStyle.MozColumnCount === ''? 'MozColumnCount' :
23 | (divStyle.WebkitColumnCount === ''? 'WebkitColumnCount' : false));
24 |
25 | if ( $.support.columnCount && $.support.columnCount !== "columnCount" ) {
26 |
27 | $.each(props, function( i, prop ) {
28 |
29 | $.cssHooks["column" + prop ] = {
30 | get: function( elem, computed, extra ) {
31 | return $.css(elem, getCssProperty( prefix, prop ) );
32 | },
33 | set: function( elem, value ) {
34 | elem.style[ getCssProperty( prefix, prop ) ] = value;
35 | }
36 | };
37 |
38 | });
39 | }
40 |
41 | div = divStyle = null;
42 |
43 | })(jQuery);
--------------------------------------------------------------------------------
/tests/unit/borderradius.js:
--------------------------------------------------------------------------------
1 | module("borderRadius");
2 |
3 | test("borderRadius", 3, function() {
4 | equals( jQuery("#test").css("borderRadius"), "5px 5px 5px 5px", "returns values in the correct order" );
5 | equals( jQuery("#test").css("borderRadius", "3px").css("borderRadius"), "3px 3px 3px 3px", "sets the values properly with 1 value" );
6 | equals( jQuery("#test").css("borderRadius", "3px 0 0 3px").css("borderRadius"), "3px 0px 0px 3px", "sets the values properly with multiple values" );
7 | });
8 |
9 | test("borderRadiusTopLeft", 2, function() {
10 | equals( jQuery("#test").css("borderRadiusTopLeft"), "5px", "returns values in the correct order" );
11 | equals( jQuery("#test").css("borderRadiusTopLeft", "3px").css("borderRadiusTopLeft"), "3px", "sets the values properly" );
12 | });
13 |
14 | test("borderRadiusTopRight", 2, function() {
15 | equals( jQuery("#test").css("borderRadiusTopRight"), "5px", "returns values in the correct order" );
16 | equals( jQuery("#test").css("borderRadiusTopRight", "3px").css("borderRadiusTopRight"), "3px", "sets the values properly" );
17 | });
18 |
19 | test("borderRadiusBottomRight", 2, function() {
20 | equals( jQuery("#test").css("borderRadiusBottomRight"), "5px", "returns values in the correct order" );
21 | equals( jQuery("#test").css("borderRadiusBottomRight", "3px").css("borderRadiusBottomRight"), "3px", "sets the values properly" );
22 | });
23 |
24 | test("borderRadiusBottomLeft", 2, function() {
25 | equals( jQuery("#test").css("borderRadiusBottomLeft"), "5px", "returns values in the correct order" );
26 | equals( jQuery("#test").css("borderRadiusBottomLeft", "3px").css("borderRadiusBottomLeft"), "3px", "sets the values properly" );
27 | });
--------------------------------------------------------------------------------
/tests/unit/userinterface.js:
--------------------------------------------------------------------------------
1 | module("User Interface");
2 |
3 | test("userSelect", 6, function() {
4 | equals( jQuery("#test").css("userSelect"), "none", "returns correct value" );
5 | equals( jQuery("#test").css("userSelect", "text").css("userSelect"), "text", "sets 1st new value, and reads new value properly" );
6 | equals( jQuery("#test").css("userSelect", "toggle").css("userSelect"), "toggle", "sets 2nd new value, and reads new value properly" );
7 | equals( jQuery("#test").css("userSelect", "element").css("userSelect"), "element", "sets 3rd new value, and reads new value properly" );
8 | equals( jQuery("#test").css("userSelect", "elements").css("userSelect"), "elements", "sets 4th new value, and reads new value properly" );
9 | equals( jQuery("#test").css("userSelect", "all").css("userSelect"), "all", "sets 5th new value, and reads new value properly" );
10 | });
11 |
12 | test("userInput", 2, function() {
13 | equals( jQuery("#test").css("userInput"), "disabled", "returns correct value" );
14 | equals( jQuery("#test").css("userInput", "enabled").css("userInput"), "enabled", "sets 1st new value, and reads new value properly" );
15 | });
16 |
17 | test("userFocus", 2, function() {
18 | equals( jQuery("#test").css("userFocus"), "ignore", "returns correct value" );
19 | equals( jQuery("#test").css("userFocus", "normal").css("userFocus"), "normal", "sets 1st new value, and reads new value properly" );
20 | });
21 |
22 | test("userModify", 2, function() {
23 | equals( jQuery("#test").css("userModify"), "read-only", "returns correct value" );
24 | equals( jQuery("#test").css("userModify", "read-write").css("userModify"), "read-write", "sets 1st new value, and reads new value properly" );
25 | });
26 |
--------------------------------------------------------------------------------
/transition.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Burin Asavesna (http://helloburin.com)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | */
4 | (function($) {
5 | var div = document.createElement('div'),
6 | divStyle = div.style,
7 | support = $.support,
8 | props = "Property Duration TimingFunction".split(" ");
9 |
10 | support.transition =
11 | divStyle.MozTransition === ''? 'MozTransition' :
12 | (divStyle.MsTransition === ''? 'MsTransition' :
13 | (divStyle.WebkitTransition === ''? 'WebkitTransition' :
14 | (divStyle.OTransition === ''? 'OTransition' :
15 | (divStyle.transition === ''? 'Transition' :
16 | false))));
17 |
18 | div = null;
19 |
20 | if ( support.transition && support.transition !== "Transition" ) {
21 | $.cssHooks.transition = {
22 | get: function( elem, computed, extra ) {
23 | return $.map(props, function( prop, i ) {
24 | return $.css(elem, support.transition + prop);
25 | }).join(" ");
26 | },
27 | set: function( elem, value ) {
28 | elem.style[ support.transition ] = value;
29 | }
30 | };
31 |
32 | $.each(props, function( i, prop ) {
33 | $.cssHooks[ "transition" + prop ] = {
34 | get: function( elem, computed, extra ) {
35 | return $.css(elem, support.transition + prop);
36 | },
37 | set: function( elem, value ) {
38 | elem.style[ support.transition + prop ] = value;
39 | }
40 | };
41 | });
42 |
43 | }
44 |
45 | })(jQuery);
46 |
--------------------------------------------------------------------------------
/userinterface.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * User Interface cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | - Works in Firefox 2+, Safari/Chrome (Partial support) only
7 | * Licensed under the MIT License (LICENSE.txt).
8 | */
9 | (function($) {
10 |
11 | var div = document.createElement( "div" ),
12 | divStyle = div.style,
13 | propertyName = 'user',
14 | suffix = 'User',
15 | props = [
16 | 'Input',
17 | 'Modify',
18 | 'Select',
19 | 'Focus'
20 | ],
21 | testProperties = [
22 | propertyName,
23 | 'Moz' + suffix,
24 | 'Webkit' + suffix,
25 | 'O' + suffix,
26 | 'ms' + suffix
27 | ],
28 | supportProperty,
29 | j = props.length;
30 | i = testProperties.length;
31 |
32 | o:for( var a = 0; a < j; a++ ){
33 |
34 | for( var b = 0; b < i; b++ ){
35 | if( ( testProperties[b] + props[a] ) in divStyle ){
36 | $.support[propertyName + props[a]] = ( testProperties[b] + props[a] );
37 | //If property is found continue to next item in outer loop
38 | continue o;
39 | }
40 | }
41 | }
42 |
43 | $.each( props, function( i, prop ){
44 |
45 | $.cssProps[propertyName+prop] = $.support[propertyName+prop];
46 |
47 | if ( $.support[propertyName+prop] && $.support[propertyName+prop] !== propertyName+prop ){
48 |
49 | $.cssHooks[propertyName+prop] = {
50 |
51 | get: function( elem, computed ) {
52 | return ( computed ? $.css( elem, $.support[propertyName+prop] ) : elem.style[$.support[propertyName+prop]] );
53 | },
54 | set: function( elem, value ) {
55 | elem.style[$.support[propertyName+prop]] = value;
56 | }
57 | };
58 | }
59 |
60 | });
61 |
62 | div = divStyle = null;
63 |
64 | })(jQuery);
--------------------------------------------------------------------------------
/tests/unit/borderradiusalt.js:
--------------------------------------------------------------------------------
1 | module("borderRadiusAlt");
2 |
3 | /*
4 | See why this doesn't work?? (Because of shorthand?)
5 | test("borderRadius", 3, function() {
6 | equals( jQuery("#test").css("borderRadius"), "5px 5px 5px 5px", "returns values in the correct order" );
7 | equals( jQuery("#test").css("borderRadius", "3px").css("borderRadius"), "3px 3px 3px 3px", "sets the values properly with 1 value" );
8 | equals( jQuery("#test").css("borderRadius", "3px 0 0 3px").css("borderRadius"), "3px 0px 0px 3px", "sets the values properly with multiple values" );
9 | });
10 | */
11 |
12 | test("borderTopLeftRadius", 2, function() {
13 | equals( jQuery("#test").css("borderTopLeftRadius"), "5px", "returns values in the correct order" );
14 | equals( jQuery("#test").css("borderTopLeftRadius", "3px").css("borderTopLeftRadius"), "3px", "sets the values properly" );
15 | });
16 |
17 | test("borderTopRightRadius", 2, function() {
18 | equals( jQuery("#test").css("borderTopRightRadius"), "5px", "returns values in the correct order" );
19 | equals( jQuery("#test").css("borderTopRightRadius", "3px").css("borderTopRightRadius"), "3px", "sets the values properly" );
20 | });
21 |
22 | test("borderBottomRightRadius", 2, function() {
23 | equals( jQuery("#test").css("borderBottomRightRadius"), "5px", "returns values in the correct order" );
24 | equals( jQuery("#test").css("borderBottomRightRadius", "3px").css("borderBottomRightRadius"), "3px", "sets the values properly" );
25 | });
26 |
27 | test("borderBottomLeftRadius", 2, function() {
28 | equals( jQuery("#test").css("borderBottomLeftRadius"), "5px", "returns values in the correct order" );
29 | equals( jQuery("#test").css("borderBottomLeftRadius", "3px").css("borderBottomLeftRadius"), "3px", "sets the values properly" );
30 | });
--------------------------------------------------------------------------------
/textshadow.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | var propStr = 'textShadow',
3 | colorStr = 'Color',
4 | props = (colorStr + " X Y Blur").split(' '),
5 | support = $.support,
6 | rWhitespace = /\s/,
7 | div = document.createElement('div'),
8 | divStyle = div.style;
9 |
10 | support.textShadow = (divStyle.textShadow === '');
11 | div = divStyle = null;
12 |
13 | if ($.cssHooks && support.textShadow) {
14 | $.each(props, function(i, suffix) {
15 | var hook = propStr + suffix;
16 |
17 | $.cssHooks[hook] = {
18 | get: function(elem, computed, extra) {
19 | return (function(elem, pos, prop) {
20 | var shadow = $.css(elem, propStr),
21 | color = $.color.normalize(shadow),
22 | ret;
23 |
24 | if (prop === colorStr) {
25 | ret = 'rgb'
26 | + (color.alpha ? 'a' : '') + '('
27 | + color.r + ', '
28 | + color.g + ', '
29 | + color.b
30 | + (color.alpha ? ', ' + color.alpha : '')
31 | + ')';
32 | }
33 | else {
34 | ret = $.trim(shadow.replace(color.source, '')).split(rWhitespace)[pos - 1];
35 | }
36 |
37 | return ret;
38 | })(elem, i, suffix);
39 | },
40 | set: function(elem, value) {
41 | elem.style.textShadow = (function(string, value, index) {
42 | var color_part = $.style(elem, propStr + colorStr),
43 | parts = string.replace(color_part, '').split(rWhitespace),
44 | ret;
45 |
46 | if (index === 0) {
47 | color_part = value;
48 | } else {
49 | parts[index] = value;
50 | }
51 |
52 | return color_part + parts.join(' ');
53 | })($.css(elem, propStr), value, i);
54 | }
55 | };
56 |
57 | if (suffix !== colorStr) {
58 | $.fx.step[hook] = function(fx) {
59 | $.cssHooks[hook].set(fx.elem, fx.now + fx.unit);
60 | };
61 | }
62 | });
63 | }
64 | })(jQuery);
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cssHooks
2 |
3 | A collection of cssHooks that work with jQuery 1.4.3+.
4 |
5 | Current Hooks:
6 |
7 | * margin and padding
8 | * backgroundPosition, backgroundPositionX, backgroundPositionY
9 | * borderRadius, borderRadiusTopLeft, borderRadiusTopRight, borderRadiusBottomRight, borderRadiusBottomLeft
10 | * boxShadow, boxShadowColor, boxShadowBlur, boxShadowSpread, boxShadowX, boxShadowY
11 | * borderImage
12 | * Alternative Border Radius Plugin with support for IE 6, 7, and 8
13 | * boxReflect
14 | * boxSizing
15 | * textShadow, and textShadowColor, textShadowX, textShadowY, and textShadowBlur
16 | * color animations for backgroundColor, borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderColor, boxShadowColor, color, outlineColor, and textShadowColor
17 | * columnCount, columnSpan, columnGap, columnWidth, columnRuleColor, columnRuleStyle, columnRuleWidth
18 | * 2D transforms
19 | * linear and radial gradients
20 |
21 | # Usage
22 |
23 | Super simple. Just request the margin, padding, backgroundPosition, boxShadow, etc like you would other CSS properties.
24 |
25 | // #myElement { margin: 1px 2px 3px 4px; }
26 | $('#myElement').css('margin'); // "1px 2px 3px 4px"
27 |
28 | What about setting properties?
29 |
30 | // #myElement { box-shadow: #000 1px 1px 3px; }
31 | $('#myElement').css('boxShadow', '#ccc 5px 5px');
32 | $('#myElement').css('boxShadowColor', '#ff5e99');
33 | $('#myElement').css('boxShadowBlur', '0px');
34 | $('#myElement').css('borderImage', 'url(image.jpg) 27 27 27 27 round round');
35 |
36 | And even animating?!
37 |
38 | $('#myElement').animate({ backgroundPositionY: 100 }, 500);
39 |
40 | # What are cssHooks?
41 |
42 | jQuery 1.4.3 introduced the concept of cssHooks. They allow you to hook directly into jQuery and override how certain css properties are retrieved or set. This allows for browser normalization or even the creation of your own unique css properties.
43 |
44 | ## License
45 |
46 | The cssHooks plugin is licensed under the MIT License (LICENSE.txt).
47 |
48 | Copyright (c) 2013 [Brandon Aaron](http://brandonaaron.net), [Burin Asavesna](http://helloburin.com), [Tom Ellis](http://www.webmuse.co.uk), [Phil Dokas](http://jetless.org) and [Louis-Rémi Babé](http://twitter.com/louis_remi).
49 |
--------------------------------------------------------------------------------
/bgpos.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | */
4 | (function($) {
5 | // backgroundPosition[X,Y] get hooks
6 | var $div = $('
');
7 | $.support.backgroundPosition = $div.css('backgroundPosition') === "3px 5px" ? true : false;
8 | $.support.backgroundPositionXY = $div.css('backgroundPositionX') === "3px" ? true : false;
9 | $div = null;
10 |
11 | var xy = ["X","Y"];
12 |
13 | // helper function to parse out the X and Y values from backgroundPosition
14 | function parseBgPos(bgPos) {
15 | var parts = bgPos.split(/\s/),
16 | values = {
17 | "X": parts[0],
18 | "Y": parts[1]
19 | };
20 | return values;
21 | }
22 |
23 | if (!$.support.backgroundPosition && $.support.backgroundPositionXY) {
24 | $.cssHooks.backgroundPosition = {
25 | get: function( elem, computed, extra ) {
26 | return $.map(xy, function( l, i ) {
27 | return $.css(elem, "backgroundPosition" + l);
28 | }).join(" ");
29 | },
30 | set: function( elem, value ) {
31 | $.each(xy, function( i, l ) {
32 | var values = parseBgPos(value);
33 | elem.style[ "backgroundPosition" + l ] = values[ l ];
34 | });
35 | }
36 | };
37 | }
38 |
39 | if ($.support.backgroundPosition && !$.support.backgroundPositionXY) {
40 | $.each(xy, function( i, l ) {
41 | $.cssHooks[ "backgroundPosition" + l ] = {
42 | get: function( elem, computed, extra ) {
43 | var values = parseBgPos( $.css(elem, "backgroundPosition") );
44 | return values[ l ];
45 | },
46 | set: function( elem, value ) {
47 | var values = parseBgPos( $.css(elem, "backgroundPosition") ),
48 | isX = l === "X";
49 | elem.style.backgroundPosition = (isX ? value : values[ "X" ]) + " " +
50 | (isX ? values[ "Y" ] : value);
51 | }
52 | };
53 | $.fx.step[ "backgroundPosition" + l ] = function( fx ) {
54 | $.cssHooks[ "backgroundPosition" + l ].set( fx.elem, fx.now + fx.unit );
55 | };
56 | });
57 | }
58 | })(jQuery);
59 |
--------------------------------------------------------------------------------
/tests/unit/boxshadow.js:
--------------------------------------------------------------------------------
1 | module("boxShadow");
2 |
3 | test("boxShadow", 2, function() {
4 | equals( jQuery("#test").css("boxShadow"), "rgb(0, 0, 0) 1px 2px 10px 0px", "returns values: color, x offset, y offset, blur, ???" );
5 | equals( jQuery("#test").css("boxShadow", "#ccc 5px 5px 5px").css("boxShadow"), "rgb(204, 204, 204) 5px 5px 5px 0px", "sets the value properly" );
6 | });
7 |
8 | test("boxShadowColor", 2, function() {
9 | equals( jQuery("#test").css("boxShadowColor"), "rgb(0, 0, 0)", "returns just the color" );
10 | equals( jQuery("#test").css("boxShadowColor", "#ccc").css("boxShadow"), "rgb(204, 204, 204) 1px 2px 10px 0px", "sets the color properly" );
11 | });
12 |
13 | test("boxShadowBlur", 3, function() {
14 | equals( jQuery("#test").css("boxShadowBlur"), "10px", "returns just the blur" );
15 | equals( jQuery("#test").css("boxShadowBlur", "42px").css("boxShadow"), "rgb(0, 0, 0) 1px 2px 42px 0px", "sets the blur properly" );
16 | stop();
17 | jQuery("#test").animate({ boxShadowBlur: 20 }, 100, function() {
18 | equals( jQuery("#test").css("boxShadowBlur"), "20px", "animates the value properly" );
19 | start();
20 | });
21 | });
22 |
23 | test("boxShadowSpread", 3, function() {
24 | equals( jQuery("#test").css("boxShadowSpread"), "0px", "returns just the spread" );
25 | equals( jQuery("#test").css("boxShadowSpread", "42px").css("boxShadow"), "rgb(0, 0, 0) 1px 2px 10px 42px", "sets the spread properly" );
26 | stop();
27 | jQuery("#test").animate({ boxShadowSpread: 20 }, 100, function() {
28 | equals( jQuery("#test").css("boxShadowSpread"), "20px", "animates the value properly" );
29 | start();
30 | });
31 | });
32 |
33 | test("boxShadowX", 3, function() {
34 | equals( jQuery("#test").css("boxShadowX"), "1px", "returns just the x offset" );
35 | equals( jQuery("#test").css("boxShadowX", "42px").css("boxShadow"), "rgb(0, 0, 0) 42px 2px 10px 0px", "sets the x offset properly" );
36 | stop();
37 | jQuery("#test").animate({ boxShadowX: 20 }, 100, function() {
38 | equals( jQuery("#test").css("boxShadowX"), "20px", "animates the value properly" );
39 | start();
40 | });
41 | });
42 |
43 | test("boxShadowY", 3, function() {
44 | equals( jQuery("#test").css("boxShadowY"), "2px", "returns just y offset" );
45 | equals( jQuery("#test").css("boxShadowY", "42px").css("boxShadow"), "rgb(0, 0, 0) 1px 42px 10px 0px", "sets the x offset properly" );
46 | stop();
47 | jQuery("#test").animate({ boxShadowY: 20 }, 100, function() {
48 | equals( jQuery("#test").css("boxShadowY"), "20px", "animates the value properly" );
49 | start();
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/tests/unit/textshadow.js:
--------------------------------------------------------------------------------
1 | module("textShadow");
2 |
3 | test("textShadowColor", 3, function() {
4 | equals( jQuery("#test").css("textShadowColor"), "rgb(0, 0, 0)", "returns just the color" );
5 | equals( jQuery("#test").css("textShadowColor", "rgb(100, 150, 200)").css("textShadowColor"), "rgb(100, 150, 200)", "sets the color properly" );
6 | stop();
7 | jQuery("#test").animate({ textShadowColor: 'rgb(255, 255, 255)' }, 100, function() {
8 | equals( jQuery("#test").css("textShadowColor"), "rgb(255, 255, 255)", "animates the color properly" );
9 | start();
10 | });
11 | });
12 |
13 | test("textShadowX", 3, function() {
14 | equals( jQuery("#test").css("textShadowX"), "1px", "returns just the X offset" );
15 | equals( jQuery("#test").css("textShadowX", "23px").css("textShadowX"), "23px", "sets the X offset properly" );
16 | stop();
17 | jQuery("#test").animate({ textShadowX: 88 }, 100, function() {
18 | equals( jQuery("#test").css("textShadowX"), "88px", "animates the X offset properly" );
19 | start();
20 | });
21 | });
22 |
23 | test("textShadowY", 3, function() {
24 | equals( jQuery("#test").css("textShadowY"), "1px", "returns just the Y offset" );
25 | equals( jQuery("#test").css("textShadowY", "23px").css("textShadowY"), "23px", "sets the Y offset properly" );
26 | stop();
27 | jQuery("#test").animate({ textShadowY: 88 }, 100, function() {
28 | equals( jQuery("#test").css("textShadowY"), "88px", "animates the Y offset properly" );
29 | start();
30 | });
31 | });
32 |
33 | test("textShadowBlur", 3, function() {
34 | equals( jQuery("#test").css("textShadowBlur"), "1px", "returns just the blur" );
35 | equals( jQuery("#test").css("textShadowBlur", "23px").css("textShadowBlur"), "23px", "sets the blur properly" );
36 | stop();
37 | jQuery("#test").animate({ textShadowBlur: 88 }, 100, function() {
38 | equals( jQuery("#test").css("textShadowBlur"), "88px", "animates the blur properly" );
39 | start();
40 | });
41 | });
42 |
43 | test("Alt syntax", 8, function() {
44 | equals( jQuery("#test").css("text-shadow-color"), "rgb(0, 0, 0)", "returns just the color" );
45 | equals( jQuery("#test").css("text-shadow-color", "rgb(100, 150, 200)").css("text-shadow-color"), "rgb(100, 150, 200)", "sets the color properly" );
46 | equals( jQuery("#test").css("text-shadow-x"), "1px", "returns just the X offset" );
47 | equals( jQuery("#test").css("text-shadow-x", "23px").css("text-shadow-x"), "23px", "sets the X offset properly" );
48 | equals( jQuery("#test").css("text-shadow-y"), "1px", "returns just the Y offset" );
49 | equals( jQuery("#test").css("text-shadow-y", "23px").css("text-shadow-y"), "23px", "sets the Y offset properly" );
50 | equals( jQuery("#test").css("text-shadow-blur"), "1px", "returns just the blur" );
51 | equals( jQuery("#test").css("text-shadow-blur", "23px").css("text-shadow-blur"), "23px", "sets the blur properly" );
52 | });
53 |
--------------------------------------------------------------------------------
/borderradius.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Burin Asavesna (http://helloburin.com)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | */
4 | (function($) {
5 | // borderRadius get hooks
6 | var div = document.createElement('div'),
7 | divStyle = div.style,
8 | support = $.support,
9 | dirs = "TopLeft TopRight BottomRight BottomLeft".split(" ");
10 |
11 | // WebKit supports "borderRadius" as well as "WebKitBorderRadius", weird
12 | support.borderRadius =
13 | divStyle.MozBorderRadius === ''? 'MozBorderRadius' :
14 | (divStyle.MsBorderRadius === ''? 'MsBorderRadius' :
15 | (divStyle.WebkitBorderRadius === ''? 'WebkitBorderRadius' :
16 | (divStyle.OBorderRadius === ''? 'OBorderRadius' :
17 | (divStyle.borderRadius === ''? 'BorderRadius' :
18 | false))));
19 |
20 | div = null;
21 |
22 | function borderCornerRadius(direction, prefix) {
23 | prefix = prefix === undefined || prefix === '' ? 'border' : prefix + 'Border';
24 | if ( support.borderRadius && support.borderRadius == "MozBorderRadius" ) {
25 | // e.g. MozBorderRadiusTopleft
26 | return prefix + "Radius" + direction.charAt(0).toUpperCase()+direction.substr(1).toLowerCase();
27 | } else {
28 | // e.g. WebKitBorderTopLeftRadius, borderTopLeftRadius, etc
29 | return prefix + direction + "Radius";
30 | }
31 | }
32 |
33 | if ( support.borderRadius && support.borderRadius !== "BorderRadius" ) {
34 | var vendor_prefix = support.borderRadius.replace('BorderRadius','');
35 | $.cssHooks.borderRadius = {
36 | get: function( elem, computed, extra ) {
37 | // return each of the directions, topleft, topright, bottomright, bottomleft
38 | return $.map(dirs, function( dir ) {
39 | return $.css(elem, borderCornerRadius( dir, vendor_prefix ));
40 | }).join(" ");
41 | },
42 | set: function( elem, value ) {
43 | // takes in a single value or shorthand (just letting the browser handle this)
44 | // e.g. 5px to set all, or 5px 0 0 5px to set left corners
45 | elem.style[ borderCornerRadius( '', vendor_prefix ) ] = value;
46 | }
47 | };
48 |
49 | $.each(dirs, function( i, dir ) {
50 | $.cssHooks[ "borderRadius" + dir ] = {
51 | get: function( elem, computed, extra ) {
52 | return $.css(elem, borderCornerRadius( dir, vendor_prefix ));
53 | },
54 | set: function( elem, value ) {
55 | elem.style[ borderCornerRadius( dir, vendor_prefix ) ] = value;
56 | }
57 | };
58 | });
59 |
60 | }
61 |
62 | })(jQuery);
63 |
--------------------------------------------------------------------------------
/gradients.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Linear and Radial Gradient cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | - Works in Firefox 3.6+, Safari 5.1+, Chrome 13+, Opera 11.10+, IE9+
7 | - Radial Gradients DO NOT work in Opera yet (Doesn't make sense I Know!)
8 | - Only works for background and background image CSS properties
9 | * Licensed under the MIT License (LICENSE.txt).
10 | */
11 | (function($) {
12 |
13 | var div = document.createElement( "div" ),
14 | divStyle = div.style,
15 | rLinear = /^(.*?)linear-gradient(.*?)$/i,
16 | rRadial = /^(.*?)radial-gradient(.*?)$/i,
17 | rLinearSettings = /^(.*?)(:?linear-gradient)(\()(.*)(\))(.*?)$/i,
18 | rRadialSettings = /^(.*?)(:?radial-gradient)(\()(.*?)(\))(.*?)$/i,
19 | rSupportLinearW3C = /(^|\s)linear-gradient/,
20 | rSupportLinearMoz = /(^|\s)-moz-linear-gradient/,
21 | rSupportLinearWebkit = /(^|\s)-webkit-linear-gradient/,
22 | rSupportLinearOpera = /(^|\s)-o-linear-gradient/,
23 | rSupportRadialW3C = /(^|\s)radial-gradient/,
24 | rSupportRadialMoz = /(^|\s)-moz-radial-gradient/,
25 | rSupportRadialWebkit = /(^|\s)-webkit-radial-gradient/,
26 | rSupportRadialOpera = /(^|\s)-o-radial-gradient/,
27 | rWhitespace = /\s/,
28 | rWhiteGlobal = /\s/g,
29 | cssProps = "background backgroundImage", //listStyleImage not supported yet
30 | cssLinear = "background-image: -moz-linear-gradient(red, blue);background-image: -webkit-linear-gradient(red, blue);background-image: -o-linear-gradient(red, blue);background-image: linear-gradient(red, blue);",
31 | cssRadial = "background-image: -moz-radial-gradient(circle, orange, red);background-image: -webkit-radial-gradient(circle, orange, red);background-image: -o-radial-gradient(circle,red, blue);background-image: radial-gradient(circle, orange, red);",
32 | cssPropsArray = cssProps.split( rWhitespace );
33 | divStyle.cssText = cssLinear,
34 | linearSettings = function ( value ) {
35 | var parts = rLinearSettings.exec( value );
36 | value = value.replace( new RegExp(parts[2], 'g') , $.support.linearGradient );
37 | return value;
38 | },
39 | radialSettings = function ( value ) {
40 | var parts = rRadialSettings.exec( value );
41 | value = value.replace( new RegExp(parts[2], 'g') , $.support.radialGradient );
42 | return value;
43 | };
44 |
45 | $.support.linearGradient =
46 | rSupportLinearW3C.test( divStyle.backgroundImage ) ? "linear-gradient" :
47 | (rSupportLinearMoz.test( divStyle.backgroundImage ) ? "-moz-linear-gradient" :
48 | (rSupportLinearWebkit.test( divStyle.backgroundImage ) ? "-webkit-linear-gradient" :
49 | (rSupportLinearOpera.test( divStyle.backgroundImage ) ? "-o-linear-gradient" :
50 | false)));
51 |
52 | divStyle.cssText = cssRadial;
53 |
54 | $.support.radialGradient =
55 | rSupportRadialW3C.test( divStyle.backgroundImage ) ? "radial-gradient" :
56 | (rSupportRadialMoz.test( divStyle.backgroundImage ) ? "-moz-radial-gradient" :
57 | (rSupportRadialWebkit.test( divStyle.backgroundImage ) ? "-webkit-radial-gradient" :
58 | (rSupportRadialOpera.test( divStyle.backgroundImage ) ? "-o-radial-gradient" :
59 | false)));
60 |
61 | if ( $.support.linearGradient && $.support.linearGradient !== "linear-gradient" ) {
62 |
63 | $.each( cssPropsArray, function( i, prop ) {
64 |
65 | $.cssHooks[ prop ] = {
66 |
67 | set: function( elem, value ) {
68 |
69 | if( rLinear.test( value ) ){
70 | elem.style[ prop ] = linearSettings( value );
71 | } else if ( rRadial.test( value ) ) {
72 | elem.style[ prop ] = radialSettings( value );
73 | } else {
74 | elem.style[ prop ] = value;
75 | }
76 | }
77 | };
78 |
79 | });
80 |
81 | }
82 |
83 | div = divStyle = null;
84 | })(jQuery);
85 |
--------------------------------------------------------------------------------
/boxshadow.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Burin Asavesna (http://helloburin.com)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | */
4 | (function($) {
5 | // boxShadow get hooks
6 | var div = document.createElement('div'),
7 | divStyle = div.style,
8 | support = $.support,
9 | rWhitespace = /\s/,
10 | rParenWhitespace = /\)\s/;
11 |
12 | support.boxShadow =
13 | divStyle.MozBoxShadow === ''? 'MozBoxShadow' :
14 | (divStyle.MsBoxShadow === ''? 'MsBoxShadow' :
15 | (divStyle.WebkitBoxShadow === ''? 'WebkitBoxShadow' :
16 | (divStyle.OBoxShadow === ''? 'OBoxShadow' :
17 | (divStyle.boxShadow === ''? 'BoxShadow' :
18 | false))));
19 |
20 | div = null;
21 |
22 | // helper function to inject a value into an existing string
23 | // is there a better way to do this? it seems like a common pattern
24 | function insert_into(string, value, index) {
25 | var parts = string.split(rWhitespace);
26 | parts[index] = value;
27 | return parts.join(" ");
28 | }
29 |
30 | if ( support.boxShadow && support.boxShadow !== "BoxShadow" ) {
31 | $.cssHooks.boxShadow = {
32 | get: function( elem, computed, extra ) {
33 | return $.css(elem, support.boxShadow);
34 | },
35 | set: function( elem, value ) {
36 | elem.style[ support.boxShadow ] = value;
37 | }
38 | };
39 |
40 | $.cssHooks.boxShadowColor = {
41 | get: function ( elem, computed, extra ) {
42 | return $.css(elem, support.boxShadow).split(rParenWhitespace)[0] + ')';
43 | },
44 | set: function( elem, value ) {
45 | elem.style[ support.boxShadow ] = value + " " + $.css(elem, support.boxShadow).split(rParenWhitespace)[1];
46 | }
47 | };
48 |
49 | $.cssHooks.boxShadowBlur = {
50 | get: function ( elem, computed, extra ) {
51 | return $.css(elem, support.boxShadow).split(rWhitespace)[5];
52 | },
53 | set: function( elem, value ) {
54 | elem.style[ support.boxShadow ] = insert_into($.css(elem, support.boxShadow), value, 5);
55 | }
56 | };
57 |
58 | $.cssHooks.boxShadowSpread = {
59 | get: function ( elem, computed, extra ) {
60 | return $.css(elem, support.boxShadow).split(rWhitespace)[6];
61 | },
62 | set: function( elem, value ) {
63 | elem.style[ support.boxShadow ] = insert_into($.css(elem, support.boxShadow), value, 6);
64 | }
65 | };
66 |
67 | $.cssHooks.boxShadowX = {
68 | get: function ( elem, computed, extra ) {
69 | return $.css(elem, support.boxShadow).split(rWhitespace)[3];
70 | },
71 | set: function( elem, value ) {
72 | elem.style[ support.boxShadow ] = insert_into($.css(elem, support.boxShadow), value, 3);
73 | }
74 | };
75 |
76 | $.cssHooks.boxShadowY = {
77 | get: function ( elem, computed, extra ) {
78 | return $.css(elem, support.boxShadow).split(rWhitespace)[4];
79 | },
80 | set: function( elem, value ) {
81 | elem.style[ support.boxShadow ] = insert_into($.css(elem, support.boxShadow), value, 4);
82 | }
83 | };
84 |
85 | // setup fx hooks
86 | var fxHooks = "Blur Spread X Y".split(" ");
87 | $.each(fxHooks, function( i, suffix ) {
88 | var hook = "boxShadow" + suffix;
89 | $.fx.step[ hook ] = function( fx ) {
90 | $.cssHooks[ hook ].set( fx.elem, fx.now + fx.unit );
91 | };
92 | });
93 | }
94 |
95 | })(jQuery);
96 |
--------------------------------------------------------------------------------
/tests/qunit/qunit.css:
--------------------------------------------------------------------------------
1 | /** Font Family and Sizes */
2 |
3 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
4 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
5 | }
6 |
7 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
8 | #qunit-tests { font-size: smaller; }
9 |
10 |
11 | /** Resets */
12 |
13 | #qunit-tests, #qunit-tests li ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 |
19 | /** Header */
20 |
21 | #qunit-header {
22 | padding: 0.5em 0 0.5em 1em;
23 |
24 | color: #fff;
25 | text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
26 | background-color: #0d3349;
27 |
28 | border-radius: 15px 15px 0 0;
29 | -moz-border-radius: 15px 15px 0 0;
30 | -webkit-border-top-right-radius: 15px;
31 | -webkit-border-top-left-radius: 15px;
32 | }
33 |
34 | #qunit-banner {
35 | height: 5px;
36 | }
37 |
38 | #qunit-testrunner-toolbar {
39 | padding: 0em 0 0.5em 2em;
40 | }
41 |
42 | #qunit-userAgent {
43 | padding: 0.5em 0 0.5em 2.5em;
44 | background-color: #2b81af;
45 | color: #fff;
46 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
47 | }
48 |
49 |
50 | /** Tests: Pass/Fail */
51 |
52 | #qunit-tests {
53 | list-style-position: inside;
54 | }
55 |
56 | #qunit-tests li {
57 | padding: 0.4em 0.5em 0.4em 2.5em;
58 | border-bottom: 1px solid #fff;
59 | list-style-position: inside;
60 | }
61 |
62 | #qunit-tests li strong {
63 | cursor: pointer;
64 | }
65 |
66 | #qunit-tests li ol {
67 | margin-top: 0.5em;
68 | padding: 0.5em;
69 |
70 | background-color: #fff;
71 |
72 | border-radius: 15px;
73 | -moz-border-radius: 15px;
74 | -webkit-border-radius: 15px;
75 |
76 | box-shadow: inset 0px 2px 13px #999;
77 | -moz-box-shadow: inset 0px 2px 13px #999;
78 | -webkit-box-shadow: inset 0px 2px 13px #999;
79 | }
80 |
81 | #qunit-tests li li {
82 | margin: 0.5em;
83 | padding: 0.4em 0.5em 0.4em 0.5em;
84 | background-color: #fff;
85 | border-bottom: none;
86 | list-style-position: inside;
87 | }
88 |
89 | /*** Passing Styles */
90 |
91 | #qunit-tests li li.pass {
92 | color: #5E740B;
93 | background-color: #fff;
94 | border-left: 26px solid #C6E746;
95 | }
96 |
97 | #qunit-tests li.pass { color: #528CE0; background-color: #D2E0E6; }
98 | #qunit-tests li.pass span.test-name { color: #366097; }
99 |
100 | #qunit-tests li li.pass span.test-actual,
101 | #qunit-tests li li.pass span.test-expected { color: #999999; }
102 |
103 | strong b.pass { color: #5E740B; }
104 |
105 | #qunit-banner.qunit-pass { background-color: #C6E746; }
106 |
107 | /*** Failing Styles */
108 |
109 | #qunit-tests li li.fail {
110 | color: #710909;
111 | background-color: #fff;
112 | border-left: 26px solid #EE5757;
113 | }
114 |
115 | #qunit-tests li.fail { color: #000000; background-color: #EE5757; }
116 | #qunit-tests li.fail span.test-name,
117 | #qunit-tests li.fail span.module-name { color: #000000; }
118 |
119 | #qunit-tests li li.fail span.test-actual { color: #EE5757; }
120 | #qunit-tests li li.fail span.test-expected { color: green; }
121 |
122 | strong b.fail { color: #710909; }
123 |
124 | #qunit-banner.qunit-fail,
125 | #qunit-testrunner-toolbar { background-color: #EE5757; }
126 |
127 |
128 | /** Footer */
129 |
130 | #qunit-testresult {
131 | padding: 0.5em 0.5em 0.5em 2.5em;
132 |
133 | color: #2b81af;
134 | background-color: #D2E0E6;
135 |
136 | border-radius: 0 0 15px 15px;
137 | -moz-border-radius: 0 0 15px 15px;
138 | -webkit-border-bottom-right-radius: 15px;
139 | -webkit-border-bottom-left-radius: 15px;
140 | }
141 |
142 | /** Fixture */
143 |
144 | #qunit-fixture {
145 | position: absolute;
146 | top: -10000px;
147 | left: -10000px;
148 | }
149 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
jQuery-cssHooks Test Suite
5 |
6 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
Hello World
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/skeleton.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
: A jQuery cssHooks adding a cross browser property to $.fn.css() and $.fn.animate()
3 | *
4 | * limitations:
5 | * - requires jQuery 1.4.3+
6 | * - compatible with Firefox , Chrome , Safari , Opera , Internet Explorer
7 | * -
8 | *
9 | * Copyright
10 | * License
11 | */
12 | (function( $ ) {
13 |
14 | var div = document.createElement("div"),
15 | divStyle = div.style,
16 | propertyName = "",
17 | // with leading upper-case
18 | suffix = "",
19 | testProperties = [
20 | "O" + suffix,
21 | // "ms", not "Ms"
22 | "ms" + suffix,
23 | "Webkit" + suffix,
24 | "Moz" + suffix,
25 | // prefix-less property
26 | propertyName
27 | ],
28 | i = testProperties.length,
29 | // use local variables instead of jQuery.support and jQuery.cssHooks
30 | // throughout the plugin to reduce file size once minified
31 | supportProperty,
32 | supportMsAlternative,
33 | propertyHook;
34 |
35 | // test different vendor prefixes of this property
36 | while ( i-- ) {
37 | if ( testProperties[i] in divStyle ) {
38 | $.support[propertyName] = supportProperty = testProperties[i];
39 | continue;
40 | }
41 | }
42 | // If a proprietary alternative exists for IE678, include another test for it
43 | if ( !supportProperty ) {
44 | $.support.MsAlternative = supportMsAlternative = divStyle[""] === "";
45 | }
46 |
47 | // the following line should be removed if "px" is the default unit for this property
48 | $.cssNumber[propertyName] = true;
49 |
50 | // prefix-less property will likely not need a hook
51 | if ( supportProperty && supportProperty != propertyName ) {
52 | // Modern browsers can use jQuery.cssProps as a basic hook
53 | $.cssProps[propertyName] = supportProperty;
54 |
55 | // Real cssHooks might be used to normalize implementations inconsistencies in some browsers
56 | // for example
57 | if ( supportProperty == "Moz" + suffix ) {
58 | propertyHook = {
59 | set: function( elem, value ) {
60 | elem.style[ supportProperty ] = normalizeFirefoxSet( value );
61 | }
62 | };
63 | /* Fix two jQuery bugs present before jQuery 1.6
64 | * - rupper is incompatible with IE9, see http://jqbug.com/8346
65 | * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402
66 | */
67 | } else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) {
68 | propertyHook = {
69 | get: function( elem, computed ) {
70 | return (computed ?
71 | $.css( elem, supportProperty.replace(/^ms/, "Ms") ):
72 | elem.style[supportProperty]
73 | )
74 | }
75 | }
76 | }
77 | // If a proprietary alternative exists for IE678, implement a complete hook for it
78 | } else if ( supportMsAlternative ) {
79 | propertyHook = {
80 | get: function( elem, computed, extra ) {
81 | // Handle crazy conversion from the proprietary alternative
82 | },
83 | set: function( elem, value ) {
84 | // Handle crazy conversion to the proprietary alternative
85 | }
86 | }
87 | }
88 | // populate jQuery.cssHooks with the appropriate hook if necessary
89 | if ( propertyHook ) {
90 | $.cssHooks[propertyName] = propertyHook;
91 | }
92 | // uncomment following line if the animation logic uses the getter
93 | //var propertyGet = propertyHook && propertyHook.get || $.css;*/
94 |
95 | // animation for simple values
96 | $.fx.step[propertyName] = function( fx ) {
97 | var value = fx.now + fx.unit;
98 | propertyHook && propertyHook.set?
99 | // Use a setter hook if it exists
100 | propertyHook.set( elem, transform ):
101 | // Otherwise modify raw DOM for maximum performances
102 | elem.style[supportProperty] = transform;
103 | }
104 | // The following code can be used as a base to animate more complex values
105 | /*$.fx.step[propertyName] = function( fx ) {
106 | // fx.start and fx.end will probably be parsed on the first step to be computable
107 | if ( !fx.start || typeof fx.start === "string" ) {
108 | // fix fx.start value
109 | if ( !fx.start ) {
110 | fx.start = propertyGet( fx.elem, supportProperty );
111 | }
112 | fx.start = parse(fx.start);
113 | fx.end = parse(fx.end);
114 | }
115 |
116 | // the code that calculates the value or components of it, is specific to the property
117 | // but it is likely to look like the following
118 | var value = fx.start + ( fx.end - fx.start ) * fx.pos;
119 |
120 | // set the value once it has been calculated
121 | propertyHook.set?
122 | propertyHook.set( elem, transform ):
123 | elem.style[supportProperty] = transform;
124 | }*/
125 |
126 | })( jQuery );
--------------------------------------------------------------------------------
/border-radius.htc:
--------------------------------------------------------------------------------
1 | --Do not remove this if you are using--
2 | Original Author: Remiz Rahnas
3 | Original Author URL: http://www.htmlremix.com
4 | Published date: 2008/09/24
5 |
6 | Changes by Nick Fetchak:
7 | - IE8 standards mode compatibility
8 | - VML elements now positioned behind original box rather than inside of it - should be less prone to breakage
9 | Published date : 2009/11/18
10 |
11 |
12 |
13 |
143 |
144 |
--------------------------------------------------------------------------------
/borderradiusalt.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2011 Tom Ellis (http://www.webmuse.co.uk)
3 | * Border Radius cssHook for jQuery
4 | * Limitations:
5 | - Works with jQuery 1.4.3 and higher
6 | - Can't animate border radius in IE
7 | * Licensed under the MIT License (LICENSE.txt).
8 | */
9 | (function($) {
10 |
11 | var div = document.createElement("div"),
12 | divStyle = div.style,
13 | rWhiteSpace = /\s/,
14 | dirs = "TopLeft TopRight BottomRight BottomLeft".split(rWhiteSpace),
15 | getRadii = function( n ){
16 | if( !n ) {
17 | return [0];
18 | } else if(typeof n == 'number') {
19 | return [n];
20 | } else {
21 | r = n.match(/(\-\d+|\d+)/g) || [0];
22 | for(var i in r) {
23 | r[i] = parseInt(r[i]);
24 | }
25 | }
26 | return r;
27 | };
28 |
29 | $.support.borderRadius =
30 | divStyle.borderRadius === '' ? 'borderRadius' :
31 | (divStyle.MozBorderRadius === '' ? 'MozBorderRadius' :
32 | (divStyle.WebkitBorderRadius === '' ? 'WebkitBorderRadius' : false));
33 |
34 | //Browsers support border radius corners differently (For now)
35 |
36 | $.support.TopLeft = false;
37 | $.support.TopRight = false;
38 | $.support.BottomLeft = false;
39 | $.support.BottomRight = false;
40 |
41 | if( $.support.borderRadius === 'borderRadius' ) {
42 |
43 | $.support.TopLeft = 'borderTopLeftRadius';
44 | $.support.TopRight = 'borderTopLeftRadius';
45 | $.support.BottomLeft = 'borderTopLeftRadius';
46 | $.support.BottomRight = 'borderTopLeftRadius';
47 |
48 | } else if( $.support.borderRadius === 'MozBorderRadius' ) {
49 |
50 | $.support.TopLeft = 'borderTopLeftRadius';
51 | $.support.TopRight = 'borderTopLeftRadius';
52 | $.support.BottomLeft = 'borderTopLeftRadius';
53 | $.support.BottomRight = 'borderTopLeftRadius';
54 |
55 | } else if( $.support.borderRadius === 'WebkitBorderRadius' ) {
56 |
57 | $.support.TopLeft = 'borderTopLeftRadius';
58 | $.support.TopRight = 'borderTopLeftRadius';
59 | $.support.BottomLeft = 'borderTopLeftRadius';
60 | $.support.BottomRight = 'borderTopLeftRadius';
61 | }
62 |
63 | if ( $.support.borderRadius && $.support.borderRadius !== "borderRadius" ){
64 | //alert('here');
65 | //BorderRadius
66 | $.cssHooks.borderRadius = {
67 | get: function( elem, computed, extra ) {
68 |
69 | return $.map(dirs, function( dir ) {
70 | return $.css( elem, $.support[dir], computed );
71 | }).join(" ");
72 |
73 | },
74 | set: function( elem, value ) {
75 |
76 | var parts = value.split(rWhiteSpace),
77 | values = {
78 | "TopLeft": parts[0],
79 | "TopRight": parts[1] || parts[0],
80 | "BottomLeft": parts[2] || parts[0],
81 | "BottomRight": parts[3] || parts[1] || parts[0]
82 | };
83 |
84 | elem.style[ $.support.borderRadius ] = value;
85 | }
86 | };
87 |
88 | $.each( dirs, function( i, dir ) {
89 |
90 | $.cssHooks[ "border" + dir + "Radius"] = {
91 | get: function( elem, computed, extra ) {
92 |
93 | return $.css( elem, $.support[dir] );
94 | },
95 | set: function( elem, value ){
96 |
97 | elem.style[ $.support[dir] ] = value;
98 | }
99 | };
100 |
101 | $.fx.step[ "border" + dir + "Radius" ] = function( fx ) {
102 |
103 | /*
104 |
105 | function ii( n ){
106 | if( !n ) {
107 | return [0];
108 | } else if(typeof n == 'number') {
109 | return [n];
110 | } else {
111 | r = n.match(/(\-\d+|\d+)/g) || [0];
112 | for(var i in r) {
113 | r[i] = parseInt(r[i]);
114 | }
115 | }
116 | return r;
117 | }
118 |
119 | if(!fx.endx) {
120 |
121 | var i = ii($(fx.elem).css( $.support[dir] ) );
122 |
123 | fx.startx = i[0];
124 | fx.starty = i[1]||i[0];
125 | fx.f = ii(fx.end);
126 | fx.endx = fx.f[0];
127 | fx.endy = fx.f[1]||fx.f[0];
128 |
129 | if((fx.endy - fx.starty) < (fx.endx - fx.startx)) {
130 | fx.which = true;
131 | fx.end = fx.endx;
132 | fx.start = fx.startx;
133 | fx.now = fx.start;
134 | fx.now2 = fx.starty;
135 | } else {
136 | fx.which = false;
137 | fx.end = fx.endy;
138 | fx.start = fx.starty;
139 | fx.now = fx.start;
140 | fx.now2 = fx.startx;
141 | }
142 | }
143 | fx.now2 = (fx.which)?
144 | fx.starty + ((fx.endy - fx.starty) * fx.pos)
145 | :
146 | fx.startx + ((fx.endx - fx.startx) * fx.pos);
147 | var set = (fx.which)?
148 | (fx.now + fx.unit+" "+fx.now2 + fx.unit)
149 | :
150 | (fx.now2 + fx.unit+" "+fx.now + fx.unit);
151 |
152 | $.cssHooks[ "border" + dir + "Radius" ].set( fx.elem, fx.now + fx.unit+" "+fx.now2 + fx.unit );
153 | */
154 |
155 | //$.cssHooks[ "border" + dir + "Radius" ].set( fx.elem, set );
156 | //console.log( fx.now + fx.unit+" "+fx.now2 + fx.unit );
157 |
158 | //$.cssHooks[ "border" + dir + "Radius" ].set( fx.elem, fx.now + fx.unit+" "+fx.now2 + fx.unit );
159 |
160 | $.cssHooks[ "border" + dir + "Radius" ].set( fx.elem, fx.now + fx.unit );
161 | };
162 |
163 |
164 | });
165 |
166 | // setup fx hooks
167 | $.fx.step.borderRadius = function( fx ) {
168 | $.cssHooks.borderRadius.set( fx.elem, fx.now + fx.unit );
169 | };
170 |
171 | } else if ( !$.support.borderRadius && "createStyleSheet" in document ) {
172 |
173 | //BorderRadius Plugin
174 | $.cssHooks.borderRadius = {
175 | get: function( elem, computed, extra ) {
176 |
177 | return $.data(elem, "borderRadiusIE");
178 | },
179 | set: function( elem, value ) {
180 |
181 | var css,
182 | parts = value.split(rWhiteSpace),
183 | one = parts[0],
184 | two = parts[1] || parts[0],
185 | three = parts[2] || parts[0],
186 | four = parts[3] || parts[1] || parts[0],
187 | values = [
188 | one,
189 | two,
190 | three,
191 | four
192 | ];
193 |
194 | css = ($.data( elem, "borderRadiusIECSS")) ?
195 | $.data( elem, "borderRadiusIECSS") : document.createStyleSheet("ie_style.css")
196 | css.cssText = "";
197 | css.addRule( "#results", "border-radius:" + values.join(" ") );
198 | //Needs to be the directory from root of index.html
199 | //or page that uses this js file to the border radius htc file
200 | elem.style.behavior = "url(js/border-radius.htc)";
201 |
202 | $.data(elem, "borderRadiusIE", values.join(" "));
203 | $.data( elem, "borderRadiusIECSS", css);
204 |
205 | }
206 | };
207 |
208 | }
209 |
210 | div = divStyle = null;
211 |
212 | })(jQuery);
--------------------------------------------------------------------------------
/color.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | var colornames = {
3 | aliceblue: { r:240, g:248, b:255 },
4 | antiquewhite: { r:250, g:235, b:215 },
5 | aqua: { r:0, g:255, b:255 },
6 | aquamarine: { r:127, g:255, b:212 },
7 | azure: { r:240, g:255, b:255 },
8 | beige: { r:245, g:245, b:220 },
9 | bisque: { r:255, g:228, b:196 },
10 | black: { r:0, g:0, b:0 },
11 | blanchedalmond: { r:255, g:235, b:205 },
12 | blue: { r:0, g:0, b:255 },
13 | blueviolet: { r:138, g:43, b:226 },
14 | brown: { r:165, g:42, b:42 },
15 | burlywood: { r:222, g:184, b:135 },
16 | cadetblue: { r:95, g:158, b:160 },
17 | chartreuse: { r:127, g:255, b:0 },
18 | chocolate: { r:210, g:105, b:30 },
19 | coral: { r:255, g:127, b:80 },
20 | cornflowerblue: { r:100, g:149, b:237 },
21 | cornsilk: { r:255, g:248, b:220 },
22 | crimson: { r:220, g:20, b:60 },
23 | cyan: { r:0, g:255, b:255 },
24 | darkblue: { r:0, g:0, b:139 },
25 | darkcyan: { r:0, g:139, b:139 },
26 | darkgoldenrod: { r:184, g:134, b:11 },
27 | darkgray: { r:169, g:169, b:169 },
28 | darkgreen: { r:0, g:100, b:0 },
29 | darkgrey: { r:169, g:169, b:169 },
30 | darkkhaki: { r:189, g:183, b:107 },
31 | darkmagenta: { r:139, g:0, b:139 },
32 | darkolivegreen: { r:85, g:107, b:47 },
33 | darkorange: { r:255, g:140, b:0 },
34 | darkorchid: { r:153, g:50, b:204 },
35 | darkred: { r:139, g:0, b:0 },
36 | darksalmon: { r:233, g:150, b:122 },
37 | darkseagreen: { r:143, g:188, b:143 },
38 | darkslateblue: { r:72, g:61, b:139 },
39 | darkslategray: { r:47, g:79, b:79 },
40 | darkslategrey: { r:47, g:79, b:79 },
41 | darkturquoise: { r:0, g:206, b:209 },
42 | darkviolet: { r:148, g:0, b:211 },
43 | deeppink: { r:255, g:20, b:147 },
44 | deepskyblue: { r:0, g:191, b:255 },
45 | dimgray: { r:105, g:105, b:105 },
46 | dimgrey: { r:105, g:105, b:105 },
47 | dodgerblue: { r:30, g:144, b:255 },
48 | firebrick: { r:178, g:34, b:34 },
49 | floralwhite: { r:255, g:250, b:240 },
50 | forestgreen: { r:34, g:139, b:34 },
51 | fuchsia: { r:255, g:0, b:255 },
52 | gainsboro: { r:220, g:220, b:220 },
53 | ghostwhite: { r:248, g:248, b:255 },
54 | gold: { r:255, g:215, b:0 },
55 | goldenrod: { r:218, g:165, b:32 },
56 | gray: { r:128, g:128, b:128 },
57 | green: { r:0, g:128, b:0 },
58 | greenyellow: { r:173, g:255, b:47 },
59 | grey: { r:128, g:128, b:128 },
60 | honeydew: { r:240, g:255, b:240 },
61 | hotpink: { r:255, g:105, b:180 },
62 | indianred: { r:205, g:92, b:92 },
63 | indigo: { r:75, g:0, b:130 },
64 | ivory: { r:255, g:255, b:240 },
65 | khaki: { r:240, g:230, b:140 },
66 | lavender: { r:230, g:230, b:250 },
67 | lavenderblush: { r:255, g:240, b:245 },
68 | lawngreen: { r:124, g:252, b:0 },
69 | lemonchiffon: { r:255, g:250, b:205 },
70 | lightblue: { r:173, g:216, b:230 },
71 | lightcoral: { r:240, g:128, b:128 },
72 | lightcyan: { r:224, g:255, b:255 },
73 | lightgoldenrodyellow: { r:250, g:250, b:210 },
74 | lightgray: { r:211, g:211, b:211 },
75 | lightgreen: { r:144, g:238, b:144 },
76 | lightgrey: { r:211, g:211, b:211 },
77 | lightpink: { r:255, g:182, b:193 },
78 | lightsalmon: { r:255, g:160, b:122 },
79 | lightseagreen: { r:32, g:178, b:170 },
80 | lightskyblue: { r:135, g:206, b:250 },
81 | lightslategray: { r:119, g:136, b:153 },
82 | lightslategrey: { r:119, g:136, b:153 },
83 | lightsteelblue: { r:176, g:196, b:222 },
84 | lightyellow: { r:255, g:255, b:224 },
85 | lime: { r:0, g:255, b:0 },
86 | limegreen: { r:50, g:205, b:50 },
87 | linen: { r:250, g:240, b:230 },
88 | magenta: { r:255, g:0, b:255 },
89 | maroon: { r:128, g:0, b:0 },
90 | mediumaquamarine: { r:102, g:205, b:170 },
91 | mediumblue: { r:0, g:0, b:205 },
92 | mediumorchid: { r:186, g:85, b:211 },
93 | mediumpurple: { r:147, g:112, b:219 },
94 | mediumseagreen: { r:60, g:179, b:113 },
95 | mediumslateblue: { r:123, g:104, b:238 },
96 | mediumspringgreen: { r:0, g:250, b:154 },
97 | mediumturquoise: { r:72, g:209, b:204 },
98 | mediumvioletred: { r:199, g:21, b:133 },
99 | midnightblue: { r:25, g:25, b:112 },
100 | mintcream: { r:245, g:255, b:250 },
101 | mistyrose: { r:255, g:228, b:225 },
102 | moccasin: { r:255, g:228, b:181 },
103 | navajowhite: { r:255, g:222, b:173 },
104 | navy: { r:0, g:0, b:128 },
105 | oldlace: { r:253, g:245, b:230 },
106 | olive: { r:128, g:128, b:0 },
107 | olivedrab: { r:107, g:142, b:35 },
108 | orange: { r:255, g:165, b:0 },
109 | orangered: { r:255, g:69, b:0 },
110 | orchid: { r:218, g:112, b:214 },
111 | palegoldenrod: { r:238, g:232, b:170 },
112 | palegreen: { r:152, g:251, b:152 },
113 | paleturquoise: { r:175, g:238, b:238 },
114 | palevioletred: { r:219, g:112, b:147 },
115 | papayawhip: { r:255, g:239, b:213 },
116 | peachpuff: { r:255, g:218, b:185 },
117 | peru: { r:205, g:133, b:63 },
118 | pink: { r:255, g:192, b:203 },
119 | plum: { r:221, g:160, b:221 },
120 | powderblue: { r:176, g:224, b:230 },
121 | purple: { r:128, g:0, b:128 },
122 | red: { r:255, g:0, b:0 },
123 | rosybrown: { r:188, g:143, b:143 },
124 | royalblue: { r:65, g:105, b:225 },
125 | saddlebrown: { r:139, g:69, b:19 },
126 | salmon: { r:250, g:128, b:114 },
127 | sandybrown: { r:244, g:164, b:96 },
128 | seagreen: { r:46, g:139, b:87 },
129 | seashell: { r:255, g:245, b:238 },
130 | sienna: { r:160, g:82, b:45 },
131 | silver: { r:192, g:192, b:192 },
132 | skyblue: { r:135, g:206, b:235 },
133 | slateblue: { r:106, g:90, b:205 },
134 | slategray: { r:112, g:128, b:144 },
135 | slategrey: { r:112, g:128, b:144 },
136 | snow: { r:255, g:250, b:250 },
137 | springgreen: { r:0, g:255, b:127 },
138 | steelblue: { r:70, g:130, b:180 },
139 | tan: { r:210, g:180, b:140 },
140 | teal: { r:0, g:128, b:128 },
141 | thistle: { r:216, g:191, b:216 },
142 | tomato: { r:255, g:99, b:71 },
143 | turquoise: { r:64, g:224, b:208 },
144 | violet: { r:238, g:130, b:238 },
145 | wheat: { r:245, g:222, b:179 },
146 | white: { r:255, g:255, b:255 },
147 | whitesmoke: { r:245, g:245, b:245 },
148 | yellow: { r:255, g:255, b:0 },
149 | yellowgreen: { r:154, g:205, b:50 },
150 | transparent: { r:-1, g:-1, b:-1 }
151 | },
152 | // Not a complete list yet...
153 | props = 'backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor borderColor boxShadowColor color outlineColor textShadowColor'.split(' ');
154 |
155 | $.color = {
156 | normalize: function(input) {
157 | var color, alpha,
158 | result, name, i, l,
159 | rhex = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
160 | rhexshort = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
161 | rrgb = /rgb(?:a)?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(0*\.?\d+)\s*)?\)/,
162 | rrgbpercent = /rgb(?:a)?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(0*\.?\d+)\s*)?\)/,
163 | rhsl = /hsl(?:a)?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(0*\.?\d+)\s*)?\)/;
164 |
165 | // Handle color: #rrggbb
166 | if (result = rhex.exec(input)) {
167 | color = {
168 | r: parseInt(result[1], 16),
169 | g: parseInt(result[2], 16),
170 | b: parseInt(result[3], 16),
171 | source: result[0]
172 | };
173 | }
174 | // Handle color: #rgb
175 | else if (result = rhexshort.exec(input)) {
176 | color = {
177 | r: parseInt(result[1]+result[1], 16),
178 | g: parseInt(result[2]+result[2], 16),
179 | b: parseInt(result[3]+result[3], 16),
180 | source: result[0]
181 | };
182 | }
183 | // Handle color: rgb[a](r, g, b [, a])
184 | else if (result = rrgb.exec(input)) {
185 | color = {
186 | r: parseInt(result[1], 10),
187 | g: parseInt(result[2], 10),
188 | b: parseInt(result[3], 10),
189 | alpha: parseFloat(result[4], 10),
190 | source: result[0]
191 | };
192 | }
193 | // Handle color: rgb[a](r%, g%, b% [, a])
194 | else if (result = rrgbpercent.exec(input)) {
195 | color = {
196 | r: parseInt(result[1] * 2.55, 10),
197 | g: parseInt(result[2] * 2.55, 10),
198 | b: parseInt(result[3] * 2.55, 10),
199 | alpha: parseFloat(result[4], 10),
200 | source: result[0]
201 | };
202 | }
203 | // Handle color: hsl[a](h%, s%, l% [, a])
204 | else if (result = rhsl.exec(input)) {
205 | color = $.color.hsl_to_rgb(
206 | parseFloat(result[1], 10) / 100,
207 | parseFloat(result[2], 10) / 100,
208 | parseFloat(result[3], 10) / 100
209 | );
210 | color.alpha = parseFloat(result[4], 10);
211 | color.source = result[0];
212 | }
213 | // Handle color: name
214 | else {
215 | result = input.split(' ');
216 | for (i = 0, l = result.length; i < l; i++) {
217 | name = result[i];
218 |
219 | if (colornames[name]) {
220 | break;
221 | }
222 | }
223 |
224 | if (!colornames[name]) {
225 | name = 'transparent';
226 | }
227 |
228 | color = colornames[name];
229 | color.source = name;
230 | }
231 |
232 | if (!color.alpha && color.alpha !== 0) {
233 | delete color.alpha;
234 | }
235 |
236 | return color;
237 | },
238 |
239 | hsl_to_rgb: function(h, s, l, a) {
240 | var r, g, b, m1, m2;
241 |
242 | if (s === 0) {
243 | r = g = b = l;
244 | } else {
245 | if (l <= 0.5) {
246 | m2 = l * (s + 1);
247 | } else {
248 | m2 = (l + s) - (l * s);
249 | }
250 |
251 | m1 = (l * 2) - m2;
252 | r = parseInt(255 * $.color.hue_to_rgb(m1, m2, h + (1/3)), 10);
253 | g = parseInt(255 * $.color.hue_to_rgb(m1, m2, h), 10);
254 | b = parseInt(255 * $.color.hue_to_rgb(m1, m2, h - (1/3)), 10);
255 | }
256 |
257 | return { r:r, g:g, b:b, alpha:a };
258 | },
259 |
260 | hue_to_rgb: function(m1, m2, h) {
261 | if (h < 0) { h++; }
262 | if (h > 1) { h--; }
263 |
264 | if ((h * 6) < 1) { return m1 + ((m2 - m1) * h * 6); }
265 | else if ((h * 2) < 1) { return m2; }
266 | else if ((h * 3) < 2) { return m1 + ((m2 - m1) * ((2/3) - h) * 6); }
267 | else { return m1; }
268 | }
269 | };
270 |
271 | if ($.cssHooks) {
272 | $.each(props, function(i, hook) {
273 | $.cssHooks[hook] = {
274 | set: function(elem, value) {
275 | value = $.color.normalize(value);
276 |
277 | if (!value.alpha) {
278 | value.alpha = 1;
279 | }
280 |
281 | elem.style[hook] = 'rgba(' + value.r + ',' + value.g + ',' + value.b + ',' + value.alpha + ')';
282 | }
283 | };
284 |
285 | $.fx.step[hook] = function(fx) {
286 | var val;
287 |
288 | if ( !fx.start || typeof fx.start === 'string' ) {
289 | if ( !fx.start ) {
290 | fx.start = $.css(fx.elem, hook);
291 | }
292 |
293 | fx.start = $.color.normalize(fx.start);
294 | fx.end = $.color.normalize(fx.end);
295 |
296 | if (!fx.start.alpha) {
297 | fx.start.alpha = 1;
298 | }
299 |
300 | if (!fx.end.alpha) {
301 | fx.end.alpha = 1;
302 | }
303 | }
304 |
305 | $.style(fx.elem, hook, 'rgba('
306 | + parseInt(fx.start.r + (fx.pos * (fx.end.r - fx.start.r)), 10) + ','
307 | + parseInt(fx.start.g + (fx.pos * (fx.end.g - fx.start.g)), 10) + ','
308 | + parseInt(fx.start.b + (fx.pos * (fx.end.b - fx.start.b)), 10) + ','
309 | + parseFloat(fx.start.alpha + (fx.pos * (fx.end.alpha - fx.start.alpha))) + ')'
310 | );
311 | };
312 | });
313 | }
314 | })(jQuery);
315 |
--------------------------------------------------------------------------------
/transform.js:
--------------------------------------------------------------------------------
1 | /*
2 | * transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate()
3 | *
4 | * limitations:
5 | * - requires jQuery 1.4.3+
6 | * - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**.
7 | * - transformOrigin is not accessible
8 | *
9 | * latest version and complete README available on Github:
10 | * https://github.com/louisremi/jquery.transform.js
11 | *
12 | * Copyright 2011 @louis_remi
13 | * Licensed under the MIT license.
14 | *
15 | * This saved you an hour of work?
16 | * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
17 | *
18 | */
19 | (function( $ ) {
20 |
21 | /*
22 | * Feature tests and global variables
23 | */
24 | var div = document.createElement('div'),
25 | divStyle = div.style,
26 | propertyName = 'transform',
27 | suffix = 'Transform',
28 | testProperties = [
29 | 'O' + suffix,
30 | 'ms' + suffix,
31 | 'Webkit' + suffix,
32 | 'Moz' + suffix,
33 | // prefix-less property
34 | propertyName
35 | ],
36 | i = testProperties.length,
37 | supportProperty,
38 | supportMatrixFilter,
39 | propertyHook,
40 | propertyGet,
41 | rMatrix = /Matrix([^)]*)/;
42 |
43 | // test different vendor prefixes of this property
44 | while ( i-- ) {
45 | if ( testProperties[i] in divStyle ) {
46 | $.support[propertyName] = supportProperty = testProperties[i];
47 | continue;
48 | }
49 | }
50 | // IE678 alternative
51 | if ( !supportProperty ) {
52 | $.support.matrixFilter = supportMatrixFilter = divStyle.filter === '';
53 | }
54 | // prevent IE memory leak
55 | div = divStyle = null;
56 |
57 | // px isn't the default unit of this property
58 | $.cssNumber[propertyName] = true;
59 |
60 | /*
61 | * fn.css() hooks
62 | */
63 | if ( supportProperty && supportProperty != propertyName ) {
64 | // Modern browsers can use jQuery.cssProps as a basic hook
65 | $.cssProps[propertyName] = supportProperty;
66 |
67 | // Firefox needs a complete hook because it stuffs matrix with 'px'
68 | if ( supportProperty == 'Moz' + suffix ) {
69 | propertyHook = {
70 | get: function( elem, computed ) {
71 | return (computed ?
72 | // remove 'px' from the computed matrix
73 | $.css( elem, supportProperty ).split('px').join(''):
74 | elem.style[supportProperty]
75 | )
76 | },
77 | set: function( elem, value ) {
78 | // remove 'px' from matrices
79 | elem.style[supportProperty] = /matrix[^)p]*\)/.test(value) ?
80 | value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, 'matrix$1$2px,$3px'):
81 | value;
82 | }
83 | }
84 | /* Fix two jQuery bugs still present in 1.5.1
85 | * - rupper is incompatible with IE9, see http://jqbug.com/8346
86 | * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402
87 | */
88 | } else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) {
89 | propertyHook = {
90 | get: function( elem, computed ) {
91 | return (computed ?
92 | $.css( elem, supportProperty.replace(/^ms/, 'Ms') ):
93 | elem.style[supportProperty]
94 | )
95 | }
96 | }
97 | }
98 | /* TODO: leverage hardware acceleration of 3d transform in Webkit only
99 | else if ( supportProperty == 'Webkit' + suffix && support3dTransform ) {
100 | propertyHook = {
101 | set: function( elem, value ) {
102 | elem.style[supportProperty] =
103 | value.replace();
104 | }
105 | }
106 | }*/
107 |
108 | } else if ( supportMatrixFilter ) {
109 | propertyHook = {
110 | get: function( elem, computed ) {
111 | var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ),
112 | matrix;
113 |
114 | if ( elemStyle && rMatrix.test( elemStyle.filter ) ) {
115 | matrix = RegExp.$1.split(',');
116 | matrix = [
117 | matrix[0].split('=')[1],
118 | matrix[2].split('=')[1],
119 | matrix[1].split('=')[1],
120 | matrix[3].split('=')[1]
121 | ];
122 | } else {
123 | matrix = [1,0,0,1];
124 | }
125 | matrix[4] = elemStyle ? elemStyle.left : 0;
126 | matrix[5] = elemStyle ? elemStyle.top : 0;
127 | return "matrix(" + matrix + ")";
128 | },
129 | set: function( elem, value, animate ) {
130 | var elemStyle = elem.style,
131 | currentStyle,
132 | Matrix,
133 | filter;
134 |
135 | if ( !animate ) {
136 | elemStyle.zoom = 1;
137 | }
138 |
139 | value = matrix(value);
140 |
141 | // rotate, scale and skew
142 | if ( !animate || animate.M ) {
143 | Matrix = [
144 | "Matrix("+
145 | "M11="+value[0],
146 | "M12="+value[2],
147 | "M21="+value[1],
148 | "M22="+value[3],
149 | "SizingMethod='auto expand'"
150 | ].join();
151 | filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || "";
152 |
153 | elemStyle.filter = rMatrix.test(filter) ?
154 | filter.replace(rMatrix, Matrix) :
155 | filter + " progid:DXImageTransform.Microsoft." + Matrix + ")";
156 |
157 | // center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie
158 | if ( (centerOrigin = $.transform.centerOrigin) ) {
159 | elemStyle[centerOrigin == 'margin' ? 'marginLeft' : 'left'] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + 'px';
160 | elemStyle[centerOrigin == 'margin' ? 'marginTop' : 'top'] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + 'px';
161 | }
162 | }
163 |
164 | // translate
165 | if ( !animate || animate.T ) {
166 | // We assume that the elements are absolute positionned inside a relative positionned wrapper
167 | elemStyle.left = value[4] + 'px';
168 | elemStyle.top = value[5] + 'px';
169 | }
170 | }
171 | }
172 | }
173 | // populate jQuery.cssHooks with the appropriate hook if necessary
174 | if ( propertyHook ) {
175 | $.cssHooks[propertyName] = propertyHook;
176 | }
177 | // we need a unique setter for the animation logic
178 | propertyGet = propertyHook && propertyHook.get || $.css;
179 |
180 | /*
181 | * fn.animate() hooks
182 | */
183 | $.fx.step.transform = function( fx ) {
184 | var elem = fx.elem,
185 | start = fx.start,
186 | end = fx.end,
187 | split,
188 | pos = fx.pos,
189 | transform,
190 | translate,
191 | rotate,
192 | scale,
193 | skew,
194 | T = false,
195 | M = false,
196 | prop;
197 | translate = rotate = scale = skew = '';
198 |
199 | // fx.end and fx.start need to be converted to their translate/rotate/scale/skew components
200 | // so that we can interpolate them
201 | if ( !start || typeof start === "string" ) {
202 | // the following block can be commented out with jQuery 1.5.1+, see #7912
203 | if (!start) {
204 | start = propertyGet( elem, supportProperty );
205 | }
206 |
207 | // force layout only once per animation
208 | if ( supportMatrixFilter ) {
209 | elem.style.zoom = 1;
210 | }
211 |
212 | // if the start computed matrix is in end, we are doing a relative animation
213 | split = end.split(start);
214 | if ( split.length == 2 ) {
215 | // remove the start computed matrix to make animations more accurate
216 | end = split.join('');
217 | fx.origin = start;
218 | start = 'none';
219 | }
220 |
221 | // start is either 'none' or a matrix(...) that has to be parsed
222 | fx.start = start = start == 'none'?
223 | {
224 | translate: [0,0],
225 | rotate: 0,
226 | scale: [1,1],
227 | skew: [0,0]
228 | }:
229 | unmatrix( toArray(start) );
230 |
231 | // fx.end has to be parsed and decomposed
232 | fx.end = end = ~end.indexOf('matrix')?
233 | // bullet-proof parser
234 | unmatrix(matrix(end)):
235 | // faster and more precise parser
236 | components(end);
237 |
238 | // get rid of properties that do not change
239 | for ( prop in start) {
240 | if ( prop == 'rotate' ?
241 | start[prop] == end[prop]:
242 | start[prop][0] == end[prop][0] && start[prop][1] == end[prop][1]
243 | ) {
244 | delete start[prop];
245 | }
246 | }
247 | }
248 |
249 | /*
250 | * We want a fast interpolation algorithm.
251 | * This implies avoiding function calls and sacrifying DRY principle:
252 | * - avoid $.each(function(){})
253 | * - round values using bitewise hacks, see http://jsperf.com/math-round-vs-hack/3
254 | */
255 | if ( start.translate ) {
256 | // round translate to the closest pixel
257 | translate = ' translate('+
258 | ((start.translate[0] + (end.translate[0] - start.translate[0]) * pos + .5) | 0) +'px,'+
259 | ((start.translate[1] + (end.translate[1] - start.translate[1]) * pos + .5) | 0) +'px'+
260 | ')';
261 | T = true;
262 | }
263 | if ( start.rotate != undefined ) {
264 | rotate = ' rotate('+ (start.rotate + (end.rotate - start.rotate) * pos) +'rad)';
265 | M = true;
266 | }
267 | if ( start.scale ) {
268 | scale = ' scale('+
269 | (start.scale[0] + (end.scale[0] - start.scale[0]) * pos) +','+
270 | (start.scale[1] + (end.scale[1] - start.scale[1]) * pos) +
271 | ')';
272 | M = true;
273 | }
274 | if ( start.skew ) {
275 | skew = ' skew('+
276 | (start.skew[0] + (end.skew[0] - start.skew[0]) * pos) +'rad,'+
277 | (start.skew[1] + (end.skew[1] - start.skew[1]) * pos) +'rad'+
278 | ')';
279 | M = true;
280 | }
281 |
282 | // In case of relative animation, restore the origin computed matrix here.
283 | transform = fx.origin ?
284 | fx.origin + translate + skew + scale + rotate:
285 | translate + rotate + scale + skew;
286 |
287 | propertyHook && propertyHook.set ?
288 | propertyHook.set( elem, transform, {M: M, T: T} ):
289 | elem.style[supportProperty] = transform;
290 | };
291 |
292 | /*
293 | * Utility functions
294 | */
295 |
296 | // turns a transform string into its 'matrix(A,B,C,D,X,Y)' form (as an array, though)
297 | function matrix( transform ) {
298 | transform = transform.split(')');
299 | var
300 | trim = $.trim
301 | // last element of the array is an empty string, get rid of it
302 | , i = transform.length -1
303 | , split, prop, val
304 | , A = 1
305 | , B = 0
306 | , C = 0
307 | , D = 1
308 | , A_, B_, C_, D_
309 | , tmp1, tmp2
310 | , X = 0
311 | , Y = 0
312 | ;
313 | // Loop through the transform properties, parse and multiply them
314 | while (i--) {
315 | split = transform[i].split('(');
316 | prop = trim(split[0]);
317 | val = split[1];
318 | A_ = B_ = C_ = D_ = 0;
319 |
320 | switch (prop) {
321 | case 'translateX':
322 | X += parseInt(val, 10);
323 | continue;
324 |
325 | case 'translateY':
326 | Y += parseInt(val, 10);
327 | continue;
328 |
329 | case 'translate':
330 | val = val.split(',');
331 | X += parseInt(val[0], 10);
332 | Y += parseInt(val[1] || 0, 10);
333 | continue;
334 |
335 | case 'rotate':
336 | val = toRadian(val);
337 | A_ = Math.cos(val);
338 | B_ = Math.sin(val);
339 | C_ = -Math.sin(val);
340 | D_ = Math.cos(val);
341 | break;
342 |
343 | case 'scaleX':
344 | A_ = val;
345 | D_ = 1;
346 | break;
347 |
348 | case 'scaleY':
349 | A_ = 1;
350 | D_ = val;
351 | break;
352 |
353 | case 'scale':
354 | val = val.split(',');
355 | A_ = val[0];
356 | D_ = val.length>1 ? val[1] : val[0];
357 | break;
358 |
359 | case 'skewX':
360 | A_ = D_ = 1;
361 | C_ = Math.tan(toRadian(val));
362 | break;
363 |
364 | case 'skewY':
365 | A_ = D_ = 1;
366 | B_ = Math.tan(toRadian(val));
367 | break;
368 |
369 | case 'skew':
370 | A_ = D_ = 1;
371 | val = val.split(',');
372 | C_ = Math.tan(toRadian(val[0]));
373 | B_ = Math.tan(toRadian(val[1] || 0));
374 | break;
375 |
376 | case 'matrix':
377 | val = val.split(',');
378 | A_ = +val[0];
379 | B_ = +val[1];
380 | C_ = +val[2];
381 | D_ = +val[3];
382 | X += parseInt(val[4], 10);
383 | Y += parseInt(val[5], 10);
384 | }
385 | // Matrix product
386 | tmp1 = A * A_ + B * C_;
387 | B = A * B_ + B * D_;
388 | tmp2 = C * A_ + D * C_;
389 | D = C * B_ + D * D_;
390 | A = tmp1;
391 | C = tmp2;
392 | }
393 | return [A,B,C,D,X,Y];
394 | }
395 |
396 | // turns a matrix into its rotate, scale and skew components
397 | // algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp
398 | function unmatrix(matrix) {
399 | var
400 | scaleX
401 | , scaleY
402 | , skew
403 | , A = matrix[0]
404 | , B = matrix[1]
405 | , C = matrix[2]
406 | , D = matrix[3]
407 | ;
408 |
409 | // Make sure matrix is not singular
410 | if ( A * D - B * C ) {
411 | // step (3)
412 | scaleX = Math.sqrt( A * A + B * B );
413 | A /= scaleX;
414 | B /= scaleX;
415 | // step (4)
416 | skew = A * C + B * D;
417 | C -= A * skew;
418 | D -= B * skew;
419 | // step (5)
420 | scaleY = Math.sqrt( C * C + D * D );
421 | C /= scaleY;
422 | D /= scaleY;
423 | skew /= scaleY;
424 | // step (6)
425 | if ( A * D < B * C ) {
426 | //scaleY = -scaleY;
427 | //skew = -skew;
428 | A = -A;
429 | B = -B;
430 | skew = -skew;
431 | scaleX = -scaleX;
432 | }
433 |
434 | // matrix is singular and cannot be interpolated
435 | } else {
436 | rotate = scaleX = scaleY = skew = 0;
437 | }
438 |
439 | return {
440 | translate: [+matrix[4], +matrix[5]],
441 | rotate: Math.atan2(B, A),
442 | scale: [scaleX, scaleY],
443 | skew: [skew, 0]
444 | }
445 | }
446 |
447 | // parse tranform components of a transform string not containing 'matrix(...)'
448 | function components( transform ) {
449 | // split the != transforms
450 | transform = transform.split(')');
451 |
452 | var translate = [0,0],
453 | rotate = 0,
454 | scale = [1,1],
455 | skew = [0,0],
456 | i = transform.length -1,
457 | trim = $.trim,
458 | split, name, value;
459 |
460 | // add components
461 | while ( i-- ) {
462 | split = transform[i].split('(');
463 | name = trim(split[0]);
464 | value = split[1];
465 |
466 | if (name == 'translateX') {
467 | translate[0] += parseInt(value, 10);
468 |
469 | } else if (name == 'translateY') {
470 | translate[1] += parseInt(value, 10);
471 |
472 | } else if (name == 'translate') {
473 | value = value.split(',');
474 | translate[0] += parseInt(value[0], 10);
475 | translate[1] += parseInt(value[1] || 0, 10);
476 |
477 | } else if (name == 'rotate') {
478 | rotate += toRadian(value);
479 |
480 | } else if (name == 'scaleX') {
481 | scale[0] *= value;
482 |
483 | } else if (name == 'scaleY') {
484 | scale[1] *= value;
485 |
486 | } else if (name == 'scale') {
487 | value = value.split(',');
488 | scale[0] *= value[0];
489 | scale[1] *= (value.length>1? value[1] : value[0]);
490 |
491 | } else if (name == 'skewX') {
492 | skew[0] += toRadian(value);
493 |
494 | } else if (name == 'skewY') {
495 | skew[1] += toRadian(value);
496 |
497 | } else if (name == 'skew') {
498 | value = value.split(',');
499 | skew[0] += toRadian(value[0]);
500 | skew[1] += toRadian(value[1] || '0');
501 | }
502 | }
503 |
504 | return {
505 | translate: translate,
506 | rotate: rotate,
507 | scale: scale,
508 | skew: skew
509 | };
510 | }
511 |
512 | // converts an angle string in any unit to a radian Float
513 | function toRadian(value) {
514 | return ~value.indexOf('deg') ?
515 | parseInt(value,10) * (Math.PI * 2 / 360):
516 | ~value.indexOf('grad') ?
517 | parseInt(value,10) * (Math.PI/200):
518 | parseFloat(value);
519 | }
520 |
521 | // Converts 'matrix(A,B,C,D,X,Y)' to [A,B,C,D,X,Y]
522 | function toArray(matrix) {
523 | // Fremove the unit of X and Y for Firefox
524 | matrix = /\(([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix);
525 | return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]];
526 | }
527 |
528 | $.transform = {
529 | centerOrigin: 'margin'
530 | };
531 |
532 | })( jQuery );
--------------------------------------------------------------------------------
/tests/qunit/qunit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * QUnit - A JavaScript Unit Testing Framework
3 | *
4 | * http://docs.jquery.com/QUnit
5 | *
6 | * Copyright (c) 2009 John Resig, Jörn Zaefferer
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | */
10 |
11 | (function(window) {
12 |
13 | var QUnit = {
14 |
15 | // call on start of module test to prepend name to all tests
16 | module: function(name, testEnvironment) {
17 | config.currentModule = name;
18 |
19 | synchronize(function() {
20 | if ( config.currentModule ) {
21 | QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
22 | }
23 |
24 | config.currentModule = name;
25 | config.moduleTestEnvironment = testEnvironment;
26 | config.moduleStats = { all: 0, bad: 0 };
27 |
28 | QUnit.moduleStart( name, testEnvironment );
29 | });
30 | },
31 |
32 | asyncTest: function(testName, expected, callback) {
33 | if ( arguments.length === 2 ) {
34 | callback = expected;
35 | expected = 0;
36 | }
37 |
38 | QUnit.test(testName, expected, callback, true);
39 | },
40 |
41 | test: function(testName, expected, callback, async) {
42 | var name = '' + testName + '', testEnvironment, testEnvironmentArg;
43 |
44 | if ( arguments.length === 2 ) {
45 | callback = expected;
46 | expected = null;
47 | }
48 | // is 2nd argument a testEnvironment?
49 | if ( expected && typeof expected === 'object') {
50 | testEnvironmentArg = expected;
51 | expected = null;
52 | }
53 |
54 | if ( config.currentModule ) {
55 | name = '' + config.currentModule + ": " + name;
56 | }
57 |
58 | if ( !validTest(config.currentModule + ": " + testName) ) {
59 | return;
60 | }
61 |
62 | synchronize(function() {
63 |
64 | testEnvironment = extend({
65 | setup: function() {},
66 | teardown: function() {}
67 | }, config.moduleTestEnvironment);
68 | if (testEnvironmentArg) {
69 | extend(testEnvironment,testEnvironmentArg);
70 | }
71 |
72 | QUnit.testStart( testName, testEnvironment );
73 |
74 | // allow utility functions to access the current test environment
75 | QUnit.current_testEnvironment = testEnvironment;
76 |
77 | config.assertions = [];
78 | config.expected = expected;
79 |
80 | var tests = id("qunit-tests");
81 | if (tests) {
82 | var b = document.createElement("strong");
83 | b.innerHTML = "Running " + name;
84 | var li = document.createElement("li");
85 | li.appendChild( b );
86 | li.id = "current-test-output";
87 | tests.appendChild( li )
88 | }
89 |
90 | try {
91 | if ( !config.pollution ) {
92 | saveGlobal();
93 | }
94 |
95 | testEnvironment.setup.call(testEnvironment);
96 | } catch(e) {
97 | QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
98 | }
99 | });
100 |
101 | synchronize(function() {
102 | if ( async ) {
103 | QUnit.stop();
104 | }
105 |
106 | try {
107 | callback.call(testEnvironment);
108 | } catch(e) {
109 | fail("Test " + name + " died, exception and test follows", e, callback);
110 | QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
111 | // else next test will carry the responsibility
112 | saveGlobal();
113 |
114 | // Restart the tests if they're blocking
115 | if ( config.blocking ) {
116 | start();
117 | }
118 | }
119 | });
120 |
121 | synchronize(function() {
122 | try {
123 | checkPollution();
124 | testEnvironment.teardown.call(testEnvironment);
125 | } catch(e) {
126 | QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
127 | }
128 | });
129 |
130 | synchronize(function() {
131 | try {
132 | QUnit.reset();
133 | } catch(e) {
134 | fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
135 | }
136 |
137 | if ( config.expected && config.expected != config.assertions.length ) {
138 | QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
139 | }
140 |
141 | var good = 0, bad = 0,
142 | tests = id("qunit-tests");
143 |
144 | config.stats.all += config.assertions.length;
145 | config.moduleStats.all += config.assertions.length;
146 |
147 | if ( tests ) {
148 | var ol = document.createElement("ol");
149 |
150 | for ( var i = 0; i < config.assertions.length; i++ ) {
151 | var assertion = config.assertions[i];
152 |
153 | var li = document.createElement("li");
154 | li.className = assertion.result ? "pass" : "fail";
155 | li.innerHTML = assertion.message || "(no message)";
156 | ol.appendChild( li );
157 |
158 | if ( assertion.result ) {
159 | good++;
160 | } else {
161 | bad++;
162 | config.stats.bad++;
163 | config.moduleStats.bad++;
164 | }
165 | }
166 | if (bad == 0) {
167 | ol.style.display = "none";
168 | }
169 |
170 | var b = document.createElement("strong");
171 | b.innerHTML = name + " (" + bad + ", " + good + ", " + config.assertions.length + ")";
172 |
173 | addEvent(b, "click", function() {
174 | var next = b.nextSibling, display = next.style.display;
175 | next.style.display = display === "none" ? "block" : "none";
176 | });
177 |
178 | addEvent(b, "dblclick", function(e) {
179 | var target = e && e.target ? e.target : window.event.srcElement;
180 | if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
181 | target = target.parentNode;
182 | }
183 | if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
184 | window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, ""));
185 | }
186 | });
187 |
188 | var li = id("current-test-output");
189 | li.id = "";
190 | li.className = bad ? "fail" : "pass";
191 | li.removeChild( li.firstChild );
192 | li.appendChild( b );
193 | li.appendChild( ol );
194 |
195 | if ( bad ) {
196 | var toolbar = id("qunit-testrunner-toolbar");
197 | if ( toolbar ) {
198 | toolbar.style.display = "block";
199 | id("qunit-filter-pass").disabled = null;
200 | id("qunit-filter-missing").disabled = null;
201 | }
202 | }
203 |
204 | } else {
205 | for ( var i = 0; i < config.assertions.length; i++ ) {
206 | if ( !config.assertions[i].result ) {
207 | bad++;
208 | config.stats.bad++;
209 | config.moduleStats.bad++;
210 | }
211 | }
212 | }
213 |
214 | QUnit.testDone( testName, bad, config.assertions.length );
215 |
216 | if ( !window.setTimeout && !config.queue.length ) {
217 | done();
218 | }
219 | });
220 |
221 | if ( window.setTimeout && !config.doneTimer ) {
222 | config.doneTimer = window.setTimeout(function(){
223 | if ( !config.queue.length ) {
224 | done();
225 | } else {
226 | synchronize( done );
227 | }
228 | }, 13);
229 | }
230 | },
231 |
232 | /**
233 | * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
234 | */
235 | expect: function(asserts) {
236 | config.expected = asserts;
237 | },
238 |
239 | /**
240 | * Asserts true.
241 | * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
242 | */
243 | ok: function(a, msg) {
244 | msg = escapeHtml(msg);
245 | QUnit.log(a, msg);
246 |
247 | config.assertions.push({
248 | result: !!a,
249 | message: msg
250 | });
251 | },
252 |
253 | /**
254 | * Checks that the first two arguments are equal, with an optional message.
255 | * Prints out both actual and expected values.
256 | *
257 | * Prefered to ok( actual == expected, message )
258 | *
259 | * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
260 | *
261 | * @param Object actual
262 | * @param Object expected
263 | * @param String message (optional)
264 | */
265 | equal: function(actual, expected, message) {
266 | push(expected == actual, actual, expected, message);
267 | },
268 |
269 | notEqual: function(actual, expected, message) {
270 | push(expected != actual, actual, expected, message);
271 | },
272 |
273 | deepEqual: function(actual, expected, message) {
274 | push(QUnit.equiv(actual, expected), actual, expected, message);
275 | },
276 |
277 | notDeepEqual: function(actual, expected, message) {
278 | push(!QUnit.equiv(actual, expected), actual, expected, message);
279 | },
280 |
281 | strictEqual: function(actual, expected, message) {
282 | push(expected === actual, actual, expected, message);
283 | },
284 |
285 | notStrictEqual: function(actual, expected, message) {
286 | push(expected !== actual, actual, expected, message);
287 | },
288 |
289 | raises: function(fn, message) {
290 | try {
291 | fn();
292 | ok( false, message );
293 | }
294 | catch (e) {
295 | ok( true, message );
296 | }
297 | },
298 |
299 | start: function() {
300 | // A slight delay, to avoid any current callbacks
301 | if ( window.setTimeout ) {
302 | window.setTimeout(function() {
303 | if ( config.timeout ) {
304 | clearTimeout(config.timeout);
305 | }
306 |
307 | config.blocking = false;
308 | process();
309 | }, 13);
310 | } else {
311 | config.blocking = false;
312 | process();
313 | }
314 | },
315 |
316 | stop: function(timeout) {
317 | config.blocking = true;
318 |
319 | if ( timeout && window.setTimeout ) {
320 | config.timeout = window.setTimeout(function() {
321 | QUnit.ok( false, "Test timed out" );
322 | QUnit.start();
323 | }, timeout);
324 | }
325 | }
326 |
327 | };
328 |
329 | // Backwards compatibility, deprecated
330 | QUnit.equals = QUnit.equal;
331 | QUnit.same = QUnit.deepEqual;
332 |
333 | // Maintain internal state
334 | var config = {
335 | // The queue of tests to run
336 | queue: [],
337 |
338 | // block until document ready
339 | blocking: true
340 | };
341 |
342 | // Load paramaters
343 | (function() {
344 | var location = window.location || { search: "", protocol: "file:" },
345 | GETParams = location.search.slice(1).split('&');
346 |
347 | for ( var i = 0; i < GETParams.length; i++ ) {
348 | GETParams[i] = decodeURIComponent( GETParams[i] );
349 | if ( GETParams[i] === "noglobals" ) {
350 | GETParams.splice( i, 1 );
351 | i--;
352 | config.noglobals = true;
353 | } else if ( GETParams[i].search('=') > -1 ) {
354 | GETParams.splice( i, 1 );
355 | i--;
356 | }
357 | }
358 |
359 | // restrict modules/tests by get parameters
360 | config.filters = GETParams;
361 |
362 | // Figure out if we're running the tests from a server or not
363 | QUnit.isLocal = !!(location.protocol === 'file:');
364 | })();
365 |
366 | // Expose the API as global variables, unless an 'exports'
367 | // object exists, in that case we assume we're in CommonJS
368 | if ( typeof exports === "undefined" || typeof require === "undefined" ) {
369 | extend(window, QUnit);
370 | window.QUnit = QUnit;
371 | } else {
372 | extend(exports, QUnit);
373 | exports.QUnit = QUnit;
374 | }
375 |
376 | // define these after exposing globals to keep them in these QUnit namespace only
377 | extend(QUnit, {
378 | config: config,
379 |
380 | // Initialize the configuration options
381 | init: function() {
382 | extend(config, {
383 | stats: { all: 0, bad: 0 },
384 | moduleStats: { all: 0, bad: 0 },
385 | started: +new Date,
386 | updateRate: 1000,
387 | blocking: false,
388 | autostart: true,
389 | autorun: false,
390 | assertions: [],
391 | filters: [],
392 | queue: []
393 | });
394 |
395 | var tests = id("qunit-tests"),
396 | banner = id("qunit-banner"),
397 | result = id("qunit-testresult");
398 |
399 | if ( tests ) {
400 | tests.innerHTML = "";
401 | }
402 |
403 | if ( banner ) {
404 | banner.className = "";
405 | }
406 |
407 | if ( result ) {
408 | result.parentNode.removeChild( result );
409 | }
410 | },
411 |
412 | /**
413 | * Resets the test setup. Useful for tests that modify the DOM.
414 | */
415 | reset: function() {
416 | if ( window.jQuery ) {
417 | jQuery("#main, #qunit-fixture").html( config.fixture );
418 | }
419 | },
420 |
421 | /**
422 | * Trigger an event on an element.
423 | *
424 | * @example triggerEvent( document.body, "click" );
425 | *
426 | * @param DOMElement elem
427 | * @param String type
428 | */
429 | triggerEvent: function( elem, type, event ) {
430 | if ( document.createEvent ) {
431 | event = document.createEvent("MouseEvents");
432 | event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
433 | 0, 0, 0, 0, 0, false, false, false, false, 0, null);
434 | elem.dispatchEvent( event );
435 |
436 | } else if ( elem.fireEvent ) {
437 | elem.fireEvent("on"+type);
438 | }
439 | },
440 |
441 | // Safe object type checking
442 | is: function( type, obj ) {
443 | return QUnit.objectType( obj ) == type;
444 | },
445 |
446 | objectType: function( obj ) {
447 | if (typeof obj === "undefined") {
448 | return "undefined";
449 |
450 | // consider: typeof null === object
451 | }
452 | if (obj === null) {
453 | return "null";
454 | }
455 |
456 | var type = Object.prototype.toString.call( obj )
457 | .match(/^\[object\s(.*)\]$/)[1] || '';
458 |
459 | switch (type) {
460 | case 'Number':
461 | if (isNaN(obj)) {
462 | return "nan";
463 | } else {
464 | return "number";
465 | }
466 | case 'String':
467 | case 'Boolean':
468 | case 'Array':
469 | case 'Date':
470 | case 'RegExp':
471 | case 'Function':
472 | return type.toLowerCase();
473 | }
474 | if (typeof obj === "object") {
475 | return "object";
476 | }
477 | return undefined;
478 | },
479 |
480 | // Logging callbacks
481 | begin: function() {},
482 | done: function(failures, total) {},
483 | log: function(result, message) {},
484 | testStart: function(name, testEnvironment) {},
485 | testDone: function(name, failures, total) {},
486 | moduleStart: function(name, testEnvironment) {},
487 | moduleDone: function(name, failures, total) {}
488 | });
489 |
490 | if ( typeof document === "undefined" || document.readyState === "complete" ) {
491 | config.autorun = true;
492 | }
493 |
494 | addEvent(window, "load", function() {
495 | QUnit.begin();
496 |
497 | // Initialize the config, saving the execution queue
498 | var oldconfig = extend({}, config);
499 | QUnit.init();
500 | extend(config, oldconfig);
501 |
502 | config.blocking = false;
503 |
504 | var userAgent = id("qunit-userAgent");
505 | if ( userAgent ) {
506 | userAgent.innerHTML = navigator.userAgent;
507 | }
508 |
509 | var toolbar = id("qunit-testrunner-toolbar");
510 | if ( toolbar ) {
511 | toolbar.style.display = "none";
512 |
513 | var filter = document.createElement("input");
514 | filter.type = "checkbox";
515 | filter.id = "qunit-filter-pass";
516 | filter.disabled = true;
517 | addEvent( filter, "click", function() {
518 | var li = document.getElementsByTagName("li");
519 | for ( var i = 0; i < li.length; i++ ) {
520 | if ( li[i].className.indexOf("pass") > -1 ) {
521 | li[i].style.display = filter.checked ? "none" : "";
522 | }
523 | }
524 | });
525 | toolbar.appendChild( filter );
526 |
527 | var label = document.createElement("label");
528 | label.setAttribute("for", "qunit-filter-pass");
529 | label.innerHTML = "Hide passed tests";
530 | toolbar.appendChild( label );
531 |
532 | var missing = document.createElement("input");
533 | missing.type = "checkbox";
534 | missing.id = "qunit-filter-missing";
535 | missing.disabled = true;
536 | addEvent( missing, "click", function() {
537 | var li = document.getElementsByTagName("li");
538 | for ( var i = 0; i < li.length; i++ ) {
539 | if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
540 | li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
541 | }
542 | }
543 | });
544 | toolbar.appendChild( missing );
545 |
546 | label = document.createElement("label");
547 | label.setAttribute("for", "qunit-filter-missing");
548 | label.innerHTML = "Hide missing tests (untested code is broken code)";
549 | toolbar.appendChild( label );
550 | }
551 |
552 | var main = id('main') || id('qunit-fixture');
553 | if ( main ) {
554 | config.fixture = main.innerHTML;
555 | }
556 |
557 | if (config.autostart) {
558 | QUnit.start();
559 | }
560 | });
561 |
562 | function done() {
563 | if ( config.doneTimer && window.clearTimeout ) {
564 | window.clearTimeout( config.doneTimer );
565 | config.doneTimer = null;
566 | }
567 |
568 | if ( config.queue.length ) {
569 | config.doneTimer = window.setTimeout(function(){
570 | if ( !config.queue.length ) {
571 | done();
572 | } else {
573 | synchronize( done );
574 | }
575 | }, 13);
576 |
577 | return;
578 | }
579 |
580 | config.autorun = true;
581 |
582 | // Log the last module results
583 | if ( config.currentModule ) {
584 | QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
585 | }
586 |
587 | var banner = id("qunit-banner"),
588 | tests = id("qunit-tests"),
589 | html = ['Tests completed in ',
590 | +new Date - config.started, ' milliseconds.
',
591 | '', config.stats.all - config.stats.bad, ' tests of ', config.stats.all, ' passed, ', config.stats.bad,' failed.'].join('');
592 |
593 | if ( banner ) {
594 | banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
595 | }
596 |
597 | if ( tests ) {
598 | var result = id("qunit-testresult");
599 |
600 | if ( !result ) {
601 | result = document.createElement("p");
602 | result.id = "qunit-testresult";
603 | result.className = "result";
604 | tests.parentNode.insertBefore( result, tests.nextSibling );
605 | }
606 |
607 | result.innerHTML = html;
608 | }
609 |
610 | QUnit.done( config.stats.bad, config.stats.all );
611 | }
612 |
613 | function validTest( name ) {
614 | var i = config.filters.length,
615 | run = false;
616 |
617 | if ( !i ) {
618 | return true;
619 | }
620 |
621 | while ( i-- ) {
622 | var filter = config.filters[i],
623 | not = filter.charAt(0) == '!';
624 |
625 | if ( not ) {
626 | filter = filter.slice(1);
627 | }
628 |
629 | if ( name.indexOf(filter) !== -1 ) {
630 | return !not;
631 | }
632 |
633 | if ( not ) {
634 | run = true;
635 | }
636 | }
637 |
638 | return run;
639 | }
640 |
641 | function escapeHtml(s) {
642 | s = s === null ? "" : s + "";
643 | return s.replace(/[\&"<>\\]/g, function(s) {
644 | switch(s) {
645 | case "&": return "&";
646 | case "\\": return "\\\\";
647 | case '"': return '\"';
648 | case "<": return "<";
649 | case ">": return ">";
650 | default: return s;
651 | }
652 | });
653 | }
654 |
655 | function push(result, actual, expected, message) {
656 | message = escapeHtml(message) || (result ? "okay" : "failed");
657 | message = '' + message + "";
658 | expected = escapeHtml(QUnit.jsDump.parse(expected));
659 | actual = escapeHtml(QUnit.jsDump.parse(actual));
660 | var output = message + ', expected: ' + expected + '';
661 | if (actual != expected) {
662 | output += ' result: ' + actual + ', diff: ' + QUnit.diff(expected, actual);
663 | }
664 |
665 | // can't use ok, as that would double-escape messages
666 | QUnit.log(result, output);
667 | config.assertions.push({
668 | result: !!result,
669 | message: output
670 | });
671 | }
672 |
673 | function synchronize( callback ) {
674 | config.queue.push( callback );
675 |
676 | if ( config.autorun && !config.blocking ) {
677 | process();
678 | }
679 | }
680 |
681 | function process() {
682 | var start = (new Date()).getTime();
683 |
684 | while ( config.queue.length && !config.blocking ) {
685 | if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
686 | config.queue.shift()();
687 |
688 | } else {
689 | setTimeout( process, 13 );
690 | break;
691 | }
692 | }
693 | }
694 |
695 | function saveGlobal() {
696 | config.pollution = [];
697 |
698 | if ( config.noglobals ) {
699 | for ( var key in window ) {
700 | config.pollution.push( key );
701 | }
702 | }
703 | }
704 |
705 | function checkPollution( name ) {
706 | var old = config.pollution;
707 | saveGlobal();
708 |
709 | var newGlobals = diff( old, config.pollution );
710 | if ( newGlobals.length > 0 ) {
711 | ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
712 | config.expected++;
713 | }
714 |
715 | var deletedGlobals = diff( config.pollution, old );
716 | if ( deletedGlobals.length > 0 ) {
717 | ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
718 | config.expected++;
719 | }
720 | }
721 |
722 | // returns a new Array with the elements that are in a but not in b
723 | function diff( a, b ) {
724 | var result = a.slice();
725 | for ( var i = 0; i < result.length; i++ ) {
726 | for ( var j = 0; j < b.length; j++ ) {
727 | if ( result[i] === b[j] ) {
728 | result.splice(i, 1);
729 | i--;
730 | break;
731 | }
732 | }
733 | }
734 | return result;
735 | }
736 |
737 | function fail(message, exception, callback) {
738 | if ( typeof console !== "undefined" && console.error && console.warn ) {
739 | console.error(message);
740 | console.error(exception);
741 | console.warn(callback.toString());
742 |
743 | } else if ( window.opera && opera.postError ) {
744 | opera.postError(message, exception, callback.toString);
745 | }
746 | }
747 |
748 | function extend(a, b) {
749 | for ( var prop in b ) {
750 | a[prop] = b[prop];
751 | }
752 |
753 | return a;
754 | }
755 |
756 | function addEvent(elem, type, fn) {
757 | if ( elem.addEventListener ) {
758 | elem.addEventListener( type, fn, false );
759 | } else if ( elem.attachEvent ) {
760 | elem.attachEvent( "on" + type, fn );
761 | } else {
762 | fn();
763 | }
764 | }
765 |
766 | function id(name) {
767 | return !!(typeof document !== "undefined" && document && document.getElementById) &&
768 | document.getElementById( name );
769 | }
770 |
771 | // Test for equality any JavaScript type.
772 | // Discussions and reference: http://philrathe.com/articles/equiv
773 | // Test suites: http://philrathe.com/tests/equiv
774 | // Author: Philippe Rathé
775 | QUnit.equiv = function () {
776 |
777 | var innerEquiv; // the real equiv function
778 | var callers = []; // stack to decide between skip/abort functions
779 | var parents = []; // stack to avoiding loops from circular referencing
780 |
781 | // Call the o related callback with the given arguments.
782 | function bindCallbacks(o, callbacks, args) {
783 | var prop = QUnit.objectType(o);
784 | if (prop) {
785 | if (QUnit.objectType(callbacks[prop]) === "function") {
786 | return callbacks[prop].apply(callbacks, args);
787 | } else {
788 | return callbacks[prop]; // or undefined
789 | }
790 | }
791 | }
792 |
793 | var callbacks = function () {
794 |
795 | // for string, boolean, number and null
796 | function useStrictEquality(b, a) {
797 | if (b instanceof a.constructor || a instanceof b.constructor) {
798 | // to catch short annotaion VS 'new' annotation of a declaration
799 | // e.g. var i = 1;
800 | // var j = new Number(1);
801 | return a == b;
802 | } else {
803 | return a === b;
804 | }
805 | }
806 |
807 | return {
808 | "string": useStrictEquality,
809 | "boolean": useStrictEquality,
810 | "number": useStrictEquality,
811 | "null": useStrictEquality,
812 | "undefined": useStrictEquality,
813 |
814 | "nan": function (b) {
815 | return isNaN(b);
816 | },
817 |
818 | "date": function (b, a) {
819 | return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();
820 | },
821 |
822 | "regexp": function (b, a) {
823 | return QUnit.objectType(b) === "regexp" &&
824 | a.source === b.source && // the regex itself
825 | a.global === b.global && // and its modifers (gmi) ...
826 | a.ignoreCase === b.ignoreCase &&
827 | a.multiline === b.multiline;
828 | },
829 |
830 | // - skip when the property is a method of an instance (OOP)
831 | // - abort otherwise,
832 | // initial === would have catch identical references anyway
833 | "function": function () {
834 | var caller = callers[callers.length - 1];
835 | return caller !== Object &&
836 | typeof caller !== "undefined";
837 | },
838 |
839 | "array": function (b, a) {
840 | var i, j, loop;
841 | var len;
842 |
843 | // b could be an object literal here
844 | if ( ! (QUnit.objectType(b) === "array")) {
845 | return false;
846 | }
847 |
848 | len = a.length;
849 | if (len !== b.length) { // safe and faster
850 | return false;
851 | }
852 |
853 | //track reference to avoid circular references
854 | parents.push(a);
855 | for (i = 0; i < len; i++) {
856 | loop = false;
857 | for(j=0;j= 0) {
1002 | type = "array";
1003 | } else {
1004 | type = typeof obj;
1005 | }
1006 | return type;
1007 | },
1008 | separator:function() {
1009 | return this.multiline ? this.HTML ? '
' : '\n' : this.HTML ? ' ' : ' ';
1010 | },
1011 | indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
1012 | if ( !this.multiline )
1013 | return '';
1014 | var chr = this.indentChar;
1015 | if ( this.HTML )
1016 | chr = chr.replace(/\t/g,' ').replace(/ /g,' ');
1017 | return Array( this._depth_ + (extra||0) ).join(chr);
1018 | },
1019 | up:function( a ) {
1020 | this._depth_ += a || 1;
1021 | },
1022 | down:function( a ) {
1023 | this._depth_ -= a || 1;
1024 | },
1025 | setParser:function( name, parser ) {
1026 | this.parsers[name] = parser;
1027 | },
1028 | // The next 3 are exposed so you can use them
1029 | quote:quote,
1030 | literal:literal,
1031 | join:join,
1032 | //
1033 | _depth_: 1,
1034 | // This is the list of parsers, to modify them, use jsDump.setParser
1035 | parsers:{
1036 | window: '[Window]',
1037 | document: '[Document]',
1038 | error:'[ERROR]', //when no parser is found, shouldn't happen
1039 | unknown: '[Unknown]',
1040 | 'null':'null',
1041 | undefined:'undefined',
1042 | 'function':function( fn ) {
1043 | var ret = 'function',
1044 | name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
1045 | if ( name )
1046 | ret += ' ' + name;
1047 | ret += '(';
1048 |
1049 | ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
1050 | return join( ret, this.parse(fn,'functionCode'), '}' );
1051 | },
1052 | array: array,
1053 | nodelist: array,
1054 | arguments: array,
1055 | object:function( map ) {
1056 | var ret = [ ];
1057 | this.up();
1058 | for ( var key in map )
1059 | ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
1060 | this.down();
1061 | return join( '{', ret, '}' );
1062 | },
1063 | node:function( node ) {
1064 | var open = this.HTML ? '<' : '<',
1065 | close = this.HTML ? '>' : '>';
1066 |
1067 | var tag = node.nodeName.toLowerCase(),
1068 | ret = open + tag;
1069 |
1070 | for ( var a in this.DOMAttrs ) {
1071 | var val = node[this.DOMAttrs[a]];
1072 | if ( val )
1073 | ret += ' ' + a + '=' + this.parse( val, 'attribute' );
1074 | }
1075 | return ret + close + open + '/' + tag + close;
1076 | },
1077 | functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
1078 | var l = fn.length;
1079 | if ( !l ) return '';
1080 |
1081 | var args = Array(l);
1082 | while ( l-- )
1083 | args[l] = String.fromCharCode(97+l);//97 is 'a'
1084 | return ' ' + args.join(', ') + ' ';
1085 | },
1086 | key:quote, //object calls it internally, the key part of an item in a map
1087 | functionCode:'[code]', //function calls it internally, it's the content of the function
1088 | attribute:quote, //node calls it internally, it's an html attribute value
1089 | string:quote,
1090 | date:quote,
1091 | regexp:literal, //regex
1092 | number:literal,
1093 | 'boolean':literal
1094 | },
1095 | DOMAttrs:{//attributes to dump from nodes, name=>realName
1096 | id:'id',
1097 | name:'name',
1098 | 'class':'className'
1099 | },
1100 | HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
1101 | indentChar:' ',//indentation unit
1102 | multiline:false //if true, items in a collection, are separated by a \n, else just a space.
1103 | };
1104 |
1105 | return jsDump;
1106 | })();
1107 |
1108 | // from Sizzle.js
1109 | function getText( elems ) {
1110 | var ret = "", elem;
1111 |
1112 | for ( var i = 0; elems[i]; i++ ) {
1113 | elem = elems[i];
1114 |
1115 | // Get the text from text nodes and CDATA nodes
1116 | if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
1117 | ret += elem.nodeValue;
1118 |
1119 | // Traverse everything else, except comment nodes
1120 | } else if ( elem.nodeType !== 8 ) {
1121 | ret += getText( elem.childNodes );
1122 | }
1123 | }
1124 |
1125 | return ret;
1126 | };
1127 |
1128 | /*
1129 | * Javascript Diff Algorithm
1130 | * By John Resig (http://ejohn.org/)
1131 | * Modified by Chu Alan "sprite"
1132 | *
1133 | * Released under the MIT license.
1134 | *
1135 | * More Info:
1136 | * http://ejohn.org/projects/javascript-diff-algorithm/
1137 | *
1138 | * Usage: QUnit.diff(expected, actual)
1139 | *
1140 | * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over"
1141 | */
1142 | QUnit.diff = (function() {
1143 | function diff(o, n){
1144 | var ns = new Object();
1145 | var os = new Object();
1146 |
1147 | for (var i = 0; i < n.length; i++) {
1148 | if (ns[n[i]] == null)
1149 | ns[n[i]] = {
1150 | rows: new Array(),
1151 | o: null
1152 | };
1153 | ns[n[i]].rows.push(i);
1154 | }
1155 |
1156 | for (var i = 0; i < o.length; i++) {
1157 | if (os[o[i]] == null)
1158 | os[o[i]] = {
1159 | rows: new Array(),
1160 | n: null
1161 | };
1162 | os[o[i]].rows.push(i);
1163 | }
1164 |
1165 | for (var i in ns) {
1166 | if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
1167 | n[ns[i].rows[0]] = {
1168 | text: n[ns[i].rows[0]],
1169 | row: os[i].rows[0]
1170 | };
1171 | o[os[i].rows[0]] = {
1172 | text: o[os[i].rows[0]],
1173 | row: ns[i].rows[0]
1174 | };
1175 | }
1176 | }
1177 |
1178 | for (var i = 0; i < n.length - 1; i++) {
1179 | if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&
1180 | n[i + 1] == o[n[i].row + 1]) {
1181 | n[i + 1] = {
1182 | text: n[i + 1],
1183 | row: n[i].row + 1
1184 | };
1185 | o[n[i].row + 1] = {
1186 | text: o[n[i].row + 1],
1187 | row: i + 1
1188 | };
1189 | }
1190 | }
1191 |
1192 | for (var i = n.length - 1; i > 0; i--) {
1193 | if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
1194 | n[i - 1] == o[n[i].row - 1]) {
1195 | n[i - 1] = {
1196 | text: n[i - 1],
1197 | row: n[i].row - 1
1198 | };
1199 | o[n[i].row - 1] = {
1200 | text: o[n[i].row - 1],
1201 | row: i - 1
1202 | };
1203 | }
1204 | }
1205 |
1206 | return {
1207 | o: o,
1208 | n: n
1209 | };
1210 | }
1211 |
1212 | return function(o, n){
1213 | o = o.replace(/\s+$/, '');
1214 | n = n.replace(/\s+$/, '');
1215 | var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));
1216 |
1217 | var str = "";
1218 |
1219 | var oSpace = o.match(/\s+/g);
1220 | if (oSpace == null) {
1221 | oSpace = [" "];
1222 | }
1223 | else {
1224 | oSpace.push(" ");
1225 | }
1226 | var nSpace = n.match(/\s+/g);
1227 | if (nSpace == null) {
1228 | nSpace = [" "];
1229 | }
1230 | else {
1231 | nSpace.push(" ");
1232 | }
1233 |
1234 | if (out.n.length == 0) {
1235 | for (var i = 0; i < out.o.length; i++) {
1236 | str += '' + out.o[i] + oSpace[i] + "";
1237 | }
1238 | }
1239 | else {
1240 | if (out.n[0].text == null) {
1241 | for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
1242 | str += '' + out.o[n] + oSpace[n] + "";
1243 | }
1244 | }
1245 |
1246 | for (var i = 0; i < out.n.length; i++) {
1247 | if (out.n[i].text == null) {
1248 | str += '' + out.n[i] + nSpace[i] + "";
1249 | }
1250 | else {
1251 | var pre = "";
1252 |
1253 | for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
1254 | pre += '' + out.o[n] + oSpace[n] + "";
1255 | }
1256 | str += " " + out.n[i].text + nSpace[i] + pre;
1257 | }
1258 | }
1259 | }
1260 |
1261 | return str;
1262 | }
1263 | })();
1264 |
1265 | })(this);
1266 |
--------------------------------------------------------------------------------