jquery-ui.js 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795
  1. /*! jQuery UI - v1.11.2 - 2014-10-16
  2. * http://jqueryui.com
  3. * Includes: core.js, widget.js, mouse.js, position.js, autocomplete.js, menu.js
  4. * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
  5. (function( factory ) {
  6. if ( typeof define === "function" && define.amd ) {
  7. // AMD. Register as an anonymous module.
  8. define([ "jquery" ], factory );
  9. } else {
  10. // Browser globals
  11. factory( jQuery );
  12. }
  13. }(function( $ ) {
  14. /*!
  15. * jQuery UI Core 1.11.2
  16. * http://jqueryui.com
  17. *
  18. * Copyright 2014 jQuery Foundation and other contributors
  19. * Released under the MIT license.
  20. * http://jquery.org/license
  21. *
  22. * http://api.jqueryui.com/category/ui-core/
  23. */
  24. // $.ui might exist from components with no dependencies, e.g., $.ui.position
  25. $.ui = $.ui || {};
  26. $.extend( $.ui, {
  27. version: "1.11.2",
  28. keyCode: {
  29. BACKSPACE: 8,
  30. COMMA: 188,
  31. DELETE: 46,
  32. DOWN: 40,
  33. END: 35,
  34. ENTER: 13,
  35. ESCAPE: 27,
  36. HOME: 36,
  37. LEFT: 37,
  38. PAGE_DOWN: 34,
  39. PAGE_UP: 33,
  40. PERIOD: 190,
  41. RIGHT: 39,
  42. SPACE: 32,
  43. TAB: 9,
  44. UP: 38
  45. }
  46. });
  47. // plugins
  48. $.fn.extend({
  49. scrollParent: function( includeHidden ) {
  50. var position = this.css( "position" ),
  51. excludeStaticParent = position === "absolute",
  52. overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
  53. scrollParent = this.parents().filter( function() {
  54. var parent = $( this );
  55. if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
  56. return false;
  57. }
  58. return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
  59. }).eq( 0 );
  60. return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
  61. },
  62. uniqueId: (function() {
  63. var uuid = 0;
  64. return function() {
  65. return this.each(function() {
  66. if ( !this.id ) {
  67. this.id = "ui-id-" + ( ++uuid );
  68. }
  69. });
  70. };
  71. })(),
  72. removeUniqueId: function() {
  73. return this.each(function() {
  74. if ( /^ui-id-\d+$/.test( this.id ) ) {
  75. $( this ).removeAttr( "id" );
  76. }
  77. });
  78. }
  79. });
  80. // selectors
  81. function focusable( element, isTabIndexNotNaN ) {
  82. var map, mapName, img,
  83. nodeName = element.nodeName.toLowerCase();
  84. if ( "area" === nodeName ) {
  85. map = element.parentNode;
  86. mapName = map.name;
  87. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  88. return false;
  89. }
  90. img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
  91. return !!img && visible( img );
  92. }
  93. return ( /input|select|textarea|button|object/.test( nodeName ) ?
  94. !element.disabled :
  95. "a" === nodeName ?
  96. element.href || isTabIndexNotNaN :
  97. isTabIndexNotNaN) &&
  98. // the element and all of its ancestors must be visible
  99. visible( element );
  100. }
  101. function visible( element ) {
  102. return $.expr.filters.visible( element ) &&
  103. !$( element ).parents().addBack().filter(function() {
  104. return $.css( this, "visibility" ) === "hidden";
  105. }).length;
  106. }
  107. $.extend( $.expr[ ":" ], {
  108. data: $.expr.createPseudo ?
  109. $.expr.createPseudo(function( dataName ) {
  110. return function( elem ) {
  111. return !!$.data( elem, dataName );
  112. };
  113. }) :
  114. // support: jQuery <1.8
  115. function( elem, i, match ) {
  116. return !!$.data( elem, match[ 3 ] );
  117. },
  118. focusable: function( element ) {
  119. return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  120. },
  121. tabbable: function( element ) {
  122. var tabIndex = $.attr( element, "tabindex" ),
  123. isTabIndexNaN = isNaN( tabIndex );
  124. return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  125. }
  126. });
  127. // support: jQuery <1.8
  128. if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
  129. $.each( [ "Width", "Height" ], function( i, name ) {
  130. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  131. type = name.toLowerCase(),
  132. orig = {
  133. innerWidth: $.fn.innerWidth,
  134. innerHeight: $.fn.innerHeight,
  135. outerWidth: $.fn.outerWidth,
  136. outerHeight: $.fn.outerHeight
  137. };
  138. function reduce( elem, size, border, margin ) {
  139. $.each( side, function() {
  140. size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
  141. if ( border ) {
  142. size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
  143. }
  144. if ( margin ) {
  145. size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
  146. }
  147. });
  148. return size;
  149. }
  150. $.fn[ "inner" + name ] = function( size ) {
  151. if ( size === undefined ) {
  152. return orig[ "inner" + name ].call( this );
  153. }
  154. return this.each(function() {
  155. $( this ).css( type, reduce( this, size ) + "px" );
  156. });
  157. };
  158. $.fn[ "outer" + name] = function( size, margin ) {
  159. if ( typeof size !== "number" ) {
  160. return orig[ "outer" + name ].call( this, size );
  161. }
  162. return this.each(function() {
  163. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  164. });
  165. };
  166. });
  167. }
  168. // support: jQuery <1.8
  169. if ( !$.fn.addBack ) {
  170. $.fn.addBack = function( selector ) {
  171. return this.add( selector == null ?
  172. this.prevObject : this.prevObject.filter( selector )
  173. );
  174. };
  175. }
  176. // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
  177. if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
  178. $.fn.removeData = (function( removeData ) {
  179. return function( key ) {
  180. if ( arguments.length ) {
  181. return removeData.call( this, $.camelCase( key ) );
  182. } else {
  183. return removeData.call( this );
  184. }
  185. };
  186. })( $.fn.removeData );
  187. }
  188. // deprecated
  189. $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
  190. $.fn.extend({
  191. focus: (function( orig ) {
  192. return function( delay, fn ) {
  193. return typeof delay === "number" ?
  194. this.each(function() {
  195. var elem = this;
  196. setTimeout(function() {
  197. $( elem ).focus();
  198. if ( fn ) {
  199. fn.call( elem );
  200. }
  201. }, delay );
  202. }) :
  203. orig.apply( this, arguments );
  204. };
  205. })( $.fn.focus ),
  206. disableSelection: (function() {
  207. var eventType = "onselectstart" in document.createElement( "div" ) ?
  208. "selectstart" :
  209. "mousedown";
  210. return function() {
  211. return this.bind( eventType + ".ui-disableSelection", function( event ) {
  212. event.preventDefault();
  213. });
  214. };
  215. })(),
  216. enableSelection: function() {
  217. return this.unbind( ".ui-disableSelection" );
  218. },
  219. zIndex: function( zIndex ) {
  220. if ( zIndex !== undefined ) {
  221. return this.css( "zIndex", zIndex );
  222. }
  223. if ( this.length ) {
  224. var elem = $( this[ 0 ] ), position, value;
  225. while ( elem.length && elem[ 0 ] !== document ) {
  226. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  227. // This makes behavior of this function consistent across browsers
  228. // WebKit always returns auto if the element is positioned
  229. position = elem.css( "position" );
  230. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  231. // IE returns 0 when zIndex is not specified
  232. // other browsers return a string
  233. // we ignore the case of nested elements with an explicit value of 0
  234. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  235. value = parseInt( elem.css( "zIndex" ), 10 );
  236. if ( !isNaN( value ) && value !== 0 ) {
  237. return value;
  238. }
  239. }
  240. elem = elem.parent();
  241. }
  242. }
  243. return 0;
  244. }
  245. });
  246. // $.ui.plugin is deprecated. Use $.widget() extensions instead.
  247. $.ui.plugin = {
  248. add: function( module, option, set ) {
  249. var i,
  250. proto = $.ui[ module ].prototype;
  251. for ( i in set ) {
  252. proto.plugins[ i ] = proto.plugins[ i ] || [];
  253. proto.plugins[ i ].push( [ option, set[ i ] ] );
  254. }
  255. },
  256. call: function( instance, name, args, allowDisconnected ) {
  257. var i,
  258. set = instance.plugins[ name ];
  259. if ( !set ) {
  260. return;
  261. }
  262. if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
  263. return;
  264. }
  265. for ( i = 0; i < set.length; i++ ) {
  266. if ( instance.options[ set[ i ][ 0 ] ] ) {
  267. set[ i ][ 1 ].apply( instance.element, args );
  268. }
  269. }
  270. }
  271. };
  272. /*!
  273. * jQuery UI Widget 1.11.2
  274. * http://jqueryui.com
  275. *
  276. * Copyright 2014 jQuery Foundation and other contributors
  277. * Released under the MIT license.
  278. * http://jquery.org/license
  279. *
  280. * http://api.jqueryui.com/jQuery.widget/
  281. */
  282. var widget_uuid = 0,
  283. widget_slice = Array.prototype.slice;
  284. $.cleanData = (function( orig ) {
  285. return function( elems ) {
  286. var events, elem, i;
  287. for ( i = 0; (elem = elems[i]) != null; i++ ) {
  288. try {
  289. // Only trigger remove when necessary to save time
  290. events = $._data( elem, "events" );
  291. if ( events && events.remove ) {
  292. $( elem ).triggerHandler( "remove" );
  293. }
  294. // http://bugs.jquery.com/ticket/8235
  295. } catch ( e ) {}
  296. }
  297. orig( elems );
  298. };
  299. })( $.cleanData );
  300. $.widget = function( name, base, prototype ) {
  301. var fullName, existingConstructor, constructor, basePrototype,
  302. // proxiedPrototype allows the provided prototype to remain unmodified
  303. // so that it can be used as a mixin for multiple widgets (#8876)
  304. proxiedPrototype = {},
  305. namespace = name.split( "." )[ 0 ];
  306. name = name.split( "." )[ 1 ];
  307. fullName = namespace + "-" + name;
  308. if ( !prototype ) {
  309. prototype = base;
  310. base = $.Widget;
  311. }
  312. // create selector for plugin
  313. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  314. return !!$.data( elem, fullName );
  315. };
  316. $[ namespace ] = $[ namespace ] || {};
  317. existingConstructor = $[ namespace ][ name ];
  318. constructor = $[ namespace ][ name ] = function( options, element ) {
  319. // allow instantiation without "new" keyword
  320. if ( !this._createWidget ) {
  321. return new constructor( options, element );
  322. }
  323. // allow instantiation without initializing for simple inheritance
  324. // must use "new" keyword (the code above always passes args)
  325. if ( arguments.length ) {
  326. this._createWidget( options, element );
  327. }
  328. };
  329. // extend with the existing constructor to carry over any static properties
  330. $.extend( constructor, existingConstructor, {
  331. version: prototype.version,
  332. // copy the object used to create the prototype in case we need to
  333. // redefine the widget later
  334. _proto: $.extend( {}, prototype ),
  335. // track widgets that inherit from this widget in case this widget is
  336. // redefined after a widget inherits from it
  337. _childConstructors: []
  338. });
  339. basePrototype = new base();
  340. // we need to make the options hash a property directly on the new instance
  341. // otherwise we'll modify the options hash on the prototype that we're
  342. // inheriting from
  343. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  344. $.each( prototype, function( prop, value ) {
  345. if ( !$.isFunction( value ) ) {
  346. proxiedPrototype[ prop ] = value;
  347. return;
  348. }
  349. proxiedPrototype[ prop ] = (function() {
  350. var _super = function() {
  351. return base.prototype[ prop ].apply( this, arguments );
  352. },
  353. _superApply = function( args ) {
  354. return base.prototype[ prop ].apply( this, args );
  355. };
  356. return function() {
  357. var __super = this._super,
  358. __superApply = this._superApply,
  359. returnValue;
  360. this._super = _super;
  361. this._superApply = _superApply;
  362. returnValue = value.apply( this, arguments );
  363. this._super = __super;
  364. this._superApply = __superApply;
  365. return returnValue;
  366. };
  367. })();
  368. });
  369. constructor.prototype = $.widget.extend( basePrototype, {
  370. // TODO: remove support for widgetEventPrefix
  371. // always use the name + a colon as the prefix, e.g., draggable:start
  372. // don't prefix for widgets that aren't DOM-based
  373. widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
  374. }, proxiedPrototype, {
  375. constructor: constructor,
  376. namespace: namespace,
  377. widgetName: name,
  378. widgetFullName: fullName
  379. });
  380. // If this widget is being redefined then we need to find all widgets that
  381. // are inheriting from it and redefine all of them so that they inherit from
  382. // the new version of this widget. We're essentially trying to replace one
  383. // level in the prototype chain.
  384. if ( existingConstructor ) {
  385. $.each( existingConstructor._childConstructors, function( i, child ) {
  386. var childPrototype = child.prototype;
  387. // redefine the child widget using the same prototype that was
  388. // originally used, but inherit from the new version of the base
  389. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  390. });
  391. // remove the list of existing child constructors from the old constructor
  392. // so the old child constructors can be garbage collected
  393. delete existingConstructor._childConstructors;
  394. } else {
  395. base._childConstructors.push( constructor );
  396. }
  397. $.widget.bridge( name, constructor );
  398. return constructor;
  399. };
  400. $.widget.extend = function( target ) {
  401. var input = widget_slice.call( arguments, 1 ),
  402. inputIndex = 0,
  403. inputLength = input.length,
  404. key,
  405. value;
  406. for ( ; inputIndex < inputLength; inputIndex++ ) {
  407. for ( key in input[ inputIndex ] ) {
  408. value = input[ inputIndex ][ key ];
  409. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  410. // Clone objects
  411. if ( $.isPlainObject( value ) ) {
  412. target[ key ] = $.isPlainObject( target[ key ] ) ?
  413. $.widget.extend( {}, target[ key ], value ) :
  414. // Don't extend strings, arrays, etc. with objects
  415. $.widget.extend( {}, value );
  416. // Copy everything else by reference
  417. } else {
  418. target[ key ] = value;
  419. }
  420. }
  421. }
  422. }
  423. return target;
  424. };
  425. $.widget.bridge = function( name, object ) {
  426. var fullName = object.prototype.widgetFullName || name;
  427. $.fn[ name ] = function( options ) {
  428. var isMethodCall = typeof options === "string",
  429. args = widget_slice.call( arguments, 1 ),
  430. returnValue = this;
  431. // allow multiple hashes to be passed on init
  432. options = !isMethodCall && args.length ?
  433. $.widget.extend.apply( null, [ options ].concat(args) ) :
  434. options;
  435. if ( isMethodCall ) {
  436. this.each(function() {
  437. var methodValue,
  438. instance = $.data( this, fullName );
  439. if ( options === "instance" ) {
  440. returnValue = instance;
  441. return false;
  442. }
  443. if ( !instance ) {
  444. return $.error( "cannot call methods on " + name + " prior to initialization; " +
  445. "attempted to call method '" + options + "'" );
  446. }
  447. if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  448. return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  449. }
  450. methodValue = instance[ options ].apply( instance, args );
  451. if ( methodValue !== instance && methodValue !== undefined ) {
  452. returnValue = methodValue && methodValue.jquery ?
  453. returnValue.pushStack( methodValue.get() ) :
  454. methodValue;
  455. return false;
  456. }
  457. });
  458. } else {
  459. this.each(function() {
  460. var instance = $.data( this, fullName );
  461. if ( instance ) {
  462. instance.option( options || {} );
  463. if ( instance._init ) {
  464. instance._init();
  465. }
  466. } else {
  467. $.data( this, fullName, new object( options, this ) );
  468. }
  469. });
  470. }
  471. return returnValue;
  472. };
  473. };
  474. $.Widget = function( /* options, element */ ) {};
  475. $.Widget._childConstructors = [];
  476. $.Widget.prototype = {
  477. widgetName: "widget",
  478. widgetEventPrefix: "",
  479. defaultElement: "<div>",
  480. options: {
  481. disabled: false,
  482. // callbacks
  483. create: null
  484. },
  485. _createWidget: function( options, element ) {
  486. element = $( element || this.defaultElement || this )[ 0 ];
  487. this.element = $( element );
  488. this.uuid = widget_uuid++;
  489. this.eventNamespace = "." + this.widgetName + this.uuid;
  490. this.bindings = $();
  491. this.hoverable = $();
  492. this.focusable = $();
  493. if ( element !== this ) {
  494. $.data( element, this.widgetFullName, this );
  495. this._on( true, this.element, {
  496. remove: function( event ) {
  497. if ( event.target === element ) {
  498. this.destroy();
  499. }
  500. }
  501. });
  502. this.document = $( element.style ?
  503. // element within the document
  504. element.ownerDocument :
  505. // element is window or document
  506. element.document || element );
  507. this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  508. }
  509. this.options = $.widget.extend( {},
  510. this.options,
  511. this._getCreateOptions(),
  512. options );
  513. this._create();
  514. this._trigger( "create", null, this._getCreateEventData() );
  515. this._init();
  516. },
  517. _getCreateOptions: $.noop,
  518. _getCreateEventData: $.noop,
  519. _create: $.noop,
  520. _init: $.noop,
  521. destroy: function() {
  522. this._destroy();
  523. // we can probably remove the unbind calls in 2.0
  524. // all event bindings should go through this._on()
  525. this.element
  526. .unbind( this.eventNamespace )
  527. .removeData( this.widgetFullName )
  528. // support: jquery <1.6.3
  529. // http://bugs.jquery.com/ticket/9413
  530. .removeData( $.camelCase( this.widgetFullName ) );
  531. this.widget()
  532. .unbind( this.eventNamespace )
  533. .removeAttr( "aria-disabled" )
  534. .removeClass(
  535. this.widgetFullName + "-disabled " +
  536. "ui-state-disabled" );
  537. // clean up events and states
  538. this.bindings.unbind( this.eventNamespace );
  539. this.hoverable.removeClass( "ui-state-hover" );
  540. this.focusable.removeClass( "ui-state-focus" );
  541. },
  542. _destroy: $.noop,
  543. widget: function() {
  544. return this.element;
  545. },
  546. option: function( key, value ) {
  547. var options = key,
  548. parts,
  549. curOption,
  550. i;
  551. if ( arguments.length === 0 ) {
  552. // don't return a reference to the internal hash
  553. return $.widget.extend( {}, this.options );
  554. }
  555. if ( typeof key === "string" ) {
  556. // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  557. options = {};
  558. parts = key.split( "." );
  559. key = parts.shift();
  560. if ( parts.length ) {
  561. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  562. for ( i = 0; i < parts.length - 1; i++ ) {
  563. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  564. curOption = curOption[ parts[ i ] ];
  565. }
  566. key = parts.pop();
  567. if ( arguments.length === 1 ) {
  568. return curOption[ key ] === undefined ? null : curOption[ key ];
  569. }
  570. curOption[ key ] = value;
  571. } else {
  572. if ( arguments.length === 1 ) {
  573. return this.options[ key ] === undefined ? null : this.options[ key ];
  574. }
  575. options[ key ] = value;
  576. }
  577. }
  578. this._setOptions( options );
  579. return this;
  580. },
  581. _setOptions: function( options ) {
  582. var key;
  583. for ( key in options ) {
  584. this._setOption( key, options[ key ] );
  585. }
  586. return this;
  587. },
  588. _setOption: function( key, value ) {
  589. this.options[ key ] = value;
  590. if ( key === "disabled" ) {
  591. this.widget()
  592. .toggleClass( this.widgetFullName + "-disabled", !!value );
  593. // If the widget is becoming disabled, then nothing is interactive
  594. if ( value ) {
  595. this.hoverable.removeClass( "ui-state-hover" );
  596. this.focusable.removeClass( "ui-state-focus" );
  597. }
  598. }
  599. return this;
  600. },
  601. enable: function() {
  602. return this._setOptions({ disabled: false });
  603. },
  604. disable: function() {
  605. return this._setOptions({ disabled: true });
  606. },
  607. _on: function( suppressDisabledCheck, element, handlers ) {
  608. var delegateElement,
  609. instance = this;
  610. // no suppressDisabledCheck flag, shuffle arguments
  611. if ( typeof suppressDisabledCheck !== "boolean" ) {
  612. handlers = element;
  613. element = suppressDisabledCheck;
  614. suppressDisabledCheck = false;
  615. }
  616. // no element argument, shuffle and use this.element
  617. if ( !handlers ) {
  618. handlers = element;
  619. element = this.element;
  620. delegateElement = this.widget();
  621. } else {
  622. element = delegateElement = $( element );
  623. this.bindings = this.bindings.add( element );
  624. }
  625. $.each( handlers, function( event, handler ) {
  626. function handlerProxy() {
  627. // allow widgets to customize the disabled handling
  628. // - disabled as an array instead of boolean
  629. // - disabled class as method for disabling individual parts
  630. if ( !suppressDisabledCheck &&
  631. ( instance.options.disabled === true ||
  632. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  633. return;
  634. }
  635. return ( typeof handler === "string" ? instance[ handler ] : handler )
  636. .apply( instance, arguments );
  637. }
  638. // copy the guid so direct unbinding works
  639. if ( typeof handler !== "string" ) {
  640. handlerProxy.guid = handler.guid =
  641. handler.guid || handlerProxy.guid || $.guid++;
  642. }
  643. var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
  644. eventName = match[1] + instance.eventNamespace,
  645. selector = match[2];
  646. if ( selector ) {
  647. delegateElement.delegate( selector, eventName, handlerProxy );
  648. } else {
  649. element.bind( eventName, handlerProxy );
  650. }
  651. });
  652. },
  653. _off: function( element, eventName ) {
  654. eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
  655. this.eventNamespace;
  656. element.unbind( eventName ).undelegate( eventName );
  657. // Clear the stack to avoid memory leaks (#10056)
  658. this.bindings = $( this.bindings.not( element ).get() );
  659. this.focusable = $( this.focusable.not( element ).get() );
  660. this.hoverable = $( this.hoverable.not( element ).get() );
  661. },
  662. _delay: function( handler, delay ) {
  663. function handlerProxy() {
  664. return ( typeof handler === "string" ? instance[ handler ] : handler )
  665. .apply( instance, arguments );
  666. }
  667. var instance = this;
  668. return setTimeout( handlerProxy, delay || 0 );
  669. },
  670. _hoverable: function( element ) {
  671. this.hoverable = this.hoverable.add( element );
  672. this._on( element, {
  673. mouseenter: function( event ) {
  674. $( event.currentTarget ).addClass( "ui-state-hover" );
  675. },
  676. mouseleave: function( event ) {
  677. $( event.currentTarget ).removeClass( "ui-state-hover" );
  678. }
  679. });
  680. },
  681. _focusable: function( element ) {
  682. this.focusable = this.focusable.add( element );
  683. this._on( element, {
  684. focusin: function( event ) {
  685. $( event.currentTarget ).addClass( "ui-state-focus" );
  686. },
  687. focusout: function( event ) {
  688. $( event.currentTarget ).removeClass( "ui-state-focus" );
  689. }
  690. });
  691. },
  692. _trigger: function( type, event, data ) {
  693. var prop, orig,
  694. callback = this.options[ type ];
  695. data = data || {};
  696. event = $.Event( event );
  697. event.type = ( type === this.widgetEventPrefix ?
  698. type :
  699. this.widgetEventPrefix + type ).toLowerCase();
  700. // the original event may come from any element
  701. // so we need to reset the target on the new event
  702. event.target = this.element[ 0 ];
  703. // copy original event properties over to the new event
  704. orig = event.originalEvent;
  705. if ( orig ) {
  706. for ( prop in orig ) {
  707. if ( !( prop in event ) ) {
  708. event[ prop ] = orig[ prop ];
  709. }
  710. }
  711. }
  712. this.element.trigger( event, data );
  713. return !( $.isFunction( callback ) &&
  714. callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  715. event.isDefaultPrevented() );
  716. }
  717. };
  718. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  719. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  720. if ( typeof options === "string" ) {
  721. options = { effect: options };
  722. }
  723. var hasOptions,
  724. effectName = !options ?
  725. method :
  726. options === true || typeof options === "number" ?
  727. defaultEffect :
  728. options.effect || defaultEffect;
  729. options = options || {};
  730. if ( typeof options === "number" ) {
  731. options = { duration: options };
  732. }
  733. hasOptions = !$.isEmptyObject( options );
  734. options.complete = callback;
  735. if ( options.delay ) {
  736. element.delay( options.delay );
  737. }
  738. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  739. element[ method ]( options );
  740. } else if ( effectName !== method && element[ effectName ] ) {
  741. element[ effectName ]( options.duration, options.easing, callback );
  742. } else {
  743. element.queue(function( next ) {
  744. $( this )[ method ]();
  745. if ( callback ) {
  746. callback.call( element[ 0 ] );
  747. }
  748. next();
  749. });
  750. }
  751. };
  752. });
  753. var widget = $.widget;
  754. /*!
  755. * jQuery UI Mouse 1.11.2
  756. * http://jqueryui.com
  757. *
  758. * Copyright 2014 jQuery Foundation and other contributors
  759. * Released under the MIT license.
  760. * http://jquery.org/license
  761. *
  762. * http://api.jqueryui.com/mouse/
  763. */
  764. var mouseHandled = false;
  765. $( document ).mouseup( function() {
  766. mouseHandled = false;
  767. });
  768. var mouse = $.widget("ui.mouse", {
  769. version: "1.11.2",
  770. options: {
  771. cancel: "input,textarea,button,select,option",
  772. distance: 1,
  773. delay: 0
  774. },
  775. _mouseInit: function() {
  776. var that = this;
  777. this.element
  778. .bind("mousedown." + this.widgetName, function(event) {
  779. return that._mouseDown(event);
  780. })
  781. .bind("click." + this.widgetName, function(event) {
  782. if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
  783. $.removeData(event.target, that.widgetName + ".preventClickEvent");
  784. event.stopImmediatePropagation();
  785. return false;
  786. }
  787. });
  788. this.started = false;
  789. },
  790. // TODO: make sure destroying one instance of mouse doesn't mess with
  791. // other instances of mouse
  792. _mouseDestroy: function() {
  793. this.element.unbind("." + this.widgetName);
  794. if ( this._mouseMoveDelegate ) {
  795. this.document
  796. .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
  797. .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
  798. }
  799. },
  800. _mouseDown: function(event) {
  801. // don't let more than one widget handle mouseStart
  802. if ( mouseHandled ) {
  803. return;
  804. }
  805. this._mouseMoved = false;
  806. // we may have missed mouseup (out of window)
  807. (this._mouseStarted && this._mouseUp(event));
  808. this._mouseDownEvent = event;
  809. var that = this,
  810. btnIsLeft = (event.which === 1),
  811. // event.target.nodeName works around a bug in IE 8 with
  812. // disabled inputs (#7620)
  813. elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
  814. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  815. return true;
  816. }
  817. this.mouseDelayMet = !this.options.delay;
  818. if (!this.mouseDelayMet) {
  819. this._mouseDelayTimer = setTimeout(function() {
  820. that.mouseDelayMet = true;
  821. }, this.options.delay);
  822. }
  823. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  824. this._mouseStarted = (this._mouseStart(event) !== false);
  825. if (!this._mouseStarted) {
  826. event.preventDefault();
  827. return true;
  828. }
  829. }
  830. // Click event may never have fired (Gecko & Opera)
  831. if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
  832. $.removeData(event.target, this.widgetName + ".preventClickEvent");
  833. }
  834. // these delegates are required to keep context
  835. this._mouseMoveDelegate = function(event) {
  836. return that._mouseMove(event);
  837. };
  838. this._mouseUpDelegate = function(event) {
  839. return that._mouseUp(event);
  840. };
  841. this.document
  842. .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  843. .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
  844. event.preventDefault();
  845. mouseHandled = true;
  846. return true;
  847. },
  848. _mouseMove: function(event) {
  849. // Only check for mouseups outside the document if you've moved inside the document
  850. // at least once. This prevents the firing of mouseup in the case of IE<9, which will
  851. // fire a mousemove event if content is placed under the cursor. See #7778
  852. // Support: IE <9
  853. if ( this._mouseMoved ) {
  854. // IE mouseup check - mouseup happened when mouse was out of window
  855. if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
  856. return this._mouseUp(event);
  857. // Iframe mouseup check - mouseup occurred in another document
  858. } else if ( !event.which ) {
  859. return this._mouseUp( event );
  860. }
  861. }
  862. if ( event.which || event.button ) {
  863. this._mouseMoved = true;
  864. }
  865. if (this._mouseStarted) {
  866. this._mouseDrag(event);
  867. return event.preventDefault();
  868. }
  869. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  870. this._mouseStarted =
  871. (this._mouseStart(this._mouseDownEvent, event) !== false);
  872. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  873. }
  874. return !this._mouseStarted;
  875. },
  876. _mouseUp: function(event) {
  877. this.document
  878. .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  879. .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
  880. if (this._mouseStarted) {
  881. this._mouseStarted = false;
  882. if (event.target === this._mouseDownEvent.target) {
  883. $.data(event.target, this.widgetName + ".preventClickEvent", true);
  884. }
  885. this._mouseStop(event);
  886. }
  887. mouseHandled = false;
  888. return false;
  889. },
  890. _mouseDistanceMet: function(event) {
  891. return (Math.max(
  892. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  893. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  894. ) >= this.options.distance
  895. );
  896. },
  897. _mouseDelayMet: function(/* event */) {
  898. return this.mouseDelayMet;
  899. },
  900. // These are placeholder methods, to be overriden by extending plugin
  901. _mouseStart: function(/* event */) {},
  902. _mouseDrag: function(/* event */) {},
  903. _mouseStop: function(/* event */) {},
  904. _mouseCapture: function(/* event */) { return true; }
  905. });
  906. /*!
  907. * jQuery UI Position 1.11.2
  908. * http://jqueryui.com
  909. *
  910. * Copyright 2014 jQuery Foundation and other contributors
  911. * Released under the MIT license.
  912. * http://jquery.org/license
  913. *
  914. * http://api.jqueryui.com/position/
  915. */
  916. (function() {
  917. $.ui = $.ui || {};
  918. var cachedScrollbarWidth, supportsOffsetFractions,
  919. max = Math.max,
  920. abs = Math.abs,
  921. round = Math.round,
  922. rhorizontal = /left|center|right/,
  923. rvertical = /top|center|bottom/,
  924. roffset = /[\+\-]\d+(\.[\d]+)?%?/,
  925. rposition = /^\w+/,
  926. rpercent = /%$/,
  927. _position = $.fn.position;
  928. function getOffsets( offsets, width, height ) {
  929. return [
  930. parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  931. parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  932. ];
  933. }
  934. function parseCss( element, property ) {
  935. return parseInt( $.css( element, property ), 10 ) || 0;
  936. }
  937. function getDimensions( elem ) {
  938. var raw = elem[0];
  939. if ( raw.nodeType === 9 ) {
  940. return {
  941. width: elem.width(),
  942. height: elem.height(),
  943. offset: { top: 0, left: 0 }
  944. };
  945. }
  946. if ( $.isWindow( raw ) ) {
  947. return {
  948. width: elem.width(),
  949. height: elem.height(),
  950. offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
  951. };
  952. }
  953. if ( raw.preventDefault ) {
  954. return {
  955. width: 0,
  956. height: 0,
  957. offset: { top: raw.pageY, left: raw.pageX }
  958. };
  959. }
  960. return {
  961. width: elem.outerWidth(),
  962. height: elem.outerHeight(),
  963. offset: elem.offset()
  964. };
  965. }
  966. $.position = {
  967. scrollbarWidth: function() {
  968. if ( cachedScrollbarWidth !== undefined ) {
  969. return cachedScrollbarWidth;
  970. }
  971. var w1, w2,
  972. div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
  973. innerDiv = div.children()[0];
  974. $( "body" ).append( div );
  975. w1 = innerDiv.offsetWidth;
  976. div.css( "overflow", "scroll" );
  977. w2 = innerDiv.offsetWidth;
  978. if ( w1 === w2 ) {
  979. w2 = div[0].clientWidth;
  980. }
  981. div.remove();
  982. return (cachedScrollbarWidth = w1 - w2);
  983. },
  984. getScrollInfo: function( within ) {
  985. var overflowX = within.isWindow || within.isDocument ? "" :
  986. within.element.css( "overflow-x" ),
  987. overflowY = within.isWindow || within.isDocument ? "" :
  988. within.element.css( "overflow-y" ),
  989. hasOverflowX = overflowX === "scroll" ||
  990. ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
  991. hasOverflowY = overflowY === "scroll" ||
  992. ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
  993. return {
  994. width: hasOverflowY ? $.position.scrollbarWidth() : 0,
  995. height: hasOverflowX ? $.position.scrollbarWidth() : 0
  996. };
  997. },
  998. getWithinInfo: function( element ) {
  999. var withinElement = $( element || window ),
  1000. isWindow = $.isWindow( withinElement[0] ),
  1001. isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
  1002. return {
  1003. element: withinElement,
  1004. isWindow: isWindow,
  1005. isDocument: isDocument,
  1006. offset: withinElement.offset() || { left: 0, top: 0 },
  1007. scrollLeft: withinElement.scrollLeft(),
  1008. scrollTop: withinElement.scrollTop(),
  1009. // support: jQuery 1.6.x
  1010. // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
  1011. width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
  1012. height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
  1013. };
  1014. }
  1015. };
  1016. $.fn.position = function( options ) {
  1017. if ( !options || !options.of ) {
  1018. return _position.apply( this, arguments );
  1019. }
  1020. // make a copy, we don't want to modify arguments
  1021. options = $.extend( {}, options );
  1022. var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
  1023. target = $( options.of ),
  1024. within = $.position.getWithinInfo( options.within ),
  1025. scrollInfo = $.position.getScrollInfo( within ),
  1026. collision = ( options.collision || "flip" ).split( " " ),
  1027. offsets = {};
  1028. dimensions = getDimensions( target );
  1029. if ( target[0].preventDefault ) {
  1030. // force left top to allow flipping
  1031. options.at = "left top";
  1032. }
  1033. targetWidth = dimensions.width;
  1034. targetHeight = dimensions.height;
  1035. targetOffset = dimensions.offset;
  1036. // clone to reuse original targetOffset later
  1037. basePosition = $.extend( {}, targetOffset );
  1038. // force my and at to have valid horizontal and vertical positions
  1039. // if a value is missing or invalid, it will be converted to center
  1040. $.each( [ "my", "at" ], function() {
  1041. var pos = ( options[ this ] || "" ).split( " " ),
  1042. horizontalOffset,
  1043. verticalOffset;
  1044. if ( pos.length === 1) {
  1045. pos = rhorizontal.test( pos[ 0 ] ) ?
  1046. pos.concat( [ "center" ] ) :
  1047. rvertical.test( pos[ 0 ] ) ?
  1048. [ "center" ].concat( pos ) :
  1049. [ "center", "center" ];
  1050. }
  1051. pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
  1052. pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
  1053. // calculate offsets
  1054. horizontalOffset = roffset.exec( pos[ 0 ] );
  1055. verticalOffset = roffset.exec( pos[ 1 ] );
  1056. offsets[ this ] = [
  1057. horizontalOffset ? horizontalOffset[ 0 ] : 0,
  1058. verticalOffset ? verticalOffset[ 0 ] : 0
  1059. ];
  1060. // reduce to just the positions without the offsets
  1061. options[ this ] = [
  1062. rposition.exec( pos[ 0 ] )[ 0 ],
  1063. rposition.exec( pos[ 1 ] )[ 0 ]
  1064. ];
  1065. });
  1066. // normalize collision option
  1067. if ( collision.length === 1 ) {
  1068. collision[ 1 ] = collision[ 0 ];
  1069. }
  1070. if ( options.at[ 0 ] === "right" ) {
  1071. basePosition.left += targetWidth;
  1072. } else if ( options.at[ 0 ] === "center" ) {
  1073. basePosition.left += targetWidth / 2;
  1074. }
  1075. if ( options.at[ 1 ] === "bottom" ) {
  1076. basePosition.top += targetHeight;
  1077. } else if ( options.at[ 1 ] === "center" ) {
  1078. basePosition.top += targetHeight / 2;
  1079. }
  1080. atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
  1081. basePosition.left += atOffset[ 0 ];
  1082. basePosition.top += atOffset[ 1 ];
  1083. return this.each(function() {
  1084. var collisionPosition, using,
  1085. elem = $( this ),
  1086. elemWidth = elem.outerWidth(),
  1087. elemHeight = elem.outerHeight(),
  1088. marginLeft = parseCss( this, "marginLeft" ),
  1089. marginTop = parseCss( this, "marginTop" ),
  1090. collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
  1091. collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
  1092. position = $.extend( {}, basePosition ),
  1093. myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
  1094. if ( options.my[ 0 ] === "right" ) {
  1095. position.left -= elemWidth;
  1096. } else if ( options.my[ 0 ] === "center" ) {
  1097. position.left -= elemWidth / 2;
  1098. }
  1099. if ( options.my[ 1 ] === "bottom" ) {
  1100. position.top -= elemHeight;
  1101. } else if ( options.my[ 1 ] === "center" ) {
  1102. position.top -= elemHeight / 2;
  1103. }
  1104. position.left += myOffset[ 0 ];
  1105. position.top += myOffset[ 1 ];
  1106. // if the browser doesn't support fractions, then round for consistent results
  1107. if ( !supportsOffsetFractions ) {
  1108. position.left = round( position.left );
  1109. position.top = round( position.top );
  1110. }
  1111. collisionPosition = {
  1112. marginLeft: marginLeft,
  1113. marginTop: marginTop
  1114. };
  1115. $.each( [ "left", "top" ], function( i, dir ) {
  1116. if ( $.ui.position[ collision[ i ] ] ) {
  1117. $.ui.position[ collision[ i ] ][ dir ]( position, {
  1118. targetWidth: targetWidth,
  1119. targetHeight: targetHeight,
  1120. elemWidth: elemWidth,
  1121. elemHeight: elemHeight,
  1122. collisionPosition: collisionPosition,
  1123. collisionWidth: collisionWidth,
  1124. collisionHeight: collisionHeight,
  1125. offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
  1126. my: options.my,
  1127. at: options.at,
  1128. within: within,
  1129. elem: elem
  1130. });
  1131. }
  1132. });
  1133. if ( options.using ) {
  1134. // adds feedback as second argument to using callback, if present
  1135. using = function( props ) {
  1136. var left = targetOffset.left - position.left,
  1137. right = left + targetWidth - elemWidth,
  1138. top = targetOffset.top - position.top,
  1139. bottom = top + targetHeight - elemHeight,
  1140. feedback = {
  1141. target: {
  1142. element: target,
  1143. left: targetOffset.left,
  1144. top: targetOffset.top,
  1145. width: targetWidth,
  1146. height: targetHeight
  1147. },
  1148. element: {
  1149. element: elem,
  1150. left: position.left,
  1151. top: position.top,
  1152. width: elemWidth,
  1153. height: elemHeight
  1154. },
  1155. horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
  1156. vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
  1157. };
  1158. if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
  1159. feedback.horizontal = "center";
  1160. }
  1161. if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
  1162. feedback.vertical = "middle";
  1163. }
  1164. if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
  1165. feedback.important = "horizontal";
  1166. } else {
  1167. feedback.important = "vertical";
  1168. }
  1169. options.using.call( this, props, feedback );
  1170. };
  1171. }
  1172. elem.offset( $.extend( position, { using: using } ) );
  1173. });
  1174. };
  1175. $.ui.position = {
  1176. fit: {
  1177. left: function( position, data ) {
  1178. var within = data.within,
  1179. withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
  1180. outerWidth = within.width,
  1181. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1182. overLeft = withinOffset - collisionPosLeft,
  1183. overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
  1184. newOverRight;
  1185. // element is wider than within
  1186. if ( data.collisionWidth > outerWidth ) {
  1187. // element is initially over the left side of within
  1188. if ( overLeft > 0 && overRight <= 0 ) {
  1189. newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
  1190. position.left += overLeft - newOverRight;
  1191. // element is initially over right side of within
  1192. } else if ( overRight > 0 && overLeft <= 0 ) {
  1193. position.left = withinOffset;
  1194. // element is initially over both left and right sides of within
  1195. } else {
  1196. if ( overLeft > overRight ) {
  1197. position.left = withinOffset + outerWidth - data.collisionWidth;
  1198. } else {
  1199. position.left = withinOffset;
  1200. }
  1201. }
  1202. // too far left -> align with left edge
  1203. } else if ( overLeft > 0 ) {
  1204. position.left += overLeft;
  1205. // too far right -> align with right edge
  1206. } else if ( overRight > 0 ) {
  1207. position.left -= overRight;
  1208. // adjust based on position and margin
  1209. } else {
  1210. position.left = max( position.left - collisionPosLeft, position.left );
  1211. }
  1212. },
  1213. top: function( position, data ) {
  1214. var within = data.within,
  1215. withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
  1216. outerHeight = data.within.height,
  1217. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1218. overTop = withinOffset - collisionPosTop,
  1219. overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
  1220. newOverBottom;
  1221. // element is taller than within
  1222. if ( data.collisionHeight > outerHeight ) {
  1223. // element is initially over the top of within
  1224. if ( overTop > 0 && overBottom <= 0 ) {
  1225. newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
  1226. position.top += overTop - newOverBottom;
  1227. // element is initially over bottom of within
  1228. } else if ( overBottom > 0 && overTop <= 0 ) {
  1229. position.top = withinOffset;
  1230. // element is initially over both top and bottom of within
  1231. } else {
  1232. if ( overTop > overBottom ) {
  1233. position.top = withinOffset + outerHeight - data.collisionHeight;
  1234. } else {
  1235. position.top = withinOffset;
  1236. }
  1237. }
  1238. // too far up -> align with top
  1239. } else if ( overTop > 0 ) {
  1240. position.top += overTop;
  1241. // too far down -> align with bottom edge
  1242. } else if ( overBottom > 0 ) {
  1243. position.top -= overBottom;
  1244. // adjust based on position and margin
  1245. } else {
  1246. position.top = max( position.top - collisionPosTop, position.top );
  1247. }
  1248. }
  1249. },
  1250. flip: {
  1251. left: function( position, data ) {
  1252. var within = data.within,
  1253. withinOffset = within.offset.left + within.scrollLeft,
  1254. outerWidth = within.width,
  1255. offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
  1256. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1257. overLeft = collisionPosLeft - offsetLeft,
  1258. overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
  1259. myOffset = data.my[ 0 ] === "left" ?
  1260. -data.elemWidth :
  1261. data.my[ 0 ] === "right" ?
  1262. data.elemWidth :
  1263. 0,
  1264. atOffset = data.at[ 0 ] === "left" ?
  1265. data.targetWidth :
  1266. data.at[ 0 ] === "right" ?
  1267. -data.targetWidth :
  1268. 0,
  1269. offset = -2 * data.offset[ 0 ],
  1270. newOverRight,
  1271. newOverLeft;
  1272. if ( overLeft < 0 ) {
  1273. newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
  1274. if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
  1275. position.left += myOffset + atOffset + offset;
  1276. }
  1277. } else if ( overRight > 0 ) {
  1278. newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
  1279. if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
  1280. position.left += myOffset + atOffset + offset;
  1281. }
  1282. }
  1283. },
  1284. top: function( position, data ) {
  1285. var within = data.within,
  1286. withinOffset = within.offset.top + within.scrollTop,
  1287. outerHeight = within.height,
  1288. offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
  1289. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1290. overTop = collisionPosTop - offsetTop,
  1291. overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
  1292. top = data.my[ 1 ] === "top",
  1293. myOffset = top ?
  1294. -data.elemHeight :
  1295. data.my[ 1 ] === "bottom" ?
  1296. data.elemHeight :
  1297. 0,
  1298. atOffset = data.at[ 1 ] === "top" ?
  1299. data.targetHeight :
  1300. data.at[ 1 ] === "bottom" ?
  1301. -data.targetHeight :
  1302. 0,
  1303. offset = -2 * data.offset[ 1 ],
  1304. newOverTop,
  1305. newOverBottom;
  1306. if ( overTop < 0 ) {
  1307. newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
  1308. if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
  1309. position.top += myOffset + atOffset + offset;
  1310. }
  1311. } else if ( overBottom > 0 ) {
  1312. newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
  1313. if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
  1314. position.top += myOffset + atOffset + offset;
  1315. }
  1316. }
  1317. }
  1318. },
  1319. flipfit: {
  1320. left: function() {
  1321. $.ui.position.flip.left.apply( this, arguments );
  1322. $.ui.position.fit.left.apply( this, arguments );
  1323. },
  1324. top: function() {
  1325. $.ui.position.flip.top.apply( this, arguments );
  1326. $.ui.position.fit.top.apply( this, arguments );
  1327. }
  1328. }
  1329. };
  1330. // fraction support test
  1331. (function() {
  1332. var testElement, testElementParent, testElementStyle, offsetLeft, i,
  1333. body = document.getElementsByTagName( "body" )[ 0 ],
  1334. div = document.createElement( "div" );
  1335. //Create a "fake body" for testing based on method used in jQuery.support
  1336. testElement = document.createElement( body ? "div" : "body" );
  1337. testElementStyle = {
  1338. visibility: "hidden",
  1339. width: 0,
  1340. height: 0,
  1341. border: 0,
  1342. margin: 0,
  1343. background: "none"
  1344. };
  1345. if ( body ) {
  1346. $.extend( testElementStyle, {
  1347. position: "absolute",
  1348. left: "-1000px",
  1349. top: "-1000px"
  1350. });
  1351. }
  1352. for ( i in testElementStyle ) {
  1353. testElement.style[ i ] = testElementStyle[ i ];
  1354. }
  1355. testElement.appendChild( div );
  1356. testElementParent = body || document.documentElement;
  1357. testElementParent.insertBefore( testElement, testElementParent.firstChild );
  1358. div.style.cssText = "position: absolute; left: 10.7432222px;";
  1359. offsetLeft = $( div ).offset().left;
  1360. supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
  1361. testElement.innerHTML = "";
  1362. testElementParent.removeChild( testElement );
  1363. })();
  1364. })();
  1365. var position = $.ui.position;
  1366. /*!
  1367. * jQuery UI Menu 1.11.2
  1368. * http://jqueryui.com
  1369. *
  1370. * Copyright 2014 jQuery Foundation and other contributors
  1371. * Released under the MIT license.
  1372. * http://jquery.org/license
  1373. *
  1374. * http://api.jqueryui.com/menu/
  1375. */
  1376. var menu = $.widget( "ui.menu", {
  1377. version: "1.11.2",
  1378. defaultElement: "<ul>",
  1379. delay: 300,
  1380. options: {
  1381. icons: {
  1382. submenu: "ui-icon-carat-1-e"
  1383. },
  1384. items: "> *",
  1385. menus: "ul",
  1386. position: {
  1387. my: "left-1 top",
  1388. at: "right top"
  1389. },
  1390. role: "menu",
  1391. // callbacks
  1392. blur: null,
  1393. focus: null,
  1394. select: null
  1395. },
  1396. _create: function() {
  1397. this.activeMenu = this.element;
  1398. // Flag used to prevent firing of the click handler
  1399. // as the event bubbles up through nested menus
  1400. this.mouseHandled = false;
  1401. this.element
  1402. .uniqueId()
  1403. .addClass( "ui-menu ui-widget ui-widget-content" )
  1404. .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
  1405. .attr({
  1406. role: this.options.role,
  1407. tabIndex: 0
  1408. });
  1409. if ( this.options.disabled ) {
  1410. this.element
  1411. .addClass( "ui-state-disabled" )
  1412. .attr( "aria-disabled", "true" );
  1413. }
  1414. this._on({
  1415. // Prevent focus from sticking to links inside menu after clicking
  1416. // them (focus should always stay on UL during navigation).
  1417. "mousedown .ui-menu-item": function( event ) {
  1418. event.preventDefault();
  1419. },
  1420. "click .ui-menu-item": function( event ) {
  1421. var target = $( event.target );
  1422. if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
  1423. this.select( event );
  1424. // Only set the mouseHandled flag if the event will bubble, see #9469.
  1425. if ( !event.isPropagationStopped() ) {
  1426. this.mouseHandled = true;
  1427. }
  1428. // Open submenu on click
  1429. if ( target.has( ".ui-menu" ).length ) {
  1430. this.expand( event );
  1431. } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
  1432. // Redirect focus to the menu
  1433. this.element.trigger( "focus", [ true ] );
  1434. // If the active item is on the top level, let it stay active.
  1435. // Otherwise, blur the active item since it is no longer visible.
  1436. if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
  1437. clearTimeout( this.timer );
  1438. }
  1439. }
  1440. }
  1441. },
  1442. "mouseenter .ui-menu-item": function( event ) {
  1443. // Ignore mouse events while typeahead is active, see #10458.
  1444. // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
  1445. // is over an item in the menu
  1446. if ( this.previousFilter ) {
  1447. return;
  1448. }
  1449. var target = $( event.currentTarget );
  1450. // Remove ui-state-active class from siblings of the newly focused menu item
  1451. // to avoid a jump caused by adjacent elements both having a class with a border
  1452. target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
  1453. this.focus( event, target );
  1454. },
  1455. mouseleave: "collapseAll",
  1456. "mouseleave .ui-menu": "collapseAll",
  1457. focus: function( event, keepActiveItem ) {
  1458. // If there's already an active item, keep it active
  1459. // If not, activate the first item
  1460. var item = this.active || this.element.find( this.options.items ).eq( 0 );
  1461. if ( !keepActiveItem ) {
  1462. this.focus( event, item );
  1463. }
  1464. },
  1465. blur: function( event ) {
  1466. this._delay(function() {
  1467. if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
  1468. this.collapseAll( event );
  1469. }
  1470. });
  1471. },
  1472. keydown: "_keydown"
  1473. });
  1474. this.refresh();
  1475. // Clicks outside of a menu collapse any open menus
  1476. this._on( this.document, {
  1477. click: function( event ) {
  1478. if ( this._closeOnDocumentClick( event ) ) {
  1479. this.collapseAll( event );
  1480. }
  1481. // Reset the mouseHandled flag
  1482. this.mouseHandled = false;
  1483. }
  1484. });
  1485. },
  1486. _destroy: function() {
  1487. // Destroy (sub)menus
  1488. this.element
  1489. .removeAttr( "aria-activedescendant" )
  1490. .find( ".ui-menu" ).addBack()
  1491. .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
  1492. .removeAttr( "role" )
  1493. .removeAttr( "tabIndex" )
  1494. .removeAttr( "aria-labelledby" )
  1495. .removeAttr( "aria-expanded" )
  1496. .removeAttr( "aria-hidden" )
  1497. .removeAttr( "aria-disabled" )
  1498. .removeUniqueId()
  1499. .show();
  1500. // Destroy menu items
  1501. this.element.find( ".ui-menu-item" )
  1502. .removeClass( "ui-menu-item" )
  1503. .removeAttr( "role" )
  1504. .removeAttr( "aria-disabled" )
  1505. .removeUniqueId()
  1506. .removeClass( "ui-state-hover" )
  1507. .removeAttr( "tabIndex" )
  1508. .removeAttr( "role" )
  1509. .removeAttr( "aria-haspopup" )
  1510. .children().each( function() {
  1511. var elem = $( this );
  1512. if ( elem.data( "ui-menu-submenu-carat" ) ) {
  1513. elem.remove();
  1514. }
  1515. });
  1516. // Destroy menu dividers
  1517. this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
  1518. },
  1519. _keydown: function( event ) {
  1520. var match, prev, character, skip,
  1521. preventDefault = true;
  1522. switch ( event.keyCode ) {
  1523. case $.ui.keyCode.PAGE_UP:
  1524. this.previousPage( event );
  1525. break;
  1526. case $.ui.keyCode.PAGE_DOWN:
  1527. this.nextPage( event );
  1528. break;
  1529. case $.ui.keyCode.HOME:
  1530. this._move( "first", "first", event );
  1531. break;
  1532. case $.ui.keyCode.END:
  1533. this._move( "last", "last", event );
  1534. break;
  1535. case $.ui.keyCode.UP:
  1536. this.previous( event );
  1537. break;
  1538. case $.ui.keyCode.DOWN:
  1539. this.next( event );
  1540. break;
  1541. case $.ui.keyCode.LEFT:
  1542. this.collapse( event );
  1543. break;
  1544. case $.ui.keyCode.RIGHT:
  1545. if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
  1546. this.expand( event );
  1547. }
  1548. break;
  1549. case $.ui.keyCode.ENTER:
  1550. case $.ui.keyCode.SPACE:
  1551. this._activate( event );
  1552. break;
  1553. case $.ui.keyCode.ESCAPE:
  1554. this.collapse( event );
  1555. break;
  1556. default:
  1557. preventDefault = false;
  1558. prev = this.previousFilter || "";
  1559. character = String.fromCharCode( event.keyCode );
  1560. skip = false;
  1561. clearTimeout( this.filterTimer );
  1562. if ( character === prev ) {
  1563. skip = true;
  1564. } else {
  1565. character = prev + character;
  1566. }
  1567. match = this._filterMenuItems( character );
  1568. match = skip && match.index( this.active.next() ) !== -1 ?
  1569. this.active.nextAll( ".ui-menu-item" ) :
  1570. match;
  1571. // If no matches on the current filter, reset to the last character pressed
  1572. // to move down the menu to the first item that starts with that character
  1573. if ( !match.length ) {
  1574. character = String.fromCharCode( event.keyCode );
  1575. match = this._filterMenuItems( character );
  1576. }
  1577. if ( match.length ) {
  1578. this.focus( event, match );
  1579. this.previousFilter = character;
  1580. this.filterTimer = this._delay(function() {
  1581. delete this.previousFilter;
  1582. }, 1000 );
  1583. } else {
  1584. delete this.previousFilter;
  1585. }
  1586. }
  1587. if ( preventDefault ) {
  1588. event.preventDefault();
  1589. }
  1590. },
  1591. _activate: function( event ) {
  1592. if ( !this.active.is( ".ui-state-disabled" ) ) {
  1593. if ( this.active.is( "[aria-haspopup='true']" ) ) {
  1594. this.expand( event );
  1595. } else {
  1596. this.select( event );
  1597. }
  1598. }
  1599. },
  1600. refresh: function() {
  1601. var menus, items,
  1602. that = this,
  1603. icon = this.options.icons.submenu,
  1604. submenus = this.element.find( this.options.menus );
  1605. this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
  1606. // Initialize nested menus
  1607. submenus.filter( ":not(.ui-menu)" )
  1608. .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
  1609. .hide()
  1610. .attr({
  1611. role: this.options.role,
  1612. "aria-hidden": "true",
  1613. "aria-expanded": "false"
  1614. })
  1615. .each(function() {
  1616. var menu = $( this ),
  1617. item = menu.parent(),
  1618. submenuCarat = $( "<span>" )
  1619. .addClass( "ui-menu-icon ui-icon " + icon )
  1620. .data( "ui-menu-submenu-carat", true );
  1621. item
  1622. .attr( "aria-haspopup", "true" )
  1623. .prepend( submenuCarat );
  1624. menu.attr( "aria-labelledby", item.attr( "id" ) );
  1625. });
  1626. menus = submenus.add( this.element );
  1627. items = menus.find( this.options.items );
  1628. // Initialize menu-items containing spaces and/or dashes only as dividers
  1629. items.not( ".ui-menu-item" ).each(function() {
  1630. var item = $( this );
  1631. if ( that._isDivider( item ) ) {
  1632. item.addClass( "ui-widget-content ui-menu-divider" );
  1633. }
  1634. });
  1635. // Don't refresh list items that are already adapted
  1636. items.not( ".ui-menu-item, .ui-menu-divider" )
  1637. .addClass( "ui-menu-item" )
  1638. .uniqueId()
  1639. .attr({
  1640. tabIndex: -1,
  1641. role: this._itemRole()
  1642. });
  1643. // Add aria-disabled attribute to any disabled menu item
  1644. items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
  1645. // If the active item has been removed, blur the menu
  1646. if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
  1647. this.blur();
  1648. }
  1649. },
  1650. _itemRole: function() {
  1651. return {
  1652. menu: "menuitem",
  1653. listbox: "option"
  1654. }[ this.options.role ];
  1655. },
  1656. _setOption: function( key, value ) {
  1657. if ( key === "icons" ) {
  1658. this.element.find( ".ui-menu-icon" )
  1659. .removeClass( this.options.icons.submenu )
  1660. .addClass( value.submenu );
  1661. }
  1662. if ( key === "disabled" ) {
  1663. this.element
  1664. .toggleClass( "ui-state-disabled", !!value )
  1665. .attr( "aria-disabled", value );
  1666. }
  1667. this._super( key, value );
  1668. },
  1669. focus: function( event, item ) {
  1670. var nested, focused;
  1671. this.blur( event, event && event.type === "focus" );
  1672. this._scrollIntoView( item );
  1673. this.active = item.first();
  1674. focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
  1675. // Only update aria-activedescendant if there's a role
  1676. // otherwise we assume focus is managed elsewhere
  1677. if ( this.options.role ) {
  1678. this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
  1679. }
  1680. // Highlight active parent menu item, if any
  1681. this.active
  1682. .parent()
  1683. .closest( ".ui-menu-item" )
  1684. .addClass( "ui-state-active" );
  1685. if ( event && event.type === "keydown" ) {
  1686. this._close();
  1687. } else {
  1688. this.timer = this._delay(function() {
  1689. this._close();
  1690. }, this.delay );
  1691. }
  1692. nested = item.children( ".ui-menu" );
  1693. if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
  1694. this._startOpening(nested);
  1695. }
  1696. this.activeMenu = item.parent();
  1697. this._trigger( "focus", event, { item: item } );
  1698. },
  1699. _scrollIntoView: function( item ) {
  1700. var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
  1701. if ( this._hasScroll() ) {
  1702. borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
  1703. paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
  1704. offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
  1705. scroll = this.activeMenu.scrollTop();
  1706. elementHeight = this.activeMenu.height();
  1707. itemHeight = item.outerHeight();
  1708. if ( offset < 0 ) {
  1709. this.activeMenu.scrollTop( scroll + offset );
  1710. } else if ( offset + itemHeight > elementHeight ) {
  1711. this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
  1712. }
  1713. }
  1714. },
  1715. blur: function( event, fromFocus ) {
  1716. if ( !fromFocus ) {
  1717. clearTimeout( this.timer );
  1718. }
  1719. if ( !this.active ) {
  1720. return;
  1721. }
  1722. this.active.removeClass( "ui-state-focus" );
  1723. this.active = null;
  1724. this._trigger( "blur", event, { item: this.active } );
  1725. },
  1726. _startOpening: function( submenu ) {
  1727. clearTimeout( this.timer );
  1728. // Don't open if already open fixes a Firefox bug that caused a .5 pixel
  1729. // shift in the submenu position when mousing over the carat icon
  1730. if ( submenu.attr( "aria-hidden" ) !== "true" ) {
  1731. return;
  1732. }
  1733. this.timer = this._delay(function() {
  1734. this._close();
  1735. this._open( submenu );
  1736. }, this.delay );
  1737. },
  1738. _open: function( submenu ) {
  1739. var position = $.extend({
  1740. of: this.active
  1741. }, this.options.position );
  1742. clearTimeout( this.timer );
  1743. this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
  1744. .hide()
  1745. .attr( "aria-hidden", "true" );
  1746. submenu
  1747. .show()
  1748. .removeAttr( "aria-hidden" )
  1749. .attr( "aria-expanded", "true" )
  1750. .position( position );
  1751. },
  1752. collapseAll: function( event, all ) {
  1753. clearTimeout( this.timer );
  1754. this.timer = this._delay(function() {
  1755. // If we were passed an event, look for the submenu that contains the event
  1756. var currentMenu = all ? this.element :
  1757. $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
  1758. // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
  1759. if ( !currentMenu.length ) {
  1760. currentMenu = this.element;
  1761. }
  1762. this._close( currentMenu );
  1763. this.blur( event );
  1764. this.activeMenu = currentMenu;
  1765. }, this.delay );
  1766. },
  1767. // With no arguments, closes the currently active menu - if nothing is active
  1768. // it closes all menus. If passed an argument, it will search for menus BELOW
  1769. _close: function( startMenu ) {
  1770. if ( !startMenu ) {
  1771. startMenu = this.active ? this.active.parent() : this.element;
  1772. }
  1773. startMenu
  1774. .find( ".ui-menu" )
  1775. .hide()
  1776. .attr( "aria-hidden", "true" )
  1777. .attr( "aria-expanded", "false" )
  1778. .end()
  1779. .find( ".ui-state-active" ).not( ".ui-state-focus" )
  1780. .removeClass( "ui-state-active" );
  1781. },
  1782. _closeOnDocumentClick: function( event ) {
  1783. return !$( event.target ).closest( ".ui-menu" ).length;
  1784. },
  1785. _isDivider: function( item ) {
  1786. // Match hyphen, em dash, en dash
  1787. return !/[^\-\u2014\u2013\s]/.test( item.text() );
  1788. },
  1789. collapse: function( event ) {
  1790. var newItem = this.active &&
  1791. this.active.parent().closest( ".ui-menu-item", this.element );
  1792. if ( newItem && newItem.length ) {
  1793. this._close();
  1794. this.focus( event, newItem );
  1795. }
  1796. },
  1797. expand: function( event ) {
  1798. var newItem = this.active &&
  1799. this.active
  1800. .children( ".ui-menu " )
  1801. .find( this.options.items )
  1802. .first();
  1803. if ( newItem && newItem.length ) {
  1804. this._open( newItem.parent() );
  1805. // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
  1806. this._delay(function() {
  1807. this.focus( event, newItem );
  1808. });
  1809. }
  1810. },
  1811. next: function( event ) {
  1812. this._move( "next", "first", event );
  1813. },
  1814. previous: function( event ) {
  1815. this._move( "prev", "last", event );
  1816. },
  1817. isFirstItem: function() {
  1818. return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
  1819. },
  1820. isLastItem: function() {
  1821. return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
  1822. },
  1823. _move: function( direction, filter, event ) {
  1824. var next;
  1825. if ( this.active ) {
  1826. if ( direction === "first" || direction === "last" ) {
  1827. next = this.active
  1828. [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
  1829. .eq( -1 );
  1830. } else {
  1831. next = this.active
  1832. [ direction + "All" ]( ".ui-menu-item" )
  1833. .eq( 0 );
  1834. }
  1835. }
  1836. if ( !next || !next.length || !this.active ) {
  1837. next = this.activeMenu.find( this.options.items )[ filter ]();
  1838. }
  1839. this.focus( event, next );
  1840. },
  1841. nextPage: function( event ) {
  1842. var item, base, height;
  1843. if ( !this.active ) {
  1844. this.next( event );
  1845. return;
  1846. }
  1847. if ( this.isLastItem() ) {
  1848. return;
  1849. }
  1850. if ( this._hasScroll() ) {
  1851. base = this.active.offset().top;
  1852. height = this.element.height();
  1853. this.active.nextAll( ".ui-menu-item" ).each(function() {
  1854. item = $( this );
  1855. return item.offset().top - base - height < 0;
  1856. });
  1857. this.focus( event, item );
  1858. } else {
  1859. this.focus( event, this.activeMenu.find( this.options.items )
  1860. [ !this.active ? "first" : "last" ]() );
  1861. }
  1862. },
  1863. previousPage: function( event ) {
  1864. var item, base, height;
  1865. if ( !this.active ) {
  1866. this.next( event );
  1867. return;
  1868. }
  1869. if ( this.isFirstItem() ) {
  1870. return;
  1871. }
  1872. if ( this._hasScroll() ) {
  1873. base = this.active.offset().top;
  1874. height = this.element.height();
  1875. this.active.prevAll( ".ui-menu-item" ).each(function() {
  1876. item = $( this );
  1877. return item.offset().top - base + height > 0;
  1878. });
  1879. this.focus( event, item );
  1880. } else {
  1881. this.focus( event, this.activeMenu.find( this.options.items ).first() );
  1882. }
  1883. },
  1884. _hasScroll: function() {
  1885. return this.element.outerHeight() < this.element.prop( "scrollHeight" );
  1886. },
  1887. select: function( event ) {
  1888. // TODO: It should never be possible to not have an active item at this
  1889. // point, but the tests don't trigger mouseenter before click.
  1890. this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
  1891. var ui = { item: this.active };
  1892. if ( !this.active.has( ".ui-menu" ).length ) {
  1893. this.collapseAll( event, true );
  1894. }
  1895. this._trigger( "select", event, ui );
  1896. },
  1897. _filterMenuItems: function(character) {
  1898. var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
  1899. regex = new RegExp( "^" + escapedCharacter, "i" );
  1900. return this.activeMenu
  1901. .find( this.options.items )
  1902. // Only match on items, not dividers or other content (#10571)
  1903. .filter( ".ui-menu-item" )
  1904. .filter(function() {
  1905. return regex.test( $.trim( $( this ).text() ) );
  1906. });
  1907. }
  1908. });
  1909. /*!
  1910. * jQuery UI Autocomplete 1.11.2
  1911. * http://jqueryui.com
  1912. *
  1913. * Copyright 2014 jQuery Foundation and other contributors
  1914. * Released under the MIT license.
  1915. * http://jquery.org/license
  1916. *
  1917. * http://api.jqueryui.com/autocomplete/
  1918. */
  1919. $.widget( "ui.autocomplete", {
  1920. version: "1.11.2",
  1921. defaultElement: "<input>",
  1922. options: {
  1923. appendTo: null,
  1924. autoFocus: false,
  1925. delay: 300,
  1926. minLength: 1,
  1927. position: {
  1928. my: "left top",
  1929. at: "left bottom",
  1930. collision: "none"
  1931. },
  1932. source: null,
  1933. // callbacks
  1934. change: null,
  1935. close: null,
  1936. focus: null,
  1937. open: null,
  1938. response: null,
  1939. search: null,
  1940. select: null
  1941. },
  1942. requestIndex: 0,
  1943. pending: 0,
  1944. _create: function() {
  1945. // Some browsers only repeat keydown events, not keypress events,
  1946. // so we use the suppressKeyPress flag to determine if we've already
  1947. // handled the keydown event. #7269
  1948. // Unfortunately the code for & in keypress is the same as the up arrow,
  1949. // so we use the suppressKeyPressRepeat flag to avoid handling keypress
  1950. // events when we know the keydown event was used to modify the
  1951. // search term. #7799
  1952. var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
  1953. nodeName = this.element[ 0 ].nodeName.toLowerCase(),
  1954. isTextarea = nodeName === "textarea",
  1955. isInput = nodeName === "input";
  1956. this.isMultiLine =
  1957. // Textareas are always multi-line
  1958. isTextarea ? true :
  1959. // Inputs are always single-line, even if inside a contentEditable element
  1960. // IE also treats inputs as contentEditable
  1961. isInput ? false :
  1962. // All other element types are determined by whether or not they're contentEditable
  1963. this.element.prop( "isContentEditable" );
  1964. this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
  1965. this.isNewMenu = true;
  1966. this.element
  1967. .addClass( "ui-autocomplete-input" )
  1968. .attr( "autocomplete", "off" );
  1969. this._on( this.element, {
  1970. keydown: function( event ) {
  1971. if ( this.element.prop( "readOnly" ) ) {
  1972. suppressKeyPress = true;
  1973. suppressInput = true;
  1974. suppressKeyPressRepeat = true;
  1975. return;
  1976. }
  1977. suppressKeyPress = false;
  1978. suppressInput = false;
  1979. suppressKeyPressRepeat = false;
  1980. var keyCode = $.ui.keyCode;
  1981. switch ( event.keyCode ) {
  1982. case keyCode.PAGE_UP:
  1983. suppressKeyPress = true;
  1984. this._move( "previousPage", event );
  1985. break;
  1986. case keyCode.PAGE_DOWN:
  1987. suppressKeyPress = true;
  1988. this._move( "nextPage", event );
  1989. break;
  1990. case keyCode.UP:
  1991. suppressKeyPress = true;
  1992. this._keyEvent( "previous", event );
  1993. break;
  1994. case keyCode.DOWN:
  1995. suppressKeyPress = true;
  1996. this._keyEvent( "next", event );
  1997. break;
  1998. case keyCode.ENTER:
  1999. // when menu is open and has focus
  2000. if ( this.menu.active ) {
  2001. // #6055 - Opera still allows the keypress to occur
  2002. // which causes forms to submit
  2003. suppressKeyPress = true;
  2004. event.preventDefault();
  2005. this.menu.select( event );
  2006. }
  2007. break;
  2008. case keyCode.TAB:
  2009. if ( this.menu.active ) {
  2010. this.menu.select( event );
  2011. }
  2012. break;
  2013. case keyCode.ESCAPE:
  2014. if ( this.menu.element.is( ":visible" ) ) {
  2015. if ( !this.isMultiLine ) {
  2016. this._value( this.term );
  2017. }
  2018. this.close( event );
  2019. // Different browsers have different default behavior for escape
  2020. // Single press can mean undo or clear
  2021. // Double press in IE means clear the whole form
  2022. event.preventDefault();
  2023. }
  2024. break;
  2025. default:
  2026. suppressKeyPressRepeat = true;
  2027. // search timeout should be triggered before the input value is changed
  2028. this._searchTimeout( event );
  2029. break;
  2030. }
  2031. },
  2032. keypress: function( event ) {
  2033. if ( suppressKeyPress ) {
  2034. suppressKeyPress = false;
  2035. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  2036. event.preventDefault();
  2037. }
  2038. return;
  2039. }
  2040. if ( suppressKeyPressRepeat ) {
  2041. return;
  2042. }
  2043. // replicate some key handlers to allow them to repeat in Firefox and Opera
  2044. var keyCode = $.ui.keyCode;
  2045. switch ( event.keyCode ) {
  2046. case keyCode.PAGE_UP:
  2047. this._move( "previousPage", event );
  2048. break;
  2049. case keyCode.PAGE_DOWN:
  2050. this._move( "nextPage", event );
  2051. break;
  2052. case keyCode.UP:
  2053. this._keyEvent( "previous", event );
  2054. break;
  2055. case keyCode.DOWN:
  2056. this._keyEvent( "next", event );
  2057. break;
  2058. }
  2059. },
  2060. input: function( event ) {
  2061. if ( suppressInput ) {
  2062. suppressInput = false;
  2063. event.preventDefault();
  2064. return;
  2065. }
  2066. this._searchTimeout( event );
  2067. },
  2068. focus: function() {
  2069. this.selectedItem = null;
  2070. this.previous = this._value();
  2071. },
  2072. blur: function( event ) {
  2073. if ( this.cancelBlur ) {
  2074. delete this.cancelBlur;
  2075. return;
  2076. }
  2077. clearTimeout( this.searching );
  2078. this.close( event );
  2079. this._change( event );
  2080. }
  2081. });
  2082. this._initSource();
  2083. this.menu = $( "<ul>" )
  2084. .addClass( "ui-autocomplete ui-front" )
  2085. .appendTo( this._appendTo() )
  2086. .menu({
  2087. // disable ARIA support, the live region takes care of that
  2088. role: null
  2089. })
  2090. .hide()
  2091. .menu( "instance" );
  2092. this._on( this.menu.element, {
  2093. mousedown: function( event ) {
  2094. // prevent moving focus out of the text field
  2095. event.preventDefault();
  2096. // IE doesn't prevent moving focus even with event.preventDefault()
  2097. // so we set a flag to know when we should ignore the blur event
  2098. this.cancelBlur = true;
  2099. this._delay(function() {
  2100. delete this.cancelBlur;
  2101. });
  2102. // clicking on the scrollbar causes focus to shift to the body
  2103. // but we can't detect a mouseup or a click immediately afterward
  2104. // so we have to track the next mousedown and close the menu if
  2105. // the user clicks somewhere outside of the autocomplete
  2106. var menuElement = this.menu.element[ 0 ];
  2107. if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
  2108. this._delay(function() {
  2109. var that = this;
  2110. this.document.one( "mousedown", function( event ) {
  2111. if ( event.target !== that.element[ 0 ] &&
  2112. event.target !== menuElement &&
  2113. !$.contains( menuElement, event.target ) ) {
  2114. that.close();
  2115. }
  2116. });
  2117. });
  2118. }
  2119. },
  2120. menufocus: function( event, ui ) {
  2121. var label, item;
  2122. // support: Firefox
  2123. // Prevent accidental activation of menu items in Firefox (#7024 #9118)
  2124. if ( this.isNewMenu ) {
  2125. this.isNewMenu = false;
  2126. if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
  2127. this.menu.blur();
  2128. this.document.one( "mousemove", function() {
  2129. $( event.target ).trigger( event.originalEvent );
  2130. });
  2131. return;
  2132. }
  2133. }
  2134. item = ui.item.data( "ui-autocomplete-item" );
  2135. if ( false !== this._trigger( "focus", event, { item: item } ) ) {
  2136. // use value to match what will end up in the input, if it was a key event
  2137. if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
  2138. this._value( item.value );
  2139. }
  2140. }
  2141. // Announce the value in the liveRegion
  2142. label = ui.item.attr( "aria-label" ) || item.value;
  2143. if ( label && $.trim( label ).length ) {
  2144. this.liveRegion.children().hide();
  2145. $( "<div>" ).text( label ).appendTo( this.liveRegion );
  2146. }
  2147. },
  2148. menuselect: function( event, ui ) {
  2149. var item = ui.item.data( "ui-autocomplete-item" ),
  2150. previous = this.previous;
  2151. // only trigger when focus was lost (click on menu)
  2152. if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
  2153. this.element.focus();
  2154. this.previous = previous;
  2155. // #6109 - IE triggers two focus events and the second
  2156. // is asynchronous, so we need to reset the previous
  2157. // term synchronously and asynchronously :-(
  2158. this._delay(function() {
  2159. this.previous = previous;
  2160. this.selectedItem = item;
  2161. });
  2162. }
  2163. if ( false !== this._trigger( "select", event, { item: item } ) ) {
  2164. this._value( item.value );
  2165. }
  2166. // reset the term after the select event
  2167. // this allows custom select handling to work properly
  2168. this.term = this._value();
  2169. this.close( event );
  2170. this.selectedItem = item;
  2171. }
  2172. });
  2173. this.liveRegion = $( "<span>", {
  2174. role: "status",
  2175. "aria-live": "assertive",
  2176. "aria-relevant": "additions"
  2177. })
  2178. .addClass( "ui-helper-hidden-accessible" )
  2179. .appendTo( this.document[ 0 ].body );
  2180. // turning off autocomplete prevents the browser from remembering the
  2181. // value when navigating through history, so we re-enable autocomplete
  2182. // if the page is unloaded before the widget is destroyed. #7790
  2183. this._on( this.window, {
  2184. beforeunload: function() {
  2185. this.element.removeAttr( "autocomplete" );
  2186. }
  2187. });
  2188. },
  2189. _destroy: function() {
  2190. clearTimeout( this.searching );
  2191. this.element
  2192. .removeClass( "ui-autocomplete-input" )
  2193. .removeAttr( "autocomplete" );
  2194. this.menu.element.remove();
  2195. this.liveRegion.remove();
  2196. },
  2197. _setOption: function( key, value ) {
  2198. this._super( key, value );
  2199. if ( key === "source" ) {
  2200. this._initSource();
  2201. }
  2202. if ( key === "appendTo" ) {
  2203. this.menu.element.appendTo( this._appendTo() );
  2204. }
  2205. if ( key === "disabled" && value && this.xhr ) {
  2206. this.xhr.abort();
  2207. }
  2208. },
  2209. _appendTo: function() {
  2210. var element = this.options.appendTo;
  2211. if ( element ) {
  2212. element = element.jquery || element.nodeType ?
  2213. $( element ) :
  2214. this.document.find( element ).eq( 0 );
  2215. }
  2216. if ( !element || !element[ 0 ] ) {
  2217. element = this.element.closest( ".ui-front" );
  2218. }
  2219. if ( !element.length ) {
  2220. element = this.document[ 0 ].body;
  2221. }
  2222. return element;
  2223. },
  2224. _initSource: function() {
  2225. var array, url,
  2226. that = this;
  2227. if ( $.isArray( this.options.source ) ) {
  2228. array = this.options.source;
  2229. this.source = function( request, response ) {
  2230. response( $.ui.autocomplete.filter( array, request.term ) );
  2231. };
  2232. } else if ( typeof this.options.source === "string" ) {
  2233. url = this.options.source;
  2234. this.source = function( request, response ) {
  2235. if ( that.xhr ) {
  2236. that.xhr.abort();
  2237. }
  2238. that.xhr = $.ajax({
  2239. url: url,
  2240. data: request,
  2241. dataType: "json",
  2242. success: function( data ) {
  2243. response( data );
  2244. },
  2245. error: function() {
  2246. response([]);
  2247. }
  2248. });
  2249. };
  2250. } else {
  2251. this.source = this.options.source;
  2252. }
  2253. },
  2254. _searchTimeout: function( event ) {
  2255. clearTimeout( this.searching );
  2256. this.searching = this._delay(function() {
  2257. // Search if the value has changed, or if the user retypes the same value (see #7434)
  2258. var equalValues = this.term === this._value(),
  2259. menuVisible = this.menu.element.is( ":visible" ),
  2260. modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
  2261. if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
  2262. this.selectedItem = null;
  2263. this.search( null, event );
  2264. }
  2265. }, this.options.delay );
  2266. },
  2267. search: function( value, event ) {
  2268. value = value != null ? value : this._value();
  2269. // always save the actual value, not the one passed as an argument
  2270. this.term = this._value();
  2271. if ( value.length < this.options.minLength ) {
  2272. return this.close( event );
  2273. }
  2274. if ( this._trigger( "search", event ) === false ) {
  2275. return;
  2276. }
  2277. return this._search( value );
  2278. },
  2279. _search: function( value ) {
  2280. this.pending++;
  2281. this.element.addClass( "ui-autocomplete-loading" );
  2282. this.cancelSearch = false;
  2283. this.source( { term: value }, this._response() );
  2284. },
  2285. _response: function() {
  2286. var index = ++this.requestIndex;
  2287. return $.proxy(function( content ) {
  2288. if ( index === this.requestIndex ) {
  2289. this.__response( content );
  2290. }
  2291. this.pending--;
  2292. if ( !this.pending ) {
  2293. this.element.removeClass( "ui-autocomplete-loading" );
  2294. }
  2295. }, this );
  2296. },
  2297. __response: function( content ) {
  2298. if ( content ) {
  2299. content = this._normalize( content );
  2300. }
  2301. this._trigger( "response", null, { content: content } );
  2302. if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
  2303. this._suggest( content );
  2304. this._trigger( "open" );
  2305. } else {
  2306. // use ._close() instead of .close() so we don't cancel future searches
  2307. this._close();
  2308. }
  2309. },
  2310. close: function( event ) {
  2311. this.cancelSearch = true;
  2312. this._close( event );
  2313. },
  2314. _close: function( event ) {
  2315. if ( this.menu.element.is( ":visible" ) ) {
  2316. this.menu.element.hide();
  2317. this.menu.blur();
  2318. this.isNewMenu = true;
  2319. this._trigger( "close", event );
  2320. }
  2321. },
  2322. _change: function( event ) {
  2323. if ( this.previous !== this._value() ) {
  2324. this._trigger( "change", event, { item: this.selectedItem } );
  2325. }
  2326. },
  2327. _normalize: function( items ) {
  2328. // assume all items have the right format when the first item is complete
  2329. if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
  2330. return items;
  2331. }
  2332. return $.map( items, function( item ) {
  2333. if ( typeof item === "string" ) {
  2334. return {
  2335. label: item,
  2336. value: item
  2337. };
  2338. }
  2339. return $.extend( {}, item, {
  2340. label: item.label || item.value,
  2341. value: item.value || item.label
  2342. });
  2343. });
  2344. },
  2345. _suggest: function( items ) {
  2346. var ul = this.menu.element.empty();
  2347. this._renderMenu( ul, items );
  2348. this.isNewMenu = true;
  2349. this.menu.refresh();
  2350. // size and position menu
  2351. ul.show();
  2352. this._resizeMenu();
  2353. ul.position( $.extend({
  2354. of: this.element
  2355. }, this.options.position ) );
  2356. if ( this.options.autoFocus ) {
  2357. this.menu.next();
  2358. }
  2359. },
  2360. _resizeMenu: function() {
  2361. var ul = this.menu.element;
  2362. ul.outerWidth( Math.max(
  2363. // Firefox wraps long text (possibly a rounding bug)
  2364. // so we add 1px to avoid the wrapping (#7513)
  2365. ul.width( "" ).outerWidth() + 1,
  2366. this.element.outerWidth()
  2367. ) );
  2368. },
  2369. _renderMenu: function( ul, items ) {
  2370. var that = this;
  2371. $.each( items, function( index, item ) {
  2372. that._renderItemData( ul, item );
  2373. });
  2374. },
  2375. _renderItemData: function( ul, item ) {
  2376. return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
  2377. },
  2378. _renderItem: function( ul, item ) {
  2379. return $( "<li>" ).text( item.label ).appendTo( ul );
  2380. },
  2381. _move: function( direction, event ) {
  2382. if ( !this.menu.element.is( ":visible" ) ) {
  2383. this.search( null, event );
  2384. return;
  2385. }
  2386. if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
  2387. this.menu.isLastItem() && /^next/.test( direction ) ) {
  2388. if ( !this.isMultiLine ) {
  2389. this._value( this.term );
  2390. }
  2391. this.menu.blur();
  2392. return;
  2393. }
  2394. this.menu[ direction ]( event );
  2395. },
  2396. widget: function() {
  2397. return this.menu.element;
  2398. },
  2399. _value: function() {
  2400. return this.valueMethod.apply( this.element, arguments );
  2401. },
  2402. _keyEvent: function( keyEvent, event ) {
  2403. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  2404. this._move( keyEvent, event );
  2405. // prevents moving cursor to beginning/end of the text field in some browsers
  2406. event.preventDefault();
  2407. }
  2408. }
  2409. });
  2410. $.extend( $.ui.autocomplete, {
  2411. escapeRegex: function( value ) {
  2412. return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
  2413. },
  2414. filter: function( array, term ) {
  2415. var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
  2416. return $.grep( array, function( value ) {
  2417. return matcher.test( value.label || value.value || value );
  2418. });
  2419. }
  2420. });
  2421. // live region extension, adding a `messages` option
  2422. // NOTE: This is an experimental API. We are still investigating
  2423. // a full solution for string manipulation and internationalization.
  2424. $.widget( "ui.autocomplete", $.ui.autocomplete, {
  2425. options: {
  2426. messages: {
  2427. noResults: "No search results.",
  2428. results: function( amount ) {
  2429. return amount + ( amount > 1 ? " results are" : " result is" ) +
  2430. " available, use up and down arrow keys to navigate.";
  2431. }
  2432. }
  2433. },
  2434. __response: function( content ) {
  2435. var message;
  2436. this._superApply( arguments );
  2437. if ( this.options.disabled || this.cancelSearch ) {
  2438. return;
  2439. }
  2440. if ( content && content.length ) {
  2441. message = this.options.messages.results( content.length );
  2442. } else {
  2443. message = this.options.messages.noResults;
  2444. }
  2445. this.liveRegion.children().hide();
  2446. $( "<div>" ).text( message ).appendTo( this.liveRegion );
  2447. }
  2448. });
  2449. var autocomplete = $.ui.autocomplete;
  2450. }));