jquery-ui.js 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109
  1. /*! jQuery UI - v1.12.1 - 2016-12-08
  2. * http://jqueryui.com
  3. * Includes: widget.js, data.js, scroll-parent.js, widgets/draggable.js, widgets/droppable.js, widgets/selectable.js, widgets/mouse.js
  4. * Copyright 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. $.ui = $.ui || {};
  15. var version = $.ui.version = "1.12.1";
  16. /*!
  17. * jQuery UI Widget 1.12.1
  18. * http://jqueryui.com
  19. *
  20. * Copyright jQuery Foundation and other contributors
  21. * Released under the MIT license.
  22. * http://jquery.org/license
  23. */
  24. //>>label: Widget
  25. //>>group: Core
  26. //>>description: Provides a factory for creating stateful widgets with a common API.
  27. //>>docs: http://api.jqueryui.com/jQuery.widget/
  28. //>>demos: http://jqueryui.com/widget/
  29. var widgetUuid = 0;
  30. var widgetSlice = Array.prototype.slice;
  31. $.cleanData = ( function( orig ) {
  32. return function( elems ) {
  33. var events, elem, i;
  34. for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
  35. try {
  36. // Only trigger remove when necessary to save time
  37. events = $._data( elem, "events" );
  38. if ( events && events.remove ) {
  39. $( elem ).triggerHandler( "remove" );
  40. }
  41. // Http://bugs.jquery.com/ticket/8235
  42. } catch ( e ) {}
  43. }
  44. orig( elems );
  45. };
  46. } )( $.cleanData );
  47. $.widget = function( name, base, prototype ) {
  48. var existingConstructor, constructor, basePrototype;
  49. // ProxiedPrototype allows the provided prototype to remain unmodified
  50. // so that it can be used as a mixin for multiple widgets (#8876)
  51. var proxiedPrototype = {};
  52. var namespace = name.split( "." )[ 0 ];
  53. name = name.split( "." )[ 1 ];
  54. var fullName = namespace + "-" + name;
  55. if ( !prototype ) {
  56. prototype = base;
  57. base = $.Widget;
  58. }
  59. if ( $.isArray( prototype ) ) {
  60. prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
  61. }
  62. // Create selector for plugin
  63. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  64. return !!$.data( elem, fullName );
  65. };
  66. $[ namespace ] = $[ namespace ] || {};
  67. existingConstructor = $[ namespace ][ name ];
  68. constructor = $[ namespace ][ name ] = function( options, element ) {
  69. // Allow instantiation without "new" keyword
  70. if ( !this._createWidget ) {
  71. return new constructor( options, element );
  72. }
  73. // Allow instantiation without initializing for simple inheritance
  74. // must use "new" keyword (the code above always passes args)
  75. if ( arguments.length ) {
  76. this._createWidget( options, element );
  77. }
  78. };
  79. // Extend with the existing constructor to carry over any static properties
  80. $.extend( constructor, existingConstructor, {
  81. version: prototype.version,
  82. // Copy the object used to create the prototype in case we need to
  83. // redefine the widget later
  84. _proto: $.extend( {}, prototype ),
  85. // Track widgets that inherit from this widget in case this widget is
  86. // redefined after a widget inherits from it
  87. _childConstructors: []
  88. } );
  89. basePrototype = new base();
  90. // We need to make the options hash a property directly on the new instance
  91. // otherwise we'll modify the options hash on the prototype that we're
  92. // inheriting from
  93. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  94. $.each( prototype, function( prop, value ) {
  95. if ( !$.isFunction( value ) ) {
  96. proxiedPrototype[ prop ] = value;
  97. return;
  98. }
  99. proxiedPrototype[ prop ] = ( function() {
  100. function _super() {
  101. return base.prototype[ prop ].apply( this, arguments );
  102. }
  103. function _superApply( args ) {
  104. return base.prototype[ prop ].apply( this, args );
  105. }
  106. return function() {
  107. var __super = this._super;
  108. var __superApply = this._superApply;
  109. var returnValue;
  110. this._super = _super;
  111. this._superApply = _superApply;
  112. returnValue = value.apply( this, arguments );
  113. this._super = __super;
  114. this._superApply = __superApply;
  115. return returnValue;
  116. };
  117. } )();
  118. } );
  119. constructor.prototype = $.widget.extend( basePrototype, {
  120. // TODO: remove support for widgetEventPrefix
  121. // always use the name + a colon as the prefix, e.g., draggable:start
  122. // don't prefix for widgets that aren't DOM-based
  123. widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
  124. }, proxiedPrototype, {
  125. constructor: constructor,
  126. namespace: namespace,
  127. widgetName: name,
  128. widgetFullName: fullName
  129. } );
  130. // If this widget is being redefined then we need to find all widgets that
  131. // are inheriting from it and redefine all of them so that they inherit from
  132. // the new version of this widget. We're essentially trying to replace one
  133. // level in the prototype chain.
  134. if ( existingConstructor ) {
  135. $.each( existingConstructor._childConstructors, function( i, child ) {
  136. var childPrototype = child.prototype;
  137. // Redefine the child widget using the same prototype that was
  138. // originally used, but inherit from the new version of the base
  139. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
  140. child._proto );
  141. } );
  142. // Remove the list of existing child constructors from the old constructor
  143. // so the old child constructors can be garbage collected
  144. delete existingConstructor._childConstructors;
  145. } else {
  146. base._childConstructors.push( constructor );
  147. }
  148. $.widget.bridge( name, constructor );
  149. return constructor;
  150. };
  151. $.widget.extend = function( target ) {
  152. var input = widgetSlice.call( arguments, 1 );
  153. var inputIndex = 0;
  154. var inputLength = input.length;
  155. var key;
  156. var value;
  157. for ( ; inputIndex < inputLength; inputIndex++ ) {
  158. for ( key in input[ inputIndex ] ) {
  159. value = input[ inputIndex ][ key ];
  160. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  161. // Clone objects
  162. if ( $.isPlainObject( value ) ) {
  163. target[ key ] = $.isPlainObject( target[ key ] ) ?
  164. $.widget.extend( {}, target[ key ], value ) :
  165. // Don't extend strings, arrays, etc. with objects
  166. $.widget.extend( {}, value );
  167. // Copy everything else by reference
  168. } else {
  169. target[ key ] = value;
  170. }
  171. }
  172. }
  173. }
  174. return target;
  175. };
  176. $.widget.bridge = function( name, object ) {
  177. var fullName = object.prototype.widgetFullName || name;
  178. $.fn[ name ] = function( options ) {
  179. var isMethodCall = typeof options === "string";
  180. var args = widgetSlice.call( arguments, 1 );
  181. var returnValue = this;
  182. if ( isMethodCall ) {
  183. // If this is an empty collection, we need to have the instance method
  184. // return undefined instead of the jQuery instance
  185. if ( !this.length && options === "instance" ) {
  186. returnValue = undefined;
  187. } else {
  188. this.each( function() {
  189. var methodValue;
  190. var instance = $.data( this, fullName );
  191. if ( options === "instance" ) {
  192. returnValue = instance;
  193. return false;
  194. }
  195. if ( !instance ) {
  196. return $.error( "cannot call methods on " + name +
  197. " prior to initialization; " +
  198. "attempted to call method '" + options + "'" );
  199. }
  200. if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
  201. return $.error( "no such method '" + options + "' for " + name +
  202. " widget instance" );
  203. }
  204. methodValue = instance[ options ].apply( instance, args );
  205. if ( methodValue !== instance && methodValue !== undefined ) {
  206. returnValue = methodValue && methodValue.jquery ?
  207. returnValue.pushStack( methodValue.get() ) :
  208. methodValue;
  209. return false;
  210. }
  211. } );
  212. }
  213. } else {
  214. // Allow multiple hashes to be passed on init
  215. if ( args.length ) {
  216. options = $.widget.extend.apply( null, [ options ].concat( args ) );
  217. }
  218. this.each( function() {
  219. var instance = $.data( this, fullName );
  220. if ( instance ) {
  221. instance.option( options || {} );
  222. if ( instance._init ) {
  223. instance._init();
  224. }
  225. } else {
  226. $.data( this, fullName, new object( options, this ) );
  227. }
  228. } );
  229. }
  230. return returnValue;
  231. };
  232. };
  233. $.Widget = function( /* options, element */ ) {};
  234. $.Widget._childConstructors = [];
  235. $.Widget.prototype = {
  236. widgetName: "widget",
  237. widgetEventPrefix: "",
  238. defaultElement: "<div>",
  239. options: {
  240. classes: {},
  241. disabled: false,
  242. // Callbacks
  243. create: null
  244. },
  245. _createWidget: function( options, element ) {
  246. element = $( element || this.defaultElement || this )[ 0 ];
  247. this.element = $( element );
  248. this.uuid = widgetUuid++;
  249. this.eventNamespace = "." + this.widgetName + this.uuid;
  250. this.bindings = $();
  251. this.hoverable = $();
  252. this.focusable = $();
  253. this.classesElementLookup = {};
  254. if ( element !== this ) {
  255. $.data( element, this.widgetFullName, this );
  256. this._on( true, this.element, {
  257. remove: function( event ) {
  258. if ( event.target === element ) {
  259. this.destroy();
  260. }
  261. }
  262. } );
  263. this.document = $( element.style ?
  264. // Element within the document
  265. element.ownerDocument :
  266. // Element is window or document
  267. element.document || element );
  268. this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
  269. }
  270. this.options = $.widget.extend( {},
  271. this.options,
  272. this._getCreateOptions(),
  273. options );
  274. this._create();
  275. if ( this.options.disabled ) {
  276. this._setOptionDisabled( this.options.disabled );
  277. }
  278. this._trigger( "create", null, this._getCreateEventData() );
  279. this._init();
  280. },
  281. _getCreateOptions: function() {
  282. return {};
  283. },
  284. _getCreateEventData: $.noop,
  285. _create: $.noop,
  286. _init: $.noop,
  287. destroy: function() {
  288. var that = this;
  289. this._destroy();
  290. $.each( this.classesElementLookup, function( key, value ) {
  291. that._removeClass( value, key );
  292. } );
  293. // We can probably remove the unbind calls in 2.0
  294. // all event bindings should go through this._on()
  295. this.element
  296. .off( this.eventNamespace )
  297. .removeData( this.widgetFullName );
  298. this.widget()
  299. .off( this.eventNamespace )
  300. .removeAttr( "aria-disabled" );
  301. // Clean up events and states
  302. this.bindings.off( this.eventNamespace );
  303. },
  304. _destroy: $.noop,
  305. widget: function() {
  306. return this.element;
  307. },
  308. option: function( key, value ) {
  309. var options = key;
  310. var parts;
  311. var curOption;
  312. var i;
  313. if ( arguments.length === 0 ) {
  314. // Don't return a reference to the internal hash
  315. return $.widget.extend( {}, this.options );
  316. }
  317. if ( typeof key === "string" ) {
  318. // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  319. options = {};
  320. parts = key.split( "." );
  321. key = parts.shift();
  322. if ( parts.length ) {
  323. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  324. for ( i = 0; i < parts.length - 1; i++ ) {
  325. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  326. curOption = curOption[ parts[ i ] ];
  327. }
  328. key = parts.pop();
  329. if ( arguments.length === 1 ) {
  330. return curOption[ key ] === undefined ? null : curOption[ key ];
  331. }
  332. curOption[ key ] = value;
  333. } else {
  334. if ( arguments.length === 1 ) {
  335. return this.options[ key ] === undefined ? null : this.options[ key ];
  336. }
  337. options[ key ] = value;
  338. }
  339. }
  340. this._setOptions( options );
  341. return this;
  342. },
  343. _setOptions: function( options ) {
  344. var key;
  345. for ( key in options ) {
  346. this._setOption( key, options[ key ] );
  347. }
  348. return this;
  349. },
  350. _setOption: function( key, value ) {
  351. if ( key === "classes" ) {
  352. this._setOptionClasses( value );
  353. }
  354. this.options[ key ] = value;
  355. if ( key === "disabled" ) {
  356. this._setOptionDisabled( value );
  357. }
  358. return this;
  359. },
  360. _setOptionClasses: function( value ) {
  361. var classKey, elements, currentElements;
  362. for ( classKey in value ) {
  363. currentElements = this.classesElementLookup[ classKey ];
  364. if ( value[ classKey ] === this.options.classes[ classKey ] ||
  365. !currentElements ||
  366. !currentElements.length ) {
  367. continue;
  368. }
  369. // We are doing this to create a new jQuery object because the _removeClass() call
  370. // on the next line is going to destroy the reference to the current elements being
  371. // tracked. We need to save a copy of this collection so that we can add the new classes
  372. // below.
  373. elements = $( currentElements.get() );
  374. this._removeClass( currentElements, classKey );
  375. // We don't use _addClass() here, because that uses this.options.classes
  376. // for generating the string of classes. We want to use the value passed in from
  377. // _setOption(), this is the new value of the classes option which was passed to
  378. // _setOption(). We pass this value directly to _classes().
  379. elements.addClass( this._classes( {
  380. element: elements,
  381. keys: classKey,
  382. classes: value,
  383. add: true
  384. } ) );
  385. }
  386. },
  387. _setOptionDisabled: function( value ) {
  388. this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
  389. // If the widget is becoming disabled, then nothing is interactive
  390. if ( value ) {
  391. this._removeClass( this.hoverable, null, "ui-state-hover" );
  392. this._removeClass( this.focusable, null, "ui-state-focus" );
  393. }
  394. },
  395. enable: function() {
  396. return this._setOptions( { disabled: false } );
  397. },
  398. disable: function() {
  399. return this._setOptions( { disabled: true } );
  400. },
  401. _classes: function( options ) {
  402. var full = [];
  403. var that = this;
  404. options = $.extend( {
  405. element: this.element,
  406. classes: this.options.classes || {}
  407. }, options );
  408. function processClassString( classes, checkOption ) {
  409. var current, i;
  410. for ( i = 0; i < classes.length; i++ ) {
  411. current = that.classesElementLookup[ classes[ i ] ] || $();
  412. if ( options.add ) {
  413. current = $( $.unique( current.get().concat( options.element.get() ) ) );
  414. } else {
  415. current = $( current.not( options.element ).get() );
  416. }
  417. that.classesElementLookup[ classes[ i ] ] = current;
  418. full.push( classes[ i ] );
  419. if ( checkOption && options.classes[ classes[ i ] ] ) {
  420. full.push( options.classes[ classes[ i ] ] );
  421. }
  422. }
  423. }
  424. this._on( options.element, {
  425. "remove": "_untrackClassesElement"
  426. } );
  427. if ( options.keys ) {
  428. processClassString( options.keys.match( /\S+/g ) || [], true );
  429. }
  430. if ( options.extra ) {
  431. processClassString( options.extra.match( /\S+/g ) || [] );
  432. }
  433. return full.join( " " );
  434. },
  435. _untrackClassesElement: function( event ) {
  436. var that = this;
  437. $.each( that.classesElementLookup, function( key, value ) {
  438. if ( $.inArray( event.target, value ) !== -1 ) {
  439. that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
  440. }
  441. } );
  442. },
  443. _removeClass: function( element, keys, extra ) {
  444. return this._toggleClass( element, keys, extra, false );
  445. },
  446. _addClass: function( element, keys, extra ) {
  447. return this._toggleClass( element, keys, extra, true );
  448. },
  449. _toggleClass: function( element, keys, extra, add ) {
  450. add = ( typeof add === "boolean" ) ? add : extra;
  451. var shift = ( typeof element === "string" || element === null ),
  452. options = {
  453. extra: shift ? keys : extra,
  454. keys: shift ? element : keys,
  455. element: shift ? this.element : element,
  456. add: add
  457. };
  458. options.element.toggleClass( this._classes( options ), add );
  459. return this;
  460. },
  461. _on: function( suppressDisabledCheck, element, handlers ) {
  462. var delegateElement;
  463. var instance = this;
  464. // No suppressDisabledCheck flag, shuffle arguments
  465. if ( typeof suppressDisabledCheck !== "boolean" ) {
  466. handlers = element;
  467. element = suppressDisabledCheck;
  468. suppressDisabledCheck = false;
  469. }
  470. // No element argument, shuffle and use this.element
  471. if ( !handlers ) {
  472. handlers = element;
  473. element = this.element;
  474. delegateElement = this.widget();
  475. } else {
  476. element = delegateElement = $( element );
  477. this.bindings = this.bindings.add( element );
  478. }
  479. $.each( handlers, function( event, handler ) {
  480. function handlerProxy() {
  481. // Allow widgets to customize the disabled handling
  482. // - disabled as an array instead of boolean
  483. // - disabled class as method for disabling individual parts
  484. if ( !suppressDisabledCheck &&
  485. ( instance.options.disabled === true ||
  486. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  487. return;
  488. }
  489. return ( typeof handler === "string" ? instance[ handler ] : handler )
  490. .apply( instance, arguments );
  491. }
  492. // Copy the guid so direct unbinding works
  493. if ( typeof handler !== "string" ) {
  494. handlerProxy.guid = handler.guid =
  495. handler.guid || handlerProxy.guid || $.guid++;
  496. }
  497. var match = event.match( /^([\w:-]*)\s*(.*)$/ );
  498. var eventName = match[ 1 ] + instance.eventNamespace;
  499. var selector = match[ 2 ];
  500. if ( selector ) {
  501. delegateElement.on( eventName, selector, handlerProxy );
  502. } else {
  503. element.on( eventName, handlerProxy );
  504. }
  505. } );
  506. },
  507. _off: function( element, eventName ) {
  508. eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
  509. this.eventNamespace;
  510. element.off( eventName ).off( eventName );
  511. // Clear the stack to avoid memory leaks (#10056)
  512. this.bindings = $( this.bindings.not( element ).get() );
  513. this.focusable = $( this.focusable.not( element ).get() );
  514. this.hoverable = $( this.hoverable.not( element ).get() );
  515. },
  516. _delay: function( handler, delay ) {
  517. function handlerProxy() {
  518. return ( typeof handler === "string" ? instance[ handler ] : handler )
  519. .apply( instance, arguments );
  520. }
  521. var instance = this;
  522. return setTimeout( handlerProxy, delay || 0 );
  523. },
  524. _hoverable: function( element ) {
  525. this.hoverable = this.hoverable.add( element );
  526. this._on( element, {
  527. mouseenter: function( event ) {
  528. this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
  529. },
  530. mouseleave: function( event ) {
  531. this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
  532. }
  533. } );
  534. },
  535. _focusable: function( element ) {
  536. this.focusable = this.focusable.add( element );
  537. this._on( element, {
  538. focusin: function( event ) {
  539. this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
  540. },
  541. focusout: function( event ) {
  542. this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
  543. }
  544. } );
  545. },
  546. _trigger: function( type, event, data ) {
  547. var prop, orig;
  548. var callback = this.options[ type ];
  549. data = data || {};
  550. event = $.Event( event );
  551. event.type = ( type === this.widgetEventPrefix ?
  552. type :
  553. this.widgetEventPrefix + type ).toLowerCase();
  554. // The original event may come from any element
  555. // so we need to reset the target on the new event
  556. event.target = this.element[ 0 ];
  557. // Copy original event properties over to the new event
  558. orig = event.originalEvent;
  559. if ( orig ) {
  560. for ( prop in orig ) {
  561. if ( !( prop in event ) ) {
  562. event[ prop ] = orig[ prop ];
  563. }
  564. }
  565. }
  566. this.element.trigger( event, data );
  567. return !( $.isFunction( callback ) &&
  568. callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
  569. event.isDefaultPrevented() );
  570. }
  571. };
  572. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  573. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  574. if ( typeof options === "string" ) {
  575. options = { effect: options };
  576. }
  577. var hasOptions;
  578. var effectName = !options ?
  579. method :
  580. options === true || typeof options === "number" ?
  581. defaultEffect :
  582. options.effect || defaultEffect;
  583. options = options || {};
  584. if ( typeof options === "number" ) {
  585. options = { duration: options };
  586. }
  587. hasOptions = !$.isEmptyObject( options );
  588. options.complete = callback;
  589. if ( options.delay ) {
  590. element.delay( options.delay );
  591. }
  592. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  593. element[ method ]( options );
  594. } else if ( effectName !== method && element[ effectName ] ) {
  595. element[ effectName ]( options.duration, options.easing, callback );
  596. } else {
  597. element.queue( function( next ) {
  598. $( this )[ method ]();
  599. if ( callback ) {
  600. callback.call( element[ 0 ] );
  601. }
  602. next();
  603. } );
  604. }
  605. };
  606. } );
  607. var widget = $.widget;
  608. /*!
  609. * jQuery UI :data 1.12.1
  610. * http://jqueryui.com
  611. *
  612. * Copyright jQuery Foundation and other contributors
  613. * Released under the MIT license.
  614. * http://jquery.org/license
  615. */
  616. //>>label: :data Selector
  617. //>>group: Core
  618. //>>description: Selects elements which have data stored under the specified key.
  619. //>>docs: http://api.jqueryui.com/data-selector/
  620. var data = $.extend( $.expr[ ":" ], {
  621. data: $.expr.createPseudo ?
  622. $.expr.createPseudo( function( dataName ) {
  623. return function( elem ) {
  624. return !!$.data( elem, dataName );
  625. };
  626. } ) :
  627. // Support: jQuery <1.8
  628. function( elem, i, match ) {
  629. return !!$.data( elem, match[ 3 ] );
  630. }
  631. } );
  632. /*!
  633. * jQuery UI Scroll Parent 1.12.1
  634. * http://jqueryui.com
  635. *
  636. * Copyright jQuery Foundation and other contributors
  637. * Released under the MIT license.
  638. * http://jquery.org/license
  639. */
  640. //>>label: scrollParent
  641. //>>group: Core
  642. //>>description: Get the closest ancestor element that is scrollable.
  643. //>>docs: http://api.jqueryui.com/scrollParent/
  644. var scrollParent = $.fn.scrollParent = function( includeHidden ) {
  645. var position = this.css( "position" ),
  646. excludeStaticParent = position === "absolute",
  647. overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
  648. scrollParent = this.parents().filter( function() {
  649. var parent = $( this );
  650. if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
  651. return false;
  652. }
  653. return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
  654. parent.css( "overflow-x" ) );
  655. } ).eq( 0 );
  656. return position === "fixed" || !scrollParent.length ?
  657. $( this[ 0 ].ownerDocument || document ) :
  658. scrollParent;
  659. };
  660. // This file is deprecated
  661. var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
  662. /*!
  663. * jQuery UI Mouse 1.12.1
  664. * http://jqueryui.com
  665. *
  666. * Copyright jQuery Foundation and other contributors
  667. * Released under the MIT license.
  668. * http://jquery.org/license
  669. */
  670. //>>label: Mouse
  671. //>>group: Widgets
  672. //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
  673. //>>docs: http://api.jqueryui.com/mouse/
  674. var mouseHandled = false;
  675. $( document ).on( "mouseup", function() {
  676. mouseHandled = false;
  677. } );
  678. var widgetsMouse = $.widget( "ui.mouse", {
  679. version: "1.12.1",
  680. options: {
  681. cancel: "input, textarea, button, select, option",
  682. distance: 1,
  683. delay: 0
  684. },
  685. _mouseInit: function() {
  686. var that = this;
  687. this.element
  688. .on( "mousedown." + this.widgetName, function( event ) {
  689. return that._mouseDown( event );
  690. } )
  691. .on( "click." + this.widgetName, function( event ) {
  692. if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
  693. $.removeData( event.target, that.widgetName + ".preventClickEvent" );
  694. event.stopImmediatePropagation();
  695. return false;
  696. }
  697. } );
  698. this.started = false;
  699. },
  700. // TODO: make sure destroying one instance of mouse doesn't mess with
  701. // other instances of mouse
  702. _mouseDestroy: function() {
  703. this.element.off( "." + this.widgetName );
  704. if ( this._mouseMoveDelegate ) {
  705. this.document
  706. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  707. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  708. }
  709. },
  710. _mouseDown: function( event ) {
  711. // don't let more than one widget handle mouseStart
  712. if ( mouseHandled ) {
  713. return;
  714. }
  715. this._mouseMoved = false;
  716. // We may have missed mouseup (out of window)
  717. ( this._mouseStarted && this._mouseUp( event ) );
  718. this._mouseDownEvent = event;
  719. var that = this,
  720. btnIsLeft = ( event.which === 1 ),
  721. // event.target.nodeName works around a bug in IE 8 with
  722. // disabled inputs (#7620)
  723. elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
  724. $( event.target ).closest( this.options.cancel ).length : false );
  725. if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
  726. return true;
  727. }
  728. this.mouseDelayMet = !this.options.delay;
  729. if ( !this.mouseDelayMet ) {
  730. this._mouseDelayTimer = setTimeout( function() {
  731. that.mouseDelayMet = true;
  732. }, this.options.delay );
  733. }
  734. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  735. this._mouseStarted = ( this._mouseStart( event ) !== false );
  736. if ( !this._mouseStarted ) {
  737. event.preventDefault();
  738. return true;
  739. }
  740. }
  741. // Click event may never have fired (Gecko & Opera)
  742. if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
  743. $.removeData( event.target, this.widgetName + ".preventClickEvent" );
  744. }
  745. // These delegates are required to keep context
  746. this._mouseMoveDelegate = function( event ) {
  747. return that._mouseMove( event );
  748. };
  749. this._mouseUpDelegate = function( event ) {
  750. return that._mouseUp( event );
  751. };
  752. this.document
  753. .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  754. .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
  755. event.preventDefault();
  756. mouseHandled = true;
  757. return true;
  758. },
  759. _mouseMove: function( event ) {
  760. // Only check for mouseups outside the document if you've moved inside the document
  761. // at least once. This prevents the firing of mouseup in the case of IE<9, which will
  762. // fire a mousemove event if content is placed under the cursor. See #7778
  763. // Support: IE <9
  764. if ( this._mouseMoved ) {
  765. // IE mouseup check - mouseup happened when mouse was out of window
  766. if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
  767. !event.button ) {
  768. return this._mouseUp( event );
  769. // Iframe mouseup check - mouseup occurred in another document
  770. } else if ( !event.which ) {
  771. // Support: Safari <=8 - 9
  772. // Safari sets which to 0 if you press any of the following keys
  773. // during a drag (#14461)
  774. if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
  775. event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
  776. this.ignoreMissingWhich = true;
  777. } else if ( !this.ignoreMissingWhich ) {
  778. return this._mouseUp( event );
  779. }
  780. }
  781. }
  782. if ( event.which || event.button ) {
  783. this._mouseMoved = true;
  784. }
  785. if ( this._mouseStarted ) {
  786. this._mouseDrag( event );
  787. return event.preventDefault();
  788. }
  789. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  790. this._mouseStarted =
  791. ( this._mouseStart( this._mouseDownEvent, event ) !== false );
  792. ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
  793. }
  794. return !this._mouseStarted;
  795. },
  796. _mouseUp: function( event ) {
  797. this.document
  798. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  799. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  800. if ( this._mouseStarted ) {
  801. this._mouseStarted = false;
  802. if ( event.target === this._mouseDownEvent.target ) {
  803. $.data( event.target, this.widgetName + ".preventClickEvent", true );
  804. }
  805. this._mouseStop( event );
  806. }
  807. if ( this._mouseDelayTimer ) {
  808. clearTimeout( this._mouseDelayTimer );
  809. delete this._mouseDelayTimer;
  810. }
  811. this.ignoreMissingWhich = false;
  812. mouseHandled = false;
  813. event.preventDefault();
  814. },
  815. _mouseDistanceMet: function( event ) {
  816. return ( Math.max(
  817. Math.abs( this._mouseDownEvent.pageX - event.pageX ),
  818. Math.abs( this._mouseDownEvent.pageY - event.pageY )
  819. ) >= this.options.distance
  820. );
  821. },
  822. _mouseDelayMet: function( /* event */ ) {
  823. return this.mouseDelayMet;
  824. },
  825. // These are placeholder methods, to be overriden by extending plugin
  826. _mouseStart: function( /* event */ ) {},
  827. _mouseDrag: function( /* event */ ) {},
  828. _mouseStop: function( /* event */ ) {},
  829. _mouseCapture: function( /* event */ ) { return true; }
  830. } );
  831. // $.ui.plugin is deprecated. Use $.widget() extensions instead.
  832. var plugin = $.ui.plugin = {
  833. add: function( module, option, set ) {
  834. var i,
  835. proto = $.ui[ module ].prototype;
  836. for ( i in set ) {
  837. proto.plugins[ i ] = proto.plugins[ i ] || [];
  838. proto.plugins[ i ].push( [ option, set[ i ] ] );
  839. }
  840. },
  841. call: function( instance, name, args, allowDisconnected ) {
  842. var i,
  843. set = instance.plugins[ name ];
  844. if ( !set ) {
  845. return;
  846. }
  847. if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
  848. instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
  849. return;
  850. }
  851. for ( i = 0; i < set.length; i++ ) {
  852. if ( instance.options[ set[ i ][ 0 ] ] ) {
  853. set[ i ][ 1 ].apply( instance.element, args );
  854. }
  855. }
  856. }
  857. };
  858. var safeActiveElement = $.ui.safeActiveElement = function( document ) {
  859. var activeElement;
  860. // Support: IE 9 only
  861. // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
  862. try {
  863. activeElement = document.activeElement;
  864. } catch ( error ) {
  865. activeElement = document.body;
  866. }
  867. // Support: IE 9 - 11 only
  868. // IE may return null instead of an element
  869. // Interestingly, this only seems to occur when NOT in an iframe
  870. if ( !activeElement ) {
  871. activeElement = document.body;
  872. }
  873. // Support: IE 11 only
  874. // IE11 returns a seemingly empty object in some cases when accessing
  875. // document.activeElement from an <iframe>
  876. if ( !activeElement.nodeName ) {
  877. activeElement = document.body;
  878. }
  879. return activeElement;
  880. };
  881. var safeBlur = $.ui.safeBlur = function( element ) {
  882. // Support: IE9 - 10 only
  883. // If the <body> is blurred, IE will switch windows, see #9420
  884. if ( element && element.nodeName.toLowerCase() !== "body" ) {
  885. $( element ).trigger( "blur" );
  886. }
  887. };
  888. /*!
  889. * jQuery UI Draggable 1.12.1
  890. * http://jqueryui.com
  891. *
  892. * Copyright jQuery Foundation and other contributors
  893. * Released under the MIT license.
  894. * http://jquery.org/license
  895. */
  896. //>>label: Draggable
  897. //>>group: Interactions
  898. //>>description: Enables dragging functionality for any element.
  899. //>>docs: http://api.jqueryui.com/draggable/
  900. //>>demos: http://jqueryui.com/draggable/
  901. //>>css.structure: ../../themes/base/draggable.css
  902. $.widget( "ui.draggable", $.ui.mouse, {
  903. version: "1.12.1",
  904. widgetEventPrefix: "drag",
  905. options: {
  906. addClasses: true,
  907. appendTo: "parent",
  908. axis: false,
  909. connectToSortable: false,
  910. containment: false,
  911. cursor: "auto",
  912. cursorAt: false,
  913. grid: false,
  914. handle: false,
  915. helper: "original",
  916. iframeFix: false,
  917. opacity: false,
  918. refreshPositions: false,
  919. revert: false,
  920. revertDuration: 500,
  921. scope: "default",
  922. scroll: true,
  923. scrollSensitivity: 20,
  924. scrollSpeed: 20,
  925. snap: false,
  926. snapMode: "both",
  927. snapTolerance: 20,
  928. stack: false,
  929. zIndex: false,
  930. // Callbacks
  931. drag: null,
  932. start: null,
  933. stop: null
  934. },
  935. _create: function() {
  936. if ( this.options.helper === "original" ) {
  937. this._setPositionRelative();
  938. }
  939. if ( this.options.addClasses ) {
  940. this._addClass( "ui-draggable" );
  941. }
  942. this._setHandleClassName();
  943. this._mouseInit();
  944. },
  945. _setOption: function( key, value ) {
  946. this._super( key, value );
  947. if ( key === "handle" ) {
  948. this._removeHandleClassName();
  949. this._setHandleClassName();
  950. }
  951. },
  952. _destroy: function() {
  953. if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
  954. this.destroyOnClear = true;
  955. return;
  956. }
  957. this._removeHandleClassName();
  958. this._mouseDestroy();
  959. },
  960. _mouseCapture: function( event ) {
  961. var o = this.options;
  962. // Among others, prevent a drag on a resizable-handle
  963. if ( this.helper || o.disabled ||
  964. $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
  965. return false;
  966. }
  967. //Quit if we're not on a valid handle
  968. this.handle = this._getHandle( event );
  969. if ( !this.handle ) {
  970. return false;
  971. }
  972. this._blurActiveElement( event );
  973. this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
  974. return true;
  975. },
  976. _blockFrames: function( selector ) {
  977. this.iframeBlocks = this.document.find( selector ).map( function() {
  978. var iframe = $( this );
  979. return $( "<div>" )
  980. .css( "position", "absolute" )
  981. .appendTo( iframe.parent() )
  982. .outerWidth( iframe.outerWidth() )
  983. .outerHeight( iframe.outerHeight() )
  984. .offset( iframe.offset() )[ 0 ];
  985. } );
  986. },
  987. _unblockFrames: function() {
  988. if ( this.iframeBlocks ) {
  989. this.iframeBlocks.remove();
  990. delete this.iframeBlocks;
  991. }
  992. },
  993. _blurActiveElement: function( event ) {
  994. var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
  995. target = $( event.target );
  996. // Don't blur if the event occurred on an element that is within
  997. // the currently focused element
  998. // See #10527, #12472
  999. if ( target.closest( activeElement ).length ) {
  1000. return;
  1001. }
  1002. // Blur any element that currently has focus, see #4261
  1003. $.ui.safeBlur( activeElement );
  1004. },
  1005. _mouseStart: function( event ) {
  1006. var o = this.options;
  1007. //Create and append the visible helper
  1008. this.helper = this._createHelper( event );
  1009. this._addClass( this.helper, "ui-draggable-dragging" );
  1010. //Cache the helper size
  1011. this._cacheHelperProportions();
  1012. //If ddmanager is used for droppables, set the global draggable
  1013. if ( $.ui.ddmanager ) {
  1014. $.ui.ddmanager.current = this;
  1015. }
  1016. /*
  1017. * - Position generation -
  1018. * This block generates everything position related - it's the core of draggables.
  1019. */
  1020. //Cache the margins of the original element
  1021. this._cacheMargins();
  1022. //Store the helper's css position
  1023. this.cssPosition = this.helper.css( "position" );
  1024. this.scrollParent = this.helper.scrollParent( true );
  1025. this.offsetParent = this.helper.offsetParent();
  1026. this.hasFixedAncestor = this.helper.parents().filter( function() {
  1027. return $( this ).css( "position" ) === "fixed";
  1028. } ).length > 0;
  1029. //The element's absolute position on the page minus margins
  1030. this.positionAbs = this.element.offset();
  1031. this._refreshOffsets( event );
  1032. //Generate the original position
  1033. this.originalPosition = this.position = this._generatePosition( event, false );
  1034. this.originalPageX = event.pageX;
  1035. this.originalPageY = event.pageY;
  1036. //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
  1037. ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
  1038. //Set a containment if given in the options
  1039. this._setContainment();
  1040. //Trigger event + callbacks
  1041. if ( this._trigger( "start", event ) === false ) {
  1042. this._clear();
  1043. return false;
  1044. }
  1045. //Recache the helper size
  1046. this._cacheHelperProportions();
  1047. //Prepare the droppable offsets
  1048. if ( $.ui.ddmanager && !o.dropBehaviour ) {
  1049. $.ui.ddmanager.prepareOffsets( this, event );
  1050. }
  1051. // Execute the drag once - this causes the helper not to be visible before getting its
  1052. // correct position
  1053. this._mouseDrag( event, true );
  1054. // If the ddmanager is used for droppables, inform the manager that dragging has started
  1055. // (see #5003)
  1056. if ( $.ui.ddmanager ) {
  1057. $.ui.ddmanager.dragStart( this, event );
  1058. }
  1059. return true;
  1060. },
  1061. _refreshOffsets: function( event ) {
  1062. this.offset = {
  1063. top: this.positionAbs.top - this.margins.top,
  1064. left: this.positionAbs.left - this.margins.left,
  1065. scroll: false,
  1066. parent: this._getParentOffset(),
  1067. relative: this._getRelativeOffset()
  1068. };
  1069. this.offset.click = {
  1070. left: event.pageX - this.offset.left,
  1071. top: event.pageY - this.offset.top
  1072. };
  1073. },
  1074. _mouseDrag: function( event, noPropagation ) {
  1075. // reset any necessary cached properties (see #5009)
  1076. if ( this.hasFixedAncestor ) {
  1077. this.offset.parent = this._getParentOffset();
  1078. }
  1079. //Compute the helpers position
  1080. this.position = this._generatePosition( event, true );
  1081. this.positionAbs = this._convertPositionTo( "absolute" );
  1082. //Call plugins and callbacks and use the resulting position if something is returned
  1083. if ( !noPropagation ) {
  1084. var ui = this._uiHash();
  1085. if ( this._trigger( "drag", event, ui ) === false ) {
  1086. this._mouseUp( new $.Event( "mouseup", event ) );
  1087. return false;
  1088. }
  1089. this.position = ui.position;
  1090. }
  1091. this.helper[ 0 ].style.left = this.position.left + "px";
  1092. this.helper[ 0 ].style.top = this.position.top + "px";
  1093. if ( $.ui.ddmanager ) {
  1094. $.ui.ddmanager.drag( this, event );
  1095. }
  1096. return false;
  1097. },
  1098. _mouseStop: function( event ) {
  1099. //If we are using droppables, inform the manager about the drop
  1100. var that = this,
  1101. dropped = false;
  1102. if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
  1103. dropped = $.ui.ddmanager.drop( this, event );
  1104. }
  1105. //if a drop comes from outside (a sortable)
  1106. if ( this.dropped ) {
  1107. dropped = this.dropped;
  1108. this.dropped = false;
  1109. }
  1110. if ( ( this.options.revert === "invalid" && !dropped ) ||
  1111. ( this.options.revert === "valid" && dropped ) ||
  1112. this.options.revert === true || ( $.isFunction( this.options.revert ) &&
  1113. this.options.revert.call( this.element, dropped ) )
  1114. ) {
  1115. $( this.helper ).animate(
  1116. this.originalPosition,
  1117. parseInt( this.options.revertDuration, 10 ),
  1118. function() {
  1119. if ( that._trigger( "stop", event ) !== false ) {
  1120. that._clear();
  1121. }
  1122. }
  1123. );
  1124. } else {
  1125. if ( this._trigger( "stop", event ) !== false ) {
  1126. this._clear();
  1127. }
  1128. }
  1129. return false;
  1130. },
  1131. _mouseUp: function( event ) {
  1132. this._unblockFrames();
  1133. // If the ddmanager is used for droppables, inform the manager that dragging has stopped
  1134. // (see #5003)
  1135. if ( $.ui.ddmanager ) {
  1136. $.ui.ddmanager.dragStop( this, event );
  1137. }
  1138. // Only need to focus if the event occurred on the draggable itself, see #10527
  1139. if ( this.handleElement.is( event.target ) ) {
  1140. // The interaction is over; whether or not the click resulted in a drag,
  1141. // focus the element
  1142. this.element.trigger( "focus" );
  1143. }
  1144. return $.ui.mouse.prototype._mouseUp.call( this, event );
  1145. },
  1146. cancel: function() {
  1147. if ( this.helper.is( ".ui-draggable-dragging" ) ) {
  1148. this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
  1149. } else {
  1150. this._clear();
  1151. }
  1152. return this;
  1153. },
  1154. _getHandle: function( event ) {
  1155. return this.options.handle ?
  1156. !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
  1157. true;
  1158. },
  1159. _setHandleClassName: function() {
  1160. this.handleElement = this.options.handle ?
  1161. this.element.find( this.options.handle ) : this.element;
  1162. this._addClass( this.handleElement, "ui-draggable-handle" );
  1163. },
  1164. _removeHandleClassName: function() {
  1165. this._removeClass( this.handleElement, "ui-draggable-handle" );
  1166. },
  1167. _createHelper: function( event ) {
  1168. var o = this.options,
  1169. helperIsFunction = $.isFunction( o.helper ),
  1170. helper = helperIsFunction ?
  1171. $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
  1172. ( o.helper === "clone" ?
  1173. this.element.clone().removeAttr( "id" ) :
  1174. this.element );
  1175. if ( !helper.parents( "body" ).length ) {
  1176. helper.appendTo( ( o.appendTo === "parent" ?
  1177. this.element[ 0 ].parentNode :
  1178. o.appendTo ) );
  1179. }
  1180. // Http://bugs.jqueryui.com/ticket/9446
  1181. // a helper function can return the original element
  1182. // which wouldn't have been set to relative in _create
  1183. if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
  1184. this._setPositionRelative();
  1185. }
  1186. if ( helper[ 0 ] !== this.element[ 0 ] &&
  1187. !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
  1188. helper.css( "position", "absolute" );
  1189. }
  1190. return helper;
  1191. },
  1192. _setPositionRelative: function() {
  1193. if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
  1194. this.element[ 0 ].style.position = "relative";
  1195. }
  1196. },
  1197. _adjustOffsetFromHelper: function( obj ) {
  1198. if ( typeof obj === "string" ) {
  1199. obj = obj.split( " " );
  1200. }
  1201. if ( $.isArray( obj ) ) {
  1202. obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
  1203. }
  1204. if ( "left" in obj ) {
  1205. this.offset.click.left = obj.left + this.margins.left;
  1206. }
  1207. if ( "right" in obj ) {
  1208. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  1209. }
  1210. if ( "top" in obj ) {
  1211. this.offset.click.top = obj.top + this.margins.top;
  1212. }
  1213. if ( "bottom" in obj ) {
  1214. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  1215. }
  1216. },
  1217. _isRootNode: function( element ) {
  1218. return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
  1219. },
  1220. _getParentOffset: function() {
  1221. //Get the offsetParent and cache its position
  1222. var po = this.offsetParent.offset(),
  1223. document = this.document[ 0 ];
  1224. // This is a special case where we need to modify a offset calculated on start, since the
  1225. // following happened:
  1226. // 1. The position of the helper is absolute, so it's position is calculated based on the
  1227. // next positioned parent
  1228. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
  1229. // the document, which means that the scroll is included in the initial calculation of the
  1230. // offset of the parent, and never recalculated upon drag
  1231. if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
  1232. $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
  1233. po.left += this.scrollParent.scrollLeft();
  1234. po.top += this.scrollParent.scrollTop();
  1235. }
  1236. if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
  1237. po = { top: 0, left: 0 };
  1238. }
  1239. return {
  1240. top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
  1241. left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
  1242. };
  1243. },
  1244. _getRelativeOffset: function() {
  1245. if ( this.cssPosition !== "relative" ) {
  1246. return { top: 0, left: 0 };
  1247. }
  1248. var p = this.element.position(),
  1249. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
  1250. return {
  1251. top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
  1252. ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
  1253. left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
  1254. ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
  1255. };
  1256. },
  1257. _cacheMargins: function() {
  1258. this.margins = {
  1259. left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
  1260. top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
  1261. right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
  1262. bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
  1263. };
  1264. },
  1265. _cacheHelperProportions: function() {
  1266. this.helperProportions = {
  1267. width: this.helper.outerWidth(),
  1268. height: this.helper.outerHeight()
  1269. };
  1270. },
  1271. _setContainment: function() {
  1272. var isUserScrollable, c, ce,
  1273. o = this.options,
  1274. document = this.document[ 0 ];
  1275. this.relativeContainer = null;
  1276. if ( !o.containment ) {
  1277. this.containment = null;
  1278. return;
  1279. }
  1280. if ( o.containment === "window" ) {
  1281. this.containment = [
  1282. $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
  1283. $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
  1284. $( window ).scrollLeft() + $( window ).width() -
  1285. this.helperProportions.width - this.margins.left,
  1286. $( window ).scrollTop() +
  1287. ( $( window ).height() || document.body.parentNode.scrollHeight ) -
  1288. this.helperProportions.height - this.margins.top
  1289. ];
  1290. return;
  1291. }
  1292. if ( o.containment === "document" ) {
  1293. this.containment = [
  1294. 0,
  1295. 0,
  1296. $( document ).width() - this.helperProportions.width - this.margins.left,
  1297. ( $( document ).height() || document.body.parentNode.scrollHeight ) -
  1298. this.helperProportions.height - this.margins.top
  1299. ];
  1300. return;
  1301. }
  1302. if ( o.containment.constructor === Array ) {
  1303. this.containment = o.containment;
  1304. return;
  1305. }
  1306. if ( o.containment === "parent" ) {
  1307. o.containment = this.helper[ 0 ].parentNode;
  1308. }
  1309. c = $( o.containment );
  1310. ce = c[ 0 ];
  1311. if ( !ce ) {
  1312. return;
  1313. }
  1314. isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
  1315. this.containment = [
  1316. ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
  1317. ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
  1318. ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
  1319. ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
  1320. ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
  1321. ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
  1322. ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
  1323. this.helperProportions.width -
  1324. this.margins.left -
  1325. this.margins.right,
  1326. ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
  1327. ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
  1328. ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
  1329. this.helperProportions.height -
  1330. this.margins.top -
  1331. this.margins.bottom
  1332. ];
  1333. this.relativeContainer = c;
  1334. },
  1335. _convertPositionTo: function( d, pos ) {
  1336. if ( !pos ) {
  1337. pos = this.position;
  1338. }
  1339. var mod = d === "absolute" ? 1 : -1,
  1340. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
  1341. return {
  1342. top: (
  1343. // The absolute mouse position
  1344. pos.top +
  1345. // Only for relative positioned nodes: Relative offset from element to offset parent
  1346. this.offset.relative.top * mod +
  1347. // The offsetParent's offset without borders (offset + border)
  1348. this.offset.parent.top * mod -
  1349. ( ( this.cssPosition === "fixed" ?
  1350. -this.offset.scroll.top :
  1351. ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
  1352. ),
  1353. left: (
  1354. // The absolute mouse position
  1355. pos.left +
  1356. // Only for relative positioned nodes: Relative offset from element to offset parent
  1357. this.offset.relative.left * mod +
  1358. // The offsetParent's offset without borders (offset + border)
  1359. this.offset.parent.left * mod -
  1360. ( ( this.cssPosition === "fixed" ?
  1361. -this.offset.scroll.left :
  1362. ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
  1363. )
  1364. };
  1365. },
  1366. _generatePosition: function( event, constrainPosition ) {
  1367. var containment, co, top, left,
  1368. o = this.options,
  1369. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
  1370. pageX = event.pageX,
  1371. pageY = event.pageY;
  1372. // Cache the scroll
  1373. if ( !scrollIsRootNode || !this.offset.scroll ) {
  1374. this.offset.scroll = {
  1375. top: this.scrollParent.scrollTop(),
  1376. left: this.scrollParent.scrollLeft()
  1377. };
  1378. }
  1379. /*
  1380. * - Position constraining -
  1381. * Constrain the position to a mix of grid, containment.
  1382. */
  1383. // If we are not dragging yet, we won't check for options
  1384. if ( constrainPosition ) {
  1385. if ( this.containment ) {
  1386. if ( this.relativeContainer ) {
  1387. co = this.relativeContainer.offset();
  1388. containment = [
  1389. this.containment[ 0 ] + co.left,
  1390. this.containment[ 1 ] + co.top,
  1391. this.containment[ 2 ] + co.left,
  1392. this.containment[ 3 ] + co.top
  1393. ];
  1394. } else {
  1395. containment = this.containment;
  1396. }
  1397. if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
  1398. pageX = containment[ 0 ] + this.offset.click.left;
  1399. }
  1400. if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
  1401. pageY = containment[ 1 ] + this.offset.click.top;
  1402. }
  1403. if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
  1404. pageX = containment[ 2 ] + this.offset.click.left;
  1405. }
  1406. if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
  1407. pageY = containment[ 3 ] + this.offset.click.top;
  1408. }
  1409. }
  1410. if ( o.grid ) {
  1411. //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
  1412. // argument errors in IE (see ticket #6950)
  1413. top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
  1414. this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
  1415. pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
  1416. top - this.offset.click.top > containment[ 3 ] ) ?
  1417. top :
  1418. ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
  1419. top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
  1420. left = o.grid[ 0 ] ? this.originalPageX +
  1421. Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
  1422. this.originalPageX;
  1423. pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
  1424. left - this.offset.click.left > containment[ 2 ] ) ?
  1425. left :
  1426. ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
  1427. left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
  1428. }
  1429. if ( o.axis === "y" ) {
  1430. pageX = this.originalPageX;
  1431. }
  1432. if ( o.axis === "x" ) {
  1433. pageY = this.originalPageY;
  1434. }
  1435. }
  1436. return {
  1437. top: (
  1438. // The absolute mouse position
  1439. pageY -
  1440. // Click offset (relative to the element)
  1441. this.offset.click.top -
  1442. // Only for relative positioned nodes: Relative offset from element to offset parent
  1443. this.offset.relative.top -
  1444. // The offsetParent's offset without borders (offset + border)
  1445. this.offset.parent.top +
  1446. ( this.cssPosition === "fixed" ?
  1447. -this.offset.scroll.top :
  1448. ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
  1449. ),
  1450. left: (
  1451. // The absolute mouse position
  1452. pageX -
  1453. // Click offset (relative to the element)
  1454. this.offset.click.left -
  1455. // Only for relative positioned nodes: Relative offset from element to offset parent
  1456. this.offset.relative.left -
  1457. // The offsetParent's offset without borders (offset + border)
  1458. this.offset.parent.left +
  1459. ( this.cssPosition === "fixed" ?
  1460. -this.offset.scroll.left :
  1461. ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
  1462. )
  1463. };
  1464. },
  1465. _clear: function() {
  1466. this._removeClass( this.helper, "ui-draggable-dragging" );
  1467. if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
  1468. this.helper.remove();
  1469. }
  1470. this.helper = null;
  1471. this.cancelHelperRemoval = false;
  1472. if ( this.destroyOnClear ) {
  1473. this.destroy();
  1474. }
  1475. },
  1476. // From now on bulk stuff - mainly helpers
  1477. _trigger: function( type, event, ui ) {
  1478. ui = ui || this._uiHash();
  1479. $.ui.plugin.call( this, type, [ event, ui, this ], true );
  1480. // Absolute position and offset (see #6884 ) have to be recalculated after plugins
  1481. if ( /^(drag|start|stop)/.test( type ) ) {
  1482. this.positionAbs = this._convertPositionTo( "absolute" );
  1483. ui.offset = this.positionAbs;
  1484. }
  1485. return $.Widget.prototype._trigger.call( this, type, event, ui );
  1486. },
  1487. plugins: {},
  1488. _uiHash: function() {
  1489. return {
  1490. helper: this.helper,
  1491. position: this.position,
  1492. originalPosition: this.originalPosition,
  1493. offset: this.positionAbs
  1494. };
  1495. }
  1496. } );
  1497. $.ui.plugin.add( "draggable", "connectToSortable", {
  1498. start: function( event, ui, draggable ) {
  1499. var uiSortable = $.extend( {}, ui, {
  1500. item: draggable.element
  1501. } );
  1502. draggable.sortables = [];
  1503. $( draggable.options.connectToSortable ).each( function() {
  1504. var sortable = $( this ).sortable( "instance" );
  1505. if ( sortable && !sortable.options.disabled ) {
  1506. draggable.sortables.push( sortable );
  1507. // RefreshPositions is called at drag start to refresh the containerCache
  1508. // which is used in drag. This ensures it's initialized and synchronized
  1509. // with any changes that might have happened on the page since initialization.
  1510. sortable.refreshPositions();
  1511. sortable._trigger( "activate", event, uiSortable );
  1512. }
  1513. } );
  1514. },
  1515. stop: function( event, ui, draggable ) {
  1516. var uiSortable = $.extend( {}, ui, {
  1517. item: draggable.element
  1518. } );
  1519. draggable.cancelHelperRemoval = false;
  1520. $.each( draggable.sortables, function() {
  1521. var sortable = this;
  1522. if ( sortable.isOver ) {
  1523. sortable.isOver = 0;
  1524. // Allow this sortable to handle removing the helper
  1525. draggable.cancelHelperRemoval = true;
  1526. sortable.cancelHelperRemoval = false;
  1527. // Use _storedCSS To restore properties in the sortable,
  1528. // as this also handles revert (#9675) since the draggable
  1529. // may have modified them in unexpected ways (#8809)
  1530. sortable._storedCSS = {
  1531. position: sortable.placeholder.css( "position" ),
  1532. top: sortable.placeholder.css( "top" ),
  1533. left: sortable.placeholder.css( "left" )
  1534. };
  1535. sortable._mouseStop( event );
  1536. // Once drag has ended, the sortable should return to using
  1537. // its original helper, not the shared helper from draggable
  1538. sortable.options.helper = sortable.options._helper;
  1539. } else {
  1540. // Prevent this Sortable from removing the helper.
  1541. // However, don't set the draggable to remove the helper
  1542. // either as another connected Sortable may yet handle the removal.
  1543. sortable.cancelHelperRemoval = true;
  1544. sortable._trigger( "deactivate", event, uiSortable );
  1545. }
  1546. } );
  1547. },
  1548. drag: function( event, ui, draggable ) {
  1549. $.each( draggable.sortables, function() {
  1550. var innermostIntersecting = false,
  1551. sortable = this;
  1552. // Copy over variables that sortable's _intersectsWith uses
  1553. sortable.positionAbs = draggable.positionAbs;
  1554. sortable.helperProportions = draggable.helperProportions;
  1555. sortable.offset.click = draggable.offset.click;
  1556. if ( sortable._intersectsWith( sortable.containerCache ) ) {
  1557. innermostIntersecting = true;
  1558. $.each( draggable.sortables, function() {
  1559. // Copy over variables that sortable's _intersectsWith uses
  1560. this.positionAbs = draggable.positionAbs;
  1561. this.helperProportions = draggable.helperProportions;
  1562. this.offset.click = draggable.offset.click;
  1563. if ( this !== sortable &&
  1564. this._intersectsWith( this.containerCache ) &&
  1565. $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
  1566. innermostIntersecting = false;
  1567. }
  1568. return innermostIntersecting;
  1569. } );
  1570. }
  1571. if ( innermostIntersecting ) {
  1572. // If it intersects, we use a little isOver variable and set it once,
  1573. // so that the move-in stuff gets fired only once.
  1574. if ( !sortable.isOver ) {
  1575. sortable.isOver = 1;
  1576. // Store draggable's parent in case we need to reappend to it later.
  1577. draggable._parent = ui.helper.parent();
  1578. sortable.currentItem = ui.helper
  1579. .appendTo( sortable.element )
  1580. .data( "ui-sortable-item", true );
  1581. // Store helper option to later restore it
  1582. sortable.options._helper = sortable.options.helper;
  1583. sortable.options.helper = function() {
  1584. return ui.helper[ 0 ];
  1585. };
  1586. // Fire the start events of the sortable with our passed browser event,
  1587. // and our own helper (so it doesn't create a new one)
  1588. event.target = sortable.currentItem[ 0 ];
  1589. sortable._mouseCapture( event, true );
  1590. sortable._mouseStart( event, true, true );
  1591. // Because the browser event is way off the new appended portlet,
  1592. // modify necessary variables to reflect the changes
  1593. sortable.offset.click.top = draggable.offset.click.top;
  1594. sortable.offset.click.left = draggable.offset.click.left;
  1595. sortable.offset.parent.left -= draggable.offset.parent.left -
  1596. sortable.offset.parent.left;
  1597. sortable.offset.parent.top -= draggable.offset.parent.top -
  1598. sortable.offset.parent.top;
  1599. draggable._trigger( "toSortable", event );
  1600. // Inform draggable that the helper is in a valid drop zone,
  1601. // used solely in the revert option to handle "valid/invalid".
  1602. draggable.dropped = sortable.element;
  1603. // Need to refreshPositions of all sortables in the case that
  1604. // adding to one sortable changes the location of the other sortables (#9675)
  1605. $.each( draggable.sortables, function() {
  1606. this.refreshPositions();
  1607. } );
  1608. // Hack so receive/update callbacks work (mostly)
  1609. draggable.currentItem = draggable.element;
  1610. sortable.fromOutside = draggable;
  1611. }
  1612. if ( sortable.currentItem ) {
  1613. sortable._mouseDrag( event );
  1614. // Copy the sortable's position because the draggable's can potentially reflect
  1615. // a relative position, while sortable is always absolute, which the dragged
  1616. // element has now become. (#8809)
  1617. ui.position = sortable.position;
  1618. }
  1619. } else {
  1620. // If it doesn't intersect with the sortable, and it intersected before,
  1621. // we fake the drag stop of the sortable, but make sure it doesn't remove
  1622. // the helper by using cancelHelperRemoval.
  1623. if ( sortable.isOver ) {
  1624. sortable.isOver = 0;
  1625. sortable.cancelHelperRemoval = true;
  1626. // Calling sortable's mouseStop would trigger a revert,
  1627. // so revert must be temporarily false until after mouseStop is called.
  1628. sortable.options._revert = sortable.options.revert;
  1629. sortable.options.revert = false;
  1630. sortable._trigger( "out", event, sortable._uiHash( sortable ) );
  1631. sortable._mouseStop( event, true );
  1632. // Restore sortable behaviors that were modfied
  1633. // when the draggable entered the sortable area (#9481)
  1634. sortable.options.revert = sortable.options._revert;
  1635. sortable.options.helper = sortable.options._helper;
  1636. if ( sortable.placeholder ) {
  1637. sortable.placeholder.remove();
  1638. }
  1639. // Restore and recalculate the draggable's offset considering the sortable
  1640. // may have modified them in unexpected ways. (#8809, #10669)
  1641. ui.helper.appendTo( draggable._parent );
  1642. draggable._refreshOffsets( event );
  1643. ui.position = draggable._generatePosition( event, true );
  1644. draggable._trigger( "fromSortable", event );
  1645. // Inform draggable that the helper is no longer in a valid drop zone
  1646. draggable.dropped = false;
  1647. // Need to refreshPositions of all sortables just in case removing
  1648. // from one sortable changes the location of other sortables (#9675)
  1649. $.each( draggable.sortables, function() {
  1650. this.refreshPositions();
  1651. } );
  1652. }
  1653. }
  1654. } );
  1655. }
  1656. } );
  1657. $.ui.plugin.add( "draggable", "cursor", {
  1658. start: function( event, ui, instance ) {
  1659. var t = $( "body" ),
  1660. o = instance.options;
  1661. if ( t.css( "cursor" ) ) {
  1662. o._cursor = t.css( "cursor" );
  1663. }
  1664. t.css( "cursor", o.cursor );
  1665. },
  1666. stop: function( event, ui, instance ) {
  1667. var o = instance.options;
  1668. if ( o._cursor ) {
  1669. $( "body" ).css( "cursor", o._cursor );
  1670. }
  1671. }
  1672. } );
  1673. $.ui.plugin.add( "draggable", "opacity", {
  1674. start: function( event, ui, instance ) {
  1675. var t = $( ui.helper ),
  1676. o = instance.options;
  1677. if ( t.css( "opacity" ) ) {
  1678. o._opacity = t.css( "opacity" );
  1679. }
  1680. t.css( "opacity", o.opacity );
  1681. },
  1682. stop: function( event, ui, instance ) {
  1683. var o = instance.options;
  1684. if ( o._opacity ) {
  1685. $( ui.helper ).css( "opacity", o._opacity );
  1686. }
  1687. }
  1688. } );
  1689. $.ui.plugin.add( "draggable", "scroll", {
  1690. start: function( event, ui, i ) {
  1691. if ( !i.scrollParentNotHidden ) {
  1692. i.scrollParentNotHidden = i.helper.scrollParent( false );
  1693. }
  1694. if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
  1695. i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
  1696. i.overflowOffset = i.scrollParentNotHidden.offset();
  1697. }
  1698. },
  1699. drag: function( event, ui, i ) {
  1700. var o = i.options,
  1701. scrolled = false,
  1702. scrollParent = i.scrollParentNotHidden[ 0 ],
  1703. document = i.document[ 0 ];
  1704. if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
  1705. if ( !o.axis || o.axis !== "x" ) {
  1706. if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
  1707. o.scrollSensitivity ) {
  1708. scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
  1709. } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
  1710. scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
  1711. }
  1712. }
  1713. if ( !o.axis || o.axis !== "y" ) {
  1714. if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
  1715. o.scrollSensitivity ) {
  1716. scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
  1717. } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
  1718. scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
  1719. }
  1720. }
  1721. } else {
  1722. if ( !o.axis || o.axis !== "x" ) {
  1723. if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
  1724. scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
  1725. } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
  1726. o.scrollSensitivity ) {
  1727. scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
  1728. }
  1729. }
  1730. if ( !o.axis || o.axis !== "y" ) {
  1731. if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
  1732. scrolled = $( document ).scrollLeft(
  1733. $( document ).scrollLeft() - o.scrollSpeed
  1734. );
  1735. } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
  1736. o.scrollSensitivity ) {
  1737. scrolled = $( document ).scrollLeft(
  1738. $( document ).scrollLeft() + o.scrollSpeed
  1739. );
  1740. }
  1741. }
  1742. }
  1743. if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
  1744. $.ui.ddmanager.prepareOffsets( i, event );
  1745. }
  1746. }
  1747. } );
  1748. $.ui.plugin.add( "draggable", "snap", {
  1749. start: function( event, ui, i ) {
  1750. var o = i.options;
  1751. i.snapElements = [];
  1752. $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
  1753. .each( function() {
  1754. var $t = $( this ),
  1755. $o = $t.offset();
  1756. if ( this !== i.element[ 0 ] ) {
  1757. i.snapElements.push( {
  1758. item: this,
  1759. width: $t.outerWidth(), height: $t.outerHeight(),
  1760. top: $o.top, left: $o.left
  1761. } );
  1762. }
  1763. } );
  1764. },
  1765. drag: function( event, ui, inst ) {
  1766. var ts, bs, ls, rs, l, r, t, b, i, first,
  1767. o = inst.options,
  1768. d = o.snapTolerance,
  1769. x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  1770. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  1771. for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
  1772. l = inst.snapElements[ i ].left - inst.margins.left;
  1773. r = l + inst.snapElements[ i ].width;
  1774. t = inst.snapElements[ i ].top - inst.margins.top;
  1775. b = t + inst.snapElements[ i ].height;
  1776. if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
  1777. !$.contains( inst.snapElements[ i ].item.ownerDocument,
  1778. inst.snapElements[ i ].item ) ) {
  1779. if ( inst.snapElements[ i ].snapping ) {
  1780. ( inst.options.snap.release &&
  1781. inst.options.snap.release.call(
  1782. inst.element,
  1783. event,
  1784. $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
  1785. ) );
  1786. }
  1787. inst.snapElements[ i ].snapping = false;
  1788. continue;
  1789. }
  1790. if ( o.snapMode !== "inner" ) {
  1791. ts = Math.abs( t - y2 ) <= d;
  1792. bs = Math.abs( b - y1 ) <= d;
  1793. ls = Math.abs( l - x2 ) <= d;
  1794. rs = Math.abs( r - x1 ) <= d;
  1795. if ( ts ) {
  1796. ui.position.top = inst._convertPositionTo( "relative", {
  1797. top: t - inst.helperProportions.height,
  1798. left: 0
  1799. } ).top;
  1800. }
  1801. if ( bs ) {
  1802. ui.position.top = inst._convertPositionTo( "relative", {
  1803. top: b,
  1804. left: 0
  1805. } ).top;
  1806. }
  1807. if ( ls ) {
  1808. ui.position.left = inst._convertPositionTo( "relative", {
  1809. top: 0,
  1810. left: l - inst.helperProportions.width
  1811. } ).left;
  1812. }
  1813. if ( rs ) {
  1814. ui.position.left = inst._convertPositionTo( "relative", {
  1815. top: 0,
  1816. left: r
  1817. } ).left;
  1818. }
  1819. }
  1820. first = ( ts || bs || ls || rs );
  1821. if ( o.snapMode !== "outer" ) {
  1822. ts = Math.abs( t - y1 ) <= d;
  1823. bs = Math.abs( b - y2 ) <= d;
  1824. ls = Math.abs( l - x1 ) <= d;
  1825. rs = Math.abs( r - x2 ) <= d;
  1826. if ( ts ) {
  1827. ui.position.top = inst._convertPositionTo( "relative", {
  1828. top: t,
  1829. left: 0
  1830. } ).top;
  1831. }
  1832. if ( bs ) {
  1833. ui.position.top = inst._convertPositionTo( "relative", {
  1834. top: b - inst.helperProportions.height,
  1835. left: 0
  1836. } ).top;
  1837. }
  1838. if ( ls ) {
  1839. ui.position.left = inst._convertPositionTo( "relative", {
  1840. top: 0,
  1841. left: l
  1842. } ).left;
  1843. }
  1844. if ( rs ) {
  1845. ui.position.left = inst._convertPositionTo( "relative", {
  1846. top: 0,
  1847. left: r - inst.helperProportions.width
  1848. } ).left;
  1849. }
  1850. }
  1851. if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
  1852. ( inst.options.snap.snap &&
  1853. inst.options.snap.snap.call(
  1854. inst.element,
  1855. event,
  1856. $.extend( inst._uiHash(), {
  1857. snapItem: inst.snapElements[ i ].item
  1858. } ) ) );
  1859. }
  1860. inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
  1861. }
  1862. }
  1863. } );
  1864. $.ui.plugin.add( "draggable", "stack", {
  1865. start: function( event, ui, instance ) {
  1866. var min,
  1867. o = instance.options,
  1868. group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
  1869. return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
  1870. ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
  1871. } );
  1872. if ( !group.length ) { return; }
  1873. min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
  1874. $( group ).each( function( i ) {
  1875. $( this ).css( "zIndex", min + i );
  1876. } );
  1877. this.css( "zIndex", ( min + group.length ) );
  1878. }
  1879. } );
  1880. $.ui.plugin.add( "draggable", "zIndex", {
  1881. start: function( event, ui, instance ) {
  1882. var t = $( ui.helper ),
  1883. o = instance.options;
  1884. if ( t.css( "zIndex" ) ) {
  1885. o._zIndex = t.css( "zIndex" );
  1886. }
  1887. t.css( "zIndex", o.zIndex );
  1888. },
  1889. stop: function( event, ui, instance ) {
  1890. var o = instance.options;
  1891. if ( o._zIndex ) {
  1892. $( ui.helper ).css( "zIndex", o._zIndex );
  1893. }
  1894. }
  1895. } );
  1896. var widgetsDraggable = $.ui.draggable;
  1897. /*!
  1898. * jQuery UI Droppable 1.12.1
  1899. * http://jqueryui.com
  1900. *
  1901. * Copyright jQuery Foundation and other contributors
  1902. * Released under the MIT license.
  1903. * http://jquery.org/license
  1904. */
  1905. //>>label: Droppable
  1906. //>>group: Interactions
  1907. //>>description: Enables drop targets for draggable elements.
  1908. //>>docs: http://api.jqueryui.com/droppable/
  1909. //>>demos: http://jqueryui.com/droppable/
  1910. $.widget( "ui.droppable", {
  1911. version: "1.12.1",
  1912. widgetEventPrefix: "drop",
  1913. options: {
  1914. accept: "*",
  1915. addClasses: true,
  1916. greedy: false,
  1917. scope: "default",
  1918. tolerance: "intersect",
  1919. // Callbacks
  1920. activate: null,
  1921. deactivate: null,
  1922. drop: null,
  1923. out: null,
  1924. over: null
  1925. },
  1926. _create: function() {
  1927. var proportions,
  1928. o = this.options,
  1929. accept = o.accept;
  1930. this.isover = false;
  1931. this.isout = true;
  1932. this.accept = $.isFunction( accept ) ? accept : function( d ) {
  1933. return d.is( accept );
  1934. };
  1935. this.proportions = function( /* valueToWrite */ ) {
  1936. if ( arguments.length ) {
  1937. // Store the droppable's proportions
  1938. proportions = arguments[ 0 ];
  1939. } else {
  1940. // Retrieve or derive the droppable's proportions
  1941. return proportions ?
  1942. proportions :
  1943. proportions = {
  1944. width: this.element[ 0 ].offsetWidth,
  1945. height: this.element[ 0 ].offsetHeight
  1946. };
  1947. }
  1948. };
  1949. this._addToManager( o.scope );
  1950. o.addClasses && this._addClass( "ui-droppable" );
  1951. },
  1952. _addToManager: function( scope ) {
  1953. // Add the reference and positions to the manager
  1954. $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
  1955. $.ui.ddmanager.droppables[ scope ].push( this );
  1956. },
  1957. _splice: function( drop ) {
  1958. var i = 0;
  1959. for ( ; i < drop.length; i++ ) {
  1960. if ( drop[ i ] === this ) {
  1961. drop.splice( i, 1 );
  1962. }
  1963. }
  1964. },
  1965. _destroy: function() {
  1966. var drop = $.ui.ddmanager.droppables[ this.options.scope ];
  1967. this._splice( drop );
  1968. },
  1969. _setOption: function( key, value ) {
  1970. if ( key === "accept" ) {
  1971. this.accept = $.isFunction( value ) ? value : function( d ) {
  1972. return d.is( value );
  1973. };
  1974. } else if ( key === "scope" ) {
  1975. var drop = $.ui.ddmanager.droppables[ this.options.scope ];
  1976. this._splice( drop );
  1977. this._addToManager( value );
  1978. }
  1979. this._super( key, value );
  1980. },
  1981. _activate: function( event ) {
  1982. var draggable = $.ui.ddmanager.current;
  1983. this._addActiveClass();
  1984. if ( draggable ) {
  1985. this._trigger( "activate", event, this.ui( draggable ) );
  1986. }
  1987. },
  1988. _deactivate: function( event ) {
  1989. var draggable = $.ui.ddmanager.current;
  1990. this._removeActiveClass();
  1991. if ( draggable ) {
  1992. this._trigger( "deactivate", event, this.ui( draggable ) );
  1993. }
  1994. },
  1995. _over: function( event ) {
  1996. var draggable = $.ui.ddmanager.current;
  1997. // Bail if draggable and droppable are same element
  1998. if ( !draggable || ( draggable.currentItem ||
  1999. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  2000. return;
  2001. }
  2002. if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
  2003. draggable.element ) ) ) {
  2004. this._addHoverClass();
  2005. this._trigger( "over", event, this.ui( draggable ) );
  2006. }
  2007. },
  2008. _out: function( event ) {
  2009. var draggable = $.ui.ddmanager.current;
  2010. // Bail if draggable and droppable are same element
  2011. if ( !draggable || ( draggable.currentItem ||
  2012. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  2013. return;
  2014. }
  2015. if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
  2016. draggable.element ) ) ) {
  2017. this._removeHoverClass();
  2018. this._trigger( "out", event, this.ui( draggable ) );
  2019. }
  2020. },
  2021. _drop: function( event, custom ) {
  2022. var draggable = custom || $.ui.ddmanager.current,
  2023. childrenIntersection = false;
  2024. // Bail if draggable and droppable are same element
  2025. if ( !draggable || ( draggable.currentItem ||
  2026. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  2027. return false;
  2028. }
  2029. this.element
  2030. .find( ":data(ui-droppable)" )
  2031. .not( ".ui-draggable-dragging" )
  2032. .each( function() {
  2033. var inst = $( this ).droppable( "instance" );
  2034. if (
  2035. inst.options.greedy &&
  2036. !inst.options.disabled &&
  2037. inst.options.scope === draggable.options.scope &&
  2038. inst.accept.call(
  2039. inst.element[ 0 ], ( draggable.currentItem || draggable.element )
  2040. ) &&
  2041. intersect(
  2042. draggable,
  2043. $.extend( inst, { offset: inst.element.offset() } ),
  2044. inst.options.tolerance, event
  2045. )
  2046. ) {
  2047. childrenIntersection = true;
  2048. return false; }
  2049. } );
  2050. if ( childrenIntersection ) {
  2051. return false;
  2052. }
  2053. if ( this.accept.call( this.element[ 0 ],
  2054. ( draggable.currentItem || draggable.element ) ) ) {
  2055. this._removeActiveClass();
  2056. this._removeHoverClass();
  2057. this._trigger( "drop", event, this.ui( draggable ) );
  2058. return this.element;
  2059. }
  2060. return false;
  2061. },
  2062. ui: function( c ) {
  2063. return {
  2064. draggable: ( c.currentItem || c.element ),
  2065. helper: c.helper,
  2066. position: c.position,
  2067. offset: c.positionAbs
  2068. };
  2069. },
  2070. // Extension points just to make backcompat sane and avoid duplicating logic
  2071. // TODO: Remove in 1.13 along with call to it below
  2072. _addHoverClass: function() {
  2073. this._addClass( "ui-droppable-hover" );
  2074. },
  2075. _removeHoverClass: function() {
  2076. this._removeClass( "ui-droppable-hover" );
  2077. },
  2078. _addActiveClass: function() {
  2079. this._addClass( "ui-droppable-active" );
  2080. },
  2081. _removeActiveClass: function() {
  2082. this._removeClass( "ui-droppable-active" );
  2083. }
  2084. } );
  2085. var intersect = $.ui.intersect = ( function() {
  2086. function isOverAxis( x, reference, size ) {
  2087. return ( x >= reference ) && ( x < ( reference + size ) );
  2088. }
  2089. return function( draggable, droppable, toleranceMode, event ) {
  2090. if ( !droppable.offset ) {
  2091. return false;
  2092. }
  2093. var x1 = ( draggable.positionAbs ||
  2094. draggable.position.absolute ).left + draggable.margins.left,
  2095. y1 = ( draggable.positionAbs ||
  2096. draggable.position.absolute ).top + draggable.margins.top,
  2097. x2 = x1 + draggable.helperProportions.width,
  2098. y2 = y1 + draggable.helperProportions.height,
  2099. l = droppable.offset.left,
  2100. t = droppable.offset.top,
  2101. r = l + droppable.proportions().width,
  2102. b = t + droppable.proportions().height;
  2103. switch ( toleranceMode ) {
  2104. case "fit":
  2105. return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
  2106. case "intersect":
  2107. return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
  2108. x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
  2109. t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
  2110. y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
  2111. case "pointer":
  2112. return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
  2113. isOverAxis( event.pageX, l, droppable.proportions().width );
  2114. case "touch":
  2115. return (
  2116. ( y1 >= t && y1 <= b ) || // Top edge touching
  2117. ( y2 >= t && y2 <= b ) || // Bottom edge touching
  2118. ( y1 < t && y2 > b ) // Surrounded vertically
  2119. ) && (
  2120. ( x1 >= l && x1 <= r ) || // Left edge touching
  2121. ( x2 >= l && x2 <= r ) || // Right edge touching
  2122. ( x1 < l && x2 > r ) // Surrounded horizontally
  2123. );
  2124. default:
  2125. return false;
  2126. }
  2127. };
  2128. } )();
  2129. /*
  2130. This manager tracks offsets of draggables and droppables
  2131. */
  2132. $.ui.ddmanager = {
  2133. current: null,
  2134. droppables: { "default": [] },
  2135. prepareOffsets: function( t, event ) {
  2136. var i, j,
  2137. m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
  2138. type = event ? event.type : null, // workaround for #2317
  2139. list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
  2140. droppablesLoop: for ( i = 0; i < m.length; i++ ) {
  2141. // No disabled and non-accepted
  2142. if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
  2143. ( t.currentItem || t.element ) ) ) ) {
  2144. continue;
  2145. }
  2146. // Filter out elements in the current dragged item
  2147. for ( j = 0; j < list.length; j++ ) {
  2148. if ( list[ j ] === m[ i ].element[ 0 ] ) {
  2149. m[ i ].proportions().height = 0;
  2150. continue droppablesLoop;
  2151. }
  2152. }
  2153. m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
  2154. if ( !m[ i ].visible ) {
  2155. continue;
  2156. }
  2157. // Activate the droppable if used directly from draggables
  2158. if ( type === "mousedown" ) {
  2159. m[ i ]._activate.call( m[ i ], event );
  2160. }
  2161. m[ i ].offset = m[ i ].element.offset();
  2162. m[ i ].proportions( {
  2163. width: m[ i ].element[ 0 ].offsetWidth,
  2164. height: m[ i ].element[ 0 ].offsetHeight
  2165. } );
  2166. }
  2167. },
  2168. drop: function( draggable, event ) {
  2169. var dropped = false;
  2170. // Create a copy of the droppables in case the list changes during the drop (#9116)
  2171. $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
  2172. if ( !this.options ) {
  2173. return;
  2174. }
  2175. if ( !this.options.disabled && this.visible &&
  2176. intersect( draggable, this, this.options.tolerance, event ) ) {
  2177. dropped = this._drop.call( this, event ) || dropped;
  2178. }
  2179. if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
  2180. ( draggable.currentItem || draggable.element ) ) ) {
  2181. this.isout = true;
  2182. this.isover = false;
  2183. this._deactivate.call( this, event );
  2184. }
  2185. } );
  2186. return dropped;
  2187. },
  2188. dragStart: function( draggable, event ) {
  2189. // Listen for scrolling so that if the dragging causes scrolling the position of the
  2190. // droppables can be recalculated (see #5003)
  2191. draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
  2192. if ( !draggable.options.refreshPositions ) {
  2193. $.ui.ddmanager.prepareOffsets( draggable, event );
  2194. }
  2195. } );
  2196. },
  2197. drag: function( draggable, event ) {
  2198. // If you have a highly dynamic page, you might try this option. It renders positions
  2199. // every time you move the mouse.
  2200. if ( draggable.options.refreshPositions ) {
  2201. $.ui.ddmanager.prepareOffsets( draggable, event );
  2202. }
  2203. // Run through all droppables and check their positions based on specific tolerance options
  2204. $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
  2205. if ( this.options.disabled || this.greedyChild || !this.visible ) {
  2206. return;
  2207. }
  2208. var parentInstance, scope, parent,
  2209. intersects = intersect( draggable, this, this.options.tolerance, event ),
  2210. c = !intersects && this.isover ?
  2211. "isout" :
  2212. ( intersects && !this.isover ? "isover" : null );
  2213. if ( !c ) {
  2214. return;
  2215. }
  2216. if ( this.options.greedy ) {
  2217. // find droppable parents with same scope
  2218. scope = this.options.scope;
  2219. parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
  2220. return $( this ).droppable( "instance" ).options.scope === scope;
  2221. } );
  2222. if ( parent.length ) {
  2223. parentInstance = $( parent[ 0 ] ).droppable( "instance" );
  2224. parentInstance.greedyChild = ( c === "isover" );
  2225. }
  2226. }
  2227. // We just moved into a greedy child
  2228. if ( parentInstance && c === "isover" ) {
  2229. parentInstance.isover = false;
  2230. parentInstance.isout = true;
  2231. parentInstance._out.call( parentInstance, event );
  2232. }
  2233. this[ c ] = true;
  2234. this[ c === "isout" ? "isover" : "isout" ] = false;
  2235. this[ c === "isover" ? "_over" : "_out" ].call( this, event );
  2236. // We just moved out of a greedy child
  2237. if ( parentInstance && c === "isout" ) {
  2238. parentInstance.isout = false;
  2239. parentInstance.isover = true;
  2240. parentInstance._over.call( parentInstance, event );
  2241. }
  2242. } );
  2243. },
  2244. dragStop: function( draggable, event ) {
  2245. draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
  2246. // Call prepareOffsets one final time since IE does not fire return scroll events when
  2247. // overflow was caused by drag (see #5003)
  2248. if ( !draggable.options.refreshPositions ) {
  2249. $.ui.ddmanager.prepareOffsets( draggable, event );
  2250. }
  2251. }
  2252. };
  2253. // DEPRECATED
  2254. // TODO: switch return back to widget declaration at top of file when this is removed
  2255. if ( $.uiBackCompat !== false ) {
  2256. // Backcompat for activeClass and hoverClass options
  2257. $.widget( "ui.droppable", $.ui.droppable, {
  2258. options: {
  2259. hoverClass: false,
  2260. activeClass: false
  2261. },
  2262. _addActiveClass: function() {
  2263. this._super();
  2264. if ( this.options.activeClass ) {
  2265. this.element.addClass( this.options.activeClass );
  2266. }
  2267. },
  2268. _removeActiveClass: function() {
  2269. this._super();
  2270. if ( this.options.activeClass ) {
  2271. this.element.removeClass( this.options.activeClass );
  2272. }
  2273. },
  2274. _addHoverClass: function() {
  2275. this._super();
  2276. if ( this.options.hoverClass ) {
  2277. this.element.addClass( this.options.hoverClass );
  2278. }
  2279. },
  2280. _removeHoverClass: function() {
  2281. this._super();
  2282. if ( this.options.hoverClass ) {
  2283. this.element.removeClass( this.options.hoverClass );
  2284. }
  2285. }
  2286. } );
  2287. }
  2288. var widgetsDroppable = $.ui.droppable;
  2289. /*!
  2290. * jQuery UI Selectable 1.12.1
  2291. * http://jqueryui.com
  2292. *
  2293. * Copyright jQuery Foundation and other contributors
  2294. * Released under the MIT license.
  2295. * http://jquery.org/license
  2296. */
  2297. //>>label: Selectable
  2298. //>>group: Interactions
  2299. //>>description: Allows groups of elements to be selected with the mouse.
  2300. //>>docs: http://api.jqueryui.com/selectable/
  2301. //>>demos: http://jqueryui.com/selectable/
  2302. //>>css.structure: ../../themes/base/selectable.css
  2303. var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
  2304. version: "1.12.1",
  2305. options: {
  2306. appendTo: "body",
  2307. autoRefresh: true,
  2308. distance: 0,
  2309. filter: "*",
  2310. tolerance: "touch",
  2311. // Callbacks
  2312. selected: null,
  2313. selecting: null,
  2314. start: null,
  2315. stop: null,
  2316. unselected: null,
  2317. unselecting: null
  2318. },
  2319. _create: function() {
  2320. var that = this;
  2321. this._addClass( "ui-selectable" );
  2322. this.dragged = false;
  2323. // Cache selectee children based on filter
  2324. this.refresh = function() {
  2325. that.elementPos = $( that.element[ 0 ] ).offset();
  2326. that.selectees = $( that.options.filter, that.element[ 0 ] );
  2327. that._addClass( that.selectees, "ui-selectee" );
  2328. that.selectees.each( function() {
  2329. var $this = $( this ),
  2330. selecteeOffset = $this.offset(),
  2331. pos = {
  2332. left: selecteeOffset.left - that.elementPos.left,
  2333. top: selecteeOffset.top - that.elementPos.top
  2334. };
  2335. $.data( this, "selectable-item", {
  2336. element: this,
  2337. $element: $this,
  2338. left: pos.left,
  2339. top: pos.top,
  2340. right: pos.left + $this.outerWidth(),
  2341. bottom: pos.top + $this.outerHeight(),
  2342. startselected: false,
  2343. selected: $this.hasClass( "ui-selected" ),
  2344. selecting: $this.hasClass( "ui-selecting" ),
  2345. unselecting: $this.hasClass( "ui-unselecting" )
  2346. } );
  2347. } );
  2348. };
  2349. this.refresh();
  2350. this._mouseInit();
  2351. this.helper = $( "<div>" );
  2352. this._addClass( this.helper, "ui-selectable-helper" );
  2353. },
  2354. _destroy: function() {
  2355. this.selectees.removeData( "selectable-item" );
  2356. this._mouseDestroy();
  2357. },
  2358. _mouseStart: function( event ) {
  2359. var that = this,
  2360. options = this.options;
  2361. this.opos = [ event.pageX, event.pageY ];
  2362. this.elementPos = $( this.element[ 0 ] ).offset();
  2363. if ( this.options.disabled ) {
  2364. return;
  2365. }
  2366. this.selectees = $( options.filter, this.element[ 0 ] );
  2367. this._trigger( "start", event );
  2368. $( options.appendTo ).append( this.helper );
  2369. // position helper (lasso)
  2370. this.helper.css( {
  2371. "left": event.pageX,
  2372. "top": event.pageY,
  2373. "width": 0,
  2374. "height": 0
  2375. } );
  2376. if ( options.autoRefresh ) {
  2377. this.refresh();
  2378. }
  2379. this.selectees.filter( ".ui-selected" ).each( function() {
  2380. var selectee = $.data( this, "selectable-item" );
  2381. selectee.startselected = true;
  2382. if ( !event.metaKey && !event.ctrlKey ) {
  2383. that._removeClass( selectee.$element, "ui-selected" );
  2384. selectee.selected = false;
  2385. that._addClass( selectee.$element, "ui-unselecting" );
  2386. selectee.unselecting = true;
  2387. // selectable UNSELECTING callback
  2388. that._trigger( "unselecting", event, {
  2389. unselecting: selectee.element
  2390. } );
  2391. }
  2392. } );
  2393. $( event.target ).parents().addBack().each( function() {
  2394. var doSelect,
  2395. selectee = $.data( this, "selectable-item" );
  2396. if ( selectee ) {
  2397. doSelect = ( !event.metaKey && !event.ctrlKey ) ||
  2398. !selectee.$element.hasClass( "ui-selected" );
  2399. that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
  2400. ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
  2401. selectee.unselecting = !doSelect;
  2402. selectee.selecting = doSelect;
  2403. selectee.selected = doSelect;
  2404. // selectable (UN)SELECTING callback
  2405. if ( doSelect ) {
  2406. that._trigger( "selecting", event, {
  2407. selecting: selectee.element
  2408. } );
  2409. } else {
  2410. that._trigger( "unselecting", event, {
  2411. unselecting: selectee.element
  2412. } );
  2413. }
  2414. return false;
  2415. }
  2416. } );
  2417. },
  2418. _mouseDrag: function( event ) {
  2419. this.dragged = true;
  2420. if ( this.options.disabled ) {
  2421. return;
  2422. }
  2423. var tmp,
  2424. that = this,
  2425. options = this.options,
  2426. x1 = this.opos[ 0 ],
  2427. y1 = this.opos[ 1 ],
  2428. x2 = event.pageX,
  2429. y2 = event.pageY;
  2430. if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
  2431. if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
  2432. this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
  2433. this.selectees.each( function() {
  2434. var selectee = $.data( this, "selectable-item" ),
  2435. hit = false,
  2436. offset = {};
  2437. //prevent helper from being selected if appendTo: selectable
  2438. if ( !selectee || selectee.element === that.element[ 0 ] ) {
  2439. return;
  2440. }
  2441. offset.left = selectee.left + that.elementPos.left;
  2442. offset.right = selectee.right + that.elementPos.left;
  2443. offset.top = selectee.top + that.elementPos.top;
  2444. offset.bottom = selectee.bottom + that.elementPos.top;
  2445. if ( options.tolerance === "touch" ) {
  2446. hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
  2447. offset.bottom < y1 ) );
  2448. } else if ( options.tolerance === "fit" ) {
  2449. hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
  2450. offset.bottom < y2 );
  2451. }
  2452. if ( hit ) {
  2453. // SELECT
  2454. if ( selectee.selected ) {
  2455. that._removeClass( selectee.$element, "ui-selected" );
  2456. selectee.selected = false;
  2457. }
  2458. if ( selectee.unselecting ) {
  2459. that._removeClass( selectee.$element, "ui-unselecting" );
  2460. selectee.unselecting = false;
  2461. }
  2462. if ( !selectee.selecting ) {
  2463. that._addClass( selectee.$element, "ui-selecting" );
  2464. selectee.selecting = true;
  2465. // selectable SELECTING callback
  2466. that._trigger( "selecting", event, {
  2467. selecting: selectee.element
  2468. } );
  2469. }
  2470. } else {
  2471. // UNSELECT
  2472. if ( selectee.selecting ) {
  2473. if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
  2474. that._removeClass( selectee.$element, "ui-selecting" );
  2475. selectee.selecting = false;
  2476. that._addClass( selectee.$element, "ui-selected" );
  2477. selectee.selected = true;
  2478. } else {
  2479. that._removeClass( selectee.$element, "ui-selecting" );
  2480. selectee.selecting = false;
  2481. if ( selectee.startselected ) {
  2482. that._addClass( selectee.$element, "ui-unselecting" );
  2483. selectee.unselecting = true;
  2484. }
  2485. // selectable UNSELECTING callback
  2486. that._trigger( "unselecting", event, {
  2487. unselecting: selectee.element
  2488. } );
  2489. }
  2490. }
  2491. if ( selectee.selected ) {
  2492. if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
  2493. that._removeClass( selectee.$element, "ui-selected" );
  2494. selectee.selected = false;
  2495. that._addClass( selectee.$element, "ui-unselecting" );
  2496. selectee.unselecting = true;
  2497. // selectable UNSELECTING callback
  2498. that._trigger( "unselecting", event, {
  2499. unselecting: selectee.element
  2500. } );
  2501. }
  2502. }
  2503. }
  2504. } );
  2505. return false;
  2506. },
  2507. _mouseStop: function( event ) {
  2508. var that = this;
  2509. this.dragged = false;
  2510. $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
  2511. var selectee = $.data( this, "selectable-item" );
  2512. that._removeClass( selectee.$element, "ui-unselecting" );
  2513. selectee.unselecting = false;
  2514. selectee.startselected = false;
  2515. that._trigger( "unselected", event, {
  2516. unselected: selectee.element
  2517. } );
  2518. } );
  2519. $( ".ui-selecting", this.element[ 0 ] ).each( function() {
  2520. var selectee = $.data( this, "selectable-item" );
  2521. that._removeClass( selectee.$element, "ui-selecting" )
  2522. ._addClass( selectee.$element, "ui-selected" );
  2523. selectee.selecting = false;
  2524. selectee.selected = true;
  2525. selectee.startselected = true;
  2526. that._trigger( "selected", event, {
  2527. selected: selectee.element
  2528. } );
  2529. } );
  2530. this._trigger( "stop", event );
  2531. this.helper.remove();
  2532. return false;
  2533. }
  2534. } );
  2535. }));