Skip to content

Commit 7f2cc46

Browse files
gibson042dmethvin
authored andcommitted
Fix #11767. Modularize build and unit tests for exluding effects.
Closes jquerygh-785. To build a version of jQuery without effects, use `grunt build:*:*:-effects`. The unit tests feature-check for the interfaces and skip the unit tests for effects if they don't detect it.
1 parent 82d4c72 commit 7f2cc46

File tree

9 files changed

+434
-320
lines changed

9 files changed

+434
-320
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ dist
77
*.patch
88
/*.html
99
.DS_Store
10-
dist/.sizecache.json
1110
build/.sizecache.json
1211
node_modules

grunt.js

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module.exports = function( grunt ) {
5050
"src/ajax/jsonp.js",
5151
"src/ajax/script.js",
5252
"src/ajax/xhr.js",
53-
"src/effects.js",
53+
{ flag: "effects", src: "src/effects.js" },
5454
"src/offset.js",
5555
"src/dimensions.js",
5656
"src/exports.js",
@@ -103,7 +103,7 @@ module.exports = function( grunt ) {
103103
});
104104

105105
// Default grunt.
106-
grunt.registerTask( "default", "selector build lint min compare_size" );
106+
grunt.registerTask( "default", "selector build:*:* lint min compare_size" );
107107

108108
grunt.loadNpmTasks("grunt-compare-size");
109109

@@ -159,29 +159,48 @@ module.exports = function( grunt ) {
159159

160160

161161
// Special concat/build task to handle various jQuery build requirements
162-
grunt.registerMultiTask( "build", "Concatenate source, embed date/version", function() {
163-
// Concat specified files.
164-
var compiled = "",
165-
name = this.file.dest;
162+
grunt.registerMultiTask(
163+
"build",
164+
"Concatenate source (include/exclude modules with +/- flags), embed date/version",
165+
function() {
166+
// Concat specified files.
167+
var compiled = "",
168+
modules = this.flags,
169+
optIn = !modules["*"],
170+
name = this.file.dest;
171+
172+
this.file.src.forEach(function( filepath ) {
173+
// Include optional modules per build flags; exclusion trumps inclusion
174+
var flag = filepath.flag;
175+
if ( flag ) {
176+
if ( modules[ "-" + flag ] ||
177+
optIn && !modules[ flag ] && !modules[ "+" + flag ] ) {
178+
179+
log.writeln( "Excluding " + filepath.flag + ": '" + filepath.src + "'." );
180+
return;
181+
}
182+
log.writeln( "Including " + filepath.flag + ": '" + filepath.src + "'." );
183+
filepath = filepath.src;
184+
}
185+
186+
// Unwrap redundant IIFEs
187+
compiled += file.read( filepath ).replace( /^\(function\( jQuery \) \{|\}\)\( jQuery \);\s*$/g, "" );
188+
});
189+
190+
// Embed Date
191+
// Embed Version
192+
compiled = compiled.replace( "@DATE", new Date() )
193+
.replace( "@VERSION", config("pkg.version") );
194+
195+
// Write concatenated source to file
196+
file.write( name, compiled );
197+
198+
// Fail task if errors were logged.
199+
if ( this.errorCount ) {
200+
return false;
201+
}
166202

167-
this.file.src.forEach(function( filepath ) {
168-
compiled += file.read( filepath ).replace( /.function..jQuery...\{/g, "" ).replace( /\}...jQuery..;/g, "" );
203+
// Otherwise, print a success message.
204+
log.writeln( "File '" + name + "' created." );
169205
});
170-
171-
// Embed Date
172-
// Embed Version
173-
compiled = compiled.replace( "@DATE", new Date() )
174-
.replace( "@VERSION", config("pkg.version") );
175-
176-
// Write concatenated source to file
177-
file.write( name, compiled );
178-
179-
// Fail task if errors were logged.
180-
if ( this.errorCount ) {
181-
return false;
182-
}
183-
184-
// Otherwise, print a success message.
185-
log.writeln( "File '" + name + "' created." );
186-
});
187206
};

src/css.js

Lines changed: 124 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
// order is important!
44
jQuery.cssExpand = [ "Top", "Right", "Bottom", "Left" ];
55

6-
var ralpha = /alpha\([^)]*\)/i,
6+
var curCSS, iframe, iframeDoc,
7+
ralpha = /alpha\([^)]*\)/i,
78
ropacity = /opacity=([^)]*)/,
89
// fixed for IE9, see #8346
910
rupper = /([A-Z]|^ms)/g,
1011
rnumsplit = /^([\-+]?(?:\d*\.)?\d+)(.*)$/i,
1112
rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
1213
rrelNum = /^([\-+])=([\-+.\de]+)/,
1314
rmargin = /^margin/,
14-
15+
elemdisplay = {},
1516
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
1617

1718
cssExpand = jQuery.cssExpand,
1819
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
1920
rposition = /^(top|right|bottom|left)$/,
2021

21-
curCSS;
22+
eventsToggle = jQuery.fn.toggle;
2223

2324
// return a css property mapped to a potentially vendor prefixed property
2425
function vendorPropName( style, name ) {
@@ -43,13 +44,83 @@ function vendorPropName( style, name ) {
4344
return origName;
4445
}
4546

46-
jQuery.fn.css = function( name, value ) {
47-
return jQuery.access( this, function( elem, name, value ) {
48-
return value !== undefined ?
49-
jQuery.style( elem, name, value ) :
50-
jQuery.css( elem, name );
51-
}, name, value, arguments.length > 1 );
52-
};
47+
function showHide( elements, show ) {
48+
var elem, display,
49+
values = [],
50+
index = 0,
51+
length = elements.length;
52+
53+
for ( ; index < length; index++ ) {
54+
elem = elements[ index ];
55+
if ( !elem.style ) {
56+
continue;
57+
}
58+
values[ index ] = jQuery._data( elem, "olddisplay" );
59+
if ( show ) {
60+
// Reset the inline display of this element to learn if it is
61+
// being hidden by cascaded rules or not
62+
if ( !values[ index ] && elem.style.display === "none" ) {
63+
elem.style.display = "";
64+
}
65+
66+
// Set elements which have been overridden with display: none
67+
// in a stylesheet to whatever the default browser style is
68+
// for such an element
69+
if ( (elem.style.display === "" && curCSS( elem, "display" ) === "none") ||
70+
!jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
71+
values[ index ] = jQuery._data( elem, "olddisplay", jQuery.defaultDisplay(elem.nodeName) );
72+
}
73+
} else {
74+
display = curCSS( elem, "display" );
75+
76+
if ( !values[ index ] && display !== "none" ) {
77+
jQuery._data( elem, "olddisplay", display );
78+
}
79+
}
80+
}
81+
82+
// Set the display of most of the elements in a second loop
83+
// to avoid the constant reflow
84+
for ( index = 0; index < length; index++ ) {
85+
elem = elements[ index ];
86+
if ( !elem.style ) {
87+
continue;
88+
}
89+
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
90+
elem.style.display = show ? values[ index ] || "" : "none";
91+
}
92+
}
93+
94+
return elements;
95+
}
96+
97+
jQuery.fn.extend({
98+
css: function( name, value ) {
99+
return jQuery.access( this, function( elem, name, value ) {
100+
return value !== undefined ?
101+
jQuery.style( elem, name, value ) :
102+
jQuery.css( elem, name );
103+
}, name, value, arguments.length > 1 );
104+
},
105+
show: function() {
106+
return showHide( this, true );
107+
},
108+
hide: function() {
109+
return showHide( this );
110+
},
111+
toggle: function( fn, fn2 ) {
112+
var bool = typeof fn === "boolean";
113+
114+
if ( jQuery.isFunction( fn ) && jQuery.isFunction( fn2 ) ) {
115+
return eventsToggle.apply( this, arguments );
116+
}
117+
118+
return this.each(function() {
119+
var state = bool ? fn : jQuery( this ).is(":hidden");
120+
showHide([ this ], state );
121+
});
122+
}
123+
});
53124

54125
jQuery.extend({
55126
// Add in style property hooks for overriding the default
@@ -200,6 +271,49 @@ jQuery.extend({
200271
}
201272

202273
return ret;
274+
},
275+
276+
// Try to determine the default display value of an element
277+
defaultDisplay: function( nodeName ) {
278+
if ( elemdisplay[ nodeName ] ) {
279+
return elemdisplay[ nodeName ];
280+
}
281+
282+
var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
283+
display = elem.css("display");
284+
elem.remove();
285+
286+
// If the simple way fails,
287+
// get element's real default display by attaching it to a temp iframe
288+
if ( display === "none" || display === "" ) {
289+
// Use the already-created iframe if possible
290+
iframe = document.body.appendChild(
291+
iframe || jQuery.extend( document.createElement("iframe"), {
292+
frameBorder: 0,
293+
width: 0,
294+
height: 0
295+
})
296+
);
297+
298+
// Create a cacheable copy of the iframe document on first call.
299+
// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
300+
// document to it; WebKit & Firefox won't allow reusing the iframe document.
301+
if ( !iframeDoc || !iframe.createElement ) {
302+
iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
303+
iframeDoc.write("<!doctype html><html><body>");
304+
iframeDoc.close();
305+
}
306+
307+
elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
308+
309+
display = curCSS( elem, "display" );
310+
document.body.removeChild( iframe );
311+
}
312+
313+
// Store the correct default display
314+
elemdisplay[ nodeName ] = display;
315+
316+
return display;
203317
}
204318
});
205319

0 commit comments

Comments
 (0)