r85038 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r85037‎ | r85038 | r85039 >
Date:19:35, 30 March 2011
Author:reedy
Status:ok
Tags:
Comment:
svn:eol-style native for r85036
Modified paths:
  • /trunk/extensions/LinkSuggest/LinkSuggest.i18n.php (modified) (history)
  • /trunk/extensions/LinkSuggest/LinkSuggest.php (modified) (history)
  • /trunk/extensions/LinkSuggest/jquery-ui.css (modified) (history)
  • /trunk/extensions/LinkSuggest/jquery.mw.linksuggest.js (modified) (history)
  • /trunk/extensions/LinkSuggest/jquery.widget.position.autocomplete-1.8.2.js (modified) (history)

Diff [purge]

Property changes on: trunk/extensions/LinkSuggest/jquery-ui.css
___________________________________________________________________
Added: svn:eol-style
11 + native
Property changes on: trunk/extensions/LinkSuggest/LinkSuggest.i18n.php
___________________________________________________________________
Added: svn:eol-style
22 + native
Index: trunk/extensions/LinkSuggest/jquery.widget.position.autocomplete-1.8.2.js
@@ -1,1201 +1,1201 @@
2 -// https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.js
3 -
4 -/*!
5 - * jQuery UI 1.8.2
6 - *
7 - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
8 - * Dual licensed under the MIT (MIT-LICENSE.txt)
9 - * and GPL (GPL-LICENSE.txt) licenses.
10 - *
11 - * http://docs.jquery.com/UI
12 - */
13 -
14 -(function($) {
15 -
16 -// prevent duplicate loading
17 -// this is only a problem because we proxy existing functions
18 -// and we don't want to double proxy them
19 -$.ui = $.ui || {};
20 -if ($.ui.version) {
21 - return;
22 -}
23 -
24 -//Helper functions and ui object
25 -$.extend($.ui, {
26 - version: "1.8.2",
27 -
28 - // $.ui.plugin is deprecated. Use the proxy pattern instead.
29 - plugin: {
30 - add: function(module, option, set) {
31 - var proto = $.ui[module].prototype;
32 - for(var i in set) {
33 - proto.plugins[i] = proto.plugins[i] || [];
34 - proto.plugins[i].push([option, set[i]]);
35 - }
36 - },
37 - call: function(instance, name, args) {
38 - var set = instance.plugins[name];
39 - if(!set || !instance.element[0].parentNode) { return; }
40 -
41 - for (var i = 0; i < set.length; i++) {
42 - if (instance.options[set[i][0]]) {
43 - set[i][1].apply(instance.element, args);
44 - }
45 - }
46 - }
47 - },
48 -
49 - contains: function(a, b) {
50 - return document.compareDocumentPosition
51 - ? a.compareDocumentPosition(b) & 16
52 - : a !== b && a.contains(b);
53 - },
54 -
55 - hasScroll: function(el, a) {
56 -
57 - //If overflow is hidden, the element might have extra content, but the user wants to hide it
58 - if ($(el).css('overflow') == 'hidden') { return false; }
59 -
60 - var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
61 - has = false;
62 -
63 - if (el[scroll] > 0) { return true; }
64 -
65 - // TODO: determine which cases actually cause this to happen
66 - // if the element doesn't have the scroll set, see if it's possible to
67 - // set the scroll
68 - el[scroll] = 1;
69 - has = (el[scroll] > 0);
70 - el[scroll] = 0;
71 - return has;
72 - },
73 -
74 - isOverAxis: function(x, reference, size) {
75 - //Determines when x coordinate is over "b" element axis
76 - return (x > reference) && (x < (reference + size));
77 - },
78 -
79 - isOver: function(y, x, top, left, height, width) {
80 - //Determines when x, y coordinates is over "b" element
81 - return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
82 - },
83 -
84 - keyCode: {
85 - ALT: 18,
86 - BACKSPACE: 8,
87 - CAPS_LOCK: 20,
88 - COMMA: 188,
89 - COMMAND: 91,
90 - COMMAND_LEFT: 91, // COMMAND
91 - COMMAND_RIGHT: 93,
92 - CONTROL: 17,
93 - DELETE: 46,
94 - DOWN: 40,
95 - END: 35,
96 - ENTER: 13,
97 - ESCAPE: 27,
98 - HOME: 36,
99 - INSERT: 45,
100 - LEFT: 37,
101 - MENU: 93, // COMMAND_RIGHT
102 - NUMPAD_ADD: 107,
103 - NUMPAD_DECIMAL: 110,
104 - NUMPAD_DIVIDE: 111,
105 - NUMPAD_ENTER: 108,
106 - NUMPAD_MULTIPLY: 106,
107 - NUMPAD_SUBTRACT: 109,
108 - PAGE_DOWN: 34,
109 - PAGE_UP: 33,
110 - PERIOD: 190,
111 - RIGHT: 39,
112 - SHIFT: 16,
113 - SPACE: 32,
114 - TAB: 9,
115 - UP: 38,
116 - WINDOWS: 91 // COMMAND
117 - }
118 -});
119 -
120 -//jQuery plugins
121 -$.fn.extend({
122 - _focus: $.fn.focus,
123 - focus: function(delay, fn) {
124 - return typeof delay === 'number'
125 - ? this.each(function() {
126 - var elem = this;
127 - setTimeout(function() {
128 - $(elem).focus();
129 - (fn && fn.call(elem));
130 - }, delay);
131 - })
132 - : this._focus.apply(this, arguments);
133 - },
134 -
135 - enableSelection: function() {
136 - return this
137 - .attr('unselectable', 'off')
138 - .css('MozUserSelect', '');
139 - },
140 -
141 - disableSelection: function() {
142 - return this
143 - .attr('unselectable', 'on')
144 - .css('MozUserSelect', 'none');
145 - },
146 -
147 - scrollParent: function() {
148 - var scrollParent;
149 - if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
150 - scrollParent = this.parents().filter(function() {
151 - 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));
152 - }).eq(0);
153 - } else {
154 - scrollParent = this.parents().filter(function() {
155 - return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
156 - }).eq(0);
157 - }
158 -
159 - return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
160 - },
161 -
162 - zIndex: function(zIndex) {
163 - if (zIndex !== undefined) {
164 - return this.css('zIndex', zIndex);
165 - }
166 -
167 - if (this.length) {
168 - var elem = $(this[0]), position, value;
169 - while (elem.length && elem[0] !== document) {
170 - // Ignore z-index if position is set to a value where z-index is ignored by the browser
171 - // This makes behavior of this function consistent across browsers
172 - // WebKit always returns auto if the element is positioned
173 - position = elem.css('position');
174 - if (position == 'absolute' || position == 'relative' || position == 'fixed')
175 - {
176 - // IE returns 0 when zIndex is not specified
177 - // other browsers return a string
178 - // we ignore the case of nested elements with an explicit value of 0
179 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
180 - value = parseInt(elem.css('zIndex'));
181 - if (!isNaN(value) && value != 0) {
182 - return value;
183 - }
184 - }
185 - elem = elem.parent();
186 - }
187 - }
188 -
189 - return 0;
190 - }
191 -});
192 -
193 -
194 -//Additional selectors
195 -$.extend($.expr[':'], {
196 - data: function(elem, i, match) {
197 - return !!$.data(elem, match[3]);
198 - },
199 -
200 - focusable: function(element) {
201 - var nodeName = element.nodeName.toLowerCase(),
202 - tabIndex = $.attr(element, 'tabindex');
203 - return (/input|select|textarea|button|object/.test(nodeName)
204 - ? !element.disabled
205 - : 'a' == nodeName || 'area' == nodeName
206 - ? element.href || !isNaN(tabIndex)
207 - : !isNaN(tabIndex))
208 - // the element and all of its ancestors must be visible
209 - // the browser may report that the area is hidden
210 - && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
211 - },
212 -
213 - tabbable: function(element) {
214 - var tabIndex = $.attr(element, 'tabindex');
215 - return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
216 - }
217 -});
218 -
219 -})(jQuery);
220 -/*!
221 - * jQuery UI Widget 1.8.2
222 - *
223 - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
224 - * Dual licensed under the MIT (MIT-LICENSE.txt)
225 - * and GPL (GPL-LICENSE.txt) licenses.
226 - *
227 - * http://docs.jquery.com/UI/Widget
228 - */
229 -(function( $ ) {
230 -
231 -var _remove = $.fn.remove;
232 -
233 -$.fn.remove = function( selector, keepData ) {
234 - return this.each(function() {
235 - if ( !keepData ) {
236 - if ( !selector || $.filter( selector, [ this ] ).length ) {
237 - $( "*", this ).add( this ).each(function() {
238 - $( this ).triggerHandler( "remove" );
239 - });
240 - }
241 - }
242 - return _remove.call( $(this), selector, keepData );
243 - });
244 -};
245 -
246 -$.widget = function( name, base, prototype ) {
247 - var namespace = name.split( "." )[ 0 ],
248 - fullName;
249 - name = name.split( "." )[ 1 ];
250 - fullName = namespace + "-" + name;
251 -
252 - if ( !prototype ) {
253 - prototype = base;
254 - base = $.Widget;
255 - }
256 -
257 - // create selector for plugin
258 - $.expr[ ":" ][ fullName ] = function( elem ) {
259 - return !!$.data( elem, name );
260 - };
261 -
262 - $[ namespace ] = $[ namespace ] || {};
263 - $[ namespace ][ name ] = function( options, element ) {
264 - // allow instantiation without initializing for simple inheritance
265 - if ( arguments.length ) {
266 - this._createWidget( options, element );
267 - }
268 - };
269 -
270 - var basePrototype = new base();
271 - // we need to make the options hash a property directly on the new instance
272 - // otherwise we'll modify the options hash on the prototype that we're
273 - // inheriting from
274 -// $.each( basePrototype, function( key, val ) {
275 -// if ( $.isPlainObject(val) ) {
276 -// basePrototype[ key ] = $.extend( {}, val );
277 -// }
278 -// });
279 - basePrototype.options = $.extend( {}, basePrototype.options );
280 - $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
281 - namespace: namespace,
282 - widgetName: name,
283 - widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
284 - widgetBaseClass: fullName
285 - }, prototype );
286 -
287 - $.widget.bridge( name, $[ namespace ][ name ] );
288 -};
289 -
290 -$.widget.bridge = function( name, object ) {
291 - $.fn[ name ] = function( options ) {
292 - var isMethodCall = typeof options === "string",
293 - args = Array.prototype.slice.call( arguments, 1 ),
294 - returnValue = this;
295 -
296 - // allow multiple hashes to be passed on init
297 - options = !isMethodCall && args.length ?
298 - $.extend.apply( null, [ true, options ].concat(args) ) :
299 - options;
300 -
301 - // prevent calls to internal methods
302 - if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
303 - return returnValue;
304 - }
305 -
306 - if ( isMethodCall ) {
307 - this.each(function() {
308 - var instance = $.data( this, name ),
309 - methodValue = instance && $.isFunction( instance[options] ) ?
310 - instance[ options ].apply( instance, args ) :
311 - instance;
312 - if ( methodValue !== instance && methodValue !== undefined ) {
313 - returnValue = methodValue;
314 - return false;
315 - }
316 - });
317 - } else {
318 - this.each(function() {
319 - var instance = $.data( this, name );
320 - if ( instance ) {
321 - if ( options ) {
322 - instance.option( options );
323 - }
324 - instance._init();
325 - } else {
326 - $.data( this, name, new object( options, this ) );
327 - }
328 - });
329 - }
330 -
331 - return returnValue;
332 - };
333 -};
334 -
335 -$.Widget = function( options, element ) {
336 - // allow instantiation without initializing for simple inheritance
337 - if ( arguments.length ) {
338 - this._createWidget( options, element );
339 - }
340 -};
341 -
342 -$.Widget.prototype = {
343 - widgetName: "widget",
344 - widgetEventPrefix: "",
345 - options: {
346 - disabled: false
347 - },
348 - _createWidget: function( options, element ) {
349 - // $.widget.bridge stores the plugin instance, but we do it anyway
350 - // so that it's stored even before the _create function runs
351 - this.element = $( element ).data( this.widgetName, this );
352 - this.options = $.extend( true, {},
353 - this.options,
354 - $.metadata && $.metadata.get( element )[ this.widgetName ],
355 - options );
356 -
357 - var self = this;
358 - this.element.bind( "remove." + this.widgetName, function() {
359 - self.destroy();
360 - });
361 -
362 - this._create();
363 - this._init();
364 - },
365 - _create: function() {},
366 - _init: function() {},
367 -
368 - destroy: function() {
369 - this.element
370 - .unbind( "." + this.widgetName )
371 - .removeData( this.widgetName );
372 - this.widget()
373 - .unbind( "." + this.widgetName )
374 - .removeAttr( "aria-disabled" )
375 - .removeClass(
376 - this.widgetBaseClass + "-disabled " +
377 - "ui-state-disabled" );
378 - },
379 -
380 - widget: function() {
381 - return this.element;
382 - },
383 -
384 - option: function( key, value ) {
385 - var options = key,
386 - self = this;
387 -
388 - if ( arguments.length === 0 ) {
389 - // don't return a reference to the internal hash
390 - return $.extend( {}, self.options );
391 - }
392 -
393 - if (typeof key === "string" ) {
394 - if ( value === undefined ) {
395 - return this.options[ key ];
396 - }
397 - options = {};
398 - options[ key ] = value;
399 - }
400 -
401 - $.each( options, function( key, value ) {
402 - self._setOption( key, value );
403 - });
404 -
405 - return self;
406 - },
407 - _setOption: function( key, value ) {
408 - this.options[ key ] = value;
409 -
410 - if ( key === "disabled" ) {
411 - this.widget()
412 - [ value ? "addClass" : "removeClass"](
413 - this.widgetBaseClass + "-disabled" + " " +
414 - "ui-state-disabled" )
415 - .attr( "aria-disabled", value );
416 - }
417 -
418 - return this;
419 - },
420 -
421 - enable: function() {
422 - return this._setOption( "disabled", false );
423 - },
424 - disable: function() {
425 - return this._setOption( "disabled", true );
426 - },
427 -
428 - _trigger: function( type, event, data ) {
429 - var callback = this.options[ type ];
430 -
431 - event = $.Event( event );
432 - event.type = ( type === this.widgetEventPrefix ?
433 - type :
434 - this.widgetEventPrefix + type ).toLowerCase();
435 - data = data || {};
436 -
437 - // copy original event properties over to the new event
438 - // this would happen if we could call $.event.fix instead of $.Event
439 - // but we don't have a way to force an event to be fixed multiple times
440 - if ( event.originalEvent ) {
441 - for ( var i = $.event.props.length, prop; i; ) {
442 - prop = $.event.props[ --i ];
443 - event[ prop ] = event.originalEvent[ prop ];
444 - }
445 - }
446 -
447 - this.element.trigger( event, data );
448 -
449 - return !( $.isFunction(callback) &&
450 - callback.call( this.element[0], event, data ) === false ||
451 - event.isDefaultPrevented() );
452 - }
453 -};
454 -
455 -})( jQuery );
456 -
457 -/*
458 - * jQuery UI Menu (not officially released)
459 - *
460 - * This widget isn't yet finished and the API is subject to change. We plan to finish
461 - * it for the next release. You're welcome to give it a try anyway and give us feedback,
462 - * as long as you're okay with migrating your code later on. We can help with that, too.
463 - *
464 - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
465 - * Dual licensed under the MIT (MIT-LICENSE.txt)
466 - * and GPL (GPL-LICENSE.txt) licenses.
467 - *
468 - * http://docs.jquery.com/UI/Menu
469 - *
470 - * Depends:
471 - * jquery.ui.core.js
472 - * jquery.ui.widget.js
473 - */
474 -(function($) {
475 -
476 -$.widget("ui.menu", {
477 - _create: function() {
478 - var self = this;
479 - this.element
480 - .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
481 - .attr({
482 - role: "listbox",
483 - "aria-activedescendant": "ui-active-menuitem"
484 - })
485 - .click(function( event ) {
486 - if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
487 - return;
488 - }
489 - // temporary
490 - event.preventDefault();
491 - self.select( event );
492 - });
493 - this.refresh();
494 - },
495 -
496 - refresh: function() {
497 - var self = this;
498 -
499 - // don't refresh list items that are already adapted
500 - var items = this.element.children("li:not(.ui-menu-item):has(a)")
501 - .addClass("ui-menu-item")
502 - .attr("role", "menuitem");
503 -
504 - items.children("a")
505 - .addClass("ui-corner-all")
506 - .attr("tabindex", -1)
507 - // mouseenter doesn't work with event delegation
508 - .mouseenter(function( event ) {
509 - self.activate( event, $(this).parent() );
510 - })
511 - .mouseleave(function() {
512 - self.deactivate();
513 - });
514 - },
515 -
516 - activate: function( event, item ) {
517 - this.deactivate();
518 - if (this.hasScroll()) {
519 - var offset = item.offset().top - this.element.offset().top,
520 - scroll = this.element.attr("scrollTop"),
521 - elementHeight = this.element.height();
522 - if (offset < 0) {
523 - this.element.attr("scrollTop", scroll + offset);
524 - } else if (offset > elementHeight) {
525 - this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
526 - }
527 - }
528 - this.active = item.eq(0)
529 - .children("a")
530 - .addClass("ui-state-hover")
531 - .attr("id", "ui-active-menuitem")
532 - .end();
533 - this._trigger("focus", event, { item: item });
534 - },
535 -
536 - deactivate: function() {
537 - if (!this.active) { return; }
538 -
539 - this.active.children("a")
540 - .removeClass("ui-state-hover")
541 - .removeAttr("id");
542 - this._trigger("blur");
543 - this.active = null;
544 - },
545 -
546 - next: function(event) {
547 - this.move("next", ".ui-menu-item:first", event);
548 - },
549 -
550 - previous: function(event) {
551 - this.move("prev", ".ui-menu-item:last", event);
552 - },
553 -
554 - first: function() {
555 - return this.active && !this.active.prev().length;
556 - },
557 -
558 - last: function() {
559 - return this.active && !this.active.next().length;
560 - },
561 -
562 - move: function(direction, edge, event) {
563 - if (!this.active) {
564 - this.activate(event, this.element.children(edge));
565 - return;
566 - }
567 - var next = this.active[direction + "All"](".ui-menu-item").eq(0);
568 - if (next.length) {
569 - this.activate(event, next);
570 - } else {
571 - this.activate(event, this.element.children(edge));
572 - }
573 - },
574 -
575 - // TODO merge with previousPage
576 - nextPage: function(event) {
577 - if (this.hasScroll()) {
578 - // TODO merge with no-scroll-else
579 - if (!this.active || this.last()) {
580 - this.activate(event, this.element.children(":first"));
581 - return;
582 - }
583 - var base = this.active.offset().top,
584 - height = this.element.height(),
585 - result = this.element.children("li").filter(function() {
586 - var close = $(this).offset().top - base - height + $(this).height();
587 - // TODO improve approximation
588 - return close < 10 && close > -10;
589 - });
590 -
591 - // TODO try to catch this earlier when scrollTop indicates the last page anyway
592 - if (!result.length) {
593 - result = this.element.children(":last");
594 - }
595 - this.activate(event, result);
596 - } else {
597 - this.activate(event, this.element.children(!this.active || this.last() ? ":first" : ":last"));
598 - }
599 - },
600 -
601 - // TODO merge with nextPage
602 - previousPage: function(event) {
603 - if (this.hasScroll()) {
604 - // TODO merge with no-scroll-else
605 - if (!this.active || this.first()) {
606 - this.activate(event, this.element.children(":last"));
607 - return;
608 - }
609 -
610 - var base = this.active.offset().top,
611 - height = this.element.height();
612 - result = this.element.children("li").filter(function() {
613 - var close = $(this).offset().top - base + height - $(this).height();
614 - // TODO improve approximation
615 - return close < 10 && close > -10;
616 - });
617 -
618 - // TODO try to catch this earlier when scrollTop indicates the last page anyway
619 - if (!result.length) {
620 - result = this.element.children(":first");
621 - }
622 - this.activate(event, result);
623 - } else {
624 - this.activate(event, this.element.children(!this.active || this.first() ? ":last" : ":first"));
625 - }
626 - },
627 -
628 - hasScroll: function() {
629 - return this.element.height() < this.element.attr("scrollHeight");
630 - },
631 -
632 - select: function( event ) {
633 - this._trigger("selected", event, { item: this.active });
634 - }
635 -});
636 -
637 -}(jQuery));
638 -
639 -/*
640 - * jQuery UI Position 1.8.2
641 - *
642 - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
643 - * Dual licensed under the MIT (MIT-LICENSE.txt)
644 - * and GPL (GPL-LICENSE.txt) licenses.
645 - *
646 - * http://docs.jquery.com/UI/Position
647 - */
648 -(function( $ ) {
649 -
650 -$.ui = $.ui || {};
651 -
652 -var horizontalPositions = /left|center|right/,
653 - horizontalDefault = "center",
654 - verticalPositions = /top|center|bottom/,
655 - verticalDefault = "center",
656 - _position = $.fn.position,
657 - _offset = $.fn.offset;
658 -
659 -$.fn.position = function( options ) {
660 - if ( !options || !options.of ) {
661 - return _position.apply( this, arguments );
662 - }
663 -
664 - // make a copy, we don't want to modify arguments
665 - options = $.extend( {}, options );
666 -
667 - var target = $( options.of ),
668 - collision = ( options.collision || "flip" ).split( " " ),
669 - offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
670 - targetWidth,
671 - targetHeight,
672 - basePosition;
673 -
674 - if ( options.of.nodeType === 9 ) {
675 - targetWidth = target.width();
676 - targetHeight = target.height();
677 - basePosition = { top: 0, left: 0 };
678 - } else if ( options.of.scrollTo && options.of.document ) {
679 - targetWidth = target.width();
680 - targetHeight = target.height();
681 - basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
682 - } else if ( options.of.preventDefault ) {
683 - // force left top to allow flipping
684 - options.at = "left top";
685 - targetWidth = targetHeight = 0;
686 - basePosition = { top: options.of.pageY, left: options.of.pageX };
687 - } else {
688 - targetWidth = target.outerWidth();
689 - targetHeight = target.outerHeight();
690 - basePosition = target.offset();
691 - }
692 -
693 - // force my and at to have valid horizontal and veritcal positions
694 - // if a value is missing or invalid, it will be converted to center
695 - $.each( [ "my", "at" ], function() {
696 - var pos = ( options[this] || "" ).split( " " );
697 - if ( pos.length === 1) {
698 - pos = horizontalPositions.test( pos[0] ) ?
699 - pos.concat( [verticalDefault] ) :
700 - verticalPositions.test( pos[0] ) ?
701 - [ horizontalDefault ].concat( pos ) :
702 - [ horizontalDefault, verticalDefault ];
703 - }
704 - pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : horizontalDefault;
705 - pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : verticalDefault;
706 - options[ this ] = pos;
707 - });
708 -
709 - // normalize collision option
710 - if ( collision.length === 1 ) {
711 - collision[ 1 ] = collision[ 0 ];
712 - }
713 -
714 - // normalize offset option
715 - offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
716 - if ( offset.length === 1 ) {
717 - offset[ 1 ] = offset[ 0 ];
718 - }
719 - offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
720 -
721 - if ( options.at[0] === "right" ) {
722 - basePosition.left += targetWidth;
723 - } else if (options.at[0] === horizontalDefault ) {
724 - basePosition.left += targetWidth / 2;
725 - }
726 -
727 - if ( options.at[1] === "bottom" ) {
728 - basePosition.top += targetHeight;
729 - } else if ( options.at[1] === verticalDefault ) {
730 - basePosition.top += targetHeight / 2;
731 - }
732 -
733 - basePosition.left += offset[ 0 ];
734 - basePosition.top += offset[ 1 ];
735 -
736 - return this.each(function() {
737 - var elem = $( this ),
738 - elemWidth = elem.outerWidth(),
739 - elemHeight = elem.outerHeight(),
740 - position = $.extend( {}, basePosition );
741 -
742 - if ( options.my[0] === "right" ) {
743 - position.left -= elemWidth;
744 - } else if ( options.my[0] === horizontalDefault ) {
745 - position.left -= elemWidth / 2;
746 - }
747 -
748 - if ( options.my[1] === "bottom" ) {
749 - position.top -= elemHeight;
750 - } else if ( options.my[1] === verticalDefault ) {
751 - position.top -= elemHeight / 2;
752 - }
753 -
754 - // prevent fractions (see #5280)
755 - position.left = parseInt( position.left );
756 - position.top = parseInt( position.top );
757 -
758 - $.each( [ "left", "top" ], function( i, dir ) {
759 - if ( $.ui.position[ collision[i] ] ) {
760 - $.ui.position[ collision[i] ][ dir ]( position, {
761 - targetWidth: targetWidth,
762 - targetHeight: targetHeight,
763 - elemWidth: elemWidth,
764 - elemHeight: elemHeight,
765 - offset: offset,
766 - my: options.my,
767 - at: options.at
768 - });
769 - }
770 - });
771 -
772 - if ( $.fn.bgiframe ) {
773 - elem.bgiframe();
774 - }
775 - elem.offset( $.extend( position, { using: options.using } ) );
776 - });
777 -};
778 -
779 -$.ui.position = {
780 - fit: {
781 - left: function( position, data ) {
782 - var win = $( window ),
783 - over = position.left + data.elemWidth - win.width() - win.scrollLeft();
784 - position.left = over > 0 ? position.left - over : Math.max( 0, position.left );
785 - },
786 - top: function( position, data ) {
787 - var win = $( window ),
788 - over = position.top + data.elemHeight - win.height() - win.scrollTop();
789 - position.top = over > 0 ? position.top - over : Math.max( 0, position.top );
790 - }
791 - },
792 -
793 - flip: {
794 - left: function( position, data ) {
795 - if ( data.at[0] === "center" ) {
796 - return;
797 - }
798 - var win = $( window ),
799 - over = position.left + data.elemWidth - win.width() - win.scrollLeft(),
800 - myOffset = data.my[ 0 ] === "left" ?
801 - -data.elemWidth :
802 - data.my[ 0 ] === "right" ?
803 - data.elemWidth :
804 - 0,
805 - offset = -2 * data.offset[ 0 ];
806 - position.left += position.left < 0 ?
807 - myOffset + data.targetWidth + offset :
808 - over > 0 ?
809 - myOffset - data.targetWidth + offset :
810 - 0;
811 - },
812 - top: function( position, data ) {
813 - if ( data.at[1] === "center" ) {
814 - return;
815 - }
816 - var win = $( window ),
817 - over = position.top + data.elemHeight - win.height() - win.scrollTop(),
818 - myOffset = data.my[ 1 ] === "top" ?
819 - -data.elemHeight :
820 - data.my[ 1 ] === "bottom" ?
821 - data.elemHeight :
822 - 0,
823 - atOffset = data.at[ 1 ] === "top" ?
824 - data.targetHeight :
825 - -data.targetHeight,
826 - offset = -2 * data.offset[ 1 ];
827 - position.top += position.top < 0 ?
828 - myOffset + data.targetHeight + offset :
829 - over > 0 ?
830 - myOffset + atOffset + offset :
831 - 0;
832 - }
833 - }
834 -};
835 -
836 -// offset setter from jQuery 1.4
837 -if ( !$.offset.setOffset ) {
838 - $.offset.setOffset = function( elem, options ) {
839 - // set position first, in-case top/left are set even on static elem
840 - if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
841 - elem.style.position = "relative";
842 - }
843 - var curElem = $( elem ),
844 - curOffset = curElem.offset(),
845 - curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
846 - curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
847 - props = {
848 - top: (options.top - curOffset.top) + curTop,
849 - left: (options.left - curOffset.left) + curLeft
850 - };
851 -
852 - if ( 'using' in options ) {
853 - options.using.call( elem, props );
854 - } else {
855 - curElem.css( props );
856 - }
857 - };
858 -
859 - $.fn.offset = function( options ) {
860 - var elem = this[ 0 ];
861 - if ( !elem || !elem.ownerDocument ) { return null; }
862 - if ( options ) {
863 - return this.each(function() {
864 - $.offset.setOffset( this, options );
865 - });
866 - }
867 - return _offset.call( this );
868 - };
869 -}
870 -
871 -}( jQuery ));
872 -
873 -
874 -/*
875 - * jQuery UI Autocomplete 1.8.2
876 - *
877 - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
878 - * Dual licensed under the MIT (MIT-LICENSE.txt)
879 - * and GPL (GPL-LICENSE.txt) licenses.
880 - *
881 - * http://docs.jquery.com/UI/Autocomplete
882 - *
883 - * Depends:
884 - * jquery.ui.core.js
885 - * jquery.ui.widget.js
886 - * jquery.ui.position.js
887 - */
888 -(function( $ ) {
889 -
890 -$.widget( "ui.autocomplete", {
891 - options: {
892 - minLength: 1,
893 - delay: 300
894 - },
895 - _create: function() {
896 - var self = this,
897 - doc = this.element[ 0 ].ownerDocument;
898 - this.element
899 - .addClass( "ui-autocomplete-input" )
900 - .attr( "autocomplete", "off" )
901 - // TODO verify these actually work as intended
902 - .attr({
903 - role: "textbox",
904 - "aria-autocomplete": "list",
905 - "aria-haspopup": "true"
906 - })
907 - .bind( "keydown.autocomplete", function( event ) {
908 - var keyCode = $.ui.keyCode;
909 - switch( event.keyCode ) {
910 - case keyCode.PAGE_UP:
911 - self._move( "previousPage", event );
912 - break;
913 - case keyCode.PAGE_DOWN:
914 - self._move( "nextPage", event );
915 - break;
916 - case keyCode.UP:
917 - self._move( "previous", event );
918 - // prevent moving cursor to beginning of text field in some browsers
919 - event.preventDefault();
920 - break;
921 - case keyCode.DOWN:
922 - self._move( "next", event );
923 - // prevent moving cursor to end of text field in some browsers
924 - event.preventDefault();
925 - break;
926 - case keyCode.ENTER:
927 - case keyCode.NUMPAD_ENTER:
928 - // when menu is open or has focus
929 - if ( self.menu.active ) {
930 - event.preventDefault();
931 - }
932 - //passthrough - ENTER and TAB both select the current element
933 - case keyCode.TAB:
934 - if ( !self.menu.active ) {
935 - return;
936 - }
937 - self.menu.select( event );
938 - break;
939 - case keyCode.ESCAPE:
940 - self.element.val( self.term );
941 - self.close( event );
942 - break;
943 - case keyCode.LEFT:
944 - case keyCode.RIGHT:
945 - case keyCode.SHIFT:
946 - case keyCode.CONTROL:
947 - case keyCode.ALT:
948 - case keyCode.COMMAND:
949 - case keyCode.COMMAND_RIGHT:
950 - case keyCode.INSERT:
951 - case keyCode.CAPS_LOCK:
952 - case keyCode.END:
953 - case keyCode.HOME:
954 - // ignore metakeys (shift, ctrl, alt)
955 - break;
956 - default:
957 - // keypress is triggered before the input value is changed
958 - clearTimeout( self.searching );
959 - self.searching = setTimeout(function() {
960 - self.search( null, event );
961 - }, self.options.delay );
962 - break;
963 - }
964 - })
965 - .bind( "focus.autocomplete", function() {
966 - self.selectedItem = null;
967 - self.previous = self.element.val();
968 - })
969 - .bind( "blur.autocomplete", function( event ) {
970 - clearTimeout( self.searching );
971 - // clicks on the menu (or a button to trigger a search) will cause a blur event
972 - self.closing = setTimeout(function() {
973 - self.close( event );
974 - self._change( event );
975 - }, 150 );
976 - });
977 - this._initSource();
978 - this.response = function() {
979 - return self._response.apply( self, arguments );
980 - };
981 - this.menu = $( "<ul></ul>" )
982 - .addClass( "ui-autocomplete" )
983 - .appendTo( "body", doc )
984 - // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
985 - .mousedown(function() {
986 - // use another timeout to make sure the blur-event-handler on the input was already triggered
987 - setTimeout(function() {
988 - clearTimeout( self.closing );
989 - }, 13);
990 - })
991 - .menu({
992 - focus: function( event, ui ) {
993 - var item = ui.item.data( "item.autocomplete" );
994 - if ( false !== self._trigger( "focus", null, { item: item } ) ) {
995 - // use value to match what will end up in the input, if it was a key event
996 - if ( /^key/.test(event.originalEvent.type) ) {
997 - self.element.val( item.value );
998 - }
999 - }
1000 - },
1001 - selected: function( event, ui ) {
1002 - var item = ui.item.data( "item.autocomplete" );
1003 - if ( false !== self._trigger( "select", event, { item: item } ) ) {
1004 - self.element.val( item.value );
1005 - }
1006 - self.close( event );
1007 - // only trigger when focus was lost (click on menu)
1008 - var previous = self.previous;
1009 - if ( self.element[0] !== doc.activeElement ) {
1010 - self.element.focus();
1011 - self.previous = previous;
1012 - }
1013 - self.selectedItem = item;
1014 - },
1015 - blur: function( event, ui ) {
1016 - if ( self.menu.element.is(":visible") ) {
1017 - self.element.val( self.term );
1018 - }
1019 - }
1020 - })
1021 - .zIndex( this.element.zIndex() + 1 )
1022 - // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
1023 - .css({ top: 0, left: 0 })
1024 - .hide()
1025 - .data( "menu" );
1026 - if ( $.fn.bgiframe ) {
1027 - this.menu.element.bgiframe();
1028 - }
1029 - },
1030 -
1031 - destroy: function() {
1032 - this.element
1033 - .removeClass( "ui-autocomplete-input" )
1034 - .removeAttr( "autocomplete" )
1035 - .removeAttr( "role" )
1036 - .removeAttr( "aria-autocomplete" )
1037 - .removeAttr( "aria-haspopup" );
1038 - this.menu.element.remove();
1039 - $.Widget.prototype.destroy.call( this );
1040 - },
1041 -
1042 - _setOption: function( key ) {
1043 - $.Widget.prototype._setOption.apply( this, arguments );
1044 - if ( key === "source" ) {
1045 - this._initSource();
1046 - }
1047 - },
1048 -
1049 - _initSource: function() {
1050 - var array,
1051 - url;
1052 - if ( $.isArray(this.options.source) ) {
1053 - array = this.options.source;
1054 - this.source = function( request, response ) {
1055 - response( $.ui.autocomplete.filter(array, request.term) );
1056 - };
1057 - } else if ( typeof this.options.source === "string" ) {
1058 - url = this.options.source;
1059 - this.source = function( request, response ) {
1060 - $.getJSON( url, request, response );
1061 - };
1062 - } else {
1063 - this.source = this.options.source;
1064 - }
1065 - },
1066 -
1067 - search: function( value, event ) {
1068 - value = value != null ? value : this.element.val();
1069 - if ( value.length < this.options.minLength ) {
1070 - return this.close( event );
1071 - }
1072 -
1073 - clearTimeout( this.closing );
1074 - if ( this._trigger("search") === false ) {
1075 - return;
1076 - }
1077 -
1078 - return this._search( value );
1079 - },
1080 -
1081 - _search: function( value ) {
1082 - this.term = this.element
1083 - .addClass( "ui-autocomplete-loading" )
1084 - // always save the actual value, not the one passed as an argument
1085 - .val();
1086 -
1087 - this.source( { term: value }, this.response );
1088 - },
1089 -
1090 - _response: function( content ) {
1091 - if ( content.length ) {
1092 - content = this._normalize( content );
1093 - this._suggest( content );
1094 - this._trigger( "open" );
1095 - } else {
1096 - this.close();
1097 - }
1098 - this.element.removeClass( "ui-autocomplete-loading" );
1099 - },
1100 -
1101 - close: function( event ) {
1102 - clearTimeout( this.closing );
1103 - if ( this.menu.element.is(":visible") ) {
1104 - this._trigger( "close", event );
1105 - this.menu.element.hide();
1106 - this.menu.deactivate();
1107 - }
1108 - },
1109 -
1110 - _change: function( event ) {
1111 - if ( this.previous !== this.element.val() ) {
1112 - this._trigger( "change", event, { item: this.selectedItem } );
1113 - }
1114 - },
1115 -
1116 - _normalize: function( items ) {
1117 - // assume all items have the right format when the first item is complete
1118 - if ( items.length && items[0].label && items[0].value ) {
1119 - return items;
1120 - }
1121 - return $.map( items, function(item) {
1122 - if ( typeof item === "string" ) {
1123 - return {
1124 - label: item,
1125 - value: item
1126 - };
1127 - }
1128 - return $.extend({
1129 - label: item.label || item.value,
1130 - value: item.value || item.label
1131 - }, item );
1132 - });
1133 - },
1134 -
1135 - _suggest: function( items ) {
1136 - var ul = this.menu.element
1137 - .empty()
1138 - .zIndex( this.element.zIndex() + 1 ),
1139 - menuWidth,
1140 - textWidth;
1141 - this._renderMenu( ul, items );
1142 - // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
1143 - this.menu.deactivate();
1144 - this.menu.refresh();
1145 - this.menu.element.show().position({
1146 - my: "left top",
1147 - at: "left bottom",
1148 - of: this.element,
1149 - collision: "none"
1150 - });
1151 -
1152 - menuWidth = ul.width( "" ).width();
1153 - textWidth = this.element.width();
1154 - ul.width( Math.max( menuWidth, textWidth ) );
1155 - },
1156 -
1157 - _renderMenu: function( ul, items ) {
1158 - var self = this;
1159 - $.each( items, function( index, item ) {
1160 - self._renderItem( ul, item );
1161 - });
1162 - },
1163 -
1164 - _renderItem: function( ul, item) {
1165 - return $( "<li></li>" )
1166 - .data( "item.autocomplete", item )
1167 - .append( "<a>" + item.label + "</a>" )
1168 - .appendTo( ul );
1169 - },
1170 -
1171 - _move: function( direction, event ) {
1172 - if ( !this.menu.element.is(":visible") ) {
1173 - this.search( null, event );
1174 - return;
1175 - }
1176 - if ( this.menu.first() && /^previous/.test(direction) ||
1177 - this.menu.last() && /^next/.test(direction) ) {
1178 - this.element.val( this.term );
1179 - this.menu.deactivate();
1180 - return;
1181 - }
1182 - this.menu[ direction ]( event );
1183 - },
1184 -
1185 - widget: function() {
1186 - return this.menu.element;
1187 - }
1188 -});
1189 -
1190 -$.extend( $.ui.autocomplete, {
1191 - escapeRegex: function( value ) {
1192 - return value.replace( /([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1" );
1193 - },
1194 - filter: function(array, term) {
1195 - var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
1196 - return $.grep( array, function(value) {
1197 - return matcher.test( value.label || value.value || value );
1198 - });
1199 - }
1200 -});
1201 -
1202 -}( jQuery ));
 2+// https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.js
 3+
 4+/*!
 5+ * jQuery UI 1.8.2
 6+ *
 7+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 8+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 9+ * and GPL (GPL-LICENSE.txt) licenses.
 10+ *
 11+ * http://docs.jquery.com/UI
 12+ */
 13+
 14+(function($) {
 15+
 16+// prevent duplicate loading
 17+// this is only a problem because we proxy existing functions
 18+// and we don't want to double proxy them
 19+$.ui = $.ui || {};
 20+if ($.ui.version) {
 21+ return;
 22+}
 23+
 24+//Helper functions and ui object
 25+$.extend($.ui, {
 26+ version: "1.8.2",
 27+
 28+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
 29+ plugin: {
 30+ add: function(module, option, set) {
 31+ var proto = $.ui[module].prototype;
 32+ for(var i in set) {
 33+ proto.plugins[i] = proto.plugins[i] || [];
 34+ proto.plugins[i].push([option, set[i]]);
 35+ }
 36+ },
 37+ call: function(instance, name, args) {
 38+ var set = instance.plugins[name];
 39+ if(!set || !instance.element[0].parentNode) { return; }
 40+
 41+ for (var i = 0; i < set.length; i++) {
 42+ if (instance.options[set[i][0]]) {
 43+ set[i][1].apply(instance.element, args);
 44+ }
 45+ }
 46+ }
 47+ },
 48+
 49+ contains: function(a, b) {
 50+ return document.compareDocumentPosition
 51+ ? a.compareDocumentPosition(b) & 16
 52+ : a !== b && a.contains(b);
 53+ },
 54+
 55+ hasScroll: function(el, a) {
 56+
 57+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
 58+ if ($(el).css('overflow') == 'hidden') { return false; }
 59+
 60+ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
 61+ has = false;
 62+
 63+ if (el[scroll] > 0) { return true; }
 64+
 65+ // TODO: determine which cases actually cause this to happen
 66+ // if the element doesn't have the scroll set, see if it's possible to
 67+ // set the scroll
 68+ el[scroll] = 1;
 69+ has = (el[scroll] > 0);
 70+ el[scroll] = 0;
 71+ return has;
 72+ },
 73+
 74+ isOverAxis: function(x, reference, size) {
 75+ //Determines when x coordinate is over "b" element axis
 76+ return (x > reference) && (x < (reference + size));
 77+ },
 78+
 79+ isOver: function(y, x, top, left, height, width) {
 80+ //Determines when x, y coordinates is over "b" element
 81+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
 82+ },
 83+
 84+ keyCode: {
 85+ ALT: 18,
 86+ BACKSPACE: 8,
 87+ CAPS_LOCK: 20,
 88+ COMMA: 188,
 89+ COMMAND: 91,
 90+ COMMAND_LEFT: 91, // COMMAND
 91+ COMMAND_RIGHT: 93,
 92+ CONTROL: 17,
 93+ DELETE: 46,
 94+ DOWN: 40,
 95+ END: 35,
 96+ ENTER: 13,
 97+ ESCAPE: 27,
 98+ HOME: 36,
 99+ INSERT: 45,
 100+ LEFT: 37,
 101+ MENU: 93, // COMMAND_RIGHT
 102+ NUMPAD_ADD: 107,
 103+ NUMPAD_DECIMAL: 110,
 104+ NUMPAD_DIVIDE: 111,
 105+ NUMPAD_ENTER: 108,
 106+ NUMPAD_MULTIPLY: 106,
 107+ NUMPAD_SUBTRACT: 109,
 108+ PAGE_DOWN: 34,
 109+ PAGE_UP: 33,
 110+ PERIOD: 190,
 111+ RIGHT: 39,
 112+ SHIFT: 16,
 113+ SPACE: 32,
 114+ TAB: 9,
 115+ UP: 38,
 116+ WINDOWS: 91 // COMMAND
 117+ }
 118+});
 119+
 120+//jQuery plugins
 121+$.fn.extend({
 122+ _focus: $.fn.focus,
 123+ focus: function(delay, fn) {
 124+ return typeof delay === 'number'
 125+ ? this.each(function() {
 126+ var elem = this;
 127+ setTimeout(function() {
 128+ $(elem).focus();
 129+ (fn && fn.call(elem));
 130+ }, delay);
 131+ })
 132+ : this._focus.apply(this, arguments);
 133+ },
 134+
 135+ enableSelection: function() {
 136+ return this
 137+ .attr('unselectable', 'off')
 138+ .css('MozUserSelect', '');
 139+ },
 140+
 141+ disableSelection: function() {
 142+ return this
 143+ .attr('unselectable', 'on')
 144+ .css('MozUserSelect', 'none');
 145+ },
 146+
 147+ scrollParent: function() {
 148+ var scrollParent;
 149+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
 150+ scrollParent = this.parents().filter(function() {
 151+ 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));
 152+ }).eq(0);
 153+ } else {
 154+ scrollParent = this.parents().filter(function() {
 155+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
 156+ }).eq(0);
 157+ }
 158+
 159+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
 160+ },
 161+
 162+ zIndex: function(zIndex) {
 163+ if (zIndex !== undefined) {
 164+ return this.css('zIndex', zIndex);
 165+ }
 166+
 167+ if (this.length) {
 168+ var elem = $(this[0]), position, value;
 169+ while (elem.length && elem[0] !== document) {
 170+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
 171+ // This makes behavior of this function consistent across browsers
 172+ // WebKit always returns auto if the element is positioned
 173+ position = elem.css('position');
 174+ if (position == 'absolute' || position == 'relative' || position == 'fixed')
 175+ {
 176+ // IE returns 0 when zIndex is not specified
 177+ // other browsers return a string
 178+ // we ignore the case of nested elements with an explicit value of 0
 179+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
 180+ value = parseInt(elem.css('zIndex'));
 181+ if (!isNaN(value) && value != 0) {
 182+ return value;
 183+ }
 184+ }
 185+ elem = elem.parent();
 186+ }
 187+ }
 188+
 189+ return 0;
 190+ }
 191+});
 192+
 193+
 194+//Additional selectors
 195+$.extend($.expr[':'], {
 196+ data: function(elem, i, match) {
 197+ return !!$.data(elem, match[3]);
 198+ },
 199+
 200+ focusable: function(element) {
 201+ var nodeName = element.nodeName.toLowerCase(),
 202+ tabIndex = $.attr(element, 'tabindex');
 203+ return (/input|select|textarea|button|object/.test(nodeName)
 204+ ? !element.disabled
 205+ : 'a' == nodeName || 'area' == nodeName
 206+ ? element.href || !isNaN(tabIndex)
 207+ : !isNaN(tabIndex))
 208+ // the element and all of its ancestors must be visible
 209+ // the browser may report that the area is hidden
 210+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
 211+ },
 212+
 213+ tabbable: function(element) {
 214+ var tabIndex = $.attr(element, 'tabindex');
 215+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
 216+ }
 217+});
 218+
 219+})(jQuery);
 220+/*!
 221+ * jQuery UI Widget 1.8.2
 222+ *
 223+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 224+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 225+ * and GPL (GPL-LICENSE.txt) licenses.
 226+ *
 227+ * http://docs.jquery.com/UI/Widget
 228+ */
 229+(function( $ ) {
 230+
 231+var _remove = $.fn.remove;
 232+
 233+$.fn.remove = function( selector, keepData ) {
 234+ return this.each(function() {
 235+ if ( !keepData ) {
 236+ if ( !selector || $.filter( selector, [ this ] ).length ) {
 237+ $( "*", this ).add( this ).each(function() {
 238+ $( this ).triggerHandler( "remove" );
 239+ });
 240+ }
 241+ }
 242+ return _remove.call( $(this), selector, keepData );
 243+ });
 244+};
 245+
 246+$.widget = function( name, base, prototype ) {
 247+ var namespace = name.split( "." )[ 0 ],
 248+ fullName;
 249+ name = name.split( "." )[ 1 ];
 250+ fullName = namespace + "-" + name;
 251+
 252+ if ( !prototype ) {
 253+ prototype = base;
 254+ base = $.Widget;
 255+ }
 256+
 257+ // create selector for plugin
 258+ $.expr[ ":" ][ fullName ] = function( elem ) {
 259+ return !!$.data( elem, name );
 260+ };
 261+
 262+ $[ namespace ] = $[ namespace ] || {};
 263+ $[ namespace ][ name ] = function( options, element ) {
 264+ // allow instantiation without initializing for simple inheritance
 265+ if ( arguments.length ) {
 266+ this._createWidget( options, element );
 267+ }
 268+ };
 269+
 270+ var basePrototype = new base();
 271+ // we need to make the options hash a property directly on the new instance
 272+ // otherwise we'll modify the options hash on the prototype that we're
 273+ // inheriting from
 274+// $.each( basePrototype, function( key, val ) {
 275+// if ( $.isPlainObject(val) ) {
 276+// basePrototype[ key ] = $.extend( {}, val );
 277+// }
 278+// });
 279+ basePrototype.options = $.extend( {}, basePrototype.options );
 280+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
 281+ namespace: namespace,
 282+ widgetName: name,
 283+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
 284+ widgetBaseClass: fullName
 285+ }, prototype );
 286+
 287+ $.widget.bridge( name, $[ namespace ][ name ] );
 288+};
 289+
 290+$.widget.bridge = function( name, object ) {
 291+ $.fn[ name ] = function( options ) {
 292+ var isMethodCall = typeof options === "string",
 293+ args = Array.prototype.slice.call( arguments, 1 ),
 294+ returnValue = this;
 295+
 296+ // allow multiple hashes to be passed on init
 297+ options = !isMethodCall && args.length ?
 298+ $.extend.apply( null, [ true, options ].concat(args) ) :
 299+ options;
 300+
 301+ // prevent calls to internal methods
 302+ if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
 303+ return returnValue;
 304+ }
 305+
 306+ if ( isMethodCall ) {
 307+ this.each(function() {
 308+ var instance = $.data( this, name ),
 309+ methodValue = instance && $.isFunction( instance[options] ) ?
 310+ instance[ options ].apply( instance, args ) :
 311+ instance;
 312+ if ( methodValue !== instance && methodValue !== undefined ) {
 313+ returnValue = methodValue;
 314+ return false;
 315+ }
 316+ });
 317+ } else {
 318+ this.each(function() {
 319+ var instance = $.data( this, name );
 320+ if ( instance ) {
 321+ if ( options ) {
 322+ instance.option( options );
 323+ }
 324+ instance._init();
 325+ } else {
 326+ $.data( this, name, new object( options, this ) );
 327+ }
 328+ });
 329+ }
 330+
 331+ return returnValue;
 332+ };
 333+};
 334+
 335+$.Widget = function( options, element ) {
 336+ // allow instantiation without initializing for simple inheritance
 337+ if ( arguments.length ) {
 338+ this._createWidget( options, element );
 339+ }
 340+};
 341+
 342+$.Widget.prototype = {
 343+ widgetName: "widget",
 344+ widgetEventPrefix: "",
 345+ options: {
 346+ disabled: false
 347+ },
 348+ _createWidget: function( options, element ) {
 349+ // $.widget.bridge stores the plugin instance, but we do it anyway
 350+ // so that it's stored even before the _create function runs
 351+ this.element = $( element ).data( this.widgetName, this );
 352+ this.options = $.extend( true, {},
 353+ this.options,
 354+ $.metadata && $.metadata.get( element )[ this.widgetName ],
 355+ options );
 356+
 357+ var self = this;
 358+ this.element.bind( "remove." + this.widgetName, function() {
 359+ self.destroy();
 360+ });
 361+
 362+ this._create();
 363+ this._init();
 364+ },
 365+ _create: function() {},
 366+ _init: function() {},
 367+
 368+ destroy: function() {
 369+ this.element
 370+ .unbind( "." + this.widgetName )
 371+ .removeData( this.widgetName );
 372+ this.widget()
 373+ .unbind( "." + this.widgetName )
 374+ .removeAttr( "aria-disabled" )
 375+ .removeClass(
 376+ this.widgetBaseClass + "-disabled " +
 377+ "ui-state-disabled" );
 378+ },
 379+
 380+ widget: function() {
 381+ return this.element;
 382+ },
 383+
 384+ option: function( key, value ) {
 385+ var options = key,
 386+ self = this;
 387+
 388+ if ( arguments.length === 0 ) {
 389+ // don't return a reference to the internal hash
 390+ return $.extend( {}, self.options );
 391+ }
 392+
 393+ if (typeof key === "string" ) {
 394+ if ( value === undefined ) {
 395+ return this.options[ key ];
 396+ }
 397+ options = {};
 398+ options[ key ] = value;
 399+ }
 400+
 401+ $.each( options, function( key, value ) {
 402+ self._setOption( key, value );
 403+ });
 404+
 405+ return self;
 406+ },
 407+ _setOption: function( key, value ) {
 408+ this.options[ key ] = value;
 409+
 410+ if ( key === "disabled" ) {
 411+ this.widget()
 412+ [ value ? "addClass" : "removeClass"](
 413+ this.widgetBaseClass + "-disabled" + " " +
 414+ "ui-state-disabled" )
 415+ .attr( "aria-disabled", value );
 416+ }
 417+
 418+ return this;
 419+ },
 420+
 421+ enable: function() {
 422+ return this._setOption( "disabled", false );
 423+ },
 424+ disable: function() {
 425+ return this._setOption( "disabled", true );
 426+ },
 427+
 428+ _trigger: function( type, event, data ) {
 429+ var callback = this.options[ type ];
 430+
 431+ event = $.Event( event );
 432+ event.type = ( type === this.widgetEventPrefix ?
 433+ type :
 434+ this.widgetEventPrefix + type ).toLowerCase();
 435+ data = data || {};
 436+
 437+ // copy original event properties over to the new event
 438+ // this would happen if we could call $.event.fix instead of $.Event
 439+ // but we don't have a way to force an event to be fixed multiple times
 440+ if ( event.originalEvent ) {
 441+ for ( var i = $.event.props.length, prop; i; ) {
 442+ prop = $.event.props[ --i ];
 443+ event[ prop ] = event.originalEvent[ prop ];
 444+ }
 445+ }
 446+
 447+ this.element.trigger( event, data );
 448+
 449+ return !( $.isFunction(callback) &&
 450+ callback.call( this.element[0], event, data ) === false ||
 451+ event.isDefaultPrevented() );
 452+ }
 453+};
 454+
 455+})( jQuery );
 456+
 457+/*
 458+ * jQuery UI Menu (not officially released)
 459+ *
 460+ * This widget isn't yet finished and the API is subject to change. We plan to finish
 461+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
 462+ * as long as you're okay with migrating your code later on. We can help with that, too.
 463+ *
 464+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 465+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 466+ * and GPL (GPL-LICENSE.txt) licenses.
 467+ *
 468+ * http://docs.jquery.com/UI/Menu
 469+ *
 470+ * Depends:
 471+ * jquery.ui.core.js
 472+ * jquery.ui.widget.js
 473+ */
 474+(function($) {
 475+
 476+$.widget("ui.menu", {
 477+ _create: function() {
 478+ var self = this;
 479+ this.element
 480+ .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
 481+ .attr({
 482+ role: "listbox",
 483+ "aria-activedescendant": "ui-active-menuitem"
 484+ })
 485+ .click(function( event ) {
 486+ if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
 487+ return;
 488+ }
 489+ // temporary
 490+ event.preventDefault();
 491+ self.select( event );
 492+ });
 493+ this.refresh();
 494+ },
 495+
 496+ refresh: function() {
 497+ var self = this;
 498+
 499+ // don't refresh list items that are already adapted
 500+ var items = this.element.children("li:not(.ui-menu-item):has(a)")
 501+ .addClass("ui-menu-item")
 502+ .attr("role", "menuitem");
 503+
 504+ items.children("a")
 505+ .addClass("ui-corner-all")
 506+ .attr("tabindex", -1)
 507+ // mouseenter doesn't work with event delegation
 508+ .mouseenter(function( event ) {
 509+ self.activate( event, $(this).parent() );
 510+ })
 511+ .mouseleave(function() {
 512+ self.deactivate();
 513+ });
 514+ },
 515+
 516+ activate: function( event, item ) {
 517+ this.deactivate();
 518+ if (this.hasScroll()) {
 519+ var offset = item.offset().top - this.element.offset().top,
 520+ scroll = this.element.attr("scrollTop"),
 521+ elementHeight = this.element.height();
 522+ if (offset < 0) {
 523+ this.element.attr("scrollTop", scroll + offset);
 524+ } else if (offset > elementHeight) {
 525+ this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
 526+ }
 527+ }
 528+ this.active = item.eq(0)
 529+ .children("a")
 530+ .addClass("ui-state-hover")
 531+ .attr("id", "ui-active-menuitem")
 532+ .end();
 533+ this._trigger("focus", event, { item: item });
 534+ },
 535+
 536+ deactivate: function() {
 537+ if (!this.active) { return; }
 538+
 539+ this.active.children("a")
 540+ .removeClass("ui-state-hover")
 541+ .removeAttr("id");
 542+ this._trigger("blur");
 543+ this.active = null;
 544+ },
 545+
 546+ next: function(event) {
 547+ this.move("next", ".ui-menu-item:first", event);
 548+ },
 549+
 550+ previous: function(event) {
 551+ this.move("prev", ".ui-menu-item:last", event);
 552+ },
 553+
 554+ first: function() {
 555+ return this.active && !this.active.prev().length;
 556+ },
 557+
 558+ last: function() {
 559+ return this.active && !this.active.next().length;
 560+ },
 561+
 562+ move: function(direction, edge, event) {
 563+ if (!this.active) {
 564+ this.activate(event, this.element.children(edge));
 565+ return;
 566+ }
 567+ var next = this.active[direction + "All"](".ui-menu-item").eq(0);
 568+ if (next.length) {
 569+ this.activate(event, next);
 570+ } else {
 571+ this.activate(event, this.element.children(edge));
 572+ }
 573+ },
 574+
 575+ // TODO merge with previousPage
 576+ nextPage: function(event) {
 577+ if (this.hasScroll()) {
 578+ // TODO merge with no-scroll-else
 579+ if (!this.active || this.last()) {
 580+ this.activate(event, this.element.children(":first"));
 581+ return;
 582+ }
 583+ var base = this.active.offset().top,
 584+ height = this.element.height(),
 585+ result = this.element.children("li").filter(function() {
 586+ var close = $(this).offset().top - base - height + $(this).height();
 587+ // TODO improve approximation
 588+ return close < 10 && close > -10;
 589+ });
 590+
 591+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
 592+ if (!result.length) {
 593+ result = this.element.children(":last");
 594+ }
 595+ this.activate(event, result);
 596+ } else {
 597+ this.activate(event, this.element.children(!this.active || this.last() ? ":first" : ":last"));
 598+ }
 599+ },
 600+
 601+ // TODO merge with nextPage
 602+ previousPage: function(event) {
 603+ if (this.hasScroll()) {
 604+ // TODO merge with no-scroll-else
 605+ if (!this.active || this.first()) {
 606+ this.activate(event, this.element.children(":last"));
 607+ return;
 608+ }
 609+
 610+ var base = this.active.offset().top,
 611+ height = this.element.height();
 612+ result = this.element.children("li").filter(function() {
 613+ var close = $(this).offset().top - base + height - $(this).height();
 614+ // TODO improve approximation
 615+ return close < 10 && close > -10;
 616+ });
 617+
 618+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
 619+ if (!result.length) {
 620+ result = this.element.children(":first");
 621+ }
 622+ this.activate(event, result);
 623+ } else {
 624+ this.activate(event, this.element.children(!this.active || this.first() ? ":last" : ":first"));
 625+ }
 626+ },
 627+
 628+ hasScroll: function() {
 629+ return this.element.height() < this.element.attr("scrollHeight");
 630+ },
 631+
 632+ select: function( event ) {
 633+ this._trigger("selected", event, { item: this.active });
 634+ }
 635+});
 636+
 637+}(jQuery));
 638+
 639+/*
 640+ * jQuery UI Position 1.8.2
 641+ *
 642+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 643+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 644+ * and GPL (GPL-LICENSE.txt) licenses.
 645+ *
 646+ * http://docs.jquery.com/UI/Position
 647+ */
 648+(function( $ ) {
 649+
 650+$.ui = $.ui || {};
 651+
 652+var horizontalPositions = /left|center|right/,
 653+ horizontalDefault = "center",
 654+ verticalPositions = /top|center|bottom/,
 655+ verticalDefault = "center",
 656+ _position = $.fn.position,
 657+ _offset = $.fn.offset;
 658+
 659+$.fn.position = function( options ) {
 660+ if ( !options || !options.of ) {
 661+ return _position.apply( this, arguments );
 662+ }
 663+
 664+ // make a copy, we don't want to modify arguments
 665+ options = $.extend( {}, options );
 666+
 667+ var target = $( options.of ),
 668+ collision = ( options.collision || "flip" ).split( " " ),
 669+ offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
 670+ targetWidth,
 671+ targetHeight,
 672+ basePosition;
 673+
 674+ if ( options.of.nodeType === 9 ) {
 675+ targetWidth = target.width();
 676+ targetHeight = target.height();
 677+ basePosition = { top: 0, left: 0 };
 678+ } else if ( options.of.scrollTo && options.of.document ) {
 679+ targetWidth = target.width();
 680+ targetHeight = target.height();
 681+ basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
 682+ } else if ( options.of.preventDefault ) {
 683+ // force left top to allow flipping
 684+ options.at = "left top";
 685+ targetWidth = targetHeight = 0;
 686+ basePosition = { top: options.of.pageY, left: options.of.pageX };
 687+ } else {
 688+ targetWidth = target.outerWidth();
 689+ targetHeight = target.outerHeight();
 690+ basePosition = target.offset();
 691+ }
 692+
 693+ // force my and at to have valid horizontal and veritcal positions
 694+ // if a value is missing or invalid, it will be converted to center
 695+ $.each( [ "my", "at" ], function() {
 696+ var pos = ( options[this] || "" ).split( " " );
 697+ if ( pos.length === 1) {
 698+ pos = horizontalPositions.test( pos[0] ) ?
 699+ pos.concat( [verticalDefault] ) :
 700+ verticalPositions.test( pos[0] ) ?
 701+ [ horizontalDefault ].concat( pos ) :
 702+ [ horizontalDefault, verticalDefault ];
 703+ }
 704+ pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : horizontalDefault;
 705+ pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : verticalDefault;
 706+ options[ this ] = pos;
 707+ });
 708+
 709+ // normalize collision option
 710+ if ( collision.length === 1 ) {
 711+ collision[ 1 ] = collision[ 0 ];
 712+ }
 713+
 714+ // normalize offset option
 715+ offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
 716+ if ( offset.length === 1 ) {
 717+ offset[ 1 ] = offset[ 0 ];
 718+ }
 719+ offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
 720+
 721+ if ( options.at[0] === "right" ) {
 722+ basePosition.left += targetWidth;
 723+ } else if (options.at[0] === horizontalDefault ) {
 724+ basePosition.left += targetWidth / 2;
 725+ }
 726+
 727+ if ( options.at[1] === "bottom" ) {
 728+ basePosition.top += targetHeight;
 729+ } else if ( options.at[1] === verticalDefault ) {
 730+ basePosition.top += targetHeight / 2;
 731+ }
 732+
 733+ basePosition.left += offset[ 0 ];
 734+ basePosition.top += offset[ 1 ];
 735+
 736+ return this.each(function() {
 737+ var elem = $( this ),
 738+ elemWidth = elem.outerWidth(),
 739+ elemHeight = elem.outerHeight(),
 740+ position = $.extend( {}, basePosition );
 741+
 742+ if ( options.my[0] === "right" ) {
 743+ position.left -= elemWidth;
 744+ } else if ( options.my[0] === horizontalDefault ) {
 745+ position.left -= elemWidth / 2;
 746+ }
 747+
 748+ if ( options.my[1] === "bottom" ) {
 749+ position.top -= elemHeight;
 750+ } else if ( options.my[1] === verticalDefault ) {
 751+ position.top -= elemHeight / 2;
 752+ }
 753+
 754+ // prevent fractions (see #5280)
 755+ position.left = parseInt( position.left );
 756+ position.top = parseInt( position.top );
 757+
 758+ $.each( [ "left", "top" ], function( i, dir ) {
 759+ if ( $.ui.position[ collision[i] ] ) {
 760+ $.ui.position[ collision[i] ][ dir ]( position, {
 761+ targetWidth: targetWidth,
 762+ targetHeight: targetHeight,
 763+ elemWidth: elemWidth,
 764+ elemHeight: elemHeight,
 765+ offset: offset,
 766+ my: options.my,
 767+ at: options.at
 768+ });
 769+ }
 770+ });
 771+
 772+ if ( $.fn.bgiframe ) {
 773+ elem.bgiframe();
 774+ }
 775+ elem.offset( $.extend( position, { using: options.using } ) );
 776+ });
 777+};
 778+
 779+$.ui.position = {
 780+ fit: {
 781+ left: function( position, data ) {
 782+ var win = $( window ),
 783+ over = position.left + data.elemWidth - win.width() - win.scrollLeft();
 784+ position.left = over > 0 ? position.left - over : Math.max( 0, position.left );
 785+ },
 786+ top: function( position, data ) {
 787+ var win = $( window ),
 788+ over = position.top + data.elemHeight - win.height() - win.scrollTop();
 789+ position.top = over > 0 ? position.top - over : Math.max( 0, position.top );
 790+ }
 791+ },
 792+
 793+ flip: {
 794+ left: function( position, data ) {
 795+ if ( data.at[0] === "center" ) {
 796+ return;
 797+ }
 798+ var win = $( window ),
 799+ over = position.left + data.elemWidth - win.width() - win.scrollLeft(),
 800+ myOffset = data.my[ 0 ] === "left" ?
 801+ -data.elemWidth :
 802+ data.my[ 0 ] === "right" ?
 803+ data.elemWidth :
 804+ 0,
 805+ offset = -2 * data.offset[ 0 ];
 806+ position.left += position.left < 0 ?
 807+ myOffset + data.targetWidth + offset :
 808+ over > 0 ?
 809+ myOffset - data.targetWidth + offset :
 810+ 0;
 811+ },
 812+ top: function( position, data ) {
 813+ if ( data.at[1] === "center" ) {
 814+ return;
 815+ }
 816+ var win = $( window ),
 817+ over = position.top + data.elemHeight - win.height() - win.scrollTop(),
 818+ myOffset = data.my[ 1 ] === "top" ?
 819+ -data.elemHeight :
 820+ data.my[ 1 ] === "bottom" ?
 821+ data.elemHeight :
 822+ 0,
 823+ atOffset = data.at[ 1 ] === "top" ?
 824+ data.targetHeight :
 825+ -data.targetHeight,
 826+ offset = -2 * data.offset[ 1 ];
 827+ position.top += position.top < 0 ?
 828+ myOffset + data.targetHeight + offset :
 829+ over > 0 ?
 830+ myOffset + atOffset + offset :
 831+ 0;
 832+ }
 833+ }
 834+};
 835+
 836+// offset setter from jQuery 1.4
 837+if ( !$.offset.setOffset ) {
 838+ $.offset.setOffset = function( elem, options ) {
 839+ // set position first, in-case top/left are set even on static elem
 840+ if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
 841+ elem.style.position = "relative";
 842+ }
 843+ var curElem = $( elem ),
 844+ curOffset = curElem.offset(),
 845+ curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
 846+ curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
 847+ props = {
 848+ top: (options.top - curOffset.top) + curTop,
 849+ left: (options.left - curOffset.left) + curLeft
 850+ };
 851+
 852+ if ( 'using' in options ) {
 853+ options.using.call( elem, props );
 854+ } else {
 855+ curElem.css( props );
 856+ }
 857+ };
 858+
 859+ $.fn.offset = function( options ) {
 860+ var elem = this[ 0 ];
 861+ if ( !elem || !elem.ownerDocument ) { return null; }
 862+ if ( options ) {
 863+ return this.each(function() {
 864+ $.offset.setOffset( this, options );
 865+ });
 866+ }
 867+ return _offset.call( this );
 868+ };
 869+}
 870+
 871+}( jQuery ));
 872+
 873+
 874+/*
 875+ * jQuery UI Autocomplete 1.8.2
 876+ *
 877+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
 878+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 879+ * and GPL (GPL-LICENSE.txt) licenses.
 880+ *
 881+ * http://docs.jquery.com/UI/Autocomplete
 882+ *
 883+ * Depends:
 884+ * jquery.ui.core.js
 885+ * jquery.ui.widget.js
 886+ * jquery.ui.position.js
 887+ */
 888+(function( $ ) {
 889+
 890+$.widget( "ui.autocomplete", {
 891+ options: {
 892+ minLength: 1,
 893+ delay: 300
 894+ },
 895+ _create: function() {
 896+ var self = this,
 897+ doc = this.element[ 0 ].ownerDocument;
 898+ this.element
 899+ .addClass( "ui-autocomplete-input" )
 900+ .attr( "autocomplete", "off" )
 901+ // TODO verify these actually work as intended
 902+ .attr({
 903+ role: "textbox",
 904+ "aria-autocomplete": "list",
 905+ "aria-haspopup": "true"
 906+ })
 907+ .bind( "keydown.autocomplete", function( event ) {
 908+ var keyCode = $.ui.keyCode;
 909+ switch( event.keyCode ) {
 910+ case keyCode.PAGE_UP:
 911+ self._move( "previousPage", event );
 912+ break;
 913+ case keyCode.PAGE_DOWN:
 914+ self._move( "nextPage", event );
 915+ break;
 916+ case keyCode.UP:
 917+ self._move( "previous", event );
 918+ // prevent moving cursor to beginning of text field in some browsers
 919+ event.preventDefault();
 920+ break;
 921+ case keyCode.DOWN:
 922+ self._move( "next", event );
 923+ // prevent moving cursor to end of text field in some browsers
 924+ event.preventDefault();
 925+ break;
 926+ case keyCode.ENTER:
 927+ case keyCode.NUMPAD_ENTER:
 928+ // when menu is open or has focus
 929+ if ( self.menu.active ) {
 930+ event.preventDefault();
 931+ }
 932+ //passthrough - ENTER and TAB both select the current element
 933+ case keyCode.TAB:
 934+ if ( !self.menu.active ) {
 935+ return;
 936+ }
 937+ self.menu.select( event );
 938+ break;
 939+ case keyCode.ESCAPE:
 940+ self.element.val( self.term );
 941+ self.close( event );
 942+ break;
 943+ case keyCode.LEFT:
 944+ case keyCode.RIGHT:
 945+ case keyCode.SHIFT:
 946+ case keyCode.CONTROL:
 947+ case keyCode.ALT:
 948+ case keyCode.COMMAND:
 949+ case keyCode.COMMAND_RIGHT:
 950+ case keyCode.INSERT:
 951+ case keyCode.CAPS_LOCK:
 952+ case keyCode.END:
 953+ case keyCode.HOME:
 954+ // ignore metakeys (shift, ctrl, alt)
 955+ break;
 956+ default:
 957+ // keypress is triggered before the input value is changed
 958+ clearTimeout( self.searching );
 959+ self.searching = setTimeout(function() {
 960+ self.search( null, event );
 961+ }, self.options.delay );
 962+ break;
 963+ }
 964+ })
 965+ .bind( "focus.autocomplete", function() {
 966+ self.selectedItem = null;
 967+ self.previous = self.element.val();
 968+ })
 969+ .bind( "blur.autocomplete", function( event ) {
 970+ clearTimeout( self.searching );
 971+ // clicks on the menu (or a button to trigger a search) will cause a blur event
 972+ self.closing = setTimeout(function() {
 973+ self.close( event );
 974+ self._change( event );
 975+ }, 150 );
 976+ });
 977+ this._initSource();
 978+ this.response = function() {
 979+ return self._response.apply( self, arguments );
 980+ };
 981+ this.menu = $( "<ul></ul>" )
 982+ .addClass( "ui-autocomplete" )
 983+ .appendTo( "body", doc )
 984+ // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
 985+ .mousedown(function() {
 986+ // use another timeout to make sure the blur-event-handler on the input was already triggered
 987+ setTimeout(function() {
 988+ clearTimeout( self.closing );
 989+ }, 13);
 990+ })
 991+ .menu({
 992+ focus: function( event, ui ) {
 993+ var item = ui.item.data( "item.autocomplete" );
 994+ if ( false !== self._trigger( "focus", null, { item: item } ) ) {
 995+ // use value to match what will end up in the input, if it was a key event
 996+ if ( /^key/.test(event.originalEvent.type) ) {
 997+ self.element.val( item.value );
 998+ }
 999+ }
 1000+ },
 1001+ selected: function( event, ui ) {
 1002+ var item = ui.item.data( "item.autocomplete" );
 1003+ if ( false !== self._trigger( "select", event, { item: item } ) ) {
 1004+ self.element.val( item.value );
 1005+ }
 1006+ self.close( event );
 1007+ // only trigger when focus was lost (click on menu)
 1008+ var previous = self.previous;
 1009+ if ( self.element[0] !== doc.activeElement ) {
 1010+ self.element.focus();
 1011+ self.previous = previous;
 1012+ }
 1013+ self.selectedItem = item;
 1014+ },
 1015+ blur: function( event, ui ) {
 1016+ if ( self.menu.element.is(":visible") ) {
 1017+ self.element.val( self.term );
 1018+ }
 1019+ }
 1020+ })
 1021+ .zIndex( this.element.zIndex() + 1 )
 1022+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
 1023+ .css({ top: 0, left: 0 })
 1024+ .hide()
 1025+ .data( "menu" );
 1026+ if ( $.fn.bgiframe ) {
 1027+ this.menu.element.bgiframe();
 1028+ }
 1029+ },
 1030+
 1031+ destroy: function() {
 1032+ this.element
 1033+ .removeClass( "ui-autocomplete-input" )
 1034+ .removeAttr( "autocomplete" )
 1035+ .removeAttr( "role" )
 1036+ .removeAttr( "aria-autocomplete" )
 1037+ .removeAttr( "aria-haspopup" );
 1038+ this.menu.element.remove();
 1039+ $.Widget.prototype.destroy.call( this );
 1040+ },
 1041+
 1042+ _setOption: function( key ) {
 1043+ $.Widget.prototype._setOption.apply( this, arguments );
 1044+ if ( key === "source" ) {
 1045+ this._initSource();
 1046+ }
 1047+ },
 1048+
 1049+ _initSource: function() {
 1050+ var array,
 1051+ url;
 1052+ if ( $.isArray(this.options.source) ) {
 1053+ array = this.options.source;
 1054+ this.source = function( request, response ) {
 1055+ response( $.ui.autocomplete.filter(array, request.term) );
 1056+ };
 1057+ } else if ( typeof this.options.source === "string" ) {
 1058+ url = this.options.source;
 1059+ this.source = function( request, response ) {
 1060+ $.getJSON( url, request, response );
 1061+ };
 1062+ } else {
 1063+ this.source = this.options.source;
 1064+ }
 1065+ },
 1066+
 1067+ search: function( value, event ) {
 1068+ value = value != null ? value : this.element.val();
 1069+ if ( value.length < this.options.minLength ) {
 1070+ return this.close( event );
 1071+ }
 1072+
 1073+ clearTimeout( this.closing );
 1074+ if ( this._trigger("search") === false ) {
 1075+ return;
 1076+ }
 1077+
 1078+ return this._search( value );
 1079+ },
 1080+
 1081+ _search: function( value ) {
 1082+ this.term = this.element
 1083+ .addClass( "ui-autocomplete-loading" )
 1084+ // always save the actual value, not the one passed as an argument
 1085+ .val();
 1086+
 1087+ this.source( { term: value }, this.response );
 1088+ },
 1089+
 1090+ _response: function( content ) {
 1091+ if ( content.length ) {
 1092+ content = this._normalize( content );
 1093+ this._suggest( content );
 1094+ this._trigger( "open" );
 1095+ } else {
 1096+ this.close();
 1097+ }
 1098+ this.element.removeClass( "ui-autocomplete-loading" );
 1099+ },
 1100+
 1101+ close: function( event ) {
 1102+ clearTimeout( this.closing );
 1103+ if ( this.menu.element.is(":visible") ) {
 1104+ this._trigger( "close", event );
 1105+ this.menu.element.hide();
 1106+ this.menu.deactivate();
 1107+ }
 1108+ },
 1109+
 1110+ _change: function( event ) {
 1111+ if ( this.previous !== this.element.val() ) {
 1112+ this._trigger( "change", event, { item: this.selectedItem } );
 1113+ }
 1114+ },
 1115+
 1116+ _normalize: function( items ) {
 1117+ // assume all items have the right format when the first item is complete
 1118+ if ( items.length && items[0].label && items[0].value ) {
 1119+ return items;
 1120+ }
 1121+ return $.map( items, function(item) {
 1122+ if ( typeof item === "string" ) {
 1123+ return {
 1124+ label: item,
 1125+ value: item
 1126+ };
 1127+ }
 1128+ return $.extend({
 1129+ label: item.label || item.value,
 1130+ value: item.value || item.label
 1131+ }, item );
 1132+ });
 1133+ },
 1134+
 1135+ _suggest: function( items ) {
 1136+ var ul = this.menu.element
 1137+ .empty()
 1138+ .zIndex( this.element.zIndex() + 1 ),
 1139+ menuWidth,
 1140+ textWidth;
 1141+ this._renderMenu( ul, items );
 1142+ // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
 1143+ this.menu.deactivate();
 1144+ this.menu.refresh();
 1145+ this.menu.element.show().position({
 1146+ my: "left top",
 1147+ at: "left bottom",
 1148+ of: this.element,
 1149+ collision: "none"
 1150+ });
 1151+
 1152+ menuWidth = ul.width( "" ).width();
 1153+ textWidth = this.element.width();
 1154+ ul.width( Math.max( menuWidth, textWidth ) );
 1155+ },
 1156+
 1157+ _renderMenu: function( ul, items ) {
 1158+ var self = this;
 1159+ $.each( items, function( index, item ) {
 1160+ self._renderItem( ul, item );
 1161+ });
 1162+ },
 1163+
 1164+ _renderItem: function( ul, item) {
 1165+ return $( "<li></li>" )
 1166+ .data( "item.autocomplete", item )
 1167+ .append( "<a>" + item.label + "</a>" )
 1168+ .appendTo( ul );
 1169+ },
 1170+
 1171+ _move: function( direction, event ) {
 1172+ if ( !this.menu.element.is(":visible") ) {
 1173+ this.search( null, event );
 1174+ return;
 1175+ }
 1176+ if ( this.menu.first() && /^previous/.test(direction) ||
 1177+ this.menu.last() && /^next/.test(direction) ) {
 1178+ this.element.val( this.term );
 1179+ this.menu.deactivate();
 1180+ return;
 1181+ }
 1182+ this.menu[ direction ]( event );
 1183+ },
 1184+
 1185+ widget: function() {
 1186+ return this.menu.element;
 1187+ }
 1188+});
 1189+
 1190+$.extend( $.ui.autocomplete, {
 1191+ escapeRegex: function( value ) {
 1192+ return value.replace( /([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1" );
 1193+ },
 1194+ filter: function(array, term) {
 1195+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
 1196+ return $.grep( array, function(value) {
 1197+ return matcher.test( value.label || value.value || value );
 1198+ });
 1199+ }
 1200+});
 1201+
 1202+}( jQuery ));
Property changes on: trunk/extensions/LinkSuggest/jquery.widget.position.autocomplete-1.8.2.js
___________________________________________________________________
Added: svn:eol-style
12031203 + native
Property changes on: trunk/extensions/LinkSuggest/LinkSuggest.php
___________________________________________________________________
Added: svn:eol-style
12041204 + native
Property changes on: trunk/extensions/LinkSuggest/jquery.mw.linksuggest.js
___________________________________________________________________
Added: svn:eol-style
12051205 + native

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r85036add LinkSuggest extension; tested with FF 3.6.13/15 and IE7 + 8 (IIRC), has s...ashley19:19, 30 March 2011

Status & tagging log