hjg
2024-07-09 30304784e82d4bba24121328da8eb8490aec4f4f
提交 | 用户 | 时间
58d006 1 /*
A 2  * jQuery UI 1.7.1
3  *
4  * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
5  * Dual licensed under the MIT (MIT-LICENSE.txt)
6  * and GPL (GPL-LICENSE.txt) licenses.
7  *
8  * http://docs.jquery.com/UI
9  */
10 ;jQuery.ui || (function($) {
11
12 var _remove = $.fn.remove,
13     isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
14
15 //Helper functions and ui object
16 $.ui = {
17     version: "1.7.1",
18
19     // $.ui.plugin is deprecated.  Use the proxy pattern instead.
20     plugin: {
21         add: function(module, option, set) {
22             var proto = $.ui[module].prototype;
23             for(var i in set) {
24                 proto.plugins[i] = proto.plugins[i] || [];
25                 proto.plugins[i].push([option, set[i]]);
26             }
27         },
28         call: function(instance, name, args) {
29             var set = instance.plugins[name];
30             if(!set || !instance.element[0].parentNode) { return; }
31
32             for (var i = 0; i < set.length; i++) {
33                 if (instance.options[set[i][0]]) {
34                     set[i][1].apply(instance.element, args);
35                 }
36             }
37         }
38     },
39
40     contains: function(a, b) {
41         return document.compareDocumentPosition
42             ? a.compareDocumentPosition(b) & 16
43             : a !== b && a.contains(b);
44     },
45
46     hasScroll: function(el, a) {
47
48         //If overflow is hidden, the element might have extra content, but the user wants to hide it
49         if ($(el).css('overflow') == 'hidden') { return false; }
50
51         var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
52             has = false;
53
54         if (el[scroll] > 0) { return true; }
55
56         // TODO: determine which cases actually cause this to happen
57         // if the element doesn't have the scroll set, see if it's possible to
58         // set the scroll
59         el[scroll] = 1;
60         has = (el[scroll] > 0);
61         el[scroll] = 0;
62         return has;
63     },
64
65     isOverAxis: function(x, reference, size) {
66         //Determines when x coordinate is over "b" element axis
67         return (x > reference) && (x < (reference + size));
68     },
69
70     isOver: function(y, x, top, left, height, width) {
71         //Determines when x, y coordinates is over "b" element
72         return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
73     },
74
75     keyCode: {
76         BACKSPACE: 8,
77         CAPS_LOCK: 20,
78         COMMA: 188,
79         CONTROL: 17,
80         DELETE: 46,
81         DOWN: 40,
82         END: 35,
83         ENTER: 13,
84         ESCAPE: 27,
85         HOME: 36,
86         INSERT: 45,
87         LEFT: 37,
88         NUMPAD_ADD: 107,
89         NUMPAD_DECIMAL: 110,
90         NUMPAD_DIVIDE: 111,
91         NUMPAD_ENTER: 108,
92         NUMPAD_MULTIPLY: 106,
93         NUMPAD_SUBTRACT: 109,
94         PAGE_DOWN: 34,
95         PAGE_UP: 33,
96         PERIOD: 190,
97         RIGHT: 39,
98         SHIFT: 16,
99         SPACE: 32,
100         TAB: 9,
101         UP: 38
102     }
103 };
104
105 // WAI-ARIA normalization
106 if (isFF2) {
107     var attr = $.attr,
108         removeAttr = $.fn.removeAttr,
109         ariaNS = "http://www.w3.org/2005/07/aaa",
110         ariaState = /^aria-/,
111         ariaRole = /^wairole:/;
112
113     $.attr = function(elem, name, value) {
114         var set = value !== undefined;
115
116         return (name == 'role'
117             ? (set
118                 ? attr.call(this, elem, name, "wairole:" + value)
119                 : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
120             : (ariaState.test(name)
121                 ? (set
122                     ? elem.setAttributeNS(ariaNS,
123                         name.replace(ariaState, "aaa:"), value)
124                     : attr.call(this, elem, name.replace(ariaState, "aaa:")))
125                 : attr.apply(this, arguments)));
126     };
127
128     $.fn.removeAttr = function(name) {
129         return (ariaState.test(name)
130             ? this.each(function() {
131                 this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
132             }) : removeAttr.call(this, name));
133     };
134 }
135
136 //jQuery plugins
137 $.fn.extend({
138     remove: function() {
139         // Safari has a native remove event which actually removes DOM elements,
140         // so we have to use triggerHandler instead of trigger (#3037).
141         $("*", this).add(this).each(function() {
142             $(this).triggerHandler("remove");
143         });
144         return _remove.apply(this, arguments );
145     },
146
147     enableSelection: function() {
148         return this
149             .attr('unselectable', 'off')
150             .css('MozUserSelect', '')
151             .unbind('selectstart.ui');
152     },
153
154     disableSelection: function() {
155         return this
156             .attr('unselectable', 'on')
157             .css('MozUserSelect', 'none')
158             .bind('selectstart.ui', function() { return false; });
159     },
160
161     scrollParent: function() {
162         var scrollParent;
163         if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
164             scrollParent = this.parents().filter(function() {
165                 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
166             }).eq(0);
167         } else {
168             scrollParent = this.parents().filter(function() {
169                 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
170             }).eq(0);
171         }
172
173         return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
174     }
175 });
176
177
178 //Additional selectors
179 $.extend($.expr[':'], {
180     data: function(elem, i, match) {
181         return !!$.data(elem, match[3]);
182     },
183
184     focusable: function(element) {
185         var nodeName = element.nodeName.toLowerCase(),
186             tabIndex = $.attr(element, 'tabindex');
187         return (/input|select|textarea|button|object/.test(nodeName)
188             ? !element.disabled
189             : 'a' == nodeName || 'area' == nodeName
190                 ? element.href || !isNaN(tabIndex)
191                 : !isNaN(tabIndex))
192             // the element and all of its ancestors must be visible
193             // the browser may report that the area is hidden
194             && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
195     },
196
197     tabbable: function(element) {
198         var tabIndex = $.attr(element, 'tabindex');
199         return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
200     }
201 });
202
203
204 // $.widget is a factory to create jQuery plugins
205 // taking some boilerplate code out of the plugin code
206 function getter(namespace, plugin, method, args) {
207     function getMethods(type) {
208         var methods = $[namespace][plugin][type] || [];
209         return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
210     }
211
212     var methods = getMethods('getter');
213     if (args.length == 1 && typeof args[0] == 'string') {
214         methods = methods.concat(getMethods('getterSetter'));
215     }
216     return ($.inArray(method, methods) != -1);
217 }
218
219 $.widget = function(name, prototype) {
220     var namespace = name.split(".")[0];
221     name = name.split(".")[1];
222
223     // create plugin method
224     $.fn[name] = function(options) {
225         var isMethodCall = (typeof options == 'string'),
226             args = Array.prototype.slice.call(arguments, 1);
227
228         // prevent calls to internal methods
229         if (isMethodCall && options.substring(0, 1) == '_') {
230             return this;
231         }
232
233         // handle getter methods
234         if (isMethodCall && getter(namespace, name, options, args)) {
235             var instance = $.data(this[0], name);
236             return (instance ? instance[options].apply(instance, args)
237                 : undefined);
238         }
239
240         // handle initialization and non-getter methods
241         return this.each(function() {
242             var instance = $.data(this, name);
243
244             // constructor
245             (!instance && !isMethodCall &&
246                 $.data(this, name, new $[namespace][name](this, options))._init());
247
248             // method call
249             (instance && isMethodCall && $.isFunction(instance[options]) &&
250                 instance[options].apply(instance, args));
251         });
252     };
253
254     // create widget constructor
255     $[namespace] = $[namespace] || {};
256     $[namespace][name] = function(element, options) {
257         var self = this;
258
259         this.namespace = namespace;
260         this.widgetName = name;
261         this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
262         this.widgetBaseClass = namespace + '-' + name;
263
264         this.options = $.extend({},
265             $.widget.defaults,
266             $[namespace][name].defaults,
267             $.metadata && $.metadata.get(element)[name],
268             options);
269
270         this.element = $(element)
271             .bind('setData.' + name, function(event, key, value) {
272                 if (event.target == element) {
273                     return self._setData(key, value);
274                 }
275             })
276             .bind('getData.' + name, function(event, key) {
277                 if (event.target == element) {
278                     return self._getData(key);
279                 }
280             })
281             .bind('remove', function() {
282                 return self.destroy();
283             });
284     };
285
286     // add widget prototype
287     $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
288
289     // TODO: merge getter and getterSetter properties from widget prototype
290     // and plugin prototype
291     $[namespace][name].getterSetter = 'option';
292 };
293
294 $.widget.prototype = {
295     _init: function() {},
296     destroy: function() {
297         this.element.removeData(this.widgetName)
298             .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
299             .removeAttr('aria-disabled');
300     },
301
302     option: function(key, value) {
303         var options = key,
304             self = this;
305
306         if (typeof key == "string") {
307             if (value === undefined) {
308                 return this._getData(key);
309             }
310             options = {};
311             options[key] = value;
312         }
313
314         $.each(options, function(key, value) {
315             self._setData(key, value);
316         });
317     },
318     _getData: function(key) {
319         return this.options[key];
320     },
321     _setData: function(key, value) {
322         this.options[key] = value;
323
324         if (key == 'disabled') {
325             this.element
326                 [value ? 'addClass' : 'removeClass'](
327                     this.widgetBaseClass + '-disabled' + ' ' +
328                     this.namespace + '-state-disabled')
329                 .attr("aria-disabled", value);
330         }
331     },
332
333     enable: function() {
334         this._setData('disabled', false);
335     },
336     disable: function() {
337         this._setData('disabled', true);
338     },
339
340     _trigger: function(type, event, data) {
341         var callback = this.options[type],
342             eventName = (type == this.widgetEventPrefix
343                 ? type : this.widgetEventPrefix + type);
344
345         event = $.Event(event);
346         event.type = eventName;
347
348         // copy original event properties over to the new event
349         // this would happen if we could call $.event.fix instead of $.Event
350         // but we don't have a way to force an event to be fixed multiple times
351         if (event.originalEvent) {
352             for (var i = $.event.props.length, prop; i;) {
353                 prop = $.event.props[--i];
354                 event[prop] = event.originalEvent[prop];
355             }
356         }
357
358         this.element.trigger(event, data);
359
360         return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
361             || event.isDefaultPrevented());
362     }
363 };
364
365 $.widget.defaults = {
366     disabled: false
367 };
368
369
370 /** Mouse Interaction Plugin **/
371
372 $.ui.mouse = {
373     _mouseInit: function() {
374         var self = this;
375
376         this.element
377             .bind('mousedown.'+this.widgetName, function(event) {
378                 return self._mouseDown(event);
379             })
380             .bind('click.'+this.widgetName, function(event) {
381                 if(self._preventClickEvent) {
382                     self._preventClickEvent = false;
383                     event.stopImmediatePropagation();
384                     return false;
385                 }
386             });
387
388         // Prevent text selection in IE
389         if ($.browser.msie) {
390             this._mouseUnselectable = this.element.attr('unselectable');
391             this.element.attr('unselectable', 'on');
392         }
393
394         this.started = false;
395     },
396
397     // TODO: make sure destroying one instance of mouse doesn't mess with
398     // other instances of mouse
399     _mouseDestroy: function() {
400         this.element.unbind('.'+this.widgetName);
401
402         // Restore text selection in IE
403         ($.browser.msie
404             && this.element.attr('unselectable', this._mouseUnselectable));
405     },
406
407     _mouseDown: function(event) {
408         // don't let more than one widget handle mouseStart
409         // TODO: figure out why we have to use originalEvent
410         event.originalEvent = event.originalEvent || {};
411         if (event.originalEvent.mouseHandled) { return; }
412
413         // we may have missed mouseup (out of window)
414         (this._mouseStarted && this._mouseUp(event));
415
416         this._mouseDownEvent = event;
417
418         var self = this,
419             btnIsLeft = (event.which == 1),
420             elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
421         if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
422             return true;
423         }
424
425         this.mouseDelayMet = !this.options.delay;
426         if (!this.mouseDelayMet) {
427             this._mouseDelayTimer = setTimeout(function() {
428                 self.mouseDelayMet = true;
429             }, this.options.delay);
430         }
431
432         if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
433             this._mouseStarted = (this._mouseStart(event) !== false);
434             if (!this._mouseStarted) {
435                 event.preventDefault();
436                 return true;
437             }
438         }
439
440         // these delegates are required to keep context
441         this._mouseMoveDelegate = function(event) {
442             return self._mouseMove(event);
443         };
444         this._mouseUpDelegate = function(event) {
445             return self._mouseUp(event);
446         };
447         $(document)
448             .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
449             .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
450
451         // preventDefault() is used to prevent the selection of text here -
452         // however, in Safari, this causes select boxes not to be selectable
453         // anymore, so this fix is needed
454         ($.browser.safari || event.preventDefault());
455
456         event.originalEvent.mouseHandled = true;
457         return true;
458     },
459
460     _mouseMove: function(event) {
461         // IE mouseup check - mouseup happened when mouse was out of window
462         if ($.browser.msie && !event.button) {
463             return this._mouseUp(event);
464         }
465
466         if (this._mouseStarted) {
467             this._mouseDrag(event);
468             return event.preventDefault();
469         }
470
471         if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
472             this._mouseStarted =
473                 (this._mouseStart(this._mouseDownEvent, event) !== false);
474             (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
475         }
476
477         return !this._mouseStarted;
478     },
479
480     _mouseUp: function(event) {
481         $(document)
482             .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
483             .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
484
485         if (this._mouseStarted) {
486             this._mouseStarted = false;
487             this._preventClickEvent = (event.target == this._mouseDownEvent.target);
488             this._mouseStop(event);
489         }
490
491         return false;
492     },
493
494     _mouseDistanceMet: function(event) {
495         return (Math.max(
496                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
497                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
498             ) >= this.options.distance
499         );
500     },
501
502     _mouseDelayMet: function(event) {
503         return this.mouseDelayMet;
504     },
505
506     // These are placeholder methods, to be overridden by extending plugin
507     _mouseStart: function(event) {},
508     _mouseDrag: function(event) {},
509     _mouseStop: function(event) {},
510     _mouseCapture: function(event) { return true; }
511 };
512
513 $.ui.mouse.defaults = {
514     cancel: null,
515     distance: 1,
516     delay: 0
517 };
518
519 })(jQuery);