Merge "Language: s/error_log/wfWarn/"
[lhc/web/wiklou.git] / resources / src / jquery / jquery.mwExtension.js
1 /*
2 * JavaScript backwards-compatibility alternatives and other convenience functions
3 */
4 ( function ( $ ) {
5
6 $.extend( {
7 trimLeft: function ( str ) {
8 return str === null ? '' : str.toString().replace( /^\s+/, '' );
9 },
10 trimRight: function ( str ) {
11 return str === null ?
12 '' : str.toString().replace( /\s+$/, '' );
13 },
14 ucFirst: function ( str ) {
15 return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
16 },
17 escapeRE: function ( str ) {
18 return str.replace ( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
19 },
20 isDomElement: function ( el ) {
21 return !!el && !!el.nodeType;
22 },
23 isEmpty: function ( v ) {
24 var key;
25 if ( v === '' || v === 0 || v === '0' || v === null
26 || v === false || v === undefined )
27 {
28 return true;
29 }
30 // the for-loop could potentially contain prototypes
31 // to avoid that we check it's length first
32 if ( v.length === 0 ) {
33 return true;
34 }
35 if ( typeof v === 'object' ) {
36 for ( key in v ) {
37 return false;
38 }
39 return true;
40 }
41 return false;
42 },
43 compareArray: function ( arrThis, arrAgainst ) {
44 if ( arrThis.length !== arrAgainst.length ) {
45 return false;
46 }
47 for ( var i = 0; i < arrThis.length; i++ ) {
48 if ( $.isArray( arrThis[i] ) ) {
49 if ( !$.compareArray( arrThis[i], arrAgainst[i] ) ) {
50 return false;
51 }
52 } else if ( arrThis[i] !== arrAgainst[i] ) {
53 return false;
54 }
55 }
56 return true;
57 },
58 compareObject: function ( objectA, objectB ) {
59 var prop, type;
60
61 // Do a simple check if the types match
62 if ( typeof objectA === typeof objectB ) {
63
64 // Only loop over the contents if it really is an object
65 if ( typeof objectA === 'object' ) {
66 // If they are aliases of the same object (ie. mw and mediaWiki) return now
67 if ( objectA === objectB ) {
68 return true;
69 } else {
70 // Iterate over each property
71 for ( prop in objectA ) {
72 // Check if this property is also present in the other object
73 if ( prop in objectB ) {
74 // Compare the types of the properties
75 type = typeof objectA[prop];
76 if ( type === typeof objectB[prop] ) {
77 // Recursively check objects inside this one
78 switch ( type ) {
79 case 'object' :
80 if ( !$.compareObject( objectA[prop], objectB[prop] ) ) {
81 return false;
82 }
83 break;
84 case 'function' :
85 // Functions need to be strings to compare them properly
86 if ( objectA[prop].toString() !== objectB[prop].toString() ) {
87 return false;
88 }
89 break;
90 default:
91 // Strings, numbers
92 if ( objectA[prop] !== objectB[prop] ) {
93 return false;
94 }
95 break;
96 }
97 } else {
98 return false;
99 }
100 } else {
101 return false;
102 }
103 }
104 // Check for properties in B but not in A
105 // This is about 15% faster (tested in Safari 5 and Firefox 3.6)
106 // ...than incrementing a count variable in the above and below loops
107 // See also: https://www.mediawiki.org/wiki/ResourceLoader/Default_modules/compareObject_test#Results
108 for ( prop in objectB ) {
109 if ( !( prop in objectA ) ) {
110 return false;
111 }
112 }
113 }
114 }
115 } else {
116 return false;
117 }
118 return true;
119 }
120 } );
121
122 }( jQuery ) );