Test Failed
Branch master (45c182)
by Julien
03:21
created

resources/assets/jquery/src/manipulation.js   F

Complexity

Total Complexity 120
Complexity/F 3.53

Size

Lines of Code 486
Function Count 34

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 120
dl 0
loc 486
rs 3.12
c 1
b 0
f 0
cc 0
nc 0
mnd 7
bc 95
fnc 34
bpm 2.794
cpm 3.5294
noi 2

How to fix   Complexity   

Complexity

Complex classes like resources/assets/jquery/src/manipulation.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
define( [
2
	"./core",
3
	"./var/concat",
4
	"./var/push",
5
	"./core/access",
6
	"./manipulation/var/rcheckableType",
7
	"./manipulation/var/rtagName",
8
	"./manipulation/var/rscriptType",
9
	"./manipulation/wrapMap",
10
	"./manipulation/getAll",
11
	"./manipulation/setGlobalEval",
12
	"./manipulation/buildFragment",
13
	"./manipulation/support",
14
15
	"./data/var/dataPriv",
16
	"./data/var/dataUser",
17
	"./data/var/acceptData",
18
	"./core/DOMEval",
19
20
	"./core/init",
21
	"./traversing",
22
	"./selector",
23
	"./event"
24
], function( jQuery, concat, push, access,
25
	rcheckableType, rtagName, rscriptType,
26
	wrapMap, getAll, setGlobalEval, buildFragment, support,
27
	dataPriv, dataUser, acceptData, DOMEval ) {
28
29
"use strict";
30
31
var
32
33
	/* eslint-disable max-len */
34
35
	// See https://github.com/eslint/eslint/issues/3229
36
	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
37
38
	/* eslint-enable */
39
40
	// Support: IE <=10 - 11, Edge 12 - 13
41
	// In IE/Edge using regex groups here causes severe slowdowns.
42
	// See https://connect.microsoft.com/IE/feedback/details/1736512/
43
	rnoInnerhtml = /<script|<style|<link/i,
44
45
	// checked="checked" or checked
46
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
47
	rscriptTypeMasked = /^true\/(.*)/,
48
	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
49
50
function manipulationTarget( elem, content ) {
51
	if ( jQuery.nodeName( elem, "table" ) &&
52
		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
53
54
		return elem.getElementsByTagName( "tbody" )[ 0 ] || elem;
55
	}
56
57
	return elem;
58
}
59
60
// Replace/restore the type attribute of script elements for safe DOM manipulation
61
function disableScript( elem ) {
62
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
63
	return elem;
64
}
65
function restoreScript( elem ) {
66
	var match = rscriptTypeMasked.exec( elem.type );
67
68
	if ( match ) {
69
		elem.type = match[ 1 ];
70
	} else {
71
		elem.removeAttribute( "type" );
72
	}
73
74
	return elem;
75
}
76
77
function cloneCopyEvent( src, dest ) {
78
	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
79
80
	if ( dest.nodeType !== 1 ) {
81
		return;
82
	}
83
84
	// 1. Copy private data: events, handlers, etc.
85
	if ( dataPriv.hasData( src ) ) {
86
		pdataOld = dataPriv.access( src );
87
		pdataCur = dataPriv.set( dest, pdataOld );
88
		events = pdataOld.events;
89
90
		if ( events ) {
91
			delete pdataCur.handle;
92
			pdataCur.events = {};
93
94
			for ( type in events ) {
95
				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
96
					jQuery.event.add( dest, type, events[ type ][ i ] );
97
				}
98
			}
99
		}
100
	}
101
102
	// 2. Copy user data
103
	if ( dataUser.hasData( src ) ) {
104
		udataOld = dataUser.access( src );
105
		udataCur = jQuery.extend( {}, udataOld );
106
107
		dataUser.set( dest, udataCur );
108
	}
109
}
110
111
// Fix IE bugs, see support tests
112
function fixInput( src, dest ) {
113
	var nodeName = dest.nodeName.toLowerCase();
114
115
	// Fails to persist the checked state of a cloned checkbox or radio button.
116
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
117
		dest.checked = src.checked;
118
119
	// Fails to return the selected option to the default selected state when cloning options
120
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
121
		dest.defaultValue = src.defaultValue;
122
	}
123
}
124
125
function domManip( collection, args, callback, ignored ) {
126
127
	// Flatten any nested arrays
128
	args = concat.apply( [], args );
129
130
	var fragment, first, scripts, hasScripts, node, doc,
131
		i = 0,
132
		l = collection.length,
133
		iNoClone = l - 1,
134
		value = args[ 0 ],
135
		isFunction = jQuery.isFunction( value );
136
137
	// We can't cloneNode fragments that contain checked, in WebKit
138
	if ( isFunction ||
139
			( l > 1 && typeof value === "string" &&
140
				!support.checkClone && rchecked.test( value ) ) ) {
141
		return collection.each( function( index ) {
142
			var self = collection.eq( index );
143
			if ( isFunction ) {
144
				args[ 0 ] = value.call( this, index, self.html() );
145
			}
146
			domManip( self, args, callback, ignored );
147
		} );
148
	}
149
150
	if ( l ) {
151
		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
152
		first = fragment.firstChild;
153
154
		if ( fragment.childNodes.length === 1 ) {
155
			fragment = first;
156
		}
157
158
		// Require either new content or an interest in ignored elements to invoke the callback
159
		if ( first || ignored ) {
160
			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
161
			hasScripts = scripts.length;
162
163
			// Use the original fragment for the last item
164
			// instead of the first because it can end up
165
			// being emptied incorrectly in certain situations (#8070).
166
			for ( ; i < l; i++ ) {
167
				node = fragment;
168
169
				if ( i !== iNoClone ) {
170
					node = jQuery.clone( node, true, true );
171
172
					// Keep references to cloned scripts for later restoration
173
					if ( hasScripts ) {
174
175
						// Support: Android <=4.0 only, PhantomJS 1 only
176
						// push.apply(_, arraylike) throws on ancient WebKit
177
						jQuery.merge( scripts, getAll( node, "script" ) );
178
					}
179
				}
180
181
				callback.call( collection[ i ], node, i );
182
			}
183
184
			if ( hasScripts ) {
185
				doc = scripts[ scripts.length - 1 ].ownerDocument;
186
187
				// Reenable scripts
188
				jQuery.map( scripts, restoreScript );
189
190
				// Evaluate executable scripts on first document insertion
191
				for ( i = 0; i < hasScripts; i++ ) {
192
					node = scripts[ i ];
193
					if ( rscriptType.test( node.type || "" ) &&
194
						!dataPriv.access( node, "globalEval" ) &&
195
						jQuery.contains( doc, node ) ) {
196
197
						if ( node.src ) {
198
199
							// Optional AJAX dependency, but won't run scripts if not present
200
							if ( jQuery._evalUrl ) {
201
								jQuery._evalUrl( node.src );
202
							}
203
						} else {
204
							DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
205
						}
206
					}
207
				}
208
			}
209
		}
210
	}
211
212
	return collection;
213
}
214
215
function remove( elem, selector, keepData ) {
216
	var node,
217
		nodes = selector ? jQuery.filter( selector, elem ) : elem,
218
		i = 0;
219
220
	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
221
		if ( !keepData && node.nodeType === 1 ) {
222
			jQuery.cleanData( getAll( node ) );
223
		}
224
225
		if ( node.parentNode ) {
226
			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
227
				setGlobalEval( getAll( node, "script" ) );
228
			}
229
			node.parentNode.removeChild( node );
230
		}
231
	}
232
233
	return elem;
234
}
235
236
jQuery.extend( {
237
	htmlPrefilter: function( html ) {
238
		return html.replace( rxhtmlTag, "<$1></$2>" );
239
	},
240
241
	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
242
		var i, l, srcElements, destElements,
243
			clone = elem.cloneNode( true ),
244
			inPage = jQuery.contains( elem.ownerDocument, elem );
245
246
		// Fix IE cloning issues
247
		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
248
				!jQuery.isXMLDoc( elem ) ) {
249
250
			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
251
			destElements = getAll( clone );
252
			srcElements = getAll( elem );
253
254
			for ( i = 0, l = srcElements.length; i < l; i++ ) {
255
				fixInput( srcElements[ i ], destElements[ i ] );
256
			}
257
		}
258
259
		// Copy the events from the original to the clone
260
		if ( dataAndEvents ) {
261
			if ( deepDataAndEvents ) {
262
				srcElements = srcElements || getAll( elem );
263
				destElements = destElements || getAll( clone );
264
265
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
266
					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
267
				}
268
			} else {
269
				cloneCopyEvent( elem, clone );
270
			}
271
		}
272
273
		// Preserve script evaluation history
274
		destElements = getAll( clone, "script" );
275
		if ( destElements.length > 0 ) {
276
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
277
		}
278
279
		// Return the cloned set
280
		return clone;
281
	},
282
283
	cleanData: function( elems ) {
284
		var data, elem, type,
285
			special = jQuery.event.special,
286
			i = 0;
287
288
		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
289
			if ( acceptData( elem ) ) {
290
				if ( ( data = elem[ dataPriv.expando ] ) ) {
291
					if ( data.events ) {
292
						for ( type in data.events ) {
293
							if ( special[ type ] ) {
294
								jQuery.event.remove( elem, type );
295
296
							// This is a shortcut to avoid jQuery.event.remove's overhead
297
							} else {
298
								jQuery.removeEvent( elem, type, data.handle );
299
							}
300
						}
301
					}
302
303
					// Support: Chrome <=35 - 45+
304
					// Assign undefined instead of using delete, see Data#remove
305
					elem[ dataPriv.expando ] = undefined;
306
				}
307
				if ( elem[ dataUser.expando ] ) {
308
309
					// Support: Chrome <=35 - 45+
310
					// Assign undefined instead of using delete, see Data#remove
311
					elem[ dataUser.expando ] = undefined;
312
				}
313
			}
314
		}
315
	}
316
} );
317
318
jQuery.fn.extend( {
319
	detach: function( selector ) {
320
		return remove( this, selector, true );
321
	},
322
323
	remove: function( selector ) {
324
		return remove( this, selector );
325
	},
326
327
	text: function( value ) {
328
		return access( this, function( value ) {
329
			return value === undefined ?
330
				jQuery.text( this ) :
331
				this.empty().each( function() {
332
					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
333
						this.textContent = value;
334
					}
335
				} );
336
		}, null, value, arguments.length );
337
	},
338
339
	append: function() {
340
		return domManip( this, arguments, function( elem ) {
341
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
342
				var target = manipulationTarget( this, elem );
343
				target.appendChild( elem );
344
			}
345
		} );
346
	},
347
348
	prepend: function() {
349
		return domManip( this, arguments, function( elem ) {
350
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
351
				var target = manipulationTarget( this, elem );
352
				target.insertBefore( elem, target.firstChild );
353
			}
354
		} );
355
	},
356
357
	before: function() {
358
		return domManip( this, arguments, function( elem ) {
359
			if ( this.parentNode ) {
360
				this.parentNode.insertBefore( elem, this );
361
			}
362
		} );
363
	},
364
365
	after: function() {
366
		return domManip( this, arguments, function( elem ) {
367
			if ( this.parentNode ) {
368
				this.parentNode.insertBefore( elem, this.nextSibling );
369
			}
370
		} );
371
	},
372
373
	empty: function() {
374
		var elem,
375
			i = 0;
376
377
		for ( ; ( elem = this[ i ] ) != null; i++ ) {
378
			if ( elem.nodeType === 1 ) {
379
380
				// Prevent memory leaks
381
				jQuery.cleanData( getAll( elem, false ) );
382
383
				// Remove any remaining nodes
384
				elem.textContent = "";
385
			}
386
		}
387
388
		return this;
389
	},
390
391
	clone: function( dataAndEvents, deepDataAndEvents ) {
392
		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
393
		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
394
395
		return this.map( function() {
396
			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
397
		} );
398
	},
399
400
	html: function( value ) {
401
		return access( this, function( value ) {
402
			var elem = this[ 0 ] || {},
403
				i = 0,
404
				l = this.length;
405
406
			if ( value === undefined && elem.nodeType === 1 ) {
407
				return elem.innerHTML;
408
			}
409
410
			// See if we can take a shortcut and just use innerHTML
411
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
412
				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
413
414
				value = jQuery.htmlPrefilter( value );
415
416
				try {
417
					for ( ; i < l; i++ ) {
418
						elem = this[ i ] || {};
419
420
						// Remove element nodes and prevent memory leaks
421
						if ( elem.nodeType === 1 ) {
422
							jQuery.cleanData( getAll( elem, false ) );
423
							elem.innerHTML = value;
424
						}
425
					}
426
427
					elem = 0;
428
429
				// If using innerHTML throws an exception, use the fallback method
430
				} catch ( e ) {}
431
			}
432
433
			if ( elem ) {
434
				this.empty().append( value );
435
			}
436
		}, null, value, arguments.length );
437
	},
438
439
	replaceWith: function() {
440
		var ignored = [];
441
442
		// Make the changes, replacing each non-ignored context element with the new content
443
		return domManip( this, arguments, function( elem ) {
444
			var parent = this.parentNode;
445
446
			if ( jQuery.inArray( this, ignored ) < 0 ) {
447
				jQuery.cleanData( getAll( this ) );
448
				if ( parent ) {
449
					parent.replaceChild( elem, this );
450
				}
451
			}
452
453
		// Force callback invocation
454
		}, ignored );
455
	}
456
} );
457
458
jQuery.each( {
459
	appendTo: "append",
460
	prependTo: "prepend",
461
	insertBefore: "before",
462
	insertAfter: "after",
463
	replaceAll: "replaceWith"
464
}, function( name, original ) {
465
	jQuery.fn[ name ] = function( selector ) {
466
		var elems,
467
			ret = [],
468
			insert = jQuery( selector ),
469
			last = insert.length - 1,
470
			i = 0;
471
472
		for ( ; i <= last; i++ ) {
473
			elems = i === last ? this : this.clone( true );
474
			jQuery( insert[ i ] )[ original ]( elems );
475
476
			// Support: Android <=4.0 only, PhantomJS 1 only
477
			// .get() because push.apply(_, arraylike) throws on ancient WebKit
478
			push.apply( ret, elems.get() );
479
		}
480
481
		return this.pushStack( ret );
482
	};
483
} );
484
485
return jQuery;
486
} );
487