parsejs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +5 -0
- data/README.markdown +85 -0
- data/Rakefile +15 -0
- data/lib/parsejs.rb +14 -0
- data/lib/parsejs/ast.rb +84 -0
- data/lib/parsejs/docs.rb +237 -0
- data/lib/parsejs/grammar.kpeg +575 -0
- data/lib/parsejs/grammar.kpeg.rb +9460 -0
- data/lib/parsejs/scope.rb +183 -0
- data/lib/parsejs/stringifier.rb +450 -0
- data/lib/parsejs/version.rb +3 -0
- data/lib/parsejs/visitor.rb +257 -0
- data/parsejs.gemspec +24 -0
- data/spec/fixtures/jquery-1.6.js +8982 -0
- data/spec/fixtures/jquery-1.7.js +9289 -0
- data/spec/fixtures/jquery-ajax.js +1000 -0
- data/spec/fixtures/jquery-attributes.js +650 -0
- data/spec/fixtures/jquery-traversing.js +330 -0
- data/spec/fixtures/metamorph.js +324 -0
- data/spec/fixtures/sizzle.js +1442 -0
- data/spec/fixtures/sproutcore-core.js +195 -0
- data/spec/fixtures/sproutcore-each-proxy.js +218 -0
- data/spec/fixtures/sproutcore-native-array.js +139 -0
- data/spec/fixtures/sproutcore.js +14319 -0
- data/spec/scope_spec.rb +111 -0
- data/spec/stringify_spec.rb +587 -0
- data/test.rb +76 -0
- metadata +145 -0
@@ -0,0 +1,650 @@
|
|
1
|
+
(function( jQuery ) {
|
2
|
+
|
3
|
+
var rclass = /[\n\t\r]/g,
|
4
|
+
rspace = /\s+/,
|
5
|
+
rreturn = /\r/g,
|
6
|
+
rtype = /^(?:button|input)$/i,
|
7
|
+
rfocusable = /^(?:button|input|object|select|textarea)$/i,
|
8
|
+
rclickable = /^a(?:rea)?$/i,
|
9
|
+
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
|
10
|
+
getSetAttribute = jQuery.support.getSetAttribute,
|
11
|
+
nodeHook, boolHook, fixSpecified;
|
12
|
+
|
13
|
+
jQuery.fn.extend({
|
14
|
+
attr: function( name, value ) {
|
15
|
+
return jQuery.access( this, name, value, true, jQuery.attr );
|
16
|
+
},
|
17
|
+
|
18
|
+
removeAttr: function( name ) {
|
19
|
+
return this.each(function() {
|
20
|
+
jQuery.removeAttr( this, name );
|
21
|
+
});
|
22
|
+
},
|
23
|
+
|
24
|
+
prop: function( name, value ) {
|
25
|
+
return jQuery.access( this, name, value, true, jQuery.prop );
|
26
|
+
},
|
27
|
+
|
28
|
+
removeProp: function( name ) {
|
29
|
+
name = jQuery.propFix[ name ] || name;
|
30
|
+
return this.each(function() {
|
31
|
+
// try/catch handles cases where IE balks (such as removing a property on window)
|
32
|
+
try {
|
33
|
+
this[ name ] = undefined;
|
34
|
+
delete this[ name ];
|
35
|
+
} catch( e ) {}
|
36
|
+
});
|
37
|
+
},
|
38
|
+
|
39
|
+
addClass: function( value ) {
|
40
|
+
var classNames, i, l, elem,
|
41
|
+
setClass, c, cl;
|
42
|
+
|
43
|
+
if ( jQuery.isFunction( value ) ) {
|
44
|
+
return this.each(function( j ) {
|
45
|
+
jQuery( this ).addClass( value.call(this, j, this.className) );
|
46
|
+
});
|
47
|
+
}
|
48
|
+
|
49
|
+
if ( value && typeof value === "string" ) {
|
50
|
+
classNames = value.split( rspace );
|
51
|
+
|
52
|
+
for ( i = 0, l = this.length; i < l; i++ ) {
|
53
|
+
elem = this[ i ];
|
54
|
+
|
55
|
+
if ( elem.nodeType === 1 ) {
|
56
|
+
if ( !elem.className && classNames.length === 1 ) {
|
57
|
+
elem.className = value;
|
58
|
+
|
59
|
+
} else {
|
60
|
+
setClass = " " + elem.className + " ";
|
61
|
+
|
62
|
+
for ( c = 0, cl = classNames.length; c < cl; c++ ) {
|
63
|
+
if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
|
64
|
+
setClass += classNames[ c ] + " ";
|
65
|
+
}
|
66
|
+
}
|
67
|
+
elem.className = jQuery.trim( setClass );
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
return this;
|
74
|
+
},
|
75
|
+
|
76
|
+
removeClass: function( value ) {
|
77
|
+
var classNames, i, l, elem, className, c, cl;
|
78
|
+
|
79
|
+
if ( jQuery.isFunction( value ) ) {
|
80
|
+
return this.each(function( j ) {
|
81
|
+
jQuery( this ).removeClass( value.call(this, j, this.className) );
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
if ( (value && typeof value === "string") || value === undefined ) {
|
86
|
+
classNames = (value || "").split( rspace );
|
87
|
+
|
88
|
+
for ( i = 0, l = this.length; i < l; i++ ) {
|
89
|
+
elem = this[ i ];
|
90
|
+
|
91
|
+
if ( elem.nodeType === 1 && elem.className ) {
|
92
|
+
if ( value ) {
|
93
|
+
className = (" " + elem.className + " ").replace( rclass, " " );
|
94
|
+
for ( c = 0, cl = classNames.length; c < cl; c++ ) {
|
95
|
+
className = className.replace(" " + classNames[ c ] + " ", " ");
|
96
|
+
}
|
97
|
+
elem.className = jQuery.trim( className );
|
98
|
+
|
99
|
+
} else {
|
100
|
+
elem.className = "";
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
return this;
|
107
|
+
},
|
108
|
+
|
109
|
+
toggleClass: function( value, stateVal ) {
|
110
|
+
var type = typeof value,
|
111
|
+
isBool = typeof stateVal === "boolean";
|
112
|
+
|
113
|
+
if ( jQuery.isFunction( value ) ) {
|
114
|
+
return this.each(function( i ) {
|
115
|
+
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
|
116
|
+
});
|
117
|
+
}
|
118
|
+
|
119
|
+
return this.each(function() {
|
120
|
+
if ( type === "string" ) {
|
121
|
+
// toggle individual class names
|
122
|
+
var className,
|
123
|
+
i = 0,
|
124
|
+
self = jQuery( this ),
|
125
|
+
state = stateVal,
|
126
|
+
classNames = value.split( rspace );
|
127
|
+
|
128
|
+
while ( (className = classNames[ i++ ]) ) {
|
129
|
+
// check each className given, space seperated list
|
130
|
+
state = isBool ? state : !self.hasClass( className );
|
131
|
+
self[ state ? "addClass" : "removeClass" ]( className );
|
132
|
+
}
|
133
|
+
|
134
|
+
} else if ( type === "undefined" || type === "boolean" ) {
|
135
|
+
if ( this.className ) {
|
136
|
+
// store className if set
|
137
|
+
jQuery._data( this, "__className__", this.className );
|
138
|
+
}
|
139
|
+
|
140
|
+
// toggle whole className
|
141
|
+
this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
|
142
|
+
}
|
143
|
+
});
|
144
|
+
},
|
145
|
+
|
146
|
+
hasClass: function( selector ) {
|
147
|
+
var className = " " + selector + " ",
|
148
|
+
i = 0,
|
149
|
+
l = this.length;
|
150
|
+
for ( ; i < l; i++ ) {
|
151
|
+
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
|
152
|
+
return true;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
return false;
|
157
|
+
},
|
158
|
+
|
159
|
+
val: function( value ) {
|
160
|
+
var hooks, ret, isFunction,
|
161
|
+
elem = this[0];
|
162
|
+
|
163
|
+
if ( !arguments.length ) {
|
164
|
+
if ( elem ) {
|
165
|
+
hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
|
166
|
+
|
167
|
+
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
|
168
|
+
return ret;
|
169
|
+
}
|
170
|
+
|
171
|
+
ret = elem.value;
|
172
|
+
|
173
|
+
return typeof ret === "string" ?
|
174
|
+
// handle most common string cases
|
175
|
+
ret.replace(rreturn, "") :
|
176
|
+
// handle cases where value is null/undef or number
|
177
|
+
ret == null ? "" : ret;
|
178
|
+
}
|
179
|
+
|
180
|
+
return undefined;
|
181
|
+
}
|
182
|
+
|
183
|
+
isFunction = jQuery.isFunction( value );
|
184
|
+
|
185
|
+
return this.each(function( i ) {
|
186
|
+
var self = jQuery(this), val;
|
187
|
+
|
188
|
+
if ( this.nodeType !== 1 ) {
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
|
192
|
+
if ( isFunction ) {
|
193
|
+
val = value.call( this, i, self.val() );
|
194
|
+
} else {
|
195
|
+
val = value;
|
196
|
+
}
|
197
|
+
|
198
|
+
// Treat null/undefined as ""; convert numbers to string
|
199
|
+
if ( val == null ) {
|
200
|
+
val = "";
|
201
|
+
} else if ( typeof val === "number" ) {
|
202
|
+
val += "";
|
203
|
+
} else if ( jQuery.isArray( val ) ) {
|
204
|
+
val = jQuery.map(val, function ( value ) {
|
205
|
+
return value == null ? "" : value + "";
|
206
|
+
});
|
207
|
+
}
|
208
|
+
|
209
|
+
hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
|
210
|
+
|
211
|
+
// If set returns undefined, fall back to normal setting
|
212
|
+
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
|
213
|
+
this.value = val;
|
214
|
+
}
|
215
|
+
});
|
216
|
+
}
|
217
|
+
});
|
218
|
+
|
219
|
+
jQuery.extend({
|
220
|
+
valHooks: {
|
221
|
+
option: {
|
222
|
+
get: function( elem ) {
|
223
|
+
// attributes.value is undefined in Blackberry 4.7 but
|
224
|
+
// uses .value. See #6932
|
225
|
+
var val = elem.attributes.value;
|
226
|
+
return !val || val.specified ? elem.value : elem.text;
|
227
|
+
}
|
228
|
+
},
|
229
|
+
select: {
|
230
|
+
get: function( elem ) {
|
231
|
+
var value, i, max, option,
|
232
|
+
index = elem.selectedIndex,
|
233
|
+
values = [],
|
234
|
+
options = elem.options,
|
235
|
+
one = elem.type === "select-one";
|
236
|
+
|
237
|
+
// Nothing was selected
|
238
|
+
if ( index < 0 ) {
|
239
|
+
return null;
|
240
|
+
}
|
241
|
+
|
242
|
+
// Loop through all the selected options
|
243
|
+
i = one ? index : 0;
|
244
|
+
max = one ? index + 1 : options.length;
|
245
|
+
for ( ; i < max; i++ ) {
|
246
|
+
option = options[ i ];
|
247
|
+
|
248
|
+
// Don't return options that are disabled or in a disabled optgroup
|
249
|
+
if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
|
250
|
+
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
|
251
|
+
|
252
|
+
// Get the specific value for the option
|
253
|
+
value = jQuery( option ).val();
|
254
|
+
|
255
|
+
// We don't need an array for one selects
|
256
|
+
if ( one ) {
|
257
|
+
return value;
|
258
|
+
}
|
259
|
+
|
260
|
+
// Multi-Selects return an array
|
261
|
+
values.push( value );
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
|
266
|
+
if ( one && !values.length && options.length ) {
|
267
|
+
return jQuery( options[ index ] ).val();
|
268
|
+
}
|
269
|
+
|
270
|
+
return values;
|
271
|
+
},
|
272
|
+
|
273
|
+
set: function( elem, value ) {
|
274
|
+
var values = jQuery.makeArray( value );
|
275
|
+
|
276
|
+
jQuery(elem).find("option").each(function() {
|
277
|
+
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
|
278
|
+
});
|
279
|
+
|
280
|
+
if ( !values.length ) {
|
281
|
+
elem.selectedIndex = -1;
|
282
|
+
}
|
283
|
+
return values;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
},
|
287
|
+
|
288
|
+
attrFn: {
|
289
|
+
val: true,
|
290
|
+
css: true,
|
291
|
+
html: true,
|
292
|
+
text: true,
|
293
|
+
data: true,
|
294
|
+
width: true,
|
295
|
+
height: true,
|
296
|
+
offset: true
|
297
|
+
},
|
298
|
+
|
299
|
+
attr: function( elem, name, value, pass ) {
|
300
|
+
var ret, hooks, notxml,
|
301
|
+
nType = elem.nodeType;
|
302
|
+
|
303
|
+
// don't get/set attributes on text, comment and attribute nodes
|
304
|
+
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
305
|
+
return undefined;
|
306
|
+
}
|
307
|
+
|
308
|
+
if ( pass && name in jQuery.attrFn ) {
|
309
|
+
return jQuery( elem )[ name ]( value );
|
310
|
+
}
|
311
|
+
|
312
|
+
// Fallback to prop when attributes are not supported
|
313
|
+
if ( !("getAttribute" in elem) ) {
|
314
|
+
return jQuery.prop( elem, name, value );
|
315
|
+
}
|
316
|
+
|
317
|
+
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
318
|
+
|
319
|
+
// All attributes are lowercase
|
320
|
+
// Grab necessary hook if one is defined
|
321
|
+
if ( notxml ) {
|
322
|
+
name = name.toLowerCase();
|
323
|
+
hooks = jQuery.attrHooks[ name ] || (rboolean.test( name ) ? boolHook : nodeHook);
|
324
|
+
}
|
325
|
+
|
326
|
+
if ( value !== undefined ) {
|
327
|
+
|
328
|
+
if ( value === null ) {
|
329
|
+
jQuery.removeAttr( elem, name );
|
330
|
+
return undefined;
|
331
|
+
|
332
|
+
} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
333
|
+
return ret;
|
334
|
+
|
335
|
+
} else {
|
336
|
+
elem.setAttribute( name, "" + value );
|
337
|
+
return value;
|
338
|
+
}
|
339
|
+
|
340
|
+
} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
|
341
|
+
return ret;
|
342
|
+
|
343
|
+
} else {
|
344
|
+
|
345
|
+
ret = elem.getAttribute( name );
|
346
|
+
|
347
|
+
// Non-existent attributes return null, we normalize to undefined
|
348
|
+
return ret === null ?
|
349
|
+
undefined :
|
350
|
+
ret;
|
351
|
+
}
|
352
|
+
},
|
353
|
+
|
354
|
+
removeAttr: function( elem, value ) {
|
355
|
+
var propName, attrNames, name, l,
|
356
|
+
i = 0;
|
357
|
+
|
358
|
+
if ( elem.nodeType === 1 ) {
|
359
|
+
attrNames = (value || "").split( rspace );
|
360
|
+
l = attrNames.length;
|
361
|
+
|
362
|
+
for ( ; i < l; i++ ) {
|
363
|
+
name = attrNames[ i ].toLowerCase();
|
364
|
+
propName = jQuery.propFix[ name ] || name;
|
365
|
+
|
366
|
+
// See #9699 for explanation of this approach (setting first, then removal)
|
367
|
+
jQuery.attr( elem, name, "" );
|
368
|
+
elem.removeAttribute( getSetAttribute ? name : propName );
|
369
|
+
|
370
|
+
// Set corresponding property to false for boolean attributes
|
371
|
+
if ( rboolean.test( name ) && propName in elem ) {
|
372
|
+
elem[ propName ] = false;
|
373
|
+
}
|
374
|
+
}
|
375
|
+
}
|
376
|
+
},
|
377
|
+
|
378
|
+
attrHooks: {
|
379
|
+
type: {
|
380
|
+
set: function( elem, value ) {
|
381
|
+
// We can't allow the type property to be changed (since it causes problems in IE)
|
382
|
+
if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
|
383
|
+
jQuery.error( "type property can't be changed" );
|
384
|
+
} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
|
385
|
+
// Setting the type on a radio button after the value resets the value in IE6-9
|
386
|
+
// Reset value to it's default in case type is set after value
|
387
|
+
// This is for element creation
|
388
|
+
var val = elem.value;
|
389
|
+
elem.setAttribute( "type", value );
|
390
|
+
if ( val ) {
|
391
|
+
elem.value = val;
|
392
|
+
}
|
393
|
+
return value;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
},
|
397
|
+
// Use the value property for back compat
|
398
|
+
// Use the nodeHook for button elements in IE6/7 (#1954)
|
399
|
+
value: {
|
400
|
+
get: function( elem, name ) {
|
401
|
+
if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
|
402
|
+
return nodeHook.get( elem, name );
|
403
|
+
}
|
404
|
+
return name in elem ?
|
405
|
+
elem.value :
|
406
|
+
null;
|
407
|
+
},
|
408
|
+
set: function( elem, value, name ) {
|
409
|
+
if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
|
410
|
+
return nodeHook.set( elem, value, name );
|
411
|
+
}
|
412
|
+
// Does not return so that setAttribute is also used
|
413
|
+
elem.value = value;
|
414
|
+
}
|
415
|
+
}
|
416
|
+
},
|
417
|
+
|
418
|
+
propFix: {
|
419
|
+
tabindex: "tabIndex",
|
420
|
+
readonly: "readOnly",
|
421
|
+
"for": "htmlFor",
|
422
|
+
"class": "className",
|
423
|
+
maxlength: "maxLength",
|
424
|
+
cellspacing: "cellSpacing",
|
425
|
+
cellpadding: "cellPadding",
|
426
|
+
rowspan: "rowSpan",
|
427
|
+
colspan: "colSpan",
|
428
|
+
usemap: "useMap",
|
429
|
+
frameborder: "frameBorder",
|
430
|
+
contenteditable: "contentEditable"
|
431
|
+
},
|
432
|
+
|
433
|
+
prop: function( elem, name, value ) {
|
434
|
+
var ret, hooks, notxml,
|
435
|
+
nType = elem.nodeType;
|
436
|
+
|
437
|
+
// don't get/set properties on text, comment and attribute nodes
|
438
|
+
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
439
|
+
return undefined;
|
440
|
+
}
|
441
|
+
|
442
|
+
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
443
|
+
|
444
|
+
if ( notxml ) {
|
445
|
+
// Fix name and attach hooks
|
446
|
+
name = jQuery.propFix[ name ] || name;
|
447
|
+
hooks = jQuery.propHooks[ name ];
|
448
|
+
}
|
449
|
+
|
450
|
+
if ( value !== undefined ) {
|
451
|
+
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
452
|
+
return ret;
|
453
|
+
|
454
|
+
} else {
|
455
|
+
return (elem[ name ] = value);
|
456
|
+
}
|
457
|
+
|
458
|
+
} else {
|
459
|
+
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
460
|
+
return ret;
|
461
|
+
|
462
|
+
} else {
|
463
|
+
return elem[ name ];
|
464
|
+
}
|
465
|
+
}
|
466
|
+
},
|
467
|
+
|
468
|
+
propHooks: {
|
469
|
+
tabIndex: {
|
470
|
+
get: function( elem ) {
|
471
|
+
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
|
472
|
+
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
473
|
+
var attributeNode = elem.getAttributeNode("tabindex");
|
474
|
+
|
475
|
+
return attributeNode && attributeNode.specified ?
|
476
|
+
parseInt( attributeNode.value, 10 ) :
|
477
|
+
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
478
|
+
0 :
|
479
|
+
undefined;
|
480
|
+
}
|
481
|
+
}
|
482
|
+
}
|
483
|
+
});
|
484
|
+
|
485
|
+
// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
|
486
|
+
jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
|
487
|
+
|
488
|
+
// Hook for boolean attributes
|
489
|
+
boolHook = {
|
490
|
+
get: function( elem, name ) {
|
491
|
+
// Align boolean attributes with corresponding properties
|
492
|
+
// Fall back to attribute presence where some booleans are not supported
|
493
|
+
var attrNode,
|
494
|
+
property = jQuery.prop( elem, name );
|
495
|
+
return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
|
496
|
+
name.toLowerCase() :
|
497
|
+
undefined;
|
498
|
+
},
|
499
|
+
set: function( elem, value, name ) {
|
500
|
+
var propName;
|
501
|
+
if ( value === false ) {
|
502
|
+
// Remove boolean attributes when set to false
|
503
|
+
jQuery.removeAttr( elem, name );
|
504
|
+
} else {
|
505
|
+
// value is true since we know at this point it's type boolean and not false
|
506
|
+
// Set boolean attributes to the same name and set the DOM property
|
507
|
+
propName = jQuery.propFix[ name ] || name;
|
508
|
+
if ( propName in elem ) {
|
509
|
+
// Only set the IDL specifically if it already exists on the element
|
510
|
+
elem[ propName ] = true;
|
511
|
+
}
|
512
|
+
|
513
|
+
elem.setAttribute( name, name.toLowerCase() );
|
514
|
+
}
|
515
|
+
return name;
|
516
|
+
}
|
517
|
+
};
|
518
|
+
|
519
|
+
// IE6/7 do not support getting/setting some attributes with get/setAttribute
|
520
|
+
if ( !getSetAttribute ) {
|
521
|
+
|
522
|
+
fixSpecified = {
|
523
|
+
name: true,
|
524
|
+
id: true
|
525
|
+
};
|
526
|
+
|
527
|
+
// Use this for any attribute in IE6/7
|
528
|
+
// This fixes almost every IE6/7 issue
|
529
|
+
nodeHook = jQuery.valHooks.button = {
|
530
|
+
get: function( elem, name ) {
|
531
|
+
var ret;
|
532
|
+
ret = elem.getAttributeNode( name );
|
533
|
+
return ret && (fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified) ?
|
534
|
+
ret.nodeValue :
|
535
|
+
undefined;
|
536
|
+
},
|
537
|
+
set: function( elem, value, name ) {
|
538
|
+
// Set the existing or create a new attribute node
|
539
|
+
var ret = elem.getAttributeNode( name );
|
540
|
+
if ( !ret ) {
|
541
|
+
ret = document.createAttribute( name );
|
542
|
+
elem.setAttributeNode( ret );
|
543
|
+
}
|
544
|
+
return (ret.nodeValue = value + "");
|
545
|
+
}
|
546
|
+
};
|
547
|
+
|
548
|
+
// Apply the nodeHook to tabindex
|
549
|
+
jQuery.attrHooks.tabindex.set = nodeHook.set;
|
550
|
+
|
551
|
+
// Set width and height to auto instead of 0 on empty string( Bug #8150 )
|
552
|
+
// This is for removals
|
553
|
+
jQuery.each([ "width", "height" ], function( i, name ) {
|
554
|
+
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
|
555
|
+
set: function( elem, value ) {
|
556
|
+
if ( value === "" ) {
|
557
|
+
elem.setAttribute( name, "auto" );
|
558
|
+
return value;
|
559
|
+
}
|
560
|
+
}
|
561
|
+
});
|
562
|
+
});
|
563
|
+
|
564
|
+
// Set contenteditable to false on removals(#10429)
|
565
|
+
// Setting to empty string throws an error as an invalid value
|
566
|
+
jQuery.attrHooks.contenteditable = {
|
567
|
+
get: nodeHook.get,
|
568
|
+
set: function( elem, value, name ) {
|
569
|
+
if ( value === "" ) {
|
570
|
+
value = "false";
|
571
|
+
}
|
572
|
+
nodeHook.set( elem, value, name );
|
573
|
+
}
|
574
|
+
};
|
575
|
+
}
|
576
|
+
|
577
|
+
|
578
|
+
// Some attributes require a special call on IE
|
579
|
+
if ( !jQuery.support.hrefNormalized ) {
|
580
|
+
jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
|
581
|
+
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
|
582
|
+
get: function( elem ) {
|
583
|
+
var ret = elem.getAttribute( name, 2 );
|
584
|
+
return ret === null ? undefined : ret;
|
585
|
+
}
|
586
|
+
});
|
587
|
+
});
|
588
|
+
}
|
589
|
+
|
590
|
+
if ( !jQuery.support.style ) {
|
591
|
+
jQuery.attrHooks.style = {
|
592
|
+
get: function( elem ) {
|
593
|
+
// Return undefined in the case of empty string
|
594
|
+
// Normalize to lowercase since IE uppercases css property names
|
595
|
+
return elem.style.cssText.toLowerCase() || undefined;
|
596
|
+
},
|
597
|
+
set: function( elem, value ) {
|
598
|
+
return (elem.style.cssText = "" + value);
|
599
|
+
}
|
600
|
+
};
|
601
|
+
}
|
602
|
+
|
603
|
+
// Safari mis-reports the default selected property of an option
|
604
|
+
// Accessing the parent's selectedIndex property fixes it
|
605
|
+
if ( !jQuery.support.optSelected ) {
|
606
|
+
jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
|
607
|
+
get: function( elem ) {
|
608
|
+
var parent = elem.parentNode;
|
609
|
+
|
610
|
+
if ( parent ) {
|
611
|
+
parent.selectedIndex;
|
612
|
+
|
613
|
+
// Make sure that it also works with optgroups, see #5701
|
614
|
+
if ( parent.parentNode ) {
|
615
|
+
parent.parentNode.selectedIndex;
|
616
|
+
}
|
617
|
+
}
|
618
|
+
return null;
|
619
|
+
}
|
620
|
+
});
|
621
|
+
}
|
622
|
+
|
623
|
+
// IE6/7 call enctype encoding
|
624
|
+
if ( !jQuery.support.enctype ) {
|
625
|
+
jQuery.propFix.enctype = "encoding";
|
626
|
+
}
|
627
|
+
|
628
|
+
// Radios and checkboxes getter/setter
|
629
|
+
if ( !jQuery.support.checkOn ) {
|
630
|
+
jQuery.each([ "radio", "checkbox" ], function() {
|
631
|
+
jQuery.valHooks[ this ] = {
|
632
|
+
get: function( elem ) {
|
633
|
+
// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
|
634
|
+
return elem.getAttribute("value") === null ? "on" : elem.value;
|
635
|
+
}
|
636
|
+
};
|
637
|
+
});
|
638
|
+
}
|
639
|
+
jQuery.each([ "radio", "checkbox" ], function() {
|
640
|
+
jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
|
641
|
+
set: function( elem, value ) {
|
642
|
+
if ( jQuery.isArray( value ) ) {
|
643
|
+
return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
|
644
|
+
}
|
645
|
+
}
|
646
|
+
});
|
647
|
+
});
|
648
|
+
|
649
|
+
})( jQuery );
|
650
|
+
|