spud_core 0.8.28 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/app/assets/javascripts/spud/admin/application.js +80 -39
  2. data/app/assets/javascripts/spud/admin/editor.js +91 -0
  3. data/app/assets/libs/bootstrap/css/bootstrap-responsive.css +799 -397
  4. data/app/assets/libs/bootstrap/css/bootstrap.css +3275 -1372
  5. data/app/assets/libs/bootstrap/img/glyphicons-halflings-white.png +0 -0
  6. data/app/assets/libs/bootstrap/img/glyphicons-halflings.png +0 -0
  7. data/app/assets/libs/bootstrap/js/bootstrap.js +716 -417
  8. data/app/assets/libs/datepicker/css/datepicker.css +223 -0
  9. data/app/assets/libs/datepicker/js/bootstrap-datepicker.js +779 -0
  10. data/app/assets/libs/datepicker/less/datepicker.less +122 -0
  11. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  12. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  13. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  14. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  15. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  17. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  18. data/app/assets/libs/jquery-ui/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  19. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_0073ea_256x240.png +0 -0
  20. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_454545_256x240.png +0 -0
  21. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_666666_256x240.png +0 -0
  22. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_ff0084_256x240.png +0 -0
  23. data/app/assets/libs/jquery-ui/css/flick/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/app/assets/libs/jquery-ui/css/flick/jquery-ui-1.9.1.custom.css +297 -0
  25. data/app/assets/libs/jquery-ui/css/flick/jquery-ui-1.9.1.custom.min.css +5 -0
  26. data/app/assets/libs/jquery-ui/js/jquery-ui-1.9.1.custom.js +4870 -0
  27. data/app/assets/libs/jquery-ui/js/jquery-ui-1.9.1.custom.min.js +6 -0
  28. data/app/assets/stylesheets/spud/admin/application.css +22 -4
  29. data/app/controllers/spud/admin/application_controller.rb +13 -4
  30. data/app/controllers/spud/admin/dashboard_controller.rb +1 -1
  31. data/app/controllers/spud/admin/users_controller.rb +4 -9
  32. data/app/controllers/spud/setup_controller.rb +3 -4
  33. data/app/models/spud_admin_permission.rb +1 -1
  34. data/app/models/spud_user.rb +4 -2
  35. data/app/views/layouts/spud/admin/application.html.erb +24 -5
  36. data/app/views/spud/admin/users/_edit.html.erb +2 -4
  37. data/app/views/spud/admin/users/_new.html.erb +3 -5
  38. data/app/views/spud/admin/users/index.html.erb +6 -5
  39. data/lib/spud_core/belongs_to_app.rb +9 -6
  40. data/lib/spud_core/configuration.rb +23 -1
  41. data/lib/spud_core/engine.rb +20 -28
  42. data/lib/spud_core/version.rb +1 -1
  43. data/spec/dummy/log/development.log +15 -37
  44. data/spec/dummy/log/test.log +72841 -25918
  45. metadata +25 -101
  46. data/app/assets/libs/bootstrap/css/bootstrap-responsive.min.css +0 -12
  47. data/app/assets/libs/bootstrap/css/bootstrap.min.css +0 -689
  48. data/app/assets/libs/bootstrap/js/bootstrap.min.js +0 -6
  49. data/app/assets/libs/tiny_mce/plugins/autosave/editor_plugin.js +0 -1
  50. data/app/assets/libs/tiny_mce/plugins/autosave/editor_plugin_src.js +0 -431
  51. data/app/assets/libs/tiny_mce/plugins/autosave/langs/en.js +0 -4
  52. data/app/assets/libs/tiny_mce/plugins/bbcode/editor_plugin.js +0 -1
  53. data/app/assets/libs/tiny_mce/plugins/bbcode/editor_plugin_src.js +0 -120
  54. data/app/assets/libs/tiny_mce/plugins/emotions/editor_plugin.js +0 -1
  55. data/app/assets/libs/tiny_mce/plugins/emotions/editor_plugin_src.js +0 -43
  56. data/app/assets/libs/tiny_mce/plugins/emotions/emotions.htm +0 -42
  57. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-cool.gif +0 -0
  58. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-cry.gif +0 -0
  59. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-embarassed.gif +0 -0
  60. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif +0 -0
  61. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-frown.gif +0 -0
  62. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-innocent.gif +0 -0
  63. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-kiss.gif +0 -0
  64. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-laughing.gif +0 -0
  65. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif +0 -0
  66. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-sealed.gif +0 -0
  67. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-smile.gif +0 -0
  68. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-surprised.gif +0 -0
  69. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif +0 -0
  70. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-undecided.gif +0 -0
  71. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-wink.gif +0 -0
  72. data/app/assets/libs/tiny_mce/plugins/emotions/img/smiley-yell.gif +0 -0
  73. data/app/assets/libs/tiny_mce/plugins/emotions/js/emotions.js +0 -43
  74. data/app/assets/libs/tiny_mce/plugins/emotions/langs/en_dlg.js +0 -1
  75. data/app/assets/libs/tiny_mce/plugins/fullpage/css/fullpage.css +0 -143
  76. data/app/assets/libs/tiny_mce/plugins/fullpage/editor_plugin.js +0 -1
  77. data/app/assets/libs/tiny_mce/plugins/fullpage/editor_plugin_src.js +0 -405
  78. data/app/assets/libs/tiny_mce/plugins/fullpage/fullpage.htm +0 -259
  79. data/app/assets/libs/tiny_mce/plugins/fullpage/js/fullpage.js +0 -232
  80. data/app/assets/libs/tiny_mce/plugins/fullpage/langs/en_dlg.js +0 -1
  81. data/app/assets/libs/tiny_mce/plugins/fullscreen/editor_plugin.js +0 -1
  82. data/app/assets/libs/tiny_mce/plugins/fullscreen/editor_plugin_src.js +0 -159
  83. data/app/assets/libs/tiny_mce/plugins/fullscreen/fullscreen.htm +0 -110
  84. data/app/assets/libs/tiny_mce/plugins/insertdatetime/editor_plugin.js +0 -1
  85. data/app/assets/libs/tiny_mce/plugins/insertdatetime/editor_plugin_src.js +0 -83
  86. data/app/assets/libs/tiny_mce/plugins/legacyoutput/editor_plugin.js +0 -1
  87. data/app/assets/libs/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +0 -139
  88. data/app/assets/libs/tiny_mce/plugins/nonbreaking/editor_plugin.js +0 -1
  89. data/app/assets/libs/tiny_mce/plugins/nonbreaking/editor_plugin_src.js +0 -54
  90. data/app/assets/libs/tiny_mce/plugins/noneditable/editor_plugin.js +0 -1
  91. data/app/assets/libs/tiny_mce/plugins/noneditable/editor_plugin_src.js +0 -454
  92. data/app/assets/libs/tiny_mce/plugins/pagebreak/editor_plugin.js +0 -1
  93. data/app/assets/libs/tiny_mce/plugins/pagebreak/editor_plugin_src.js +0 -74
  94. data/app/assets/libs/tiny_mce/plugins/preview/editor_plugin.js +0 -1
  95. data/app/assets/libs/tiny_mce/plugins/preview/editor_plugin_src.js +0 -53
  96. data/app/assets/libs/tiny_mce/plugins/preview/example.html +0 -28
  97. data/app/assets/libs/tiny_mce/plugins/preview/jscripts/embed.js +0 -73
  98. data/app/assets/libs/tiny_mce/plugins/preview/preview.html +0 -17
  99. data/app/assets/libs/tiny_mce/plugins/print/editor_plugin.js +0 -1
  100. data/app/assets/libs/tiny_mce/plugins/print/editor_plugin_src.js +0 -34
  101. data/app/assets/libs/tiny_mce/plugins/save/editor_plugin.js +0 -1
  102. data/app/assets/libs/tiny_mce/plugins/save/editor_plugin_src.js +0 -101
  103. data/app/assets/libs/tiny_mce/plugins/searchreplace/css/searchreplace.css +0 -6
  104. data/app/assets/libs/tiny_mce/plugins/searchreplace/editor_plugin.js +0 -1
  105. data/app/assets/libs/tiny_mce/plugins/searchreplace/editor_plugin_src.js +0 -61
  106. data/app/assets/libs/tiny_mce/plugins/searchreplace/js/searchreplace.js +0 -142
  107. data/app/assets/libs/tiny_mce/plugins/searchreplace/langs/en_dlg.js +0 -1
  108. data/app/assets/libs/tiny_mce/plugins/searchreplace/searchreplace.htm +0 -100
  109. data/app/assets/libs/tiny_mce/plugins/tabfocus/editor_plugin.js +0 -1
  110. data/app/assets/libs/tiny_mce/plugins/tabfocus/editor_plugin_src.js +0 -122
  111. data/app/assets/libs/tiny_mce/plugins/template/blank.htm +0 -12
  112. data/app/assets/libs/tiny_mce/plugins/template/css/template.css +0 -23
  113. data/app/assets/libs/tiny_mce/plugins/template/editor_plugin.js +0 -1
  114. data/app/assets/libs/tiny_mce/plugins/template/editor_plugin_src.js +0 -159
  115. data/app/assets/libs/tiny_mce/plugins/template/js/template.js +0 -106
  116. data/app/assets/libs/tiny_mce/plugins/template/langs/en_dlg.js +0 -1
  117. data/app/assets/libs/tiny_mce/plugins/template/template.htm +0 -31
  118. data/app/assets/libs/tiny_mce/plugins/visualblocks/css/visualblocks.css +0 -21
  119. data/app/assets/libs/tiny_mce/plugins/visualblocks/editor_plugin.js +0 -1
  120. data/app/assets/libs/tiny_mce/plugins/visualblocks/editor_plugin_src.js +0 -63
  121. data/app/assets/libs/tiny_mce/plugins/visualchars/editor_plugin.js +0 -1
  122. data/app/assets/libs/tiny_mce/plugins/visualchars/editor_plugin_src.js +0 -83
  123. data/app/assets/libs/tiny_mce/plugins/wordcount/editor_plugin.js +0 -1
  124. data/app/assets/libs/tiny_mce/plugins/wordcount/editor_plugin_src.js +0 -122
  125. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/abbr.htm +0 -142
  126. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/acronym.htm +0 -142
  127. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/attributes.htm +0 -149
  128. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/cite.htm +0 -142
  129. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/css/attributes.css +0 -11
  130. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/css/popup.css +0 -9
  131. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/del.htm +0 -162
  132. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +0 -1
  133. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +0 -132
  134. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/ins.htm +0 -162
  135. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/abbr.js +0 -28
  136. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/acronym.js +0 -28
  137. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/attributes.js +0 -111
  138. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/cite.js +0 -28
  139. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/del.js +0 -53
  140. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/element_common.js +0 -229
  141. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/js/ins.js +0 -53
  142. data/app/assets/libs/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js +0 -1
@@ -0,0 +1,4870 @@
1
+ /*! jQuery UI - v1.9.1 - 2012-11-07
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.sortable.js, jquery.ui.autocomplete.js, jquery.ui.menu.js
4
+ * Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
5
+
6
+ (function( $, undefined ) {
7
+
8
+ var uuid = 0,
9
+ runiqueId = /^ui-id-\d+$/;
10
+
11
+ // prevent duplicate loading
12
+ // this is only a problem because we proxy existing functions
13
+ // and we don't want to double proxy them
14
+ $.ui = $.ui || {};
15
+ if ( $.ui.version ) {
16
+ return;
17
+ }
18
+
19
+ $.extend( $.ui, {
20
+ version: "1.9.1",
21
+
22
+ keyCode: {
23
+ BACKSPACE: 8,
24
+ COMMA: 188,
25
+ DELETE: 46,
26
+ DOWN: 40,
27
+ END: 35,
28
+ ENTER: 13,
29
+ ESCAPE: 27,
30
+ HOME: 36,
31
+ LEFT: 37,
32
+ NUMPAD_ADD: 107,
33
+ NUMPAD_DECIMAL: 110,
34
+ NUMPAD_DIVIDE: 111,
35
+ NUMPAD_ENTER: 108,
36
+ NUMPAD_MULTIPLY: 106,
37
+ NUMPAD_SUBTRACT: 109,
38
+ PAGE_DOWN: 34,
39
+ PAGE_UP: 33,
40
+ PERIOD: 190,
41
+ RIGHT: 39,
42
+ SPACE: 32,
43
+ TAB: 9,
44
+ UP: 38
45
+ }
46
+ });
47
+
48
+ // plugins
49
+ $.fn.extend({
50
+ _focus: $.fn.focus,
51
+ focus: function( delay, fn ) {
52
+ return typeof delay === "number" ?
53
+ this.each(function() {
54
+ var elem = this;
55
+ setTimeout(function() {
56
+ $( elem ).focus();
57
+ if ( fn ) {
58
+ fn.call( elem );
59
+ }
60
+ }, delay );
61
+ }) :
62
+ this._focus.apply( this, arguments );
63
+ },
64
+
65
+ scrollParent: function() {
66
+ var scrollParent;
67
+ if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
68
+ scrollParent = this.parents().filter(function() {
69
+ return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
70
+ }).eq(0);
71
+ } else {
72
+ scrollParent = this.parents().filter(function() {
73
+ return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
74
+ }).eq(0);
75
+ }
76
+
77
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
78
+ },
79
+
80
+ zIndex: function( zIndex ) {
81
+ if ( zIndex !== undefined ) {
82
+ return this.css( "zIndex", zIndex );
83
+ }
84
+
85
+ if ( this.length ) {
86
+ var elem = $( this[ 0 ] ), position, value;
87
+ while ( elem.length && elem[ 0 ] !== document ) {
88
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
89
+ // This makes behavior of this function consistent across browsers
90
+ // WebKit always returns auto if the element is positioned
91
+ position = elem.css( "position" );
92
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93
+ // IE returns 0 when zIndex is not specified
94
+ // other browsers return a string
95
+ // we ignore the case of nested elements with an explicit value of 0
96
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97
+ value = parseInt( elem.css( "zIndex" ), 10 );
98
+ if ( !isNaN( value ) && value !== 0 ) {
99
+ return value;
100
+ }
101
+ }
102
+ elem = elem.parent();
103
+ }
104
+ }
105
+
106
+ return 0;
107
+ },
108
+
109
+ uniqueId: function() {
110
+ return this.each(function() {
111
+ if ( !this.id ) {
112
+ this.id = "ui-id-" + (++uuid);
113
+ }
114
+ });
115
+ },
116
+
117
+ removeUniqueId: function() {
118
+ return this.each(function() {
119
+ if ( runiqueId.test( this.id ) ) {
120
+ $( this ).removeAttr( "id" );
121
+ }
122
+ });
123
+ }
124
+ });
125
+
126
+ // support: jQuery <1.8
127
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
128
+ $.each( [ "Width", "Height" ], function( i, name ) {
129
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
130
+ type = name.toLowerCase(),
131
+ orig = {
132
+ innerWidth: $.fn.innerWidth,
133
+ innerHeight: $.fn.innerHeight,
134
+ outerWidth: $.fn.outerWidth,
135
+ outerHeight: $.fn.outerHeight
136
+ };
137
+
138
+ function reduce( elem, size, border, margin ) {
139
+ $.each( side, function() {
140
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
141
+ if ( border ) {
142
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
143
+ }
144
+ if ( margin ) {
145
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
146
+ }
147
+ });
148
+ return size;
149
+ }
150
+
151
+ $.fn[ "inner" + name ] = function( size ) {
152
+ if ( size === undefined ) {
153
+ return orig[ "inner" + name ].call( this );
154
+ }
155
+
156
+ return this.each(function() {
157
+ $( this ).css( type, reduce( this, size ) + "px" );
158
+ });
159
+ };
160
+
161
+ $.fn[ "outer" + name] = function( size, margin ) {
162
+ if ( typeof size !== "number" ) {
163
+ return orig[ "outer" + name ].call( this, size );
164
+ }
165
+
166
+ return this.each(function() {
167
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
168
+ });
169
+ };
170
+ });
171
+ }
172
+
173
+ // selectors
174
+ function focusable( element, isTabIndexNotNaN ) {
175
+ var map, mapName, img,
176
+ nodeName = element.nodeName.toLowerCase();
177
+ if ( "area" === nodeName ) {
178
+ map = element.parentNode;
179
+ mapName = map.name;
180
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
181
+ return false;
182
+ }
183
+ img = $( "img[usemap=#" + mapName + "]" )[0];
184
+ return !!img && visible( img );
185
+ }
186
+ return ( /input|select|textarea|button|object/.test( nodeName ) ?
187
+ !element.disabled :
188
+ "a" === nodeName ?
189
+ element.href || isTabIndexNotNaN :
190
+ isTabIndexNotNaN) &&
191
+ // the element and all of its ancestors must be visible
192
+ visible( element );
193
+ }
194
+
195
+ function visible( element ) {
196
+ return $.expr.filters.visible( element ) &&
197
+ !$( element ).parents().andSelf().filter(function() {
198
+ return $.css( this, "visibility" ) === "hidden";
199
+ }).length;
200
+ }
201
+
202
+ $.extend( $.expr[ ":" ], {
203
+ data: $.expr.createPseudo ?
204
+ $.expr.createPseudo(function( dataName ) {
205
+ return function( elem ) {
206
+ return !!$.data( elem, dataName );
207
+ };
208
+ }) :
209
+ // support: jQuery <1.8
210
+ function( elem, i, match ) {
211
+ return !!$.data( elem, match[ 3 ] );
212
+ },
213
+
214
+ focusable: function( element ) {
215
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
216
+ },
217
+
218
+ tabbable: function( element ) {
219
+ var tabIndex = $.attr( element, "tabindex" ),
220
+ isTabIndexNaN = isNaN( tabIndex );
221
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
222
+ }
223
+ });
224
+
225
+ // support
226
+ $(function() {
227
+ var body = document.body,
228
+ div = body.appendChild( div = document.createElement( "div" ) );
229
+
230
+ // access offsetHeight before setting the style to prevent a layout bug
231
+ // in IE 9 which causes the element to continue to take up space even
232
+ // after it is removed from the DOM (#8026)
233
+ div.offsetHeight;
234
+
235
+ $.extend( div.style, {
236
+ minHeight: "100px",
237
+ height: "auto",
238
+ padding: 0,
239
+ borderWidth: 0
240
+ });
241
+
242
+ $.support.minHeight = div.offsetHeight === 100;
243
+ $.support.selectstart = "onselectstart" in div;
244
+
245
+ // set display to none to avoid a layout bug in IE
246
+ // http://dev.jquery.com/ticket/4014
247
+ body.removeChild( div ).style.display = "none";
248
+ });
249
+
250
+
251
+
252
+
253
+
254
+ // deprecated
255
+
256
+ (function() {
257
+ var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
258
+ $.ui.ie = uaMatch.length ? true : false;
259
+ $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
260
+ })();
261
+
262
+ $.fn.extend({
263
+ disableSelection: function() {
264
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
265
+ ".ui-disableSelection", function( event ) {
266
+ event.preventDefault();
267
+ });
268
+ },
269
+
270
+ enableSelection: function() {
271
+ return this.unbind( ".ui-disableSelection" );
272
+ }
273
+ });
274
+
275
+ $.extend( $.ui, {
276
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
277
+ plugin: {
278
+ add: function( module, option, set ) {
279
+ var i,
280
+ proto = $.ui[ module ].prototype;
281
+ for ( i in set ) {
282
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
283
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
284
+ }
285
+ },
286
+ call: function( instance, name, args ) {
287
+ var i,
288
+ set = instance.plugins[ name ];
289
+ if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
290
+ return;
291
+ }
292
+
293
+ for ( i = 0; i < set.length; i++ ) {
294
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
295
+ set[ i ][ 1 ].apply( instance.element, args );
296
+ }
297
+ }
298
+ }
299
+ },
300
+
301
+ contains: $.contains,
302
+
303
+ // only used by resizable
304
+ hasScroll: function( el, a ) {
305
+
306
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
307
+ if ( $( el ).css( "overflow" ) === "hidden") {
308
+ return false;
309
+ }
310
+
311
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
312
+ has = false;
313
+
314
+ if ( el[ scroll ] > 0 ) {
315
+ return true;
316
+ }
317
+
318
+ // TODO: determine which cases actually cause this to happen
319
+ // if the element doesn't have the scroll set, see if it's possible to
320
+ // set the scroll
321
+ el[ scroll ] = 1;
322
+ has = ( el[ scroll ] > 0 );
323
+ el[ scroll ] = 0;
324
+ return has;
325
+ },
326
+
327
+ // these are odd functions, fix the API or move into individual plugins
328
+ isOverAxis: function( x, reference, size ) {
329
+ //Determines when x coordinate is over "b" element axis
330
+ return ( x > reference ) && ( x < ( reference + size ) );
331
+ },
332
+ isOver: function( y, x, top, left, height, width ) {
333
+ //Determines when x, y coordinates is over "b" element
334
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
335
+ }
336
+ });
337
+
338
+ })( jQuery );
339
+ (function( $, undefined ) {
340
+
341
+ var uuid = 0,
342
+ slice = Array.prototype.slice,
343
+ _cleanData = $.cleanData;
344
+ $.cleanData = function( elems ) {
345
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
346
+ try {
347
+ $( elem ).triggerHandler( "remove" );
348
+ // http://bugs.jquery.com/ticket/8235
349
+ } catch( e ) {}
350
+ }
351
+ _cleanData( elems );
352
+ };
353
+
354
+ $.widget = function( name, base, prototype ) {
355
+ var fullName, existingConstructor, constructor, basePrototype,
356
+ namespace = name.split( "." )[ 0 ];
357
+
358
+ name = name.split( "." )[ 1 ];
359
+ fullName = namespace + "-" + name;
360
+
361
+ if ( !prototype ) {
362
+ prototype = base;
363
+ base = $.Widget;
364
+ }
365
+
366
+ // create selector for plugin
367
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
368
+ return !!$.data( elem, fullName );
369
+ };
370
+
371
+ $[ namespace ] = $[ namespace ] || {};
372
+ existingConstructor = $[ namespace ][ name ];
373
+ constructor = $[ namespace ][ name ] = function( options, element ) {
374
+ // allow instantiation without "new" keyword
375
+ if ( !this._createWidget ) {
376
+ return new constructor( options, element );
377
+ }
378
+
379
+ // allow instantiation without initializing for simple inheritance
380
+ // must use "new" keyword (the code above always passes args)
381
+ if ( arguments.length ) {
382
+ this._createWidget( options, element );
383
+ }
384
+ };
385
+ // extend with the existing constructor to carry over any static properties
386
+ $.extend( constructor, existingConstructor, {
387
+ version: prototype.version,
388
+ // copy the object used to create the prototype in case we need to
389
+ // redefine the widget later
390
+ _proto: $.extend( {}, prototype ),
391
+ // track widgets that inherit from this widget in case this widget is
392
+ // redefined after a widget inherits from it
393
+ _childConstructors: []
394
+ });
395
+
396
+ basePrototype = new base();
397
+ // we need to make the options hash a property directly on the new instance
398
+ // otherwise we'll modify the options hash on the prototype that we're
399
+ // inheriting from
400
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
401
+ $.each( prototype, function( prop, value ) {
402
+ if ( $.isFunction( value ) ) {
403
+ prototype[ prop ] = (function() {
404
+ var _super = function() {
405
+ return base.prototype[ prop ].apply( this, arguments );
406
+ },
407
+ _superApply = function( args ) {
408
+ return base.prototype[ prop ].apply( this, args );
409
+ };
410
+ return function() {
411
+ var __super = this._super,
412
+ __superApply = this._superApply,
413
+ returnValue;
414
+
415
+ this._super = _super;
416
+ this._superApply = _superApply;
417
+
418
+ returnValue = value.apply( this, arguments );
419
+
420
+ this._super = __super;
421
+ this._superApply = __superApply;
422
+
423
+ return returnValue;
424
+ };
425
+ })();
426
+ }
427
+ });
428
+ constructor.prototype = $.widget.extend( basePrototype, {
429
+ // TODO: remove support for widgetEventPrefix
430
+ // always use the name + a colon as the prefix, e.g., draggable:start
431
+ // don't prefix for widgets that aren't DOM-based
432
+ widgetEventPrefix: basePrototype.widgetEventPrefix || name
433
+ }, prototype, {
434
+ constructor: constructor,
435
+ namespace: namespace,
436
+ widgetName: name,
437
+ // TODO remove widgetBaseClass, see #8155
438
+ widgetBaseClass: fullName,
439
+ widgetFullName: fullName
440
+ });
441
+
442
+ // If this widget is being redefined then we need to find all widgets that
443
+ // are inheriting from it and redefine all of them so that they inherit from
444
+ // the new version of this widget. We're essentially trying to replace one
445
+ // level in the prototype chain.
446
+ if ( existingConstructor ) {
447
+ $.each( existingConstructor._childConstructors, function( i, child ) {
448
+ var childPrototype = child.prototype;
449
+
450
+ // redefine the child widget using the same prototype that was
451
+ // originally used, but inherit from the new version of the base
452
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
453
+ });
454
+ // remove the list of existing child constructors from the old constructor
455
+ // so the old child constructors can be garbage collected
456
+ delete existingConstructor._childConstructors;
457
+ } else {
458
+ base._childConstructors.push( constructor );
459
+ }
460
+
461
+ $.widget.bridge( name, constructor );
462
+ };
463
+
464
+ $.widget.extend = function( target ) {
465
+ var input = slice.call( arguments, 1 ),
466
+ inputIndex = 0,
467
+ inputLength = input.length,
468
+ key,
469
+ value;
470
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
471
+ for ( key in input[ inputIndex ] ) {
472
+ value = input[ inputIndex ][ key ];
473
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
474
+ // Clone objects
475
+ if ( $.isPlainObject( value ) ) {
476
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
477
+ $.widget.extend( {}, target[ key ], value ) :
478
+ // Don't extend strings, arrays, etc. with objects
479
+ $.widget.extend( {}, value );
480
+ // Copy everything else by reference
481
+ } else {
482
+ target[ key ] = value;
483
+ }
484
+ }
485
+ }
486
+ }
487
+ return target;
488
+ };
489
+
490
+ $.widget.bridge = function( name, object ) {
491
+ var fullName = object.prototype.widgetFullName;
492
+ $.fn[ name ] = function( options ) {
493
+ var isMethodCall = typeof options === "string",
494
+ args = slice.call( arguments, 1 ),
495
+ returnValue = this;
496
+
497
+ // allow multiple hashes to be passed on init
498
+ options = !isMethodCall && args.length ?
499
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
500
+ options;
501
+
502
+ if ( isMethodCall ) {
503
+ this.each(function() {
504
+ var methodValue,
505
+ instance = $.data( this, fullName );
506
+ if ( !instance ) {
507
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
508
+ "attempted to call method '" + options + "'" );
509
+ }
510
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
511
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
512
+ }
513
+ methodValue = instance[ options ].apply( instance, args );
514
+ if ( methodValue !== instance && methodValue !== undefined ) {
515
+ returnValue = methodValue && methodValue.jquery ?
516
+ returnValue.pushStack( methodValue.get() ) :
517
+ methodValue;
518
+ return false;
519
+ }
520
+ });
521
+ } else {
522
+ this.each(function() {
523
+ var instance = $.data( this, fullName );
524
+ if ( instance ) {
525
+ instance.option( options || {} )._init();
526
+ } else {
527
+ new object( options, this );
528
+ }
529
+ });
530
+ }
531
+
532
+ return returnValue;
533
+ };
534
+ };
535
+
536
+ $.Widget = function( /* options, element */ ) {};
537
+ $.Widget._childConstructors = [];
538
+
539
+ $.Widget.prototype = {
540
+ widgetName: "widget",
541
+ widgetEventPrefix: "",
542
+ defaultElement: "<div>",
543
+ options: {
544
+ disabled: false,
545
+
546
+ // callbacks
547
+ create: null
548
+ },
549
+ _createWidget: function( options, element ) {
550
+ element = $( element || this.defaultElement || this )[ 0 ];
551
+ this.element = $( element );
552
+ this.uuid = uuid++;
553
+ this.eventNamespace = "." + this.widgetName + this.uuid;
554
+ this.options = $.widget.extend( {},
555
+ this.options,
556
+ this._getCreateOptions(),
557
+ options );
558
+
559
+ this.bindings = $();
560
+ this.hoverable = $();
561
+ this.focusable = $();
562
+
563
+ if ( element !== this ) {
564
+ // 1.9 BC for #7810
565
+ // TODO remove dual storage
566
+ $.data( element, this.widgetName, this );
567
+ $.data( element, this.widgetFullName, this );
568
+ this._on( this.element, {
569
+ remove: function( event ) {
570
+ if ( event.target === element ) {
571
+ this.destroy();
572
+ }
573
+ }
574
+ });
575
+ this.document = $( element.style ?
576
+ // element within the document
577
+ element.ownerDocument :
578
+ // element is window or document
579
+ element.document || element );
580
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
581
+ }
582
+
583
+ this._create();
584
+ this._trigger( "create", null, this._getCreateEventData() );
585
+ this._init();
586
+ },
587
+ _getCreateOptions: $.noop,
588
+ _getCreateEventData: $.noop,
589
+ _create: $.noop,
590
+ _init: $.noop,
591
+
592
+ destroy: function() {
593
+ this._destroy();
594
+ // we can probably remove the unbind calls in 2.0
595
+ // all event bindings should go through this._on()
596
+ this.element
597
+ .unbind( this.eventNamespace )
598
+ // 1.9 BC for #7810
599
+ // TODO remove dual storage
600
+ .removeData( this.widgetName )
601
+ .removeData( this.widgetFullName )
602
+ // support: jquery <1.6.3
603
+ // http://bugs.jquery.com/ticket/9413
604
+ .removeData( $.camelCase( this.widgetFullName ) );
605
+ this.widget()
606
+ .unbind( this.eventNamespace )
607
+ .removeAttr( "aria-disabled" )
608
+ .removeClass(
609
+ this.widgetFullName + "-disabled " +
610
+ "ui-state-disabled" );
611
+
612
+ // clean up events and states
613
+ this.bindings.unbind( this.eventNamespace );
614
+ this.hoverable.removeClass( "ui-state-hover" );
615
+ this.focusable.removeClass( "ui-state-focus" );
616
+ },
617
+ _destroy: $.noop,
618
+
619
+ widget: function() {
620
+ return this.element;
621
+ },
622
+
623
+ option: function( key, value ) {
624
+ var options = key,
625
+ parts,
626
+ curOption,
627
+ i;
628
+
629
+ if ( arguments.length === 0 ) {
630
+ // don't return a reference to the internal hash
631
+ return $.widget.extend( {}, this.options );
632
+ }
633
+
634
+ if ( typeof key === "string" ) {
635
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
636
+ options = {};
637
+ parts = key.split( "." );
638
+ key = parts.shift();
639
+ if ( parts.length ) {
640
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
641
+ for ( i = 0; i < parts.length - 1; i++ ) {
642
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
643
+ curOption = curOption[ parts[ i ] ];
644
+ }
645
+ key = parts.pop();
646
+ if ( value === undefined ) {
647
+ return curOption[ key ] === undefined ? null : curOption[ key ];
648
+ }
649
+ curOption[ key ] = value;
650
+ } else {
651
+ if ( value === undefined ) {
652
+ return this.options[ key ] === undefined ? null : this.options[ key ];
653
+ }
654
+ options[ key ] = value;
655
+ }
656
+ }
657
+
658
+ this._setOptions( options );
659
+
660
+ return this;
661
+ },
662
+ _setOptions: function( options ) {
663
+ var key;
664
+
665
+ for ( key in options ) {
666
+ this._setOption( key, options[ key ] );
667
+ }
668
+
669
+ return this;
670
+ },
671
+ _setOption: function( key, value ) {
672
+ this.options[ key ] = value;
673
+
674
+ if ( key === "disabled" ) {
675
+ this.widget()
676
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
677
+ .attr( "aria-disabled", value );
678
+ this.hoverable.removeClass( "ui-state-hover" );
679
+ this.focusable.removeClass( "ui-state-focus" );
680
+ }
681
+
682
+ return this;
683
+ },
684
+
685
+ enable: function() {
686
+ return this._setOption( "disabled", false );
687
+ },
688
+ disable: function() {
689
+ return this._setOption( "disabled", true );
690
+ },
691
+
692
+ _on: function( element, handlers ) {
693
+ var delegateElement,
694
+ instance = this;
695
+ // no element argument, shuffle and use this.element
696
+ if ( !handlers ) {
697
+ handlers = element;
698
+ element = this.element;
699
+ delegateElement = this.widget();
700
+ } else {
701
+ // accept selectors, DOM elements
702
+ element = delegateElement = $( element );
703
+ this.bindings = this.bindings.add( element );
704
+ }
705
+
706
+ $.each( handlers, function( event, handler ) {
707
+ function handlerProxy() {
708
+ // allow widgets to customize the disabled handling
709
+ // - disabled as an array instead of boolean
710
+ // - disabled class as method for disabling individual parts
711
+ if ( instance.options.disabled === true ||
712
+ $( this ).hasClass( "ui-state-disabled" ) ) {
713
+ return;
714
+ }
715
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
716
+ .apply( instance, arguments );
717
+ }
718
+
719
+ // copy the guid so direct unbinding works
720
+ if ( typeof handler !== "string" ) {
721
+ handlerProxy.guid = handler.guid =
722
+ handler.guid || handlerProxy.guid || $.guid++;
723
+ }
724
+
725
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
726
+ eventName = match[1] + instance.eventNamespace,
727
+ selector = match[2];
728
+ if ( selector ) {
729
+ delegateElement.delegate( selector, eventName, handlerProxy );
730
+ } else {
731
+ element.bind( eventName, handlerProxy );
732
+ }
733
+ });
734
+ },
735
+
736
+ _off: function( element, eventName ) {
737
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
738
+ element.unbind( eventName ).undelegate( eventName );
739
+ },
740
+
741
+ _delay: function( handler, delay ) {
742
+ function handlerProxy() {
743
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
744
+ .apply( instance, arguments );
745
+ }
746
+ var instance = this;
747
+ return setTimeout( handlerProxy, delay || 0 );
748
+ },
749
+
750
+ _hoverable: function( element ) {
751
+ this.hoverable = this.hoverable.add( element );
752
+ this._on( element, {
753
+ mouseenter: function( event ) {
754
+ $( event.currentTarget ).addClass( "ui-state-hover" );
755
+ },
756
+ mouseleave: function( event ) {
757
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
758
+ }
759
+ });
760
+ },
761
+
762
+ _focusable: function( element ) {
763
+ this.focusable = this.focusable.add( element );
764
+ this._on( element, {
765
+ focusin: function( event ) {
766
+ $( event.currentTarget ).addClass( "ui-state-focus" );
767
+ },
768
+ focusout: function( event ) {
769
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
770
+ }
771
+ });
772
+ },
773
+
774
+ _trigger: function( type, event, data ) {
775
+ var prop, orig,
776
+ callback = this.options[ type ];
777
+
778
+ data = data || {};
779
+ event = $.Event( event );
780
+ event.type = ( type === this.widgetEventPrefix ?
781
+ type :
782
+ this.widgetEventPrefix + type ).toLowerCase();
783
+ // the original event may come from any element
784
+ // so we need to reset the target on the new event
785
+ event.target = this.element[ 0 ];
786
+
787
+ // copy original event properties over to the new event
788
+ orig = event.originalEvent;
789
+ if ( orig ) {
790
+ for ( prop in orig ) {
791
+ if ( !( prop in event ) ) {
792
+ event[ prop ] = orig[ prop ];
793
+ }
794
+ }
795
+ }
796
+
797
+ this.element.trigger( event, data );
798
+ return !( $.isFunction( callback ) &&
799
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
800
+ event.isDefaultPrevented() );
801
+ }
802
+ };
803
+
804
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
805
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
806
+ if ( typeof options === "string" ) {
807
+ options = { effect: options };
808
+ }
809
+ var hasOptions,
810
+ effectName = !options ?
811
+ method :
812
+ options === true || typeof options === "number" ?
813
+ defaultEffect :
814
+ options.effect || defaultEffect;
815
+ options = options || {};
816
+ if ( typeof options === "number" ) {
817
+ options = { duration: options };
818
+ }
819
+ hasOptions = !$.isEmptyObject( options );
820
+ options.complete = callback;
821
+ if ( options.delay ) {
822
+ element.delay( options.delay );
823
+ }
824
+ if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
825
+ element[ method ]( options );
826
+ } else if ( effectName !== method && element[ effectName ] ) {
827
+ element[ effectName ]( options.duration, options.easing, callback );
828
+ } else {
829
+ element.queue(function( next ) {
830
+ $( this )[ method ]();
831
+ if ( callback ) {
832
+ callback.call( element[ 0 ] );
833
+ }
834
+ next();
835
+ });
836
+ }
837
+ };
838
+ });
839
+
840
+ // DEPRECATED
841
+ if ( $.uiBackCompat !== false ) {
842
+ $.Widget.prototype._getCreateOptions = function() {
843
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
844
+ };
845
+ }
846
+
847
+ })( jQuery );
848
+ (function( $, undefined ) {
849
+
850
+ var mouseHandled = false;
851
+ $( document ).mouseup( function( e ) {
852
+ mouseHandled = false;
853
+ });
854
+
855
+ $.widget("ui.mouse", {
856
+ version: "1.9.1",
857
+ options: {
858
+ cancel: 'input,textarea,button,select,option',
859
+ distance: 1,
860
+ delay: 0
861
+ },
862
+ _mouseInit: function() {
863
+ var that = this;
864
+
865
+ this.element
866
+ .bind('mousedown.'+this.widgetName, function(event) {
867
+ return that._mouseDown(event);
868
+ })
869
+ .bind('click.'+this.widgetName, function(event) {
870
+ if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
871
+ $.removeData(event.target, that.widgetName + '.preventClickEvent');
872
+ event.stopImmediatePropagation();
873
+ return false;
874
+ }
875
+ });
876
+
877
+ this.started = false;
878
+ },
879
+
880
+ // TODO: make sure destroying one instance of mouse doesn't mess with
881
+ // other instances of mouse
882
+ _mouseDestroy: function() {
883
+ this.element.unbind('.'+this.widgetName);
884
+ if ( this._mouseMoveDelegate ) {
885
+ $(document)
886
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
887
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
888
+ }
889
+ },
890
+
891
+ _mouseDown: function(event) {
892
+ // don't let more than one widget handle mouseStart
893
+ if( mouseHandled ) { return; }
894
+
895
+ // we may have missed mouseup (out of window)
896
+ (this._mouseStarted && this._mouseUp(event));
897
+
898
+ this._mouseDownEvent = event;
899
+
900
+ var that = this,
901
+ btnIsLeft = (event.which === 1),
902
+ // event.target.nodeName works around a bug in IE 8 with
903
+ // disabled inputs (#7620)
904
+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
905
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
906
+ return true;
907
+ }
908
+
909
+ this.mouseDelayMet = !this.options.delay;
910
+ if (!this.mouseDelayMet) {
911
+ this._mouseDelayTimer = setTimeout(function() {
912
+ that.mouseDelayMet = true;
913
+ }, this.options.delay);
914
+ }
915
+
916
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
917
+ this._mouseStarted = (this._mouseStart(event) !== false);
918
+ if (!this._mouseStarted) {
919
+ event.preventDefault();
920
+ return true;
921
+ }
922
+ }
923
+
924
+ // Click event may never have fired (Gecko & Opera)
925
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
926
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
927
+ }
928
+
929
+ // these delegates are required to keep context
930
+ this._mouseMoveDelegate = function(event) {
931
+ return that._mouseMove(event);
932
+ };
933
+ this._mouseUpDelegate = function(event) {
934
+ return that._mouseUp(event);
935
+ };
936
+ $(document)
937
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
938
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
939
+
940
+ event.preventDefault();
941
+
942
+ mouseHandled = true;
943
+ return true;
944
+ },
945
+
946
+ _mouseMove: function(event) {
947
+ // IE mouseup check - mouseup happened when mouse was out of window
948
+ if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
949
+ return this._mouseUp(event);
950
+ }
951
+
952
+ if (this._mouseStarted) {
953
+ this._mouseDrag(event);
954
+ return event.preventDefault();
955
+ }
956
+
957
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
958
+ this._mouseStarted =
959
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
960
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
961
+ }
962
+
963
+ return !this._mouseStarted;
964
+ },
965
+
966
+ _mouseUp: function(event) {
967
+ $(document)
968
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
969
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
970
+
971
+ if (this._mouseStarted) {
972
+ this._mouseStarted = false;
973
+
974
+ if (event.target === this._mouseDownEvent.target) {
975
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
976
+ }
977
+
978
+ this._mouseStop(event);
979
+ }
980
+
981
+ return false;
982
+ },
983
+
984
+ _mouseDistanceMet: function(event) {
985
+ return (Math.max(
986
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
987
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
988
+ ) >= this.options.distance
989
+ );
990
+ },
991
+
992
+ _mouseDelayMet: function(event) {
993
+ return this.mouseDelayMet;
994
+ },
995
+
996
+ // These are placeholder methods, to be overriden by extending plugin
997
+ _mouseStart: function(event) {},
998
+ _mouseDrag: function(event) {},
999
+ _mouseStop: function(event) {},
1000
+ _mouseCapture: function(event) { return true; }
1001
+ });
1002
+
1003
+ })(jQuery);
1004
+ (function( $, undefined ) {
1005
+
1006
+ $.ui = $.ui || {};
1007
+
1008
+ var cachedScrollbarWidth,
1009
+ max = Math.max,
1010
+ abs = Math.abs,
1011
+ round = Math.round,
1012
+ rhorizontal = /left|center|right/,
1013
+ rvertical = /top|center|bottom/,
1014
+ roffset = /[\+\-]\d+%?/,
1015
+ rposition = /^\w+/,
1016
+ rpercent = /%$/,
1017
+ _position = $.fn.position;
1018
+
1019
+ function getOffsets( offsets, width, height ) {
1020
+ return [
1021
+ parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1022
+ parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1023
+ ];
1024
+ }
1025
+ function parseCss( element, property ) {
1026
+ return parseInt( $.css( element, property ), 10 ) || 0;
1027
+ }
1028
+
1029
+ $.position = {
1030
+ scrollbarWidth: function() {
1031
+ if ( cachedScrollbarWidth !== undefined ) {
1032
+ return cachedScrollbarWidth;
1033
+ }
1034
+ var w1, w2,
1035
+ div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1036
+ innerDiv = div.children()[0];
1037
+
1038
+ $( "body" ).append( div );
1039
+ w1 = innerDiv.offsetWidth;
1040
+ div.css( "overflow", "scroll" );
1041
+
1042
+ w2 = innerDiv.offsetWidth;
1043
+
1044
+ if ( w1 === w2 ) {
1045
+ w2 = div[0].clientWidth;
1046
+ }
1047
+
1048
+ div.remove();
1049
+
1050
+ return (cachedScrollbarWidth = w1 - w2);
1051
+ },
1052
+ getScrollInfo: function( within ) {
1053
+ var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1054
+ overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1055
+ hasOverflowX = overflowX === "scroll" ||
1056
+ ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1057
+ hasOverflowY = overflowY === "scroll" ||
1058
+ ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1059
+ return {
1060
+ width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1061
+ height: hasOverflowY ? $.position.scrollbarWidth() : 0
1062
+ };
1063
+ },
1064
+ getWithinInfo: function( element ) {
1065
+ var withinElement = $( element || window ),
1066
+ isWindow = $.isWindow( withinElement[0] );
1067
+ return {
1068
+ element: withinElement,
1069
+ isWindow: isWindow,
1070
+ offset: withinElement.offset() || { left: 0, top: 0 },
1071
+ scrollLeft: withinElement.scrollLeft(),
1072
+ scrollTop: withinElement.scrollTop(),
1073
+ width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1074
+ height: isWindow ? withinElement.height() : withinElement.outerHeight()
1075
+ };
1076
+ }
1077
+ };
1078
+
1079
+ $.fn.position = function( options ) {
1080
+ if ( !options || !options.of ) {
1081
+ return _position.apply( this, arguments );
1082
+ }
1083
+
1084
+ // make a copy, we don't want to modify arguments
1085
+ options = $.extend( {}, options );
1086
+
1087
+ var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1088
+ target = $( options.of ),
1089
+ within = $.position.getWithinInfo( options.within ),
1090
+ scrollInfo = $.position.getScrollInfo( within ),
1091
+ targetElem = target[0],
1092
+ collision = ( options.collision || "flip" ).split( " " ),
1093
+ offsets = {};
1094
+
1095
+ if ( targetElem.nodeType === 9 ) {
1096
+ targetWidth = target.width();
1097
+ targetHeight = target.height();
1098
+ targetOffset = { top: 0, left: 0 };
1099
+ } else if ( $.isWindow( targetElem ) ) {
1100
+ targetWidth = target.width();
1101
+ targetHeight = target.height();
1102
+ targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1103
+ } else if ( targetElem.preventDefault ) {
1104
+ // force left top to allow flipping
1105
+ options.at = "left top";
1106
+ targetWidth = targetHeight = 0;
1107
+ targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1108
+ } else {
1109
+ targetWidth = target.outerWidth();
1110
+ targetHeight = target.outerHeight();
1111
+ targetOffset = target.offset();
1112
+ }
1113
+ // clone to reuse original targetOffset later
1114
+ basePosition = $.extend( {}, targetOffset );
1115
+
1116
+ // force my and at to have valid horizontal and vertical positions
1117
+ // if a value is missing or invalid, it will be converted to center
1118
+ $.each( [ "my", "at" ], function() {
1119
+ var pos = ( options[ this ] || "" ).split( " " ),
1120
+ horizontalOffset,
1121
+ verticalOffset;
1122
+
1123
+ if ( pos.length === 1) {
1124
+ pos = rhorizontal.test( pos[ 0 ] ) ?
1125
+ pos.concat( [ "center" ] ) :
1126
+ rvertical.test( pos[ 0 ] ) ?
1127
+ [ "center" ].concat( pos ) :
1128
+ [ "center", "center" ];
1129
+ }
1130
+ pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1131
+ pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1132
+
1133
+ // calculate offsets
1134
+ horizontalOffset = roffset.exec( pos[ 0 ] );
1135
+ verticalOffset = roffset.exec( pos[ 1 ] );
1136
+ offsets[ this ] = [
1137
+ horizontalOffset ? horizontalOffset[ 0 ] : 0,
1138
+ verticalOffset ? verticalOffset[ 0 ] : 0
1139
+ ];
1140
+
1141
+ // reduce to just the positions without the offsets
1142
+ options[ this ] = [
1143
+ rposition.exec( pos[ 0 ] )[ 0 ],
1144
+ rposition.exec( pos[ 1 ] )[ 0 ]
1145
+ ];
1146
+ });
1147
+
1148
+ // normalize collision option
1149
+ if ( collision.length === 1 ) {
1150
+ collision[ 1 ] = collision[ 0 ];
1151
+ }
1152
+
1153
+ if ( options.at[ 0 ] === "right" ) {
1154
+ basePosition.left += targetWidth;
1155
+ } else if ( options.at[ 0 ] === "center" ) {
1156
+ basePosition.left += targetWidth / 2;
1157
+ }
1158
+
1159
+ if ( options.at[ 1 ] === "bottom" ) {
1160
+ basePosition.top += targetHeight;
1161
+ } else if ( options.at[ 1 ] === "center" ) {
1162
+ basePosition.top += targetHeight / 2;
1163
+ }
1164
+
1165
+ atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1166
+ basePosition.left += atOffset[ 0 ];
1167
+ basePosition.top += atOffset[ 1 ];
1168
+
1169
+ return this.each(function() {
1170
+ var collisionPosition, using,
1171
+ elem = $( this ),
1172
+ elemWidth = elem.outerWidth(),
1173
+ elemHeight = elem.outerHeight(),
1174
+ marginLeft = parseCss( this, "marginLeft" ),
1175
+ marginTop = parseCss( this, "marginTop" ),
1176
+ collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1177
+ collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1178
+ position = $.extend( {}, basePosition ),
1179
+ myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1180
+
1181
+ if ( options.my[ 0 ] === "right" ) {
1182
+ position.left -= elemWidth;
1183
+ } else if ( options.my[ 0 ] === "center" ) {
1184
+ position.left -= elemWidth / 2;
1185
+ }
1186
+
1187
+ if ( options.my[ 1 ] === "bottom" ) {
1188
+ position.top -= elemHeight;
1189
+ } else if ( options.my[ 1 ] === "center" ) {
1190
+ position.top -= elemHeight / 2;
1191
+ }
1192
+
1193
+ position.left += myOffset[ 0 ];
1194
+ position.top += myOffset[ 1 ];
1195
+
1196
+ // if the browser doesn't support fractions, then round for consistent results
1197
+ if ( !$.support.offsetFractions ) {
1198
+ position.left = round( position.left );
1199
+ position.top = round( position.top );
1200
+ }
1201
+
1202
+ collisionPosition = {
1203
+ marginLeft: marginLeft,
1204
+ marginTop: marginTop
1205
+ };
1206
+
1207
+ $.each( [ "left", "top" ], function( i, dir ) {
1208
+ if ( $.ui.position[ collision[ i ] ] ) {
1209
+ $.ui.position[ collision[ i ] ][ dir ]( position, {
1210
+ targetWidth: targetWidth,
1211
+ targetHeight: targetHeight,
1212
+ elemWidth: elemWidth,
1213
+ elemHeight: elemHeight,
1214
+ collisionPosition: collisionPosition,
1215
+ collisionWidth: collisionWidth,
1216
+ collisionHeight: collisionHeight,
1217
+ offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1218
+ my: options.my,
1219
+ at: options.at,
1220
+ within: within,
1221
+ elem : elem
1222
+ });
1223
+ }
1224
+ });
1225
+
1226
+ if ( $.fn.bgiframe ) {
1227
+ elem.bgiframe();
1228
+ }
1229
+
1230
+ if ( options.using ) {
1231
+ // adds feedback as second argument to using callback, if present
1232
+ using = function( props ) {
1233
+ var left = targetOffset.left - position.left,
1234
+ right = left + targetWidth - elemWidth,
1235
+ top = targetOffset.top - position.top,
1236
+ bottom = top + targetHeight - elemHeight,
1237
+ feedback = {
1238
+ target: {
1239
+ element: target,
1240
+ left: targetOffset.left,
1241
+ top: targetOffset.top,
1242
+ width: targetWidth,
1243
+ height: targetHeight
1244
+ },
1245
+ element: {
1246
+ element: elem,
1247
+ left: position.left,
1248
+ top: position.top,
1249
+ width: elemWidth,
1250
+ height: elemHeight
1251
+ },
1252
+ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1253
+ vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1254
+ };
1255
+ if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1256
+ feedback.horizontal = "center";
1257
+ }
1258
+ if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1259
+ feedback.vertical = "middle";
1260
+ }
1261
+ if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1262
+ feedback.important = "horizontal";
1263
+ } else {
1264
+ feedback.important = "vertical";
1265
+ }
1266
+ options.using.call( this, props, feedback );
1267
+ };
1268
+ }
1269
+
1270
+ elem.offset( $.extend( position, { using: using } ) );
1271
+ });
1272
+ };
1273
+
1274
+ $.ui.position = {
1275
+ fit: {
1276
+ left: function( position, data ) {
1277
+ var within = data.within,
1278
+ withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1279
+ outerWidth = within.width,
1280
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1281
+ overLeft = withinOffset - collisionPosLeft,
1282
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1283
+ newOverRight;
1284
+
1285
+ // element is wider than within
1286
+ if ( data.collisionWidth > outerWidth ) {
1287
+ // element is initially over the left side of within
1288
+ if ( overLeft > 0 && overRight <= 0 ) {
1289
+ newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1290
+ position.left += overLeft - newOverRight;
1291
+ // element is initially over right side of within
1292
+ } else if ( overRight > 0 && overLeft <= 0 ) {
1293
+ position.left = withinOffset;
1294
+ // element is initially over both left and right sides of within
1295
+ } else {
1296
+ if ( overLeft > overRight ) {
1297
+ position.left = withinOffset + outerWidth - data.collisionWidth;
1298
+ } else {
1299
+ position.left = withinOffset;
1300
+ }
1301
+ }
1302
+ // too far left -> align with left edge
1303
+ } else if ( overLeft > 0 ) {
1304
+ position.left += overLeft;
1305
+ // too far right -> align with right edge
1306
+ } else if ( overRight > 0 ) {
1307
+ position.left -= overRight;
1308
+ // adjust based on position and margin
1309
+ } else {
1310
+ position.left = max( position.left - collisionPosLeft, position.left );
1311
+ }
1312
+ },
1313
+ top: function( position, data ) {
1314
+ var within = data.within,
1315
+ withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1316
+ outerHeight = data.within.height,
1317
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1318
+ overTop = withinOffset - collisionPosTop,
1319
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1320
+ newOverBottom;
1321
+
1322
+ // element is taller than within
1323
+ if ( data.collisionHeight > outerHeight ) {
1324
+ // element is initially over the top of within
1325
+ if ( overTop > 0 && overBottom <= 0 ) {
1326
+ newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1327
+ position.top += overTop - newOverBottom;
1328
+ // element is initially over bottom of within
1329
+ } else if ( overBottom > 0 && overTop <= 0 ) {
1330
+ position.top = withinOffset;
1331
+ // element is initially over both top and bottom of within
1332
+ } else {
1333
+ if ( overTop > overBottom ) {
1334
+ position.top = withinOffset + outerHeight - data.collisionHeight;
1335
+ } else {
1336
+ position.top = withinOffset;
1337
+ }
1338
+ }
1339
+ // too far up -> align with top
1340
+ } else if ( overTop > 0 ) {
1341
+ position.top += overTop;
1342
+ // too far down -> align with bottom edge
1343
+ } else if ( overBottom > 0 ) {
1344
+ position.top -= overBottom;
1345
+ // adjust based on position and margin
1346
+ } else {
1347
+ position.top = max( position.top - collisionPosTop, position.top );
1348
+ }
1349
+ }
1350
+ },
1351
+ flip: {
1352
+ left: function( position, data ) {
1353
+ var within = data.within,
1354
+ withinOffset = within.offset.left + within.scrollLeft,
1355
+ outerWidth = within.width,
1356
+ offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1357
+ collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1358
+ overLeft = collisionPosLeft - offsetLeft,
1359
+ overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1360
+ myOffset = data.my[ 0 ] === "left" ?
1361
+ -data.elemWidth :
1362
+ data.my[ 0 ] === "right" ?
1363
+ data.elemWidth :
1364
+ 0,
1365
+ atOffset = data.at[ 0 ] === "left" ?
1366
+ data.targetWidth :
1367
+ data.at[ 0 ] === "right" ?
1368
+ -data.targetWidth :
1369
+ 0,
1370
+ offset = -2 * data.offset[ 0 ],
1371
+ newOverRight,
1372
+ newOverLeft;
1373
+
1374
+ if ( overLeft < 0 ) {
1375
+ newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1376
+ if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1377
+ position.left += myOffset + atOffset + offset;
1378
+ }
1379
+ }
1380
+ else if ( overRight > 0 ) {
1381
+ newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1382
+ if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1383
+ position.left += myOffset + atOffset + offset;
1384
+ }
1385
+ }
1386
+ },
1387
+ top: function( position, data ) {
1388
+ var within = data.within,
1389
+ withinOffset = within.offset.top + within.scrollTop,
1390
+ outerHeight = within.height,
1391
+ offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1392
+ collisionPosTop = position.top - data.collisionPosition.marginTop,
1393
+ overTop = collisionPosTop - offsetTop,
1394
+ overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1395
+ top = data.my[ 1 ] === "top",
1396
+ myOffset = top ?
1397
+ -data.elemHeight :
1398
+ data.my[ 1 ] === "bottom" ?
1399
+ data.elemHeight :
1400
+ 0,
1401
+ atOffset = data.at[ 1 ] === "top" ?
1402
+ data.targetHeight :
1403
+ data.at[ 1 ] === "bottom" ?
1404
+ -data.targetHeight :
1405
+ 0,
1406
+ offset = -2 * data.offset[ 1 ],
1407
+ newOverTop,
1408
+ newOverBottom;
1409
+ if ( overTop < 0 ) {
1410
+ newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1411
+ if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1412
+ position.top += myOffset + atOffset + offset;
1413
+ }
1414
+ }
1415
+ else if ( overBottom > 0 ) {
1416
+ newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1417
+ if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1418
+ position.top += myOffset + atOffset + offset;
1419
+ }
1420
+ }
1421
+ }
1422
+ },
1423
+ flipfit: {
1424
+ left: function() {
1425
+ $.ui.position.flip.left.apply( this, arguments );
1426
+ $.ui.position.fit.left.apply( this, arguments );
1427
+ },
1428
+ top: function() {
1429
+ $.ui.position.flip.top.apply( this, arguments );
1430
+ $.ui.position.fit.top.apply( this, arguments );
1431
+ }
1432
+ }
1433
+ };
1434
+
1435
+ // fraction support test
1436
+ (function () {
1437
+ var testElement, testElementParent, testElementStyle, offsetLeft, i,
1438
+ body = document.getElementsByTagName( "body" )[ 0 ],
1439
+ div = document.createElement( "div" );
1440
+
1441
+ //Create a "fake body" for testing based on method used in jQuery.support
1442
+ testElement = document.createElement( body ? "div" : "body" );
1443
+ testElementStyle = {
1444
+ visibility: "hidden",
1445
+ width: 0,
1446
+ height: 0,
1447
+ border: 0,
1448
+ margin: 0,
1449
+ background: "none"
1450
+ };
1451
+ if ( body ) {
1452
+ $.extend( testElementStyle, {
1453
+ position: "absolute",
1454
+ left: "-1000px",
1455
+ top: "-1000px"
1456
+ });
1457
+ }
1458
+ for ( i in testElementStyle ) {
1459
+ testElement.style[ i ] = testElementStyle[ i ];
1460
+ }
1461
+ testElement.appendChild( div );
1462
+ testElementParent = body || document.documentElement;
1463
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
1464
+
1465
+ div.style.cssText = "position: absolute; left: 10.7432222px;";
1466
+
1467
+ offsetLeft = $( div ).offset().left;
1468
+ $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1469
+
1470
+ testElement.innerHTML = "";
1471
+ testElementParent.removeChild( testElement );
1472
+ })();
1473
+
1474
+ // DEPRECATED
1475
+ if ( $.uiBackCompat !== false ) {
1476
+ // offset option
1477
+ (function( $ ) {
1478
+ var _position = $.fn.position;
1479
+ $.fn.position = function( options ) {
1480
+ if ( !options || !options.offset ) {
1481
+ return _position.call( this, options );
1482
+ }
1483
+ var offset = options.offset.split( " " ),
1484
+ at = options.at.split( " " );
1485
+ if ( offset.length === 1 ) {
1486
+ offset[ 1 ] = offset[ 0 ];
1487
+ }
1488
+ if ( /^\d/.test( offset[ 0 ] ) ) {
1489
+ offset[ 0 ] = "+" + offset[ 0 ];
1490
+ }
1491
+ if ( /^\d/.test( offset[ 1 ] ) ) {
1492
+ offset[ 1 ] = "+" + offset[ 1 ];
1493
+ }
1494
+ if ( at.length === 1 ) {
1495
+ if ( /left|center|right/.test( at[ 0 ] ) ) {
1496
+ at[ 1 ] = "center";
1497
+ } else {
1498
+ at[ 1 ] = at[ 0 ];
1499
+ at[ 0 ] = "center";
1500
+ }
1501
+ }
1502
+ return _position.call( this, $.extend( options, {
1503
+ at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1504
+ offset: undefined
1505
+ } ) );
1506
+ };
1507
+ }( jQuery ) );
1508
+ }
1509
+
1510
+ }( jQuery ) );
1511
+ (function( $, undefined ) {
1512
+
1513
+ $.widget("ui.draggable", $.ui.mouse, {
1514
+ version: "1.9.1",
1515
+ widgetEventPrefix: "drag",
1516
+ options: {
1517
+ addClasses: true,
1518
+ appendTo: "parent",
1519
+ axis: false,
1520
+ connectToSortable: false,
1521
+ containment: false,
1522
+ cursor: "auto",
1523
+ cursorAt: false,
1524
+ grid: false,
1525
+ handle: false,
1526
+ helper: "original",
1527
+ iframeFix: false,
1528
+ opacity: false,
1529
+ refreshPositions: false,
1530
+ revert: false,
1531
+ revertDuration: 500,
1532
+ scope: "default",
1533
+ scroll: true,
1534
+ scrollSensitivity: 20,
1535
+ scrollSpeed: 20,
1536
+ snap: false,
1537
+ snapMode: "both",
1538
+ snapTolerance: 20,
1539
+ stack: false,
1540
+ zIndex: false
1541
+ },
1542
+ _create: function() {
1543
+
1544
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1545
+ this.element[0].style.position = 'relative';
1546
+
1547
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
1548
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1549
+
1550
+ this._mouseInit();
1551
+
1552
+ },
1553
+
1554
+ _destroy: function() {
1555
+ this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1556
+ this._mouseDestroy();
1557
+ },
1558
+
1559
+ _mouseCapture: function(event) {
1560
+
1561
+ var o = this.options;
1562
+
1563
+ // among others, prevent a drag on a resizable-handle
1564
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1565
+ return false;
1566
+
1567
+ //Quit if we're not on a valid handle
1568
+ this.handle = this._getHandle(event);
1569
+ if (!this.handle)
1570
+ return false;
1571
+
1572
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1573
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1574
+ .css({
1575
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1576
+ position: "absolute", opacity: "0.001", zIndex: 1000
1577
+ })
1578
+ .css($(this).offset())
1579
+ .appendTo("body");
1580
+ });
1581
+
1582
+ return true;
1583
+
1584
+ },
1585
+
1586
+ _mouseStart: function(event) {
1587
+
1588
+ var o = this.options;
1589
+
1590
+ //Create and append the visible helper
1591
+ this.helper = this._createHelper(event);
1592
+
1593
+ this.helper.addClass("ui-draggable-dragging");
1594
+
1595
+ //Cache the helper size
1596
+ this._cacheHelperProportions();
1597
+
1598
+ //If ddmanager is used for droppables, set the global draggable
1599
+ if($.ui.ddmanager)
1600
+ $.ui.ddmanager.current = this;
1601
+
1602
+ /*
1603
+ * - Position generation -
1604
+ * This block generates everything position related - it's the core of draggables.
1605
+ */
1606
+
1607
+ //Cache the margins of the original element
1608
+ this._cacheMargins();
1609
+
1610
+ //Store the helper's css position
1611
+ this.cssPosition = this.helper.css("position");
1612
+ this.scrollParent = this.helper.scrollParent();
1613
+
1614
+ //The element's absolute position on the page minus margins
1615
+ this.offset = this.positionAbs = this.element.offset();
1616
+ this.offset = {
1617
+ top: this.offset.top - this.margins.top,
1618
+ left: this.offset.left - this.margins.left
1619
+ };
1620
+
1621
+ $.extend(this.offset, {
1622
+ click: { //Where the click happened, relative to the element
1623
+ left: event.pageX - this.offset.left,
1624
+ top: event.pageY - this.offset.top
1625
+ },
1626
+ parent: this._getParentOffset(),
1627
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1628
+ });
1629
+
1630
+ //Generate the original position
1631
+ this.originalPosition = this.position = this._generatePosition(event);
1632
+ this.originalPageX = event.pageX;
1633
+ this.originalPageY = event.pageY;
1634
+
1635
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1636
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1637
+
1638
+ //Set a containment if given in the options
1639
+ if(o.containment)
1640
+ this._setContainment();
1641
+
1642
+ //Trigger event + callbacks
1643
+ if(this._trigger("start", event) === false) {
1644
+ this._clear();
1645
+ return false;
1646
+ }
1647
+
1648
+ //Recache the helper size
1649
+ this._cacheHelperProportions();
1650
+
1651
+ //Prepare the droppable offsets
1652
+ if ($.ui.ddmanager && !o.dropBehaviour)
1653
+ $.ui.ddmanager.prepareOffsets(this, event);
1654
+
1655
+
1656
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1657
+
1658
+ //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1659
+ if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1660
+
1661
+ return true;
1662
+ },
1663
+
1664
+ _mouseDrag: function(event, noPropagation) {
1665
+
1666
+ //Compute the helpers position
1667
+ this.position = this._generatePosition(event);
1668
+ this.positionAbs = this._convertPositionTo("absolute");
1669
+
1670
+ //Call plugins and callbacks and use the resulting position if something is returned
1671
+ if (!noPropagation) {
1672
+ var ui = this._uiHash();
1673
+ if(this._trigger('drag', event, ui) === false) {
1674
+ this._mouseUp({});
1675
+ return false;
1676
+ }
1677
+ this.position = ui.position;
1678
+ }
1679
+
1680
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1681
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1682
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1683
+
1684
+ return false;
1685
+ },
1686
+
1687
+ _mouseStop: function(event) {
1688
+
1689
+ //If we are using droppables, inform the manager about the drop
1690
+ var dropped = false;
1691
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
1692
+ dropped = $.ui.ddmanager.drop(this, event);
1693
+
1694
+ //if a drop comes from outside (a sortable)
1695
+ if(this.dropped) {
1696
+ dropped = this.dropped;
1697
+ this.dropped = false;
1698
+ }
1699
+
1700
+ //if the original element is no longer in the DOM don't bother to continue (see #8269)
1701
+ var element = this.element[0], elementInDom = false;
1702
+ while ( element && (element = element.parentNode) ) {
1703
+ if (element == document ) {
1704
+ elementInDom = true;
1705
+ }
1706
+ }
1707
+ if ( !elementInDom && this.options.helper === "original" )
1708
+ return false;
1709
+
1710
+ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1711
+ var that = this;
1712
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1713
+ if(that._trigger("stop", event) !== false) {
1714
+ that._clear();
1715
+ }
1716
+ });
1717
+ } else {
1718
+ if(this._trigger("stop", event) !== false) {
1719
+ this._clear();
1720
+ }
1721
+ }
1722
+
1723
+ return false;
1724
+ },
1725
+
1726
+ _mouseUp: function(event) {
1727
+ //Remove frame helpers
1728
+ $("div.ui-draggable-iframeFix").each(function() {
1729
+ this.parentNode.removeChild(this);
1730
+ });
1731
+
1732
+ //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1733
+ if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1734
+
1735
+ return $.ui.mouse.prototype._mouseUp.call(this, event);
1736
+ },
1737
+
1738
+ cancel: function() {
1739
+
1740
+ if(this.helper.is(".ui-draggable-dragging")) {
1741
+ this._mouseUp({});
1742
+ } else {
1743
+ this._clear();
1744
+ }
1745
+
1746
+ return this;
1747
+
1748
+ },
1749
+
1750
+ _getHandle: function(event) {
1751
+
1752
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1753
+ $(this.options.handle, this.element)
1754
+ .find("*")
1755
+ .andSelf()
1756
+ .each(function() {
1757
+ if(this == event.target) handle = true;
1758
+ });
1759
+
1760
+ return handle;
1761
+
1762
+ },
1763
+
1764
+ _createHelper: function(event) {
1765
+
1766
+ var o = this.options;
1767
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1768
+
1769
+ if(!helper.parents('body').length)
1770
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1771
+
1772
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1773
+ helper.css("position", "absolute");
1774
+
1775
+ return helper;
1776
+
1777
+ },
1778
+
1779
+ _adjustOffsetFromHelper: function(obj) {
1780
+ if (typeof obj == 'string') {
1781
+ obj = obj.split(' ');
1782
+ }
1783
+ if ($.isArray(obj)) {
1784
+ obj = {left: +obj[0], top: +obj[1] || 0};
1785
+ }
1786
+ if ('left' in obj) {
1787
+ this.offset.click.left = obj.left + this.margins.left;
1788
+ }
1789
+ if ('right' in obj) {
1790
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1791
+ }
1792
+ if ('top' in obj) {
1793
+ this.offset.click.top = obj.top + this.margins.top;
1794
+ }
1795
+ if ('bottom' in obj) {
1796
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1797
+ }
1798
+ },
1799
+
1800
+ _getParentOffset: function() {
1801
+
1802
+ //Get the offsetParent and cache its position
1803
+ this.offsetParent = this.helper.offsetParent();
1804
+ var po = this.offsetParent.offset();
1805
+
1806
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
1807
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1808
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1809
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1810
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1811
+ po.left += this.scrollParent.scrollLeft();
1812
+ po.top += this.scrollParent.scrollTop();
1813
+ }
1814
+
1815
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1816
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1817
+ po = { top: 0, left: 0 };
1818
+
1819
+ return {
1820
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1821
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1822
+ };
1823
+
1824
+ },
1825
+
1826
+ _getRelativeOffset: function() {
1827
+
1828
+ if(this.cssPosition == "relative") {
1829
+ var p = this.element.position();
1830
+ return {
1831
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1832
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1833
+ };
1834
+ } else {
1835
+ return { top: 0, left: 0 };
1836
+ }
1837
+
1838
+ },
1839
+
1840
+ _cacheMargins: function() {
1841
+ this.margins = {
1842
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
1843
+ top: (parseInt(this.element.css("marginTop"),10) || 0),
1844
+ right: (parseInt(this.element.css("marginRight"),10) || 0),
1845
+ bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1846
+ };
1847
+ },
1848
+
1849
+ _cacheHelperProportions: function() {
1850
+ this.helperProportions = {
1851
+ width: this.helper.outerWidth(),
1852
+ height: this.helper.outerHeight()
1853
+ };
1854
+ },
1855
+
1856
+ _setContainment: function() {
1857
+
1858
+ var o = this.options;
1859
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1860
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
1861
+ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1862
+ o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1863
+ (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1864
+ (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1865
+ ];
1866
+
1867
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1868
+ var c = $(o.containment);
1869
+ var ce = c[0]; if(!ce) return;
1870
+ var co = c.offset();
1871
+ var over = ($(ce).css("overflow") != 'hidden');
1872
+
1873
+ this.containment = [
1874
+ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1875
+ (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1876
+ (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1877
+ (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
1878
+ ];
1879
+ this.relative_container = c;
1880
+
1881
+ } else if(o.containment.constructor == Array) {
1882
+ this.containment = o.containment;
1883
+ }
1884
+
1885
+ },
1886
+
1887
+ _convertPositionTo: function(d, pos) {
1888
+
1889
+ if(!pos) pos = this.position;
1890
+ var mod = d == "absolute" ? 1 : -1;
1891
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1892
+
1893
+ return {
1894
+ top: (
1895
+ pos.top // The absolute mouse position
1896
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1897
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1898
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1899
+ ),
1900
+ left: (
1901
+ pos.left // The absolute mouse position
1902
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1903
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1904
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1905
+ )
1906
+ };
1907
+
1908
+ },
1909
+
1910
+ _generatePosition: function(event) {
1911
+
1912
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1913
+ var pageX = event.pageX;
1914
+ var pageY = event.pageY;
1915
+
1916
+ /*
1917
+ * - Position constraining -
1918
+ * Constrain the position to a mix of grid, containment.
1919
+ */
1920
+
1921
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1922
+ var containment;
1923
+ if(this.containment) {
1924
+ if (this.relative_container){
1925
+ var co = this.relative_container.offset();
1926
+ containment = [ this.containment[0] + co.left,
1927
+ this.containment[1] + co.top,
1928
+ this.containment[2] + co.left,
1929
+ this.containment[3] + co.top ];
1930
+ }
1931
+ else {
1932
+ containment = this.containment;
1933
+ }
1934
+
1935
+ if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1936
+ if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1937
+ if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1938
+ if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1939
+ }
1940
+
1941
+ if(o.grid) {
1942
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1943
+ var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1944
+ pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1945
+
1946
+ var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1947
+ pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1948
+ }
1949
+
1950
+ }
1951
+
1952
+ return {
1953
+ top: (
1954
+ pageY // The absolute mouse position
1955
+ - this.offset.click.top // Click offset (relative to the element)
1956
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1957
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1958
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1959
+ ),
1960
+ left: (
1961
+ pageX // The absolute mouse position
1962
+ - this.offset.click.left // Click offset (relative to the element)
1963
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1964
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1965
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1966
+ )
1967
+ };
1968
+
1969
+ },
1970
+
1971
+ _clear: function() {
1972
+ this.helper.removeClass("ui-draggable-dragging");
1973
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1974
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1975
+ this.helper = null;
1976
+ this.cancelHelperRemoval = false;
1977
+ },
1978
+
1979
+ // From now on bulk stuff - mainly helpers
1980
+
1981
+ _trigger: function(type, event, ui) {
1982
+ ui = ui || this._uiHash();
1983
+ $.ui.plugin.call(this, type, [event, ui]);
1984
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1985
+ return $.Widget.prototype._trigger.call(this, type, event, ui);
1986
+ },
1987
+
1988
+ plugins: {},
1989
+
1990
+ _uiHash: function(event) {
1991
+ return {
1992
+ helper: this.helper,
1993
+ position: this.position,
1994
+ originalPosition: this.originalPosition,
1995
+ offset: this.positionAbs
1996
+ };
1997
+ }
1998
+
1999
+ });
2000
+
2001
+ $.ui.plugin.add("draggable", "connectToSortable", {
2002
+ start: function(event, ui) {
2003
+
2004
+ var inst = $(this).data("draggable"), o = inst.options,
2005
+ uiSortable = $.extend({}, ui, { item: inst.element });
2006
+ inst.sortables = [];
2007
+ $(o.connectToSortable).each(function() {
2008
+ var sortable = $.data(this, 'sortable');
2009
+ if (sortable && !sortable.options.disabled) {
2010
+ inst.sortables.push({
2011
+ instance: sortable,
2012
+ shouldRevert: sortable.options.revert
2013
+ });
2014
+ sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
2015
+ sortable._trigger("activate", event, uiSortable);
2016
+ }
2017
+ });
2018
+
2019
+ },
2020
+ stop: function(event, ui) {
2021
+
2022
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2023
+ var inst = $(this).data("draggable"),
2024
+ uiSortable = $.extend({}, ui, { item: inst.element });
2025
+
2026
+ $.each(inst.sortables, function() {
2027
+ if(this.instance.isOver) {
2028
+
2029
+ this.instance.isOver = 0;
2030
+
2031
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2032
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2033
+
2034
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
2035
+ if(this.shouldRevert) this.instance.options.revert = true;
2036
+
2037
+ //Trigger the stop of the sortable
2038
+ this.instance._mouseStop(event);
2039
+
2040
+ this.instance.options.helper = this.instance.options._helper;
2041
+
2042
+ //If the helper has been the original item, restore properties in the sortable
2043
+ if(inst.options.helper == 'original')
2044
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
2045
+
2046
+ } else {
2047
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2048
+ this.instance._trigger("deactivate", event, uiSortable);
2049
+ }
2050
+
2051
+ });
2052
+
2053
+ },
2054
+ drag: function(event, ui) {
2055
+
2056
+ var inst = $(this).data("draggable"), that = this;
2057
+
2058
+ var checkPos = function(o) {
2059
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2060
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2061
+ var itemHeight = o.height, itemWidth = o.width;
2062
+ var itemTop = o.top, itemLeft = o.left;
2063
+
2064
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2065
+ };
2066
+
2067
+ $.each(inst.sortables, function(i) {
2068
+
2069
+ var innermostIntersecting = false;
2070
+ var thisSortable = this;
2071
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
2072
+ this.instance.positionAbs = inst.positionAbs;
2073
+ this.instance.helperProportions = inst.helperProportions;
2074
+ this.instance.offset.click = inst.offset.click;
2075
+
2076
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
2077
+ innermostIntersecting = true;
2078
+ $.each(inst.sortables, function () {
2079
+ this.instance.positionAbs = inst.positionAbs;
2080
+ this.instance.helperProportions = inst.helperProportions;
2081
+ this.instance.offset.click = inst.offset.click;
2082
+ if (this != thisSortable
2083
+ && this.instance._intersectsWith(this.instance.containerCache)
2084
+ && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
2085
+ innermostIntersecting = false;
2086
+ return innermostIntersecting;
2087
+ });
2088
+ }
2089
+
2090
+
2091
+ if(innermostIntersecting) {
2092
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2093
+ if(!this.instance.isOver) {
2094
+
2095
+ this.instance.isOver = 1;
2096
+ //Now we fake the start of dragging for the sortable instance,
2097
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2098
+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
2099
+ this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
2100
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2101
+ this.instance.options.helper = function() { return ui.helper[0]; };
2102
+
2103
+ event.target = this.instance.currentItem[0];
2104
+ this.instance._mouseCapture(event, true);
2105
+ this.instance._mouseStart(event, true, true);
2106
+
2107
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2108
+ this.instance.offset.click.top = inst.offset.click.top;
2109
+ this.instance.offset.click.left = inst.offset.click.left;
2110
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2111
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2112
+
2113
+ inst._trigger("toSortable", event);
2114
+ inst.dropped = this.instance.element; //draggable revert needs that
2115
+ //hack so receive/update callbacks work (mostly)
2116
+ inst.currentItem = inst.element;
2117
+ this.instance.fromOutside = inst;
2118
+
2119
+ }
2120
+
2121
+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2122
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
2123
+
2124
+ } else {
2125
+
2126
+ //If it doesn't intersect with the sortable, and it intersected before,
2127
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2128
+ if(this.instance.isOver) {
2129
+
2130
+ this.instance.isOver = 0;
2131
+ this.instance.cancelHelperRemoval = true;
2132
+
2133
+ //Prevent reverting on this forced stop
2134
+ this.instance.options.revert = false;
2135
+
2136
+ // The out event needs to be triggered independently
2137
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
2138
+
2139
+ this.instance._mouseStop(event, true);
2140
+ this.instance.options.helper = this.instance.options._helper;
2141
+
2142
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2143
+ this.instance.currentItem.remove();
2144
+ if(this.instance.placeholder) this.instance.placeholder.remove();
2145
+
2146
+ inst._trigger("fromSortable", event);
2147
+ inst.dropped = false; //draggable revert needs that
2148
+ }
2149
+
2150
+ };
2151
+
2152
+ });
2153
+
2154
+ }
2155
+ });
2156
+
2157
+ $.ui.plugin.add("draggable", "cursor", {
2158
+ start: function(event, ui) {
2159
+ var t = $('body'), o = $(this).data('draggable').options;
2160
+ if (t.css("cursor")) o._cursor = t.css("cursor");
2161
+ t.css("cursor", o.cursor);
2162
+ },
2163
+ stop: function(event, ui) {
2164
+ var o = $(this).data('draggable').options;
2165
+ if (o._cursor) $('body').css("cursor", o._cursor);
2166
+ }
2167
+ });
2168
+
2169
+ $.ui.plugin.add("draggable", "opacity", {
2170
+ start: function(event, ui) {
2171
+ var t = $(ui.helper), o = $(this).data('draggable').options;
2172
+ if(t.css("opacity")) o._opacity = t.css("opacity");
2173
+ t.css('opacity', o.opacity);
2174
+ },
2175
+ stop: function(event, ui) {
2176
+ var o = $(this).data('draggable').options;
2177
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
2178
+ }
2179
+ });
2180
+
2181
+ $.ui.plugin.add("draggable", "scroll", {
2182
+ start: function(event, ui) {
2183
+ var i = $(this).data("draggable");
2184
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
2185
+ },
2186
+ drag: function(event, ui) {
2187
+
2188
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
2189
+
2190
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
2191
+
2192
+ if(!o.axis || o.axis != 'x') {
2193
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2194
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2195
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
2196
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2197
+ }
2198
+
2199
+ if(!o.axis || o.axis != 'y') {
2200
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2201
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2202
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
2203
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2204
+ }
2205
+
2206
+ } else {
2207
+
2208
+ if(!o.axis || o.axis != 'x') {
2209
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2210
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2211
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2212
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2213
+ }
2214
+
2215
+ if(!o.axis || o.axis != 'y') {
2216
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2217
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2218
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2219
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2220
+ }
2221
+
2222
+ }
2223
+
2224
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2225
+ $.ui.ddmanager.prepareOffsets(i, event);
2226
+
2227
+ }
2228
+ });
2229
+
2230
+ $.ui.plugin.add("draggable", "snap", {
2231
+ start: function(event, ui) {
2232
+
2233
+ var i = $(this).data("draggable"), o = i.options;
2234
+ i.snapElements = [];
2235
+
2236
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
2237
+ var $t = $(this); var $o = $t.offset();
2238
+ if(this != i.element[0]) i.snapElements.push({
2239
+ item: this,
2240
+ width: $t.outerWidth(), height: $t.outerHeight(),
2241
+ top: $o.top, left: $o.left
2242
+ });
2243
+ });
2244
+
2245
+ },
2246
+ drag: function(event, ui) {
2247
+
2248
+ var inst = $(this).data("draggable"), o = inst.options;
2249
+ var d = o.snapTolerance;
2250
+
2251
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2252
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2253
+
2254
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
2255
+
2256
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
2257
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
2258
+
2259
+ //Yes, I know, this is insane ;)
2260
+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
2261
+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2262
+ inst.snapElements[i].snapping = false;
2263
+ continue;
2264
+ }
2265
+
2266
+ if(o.snapMode != 'inner') {
2267
+ var ts = Math.abs(t - y2) <= d;
2268
+ var bs = Math.abs(b - y1) <= d;
2269
+ var ls = Math.abs(l - x2) <= d;
2270
+ var rs = Math.abs(r - x1) <= d;
2271
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2272
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2273
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2274
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2275
+ }
2276
+
2277
+ var first = (ts || bs || ls || rs);
2278
+
2279
+ if(o.snapMode != 'outer') {
2280
+ var ts = Math.abs(t - y1) <= d;
2281
+ var bs = Math.abs(b - y2) <= d;
2282
+ var ls = Math.abs(l - x1) <= d;
2283
+ var rs = Math.abs(r - x2) <= d;
2284
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2285
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2286
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2287
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2288
+ }
2289
+
2290
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
2291
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2292
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2293
+
2294
+ };
2295
+
2296
+ }
2297
+ });
2298
+
2299
+ $.ui.plugin.add("draggable", "stack", {
2300
+ start: function(event, ui) {
2301
+
2302
+ var o = $(this).data("draggable").options;
2303
+
2304
+ var group = $.makeArray($(o.stack)).sort(function(a,b) {
2305
+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2306
+ });
2307
+ if (!group.length) { return; }
2308
+
2309
+ var min = parseInt(group[0].style.zIndex) || 0;
2310
+ $(group).each(function(i) {
2311
+ this.style.zIndex = min + i;
2312
+ });
2313
+
2314
+ this[0].style.zIndex = min + group.length;
2315
+
2316
+ }
2317
+ });
2318
+
2319
+ $.ui.plugin.add("draggable", "zIndex", {
2320
+ start: function(event, ui) {
2321
+ var t = $(ui.helper), o = $(this).data("draggable").options;
2322
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
2323
+ t.css('zIndex', o.zIndex);
2324
+ },
2325
+ stop: function(event, ui) {
2326
+ var o = $(this).data("draggable").options;
2327
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
2328
+ }
2329
+ });
2330
+
2331
+ })(jQuery);
2332
+ (function( $, undefined ) {
2333
+
2334
+ $.widget("ui.droppable", {
2335
+ version: "1.9.1",
2336
+ widgetEventPrefix: "drop",
2337
+ options: {
2338
+ accept: '*',
2339
+ activeClass: false,
2340
+ addClasses: true,
2341
+ greedy: false,
2342
+ hoverClass: false,
2343
+ scope: 'default',
2344
+ tolerance: 'intersect'
2345
+ },
2346
+ _create: function() {
2347
+
2348
+ var o = this.options, accept = o.accept;
2349
+ this.isover = 0; this.isout = 1;
2350
+
2351
+ this.accept = $.isFunction(accept) ? accept : function(d) {
2352
+ return d.is(accept);
2353
+ };
2354
+
2355
+ //Store the droppable's proportions
2356
+ this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2357
+
2358
+ // Add the reference and positions to the manager
2359
+ $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2360
+ $.ui.ddmanager.droppables[o.scope].push(this);
2361
+
2362
+ (o.addClasses && this.element.addClass("ui-droppable"));
2363
+
2364
+ },
2365
+
2366
+ _destroy: function() {
2367
+ var drop = $.ui.ddmanager.droppables[this.options.scope];
2368
+ for ( var i = 0; i < drop.length; i++ )
2369
+ if ( drop[i] == this )
2370
+ drop.splice(i, 1);
2371
+
2372
+ this.element.removeClass("ui-droppable ui-droppable-disabled");
2373
+ },
2374
+
2375
+ _setOption: function(key, value) {
2376
+
2377
+ if(key == 'accept') {
2378
+ this.accept = $.isFunction(value) ? value : function(d) {
2379
+ return d.is(value);
2380
+ };
2381
+ }
2382
+ $.Widget.prototype._setOption.apply(this, arguments);
2383
+ },
2384
+
2385
+ _activate: function(event) {
2386
+ var draggable = $.ui.ddmanager.current;
2387
+ if(this.options.activeClass) this.element.addClass(this.options.activeClass);
2388
+ (draggable && this._trigger('activate', event, this.ui(draggable)));
2389
+ },
2390
+
2391
+ _deactivate: function(event) {
2392
+ var draggable = $.ui.ddmanager.current;
2393
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2394
+ (draggable && this._trigger('deactivate', event, this.ui(draggable)));
2395
+ },
2396
+
2397
+ _over: function(event) {
2398
+
2399
+ var draggable = $.ui.ddmanager.current;
2400
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2401
+
2402
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2403
+ if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
2404
+ this._trigger('over', event, this.ui(draggable));
2405
+ }
2406
+
2407
+ },
2408
+
2409
+ _out: function(event) {
2410
+
2411
+ var draggable = $.ui.ddmanager.current;
2412
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2413
+
2414
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2415
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2416
+ this._trigger('out', event, this.ui(draggable));
2417
+ }
2418
+
2419
+ },
2420
+
2421
+ _drop: function(event,custom) {
2422
+
2423
+ var draggable = custom || $.ui.ddmanager.current;
2424
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2425
+
2426
+ var childrenIntersection = false;
2427
+ this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2428
+ var inst = $.data(this, 'droppable');
2429
+ if(
2430
+ inst.options.greedy
2431
+ && !inst.options.disabled
2432
+ && inst.options.scope == draggable.options.scope
2433
+ && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2434
+ && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2435
+ ) { childrenIntersection = true; return false; }
2436
+ });
2437
+ if(childrenIntersection) return false;
2438
+
2439
+ if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2440
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2441
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2442
+ this._trigger('drop', event, this.ui(draggable));
2443
+ return this.element;
2444
+ }
2445
+
2446
+ return false;
2447
+
2448
+ },
2449
+
2450
+ ui: function(c) {
2451
+ return {
2452
+ draggable: (c.currentItem || c.element),
2453
+ helper: c.helper,
2454
+ position: c.position,
2455
+ offset: c.positionAbs
2456
+ };
2457
+ }
2458
+
2459
+ });
2460
+
2461
+ $.ui.intersect = function(draggable, droppable, toleranceMode) {
2462
+
2463
+ if (!droppable.offset) return false;
2464
+
2465
+ var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2466
+ y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2467
+ var l = droppable.offset.left, r = l + droppable.proportions.width,
2468
+ t = droppable.offset.top, b = t + droppable.proportions.height;
2469
+
2470
+ switch (toleranceMode) {
2471
+ case 'fit':
2472
+ return (l <= x1 && x2 <= r
2473
+ && t <= y1 && y2 <= b);
2474
+ break;
2475
+ case 'intersect':
2476
+ return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2477
+ && x2 - (draggable.helperProportions.width / 2) < r // Left Half
2478
+ && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2479
+ && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2480
+ break;
2481
+ case 'pointer':
2482
+ var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2483
+ draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2484
+ isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2485
+ return isOver;
2486
+ break;
2487
+ case 'touch':
2488
+ return (
2489
+ (y1 >= t && y1 <= b) || // Top edge touching
2490
+ (y2 >= t && y2 <= b) || // Bottom edge touching
2491
+ (y1 < t && y2 > b) // Surrounded vertically
2492
+ ) && (
2493
+ (x1 >= l && x1 <= r) || // Left edge touching
2494
+ (x2 >= l && x2 <= r) || // Right edge touching
2495
+ (x1 < l && x2 > r) // Surrounded horizontally
2496
+ );
2497
+ break;
2498
+ default:
2499
+ return false;
2500
+ break;
2501
+ }
2502
+
2503
+ };
2504
+
2505
+ /*
2506
+ This manager tracks offsets of draggables and droppables
2507
+ */
2508
+ $.ui.ddmanager = {
2509
+ current: null,
2510
+ droppables: { 'default': [] },
2511
+ prepareOffsets: function(t, event) {
2512
+
2513
+ var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2514
+ var type = event ? event.type : null; // workaround for #2317
2515
+ var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2516
+
2517
+ droppablesLoop: for (var i = 0; i < m.length; i++) {
2518
+
2519
+ if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
2520
+ for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2521
+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
2522
+
2523
+ if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2524
+
2525
+ m[i].offset = m[i].element.offset();
2526
+ m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2527
+
2528
+ }
2529
+
2530
+ },
2531
+ drop: function(draggable, event) {
2532
+
2533
+ var dropped = false;
2534
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2535
+
2536
+ if(!this.options) return;
2537
+ if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2538
+ dropped = this._drop.call(this, event) || dropped;
2539
+
2540
+ if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2541
+ this.isout = 1; this.isover = 0;
2542
+ this._deactivate.call(this, event);
2543
+ }
2544
+
2545
+ });
2546
+ return dropped;
2547
+
2548
+ },
2549
+ dragStart: function( draggable, event ) {
2550
+ //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2551
+ draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2552
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2553
+ });
2554
+ },
2555
+ drag: function(draggable, event) {
2556
+
2557
+ //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2558
+ if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2559
+
2560
+ //Run through all droppables and check their positions based on specific tolerance options
2561
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2562
+
2563
+ if(this.options.disabled || this.greedyChild || !this.visible) return;
2564
+ var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2565
+
2566
+ var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2567
+ if(!c) return;
2568
+
2569
+ var parentInstance;
2570
+ if (this.options.greedy) {
2571
+ // find droppable parents with same scope
2572
+ var scope = this.options.scope;
2573
+ var parent = this.element.parents(':data(droppable)').filter(function () {
2574
+ return $.data(this, 'droppable').options.scope === scope;
2575
+ });
2576
+
2577
+ if (parent.length) {
2578
+ parentInstance = $.data(parent[0], 'droppable');
2579
+ parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2580
+ }
2581
+ }
2582
+
2583
+ // we just moved into a greedy child
2584
+ if (parentInstance && c == 'isover') {
2585
+ parentInstance['isover'] = 0;
2586
+ parentInstance['isout'] = 1;
2587
+ parentInstance._out.call(parentInstance, event);
2588
+ }
2589
+
2590
+ this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2591
+ this[c == "isover" ? "_over" : "_out"].call(this, event);
2592
+
2593
+ // we just moved out of a greedy child
2594
+ if (parentInstance && c == 'isout') {
2595
+ parentInstance['isout'] = 0;
2596
+ parentInstance['isover'] = 1;
2597
+ parentInstance._over.call(parentInstance, event);
2598
+ }
2599
+ });
2600
+
2601
+ },
2602
+ dragStop: function( draggable, event ) {
2603
+ draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2604
+ //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2605
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2606
+ }
2607
+ };
2608
+
2609
+ })(jQuery);
2610
+ (function( $, undefined ) {
2611
+
2612
+ $.widget("ui.sortable", $.ui.mouse, {
2613
+ version: "1.9.1",
2614
+ widgetEventPrefix: "sort",
2615
+ ready: false,
2616
+ options: {
2617
+ appendTo: "parent",
2618
+ axis: false,
2619
+ connectWith: false,
2620
+ containment: false,
2621
+ cursor: 'auto',
2622
+ cursorAt: false,
2623
+ dropOnEmpty: true,
2624
+ forcePlaceholderSize: false,
2625
+ forceHelperSize: false,
2626
+ grid: false,
2627
+ handle: false,
2628
+ helper: "original",
2629
+ items: '> *',
2630
+ opacity: false,
2631
+ placeholder: false,
2632
+ revert: false,
2633
+ scroll: true,
2634
+ scrollSensitivity: 20,
2635
+ scrollSpeed: 20,
2636
+ scope: "default",
2637
+ tolerance: "intersect",
2638
+ zIndex: 1000
2639
+ },
2640
+ _create: function() {
2641
+
2642
+ var o = this.options;
2643
+ this.containerCache = {};
2644
+ this.element.addClass("ui-sortable");
2645
+
2646
+ //Get the items
2647
+ this.refresh();
2648
+
2649
+ //Let's determine if the items are being displayed horizontally
2650
+ this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
2651
+
2652
+ //Let's determine the parent's offset
2653
+ this.offset = this.element.offset();
2654
+
2655
+ //Initialize mouse events for interaction
2656
+ this._mouseInit();
2657
+
2658
+ //We're ready to go
2659
+ this.ready = true
2660
+
2661
+ },
2662
+
2663
+ _destroy: function() {
2664
+ this.element
2665
+ .removeClass("ui-sortable ui-sortable-disabled");
2666
+ this._mouseDestroy();
2667
+
2668
+ for ( var i = this.items.length - 1; i >= 0; i-- )
2669
+ this.items[i].item.removeData(this.widgetName + "-item");
2670
+
2671
+ return this;
2672
+ },
2673
+
2674
+ _setOption: function(key, value){
2675
+ if ( key === "disabled" ) {
2676
+ this.options[ key ] = value;
2677
+
2678
+ this.widget().toggleClass( "ui-sortable-disabled", !!value );
2679
+ } else {
2680
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
2681
+ $.Widget.prototype._setOption.apply(this, arguments);
2682
+ }
2683
+ },
2684
+
2685
+ _mouseCapture: function(event, overrideHandle) {
2686
+ var that = this;
2687
+
2688
+ if (this.reverting) {
2689
+ return false;
2690
+ }
2691
+
2692
+ if(this.options.disabled || this.options.type == 'static') return false;
2693
+
2694
+ //We have to refresh the items data once first
2695
+ this._refreshItems(event);
2696
+
2697
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
2698
+ var currentItem = null, nodes = $(event.target).parents().each(function() {
2699
+ if($.data(this, that.widgetName + '-item') == that) {
2700
+ currentItem = $(this);
2701
+ return false;
2702
+ }
2703
+ });
2704
+ if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
2705
+
2706
+ if(!currentItem) return false;
2707
+ if(this.options.handle && !overrideHandle) {
2708
+ var validHandle = false;
2709
+
2710
+ $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
2711
+ if(!validHandle) return false;
2712
+ }
2713
+
2714
+ this.currentItem = currentItem;
2715
+ this._removeCurrentsFromItems();
2716
+ return true;
2717
+
2718
+ },
2719
+
2720
+ _mouseStart: function(event, overrideHandle, noActivation) {
2721
+
2722
+ var o = this.options;
2723
+ this.currentContainer = this;
2724
+
2725
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
2726
+ this.refreshPositions();
2727
+
2728
+ //Create and append the visible helper
2729
+ this.helper = this._createHelper(event);
2730
+
2731
+ //Cache the helper size
2732
+ this._cacheHelperProportions();
2733
+
2734
+ /*
2735
+ * - Position generation -
2736
+ * This block generates everything position related - it's the core of draggables.
2737
+ */
2738
+
2739
+ //Cache the margins of the original element
2740
+ this._cacheMargins();
2741
+
2742
+ //Get the next scrolling parent
2743
+ this.scrollParent = this.helper.scrollParent();
2744
+
2745
+ //The element's absolute position on the page minus margins
2746
+ this.offset = this.currentItem.offset();
2747
+ this.offset = {
2748
+ top: this.offset.top - this.margins.top,
2749
+ left: this.offset.left - this.margins.left
2750
+ };
2751
+
2752
+ $.extend(this.offset, {
2753
+ click: { //Where the click happened, relative to the element
2754
+ left: event.pageX - this.offset.left,
2755
+ top: event.pageY - this.offset.top
2756
+ },
2757
+ parent: this._getParentOffset(),
2758
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
2759
+ });
2760
+
2761
+ // Only after we got the offset, we can change the helper's position to absolute
2762
+ // TODO: Still need to figure out a way to make relative sorting possible
2763
+ this.helper.css("position", "absolute");
2764
+ this.cssPosition = this.helper.css("position");
2765
+
2766
+ //Generate the original position
2767
+ this.originalPosition = this._generatePosition(event);
2768
+ this.originalPageX = event.pageX;
2769
+ this.originalPageY = event.pageY;
2770
+
2771
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
2772
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
2773
+
2774
+ //Cache the former DOM position
2775
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
2776
+
2777
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
2778
+ if(this.helper[0] != this.currentItem[0]) {
2779
+ this.currentItem.hide();
2780
+ }
2781
+
2782
+ //Create the placeholder
2783
+ this._createPlaceholder();
2784
+
2785
+ //Set a containment if given in the options
2786
+ if(o.containment)
2787
+ this._setContainment();
2788
+
2789
+ if(o.cursor) { // cursor option
2790
+ if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
2791
+ $('body').css("cursor", o.cursor);
2792
+ }
2793
+
2794
+ if(o.opacity) { // opacity option
2795
+ if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
2796
+ this.helper.css("opacity", o.opacity);
2797
+ }
2798
+
2799
+ if(o.zIndex) { // zIndex option
2800
+ if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
2801
+ this.helper.css("zIndex", o.zIndex);
2802
+ }
2803
+
2804
+ //Prepare scrolling
2805
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
2806
+ this.overflowOffset = this.scrollParent.offset();
2807
+
2808
+ //Call callbacks
2809
+ this._trigger("start", event, this._uiHash());
2810
+
2811
+ //Recache the helper size
2812
+ if(!this._preserveHelperProportions)
2813
+ this._cacheHelperProportions();
2814
+
2815
+
2816
+ //Post 'activate' events to possible containers
2817
+ if(!noActivation) {
2818
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
2819
+ }
2820
+
2821
+ //Prepare possible droppables
2822
+ if($.ui.ddmanager)
2823
+ $.ui.ddmanager.current = this;
2824
+
2825
+ if ($.ui.ddmanager && !o.dropBehaviour)
2826
+ $.ui.ddmanager.prepareOffsets(this, event);
2827
+
2828
+ this.dragging = true;
2829
+
2830
+ this.helper.addClass("ui-sortable-helper");
2831
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
2832
+ return true;
2833
+
2834
+ },
2835
+
2836
+ _mouseDrag: function(event) {
2837
+
2838
+ //Compute the helpers position
2839
+ this.position = this._generatePosition(event);
2840
+ this.positionAbs = this._convertPositionTo("absolute");
2841
+
2842
+ if (!this.lastPositionAbs) {
2843
+ this.lastPositionAbs = this.positionAbs;
2844
+ }
2845
+
2846
+ //Do scrolling
2847
+ if(this.options.scroll) {
2848
+ var o = this.options, scrolled = false;
2849
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
2850
+
2851
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2852
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
2853
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
2854
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
2855
+
2856
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2857
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
2858
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
2859
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
2860
+
2861
+ } else {
2862
+
2863
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2864
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2865
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2866
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2867
+
2868
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2869
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2870
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2871
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2872
+
2873
+ }
2874
+
2875
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2876
+ $.ui.ddmanager.prepareOffsets(this, event);
2877
+ }
2878
+
2879
+ //Regenerate the absolute position used for position checks
2880
+ this.positionAbs = this._convertPositionTo("absolute");
2881
+
2882
+ //Set the helper position
2883
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
2884
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
2885
+
2886
+ //Rearrange
2887
+ for (var i = this.items.length - 1; i >= 0; i--) {
2888
+
2889
+ //Cache variables and intersection, continue if no intersection
2890
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
2891
+ if (!intersection) continue;
2892
+
2893
+ // Only put the placeholder inside the current Container, skip all
2894
+ // items form other containers. This works because when moving
2895
+ // an item from one container to another the
2896
+ // currentContainer is switched before the placeholder is moved.
2897
+ //
2898
+ // Without this moving items in "sub-sortables" can cause the placeholder to jitter
2899
+ // beetween the outer and inner container.
2900
+ if (item.instance !== this.currentContainer) continue;
2901
+
2902
+ if (itemElement != this.currentItem[0] //cannot intersect with itself
2903
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
2904
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
2905
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
2906
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
2907
+ ) {
2908
+
2909
+ this.direction = intersection == 1 ? "down" : "up";
2910
+
2911
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
2912
+ this._rearrange(event, item);
2913
+ } else {
2914
+ break;
2915
+ }
2916
+
2917
+ this._trigger("change", event, this._uiHash());
2918
+ break;
2919
+ }
2920
+ }
2921
+
2922
+ //Post events to containers
2923
+ this._contactContainers(event);
2924
+
2925
+ //Interconnect with droppables
2926
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
2927
+
2928
+ //Call callbacks
2929
+ this._trigger('sort', event, this._uiHash());
2930
+
2931
+ this.lastPositionAbs = this.positionAbs;
2932
+ return false;
2933
+
2934
+ },
2935
+
2936
+ _mouseStop: function(event, noPropagation) {
2937
+
2938
+ if(!event) return;
2939
+
2940
+ //If we are using droppables, inform the manager about the drop
2941
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
2942
+ $.ui.ddmanager.drop(this, event);
2943
+
2944
+ if(this.options.revert) {
2945
+ var that = this;
2946
+ var cur = this.placeholder.offset();
2947
+
2948
+ this.reverting = true;
2949
+
2950
+ $(this.helper).animate({
2951
+ left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
2952
+ top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
2953
+ }, parseInt(this.options.revert, 10) || 500, function() {
2954
+ that._clear(event);
2955
+ });
2956
+ } else {
2957
+ this._clear(event, noPropagation);
2958
+ }
2959
+
2960
+ return false;
2961
+
2962
+ },
2963
+
2964
+ cancel: function() {
2965
+
2966
+ if(this.dragging) {
2967
+
2968
+ this._mouseUp({ target: null });
2969
+
2970
+ if(this.options.helper == "original")
2971
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2972
+ else
2973
+ this.currentItem.show();
2974
+
2975
+ //Post deactivating events to containers
2976
+ for (var i = this.containers.length - 1; i >= 0; i--){
2977
+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
2978
+ if(this.containers[i].containerCache.over) {
2979
+ this.containers[i]._trigger("out", null, this._uiHash(this));
2980
+ this.containers[i].containerCache.over = 0;
2981
+ }
2982
+ }
2983
+
2984
+ }
2985
+
2986
+ if (this.placeholder) {
2987
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
2988
+ if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
2989
+ if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
2990
+
2991
+ $.extend(this, {
2992
+ helper: null,
2993
+ dragging: false,
2994
+ reverting: false,
2995
+ _noFinalSort: null
2996
+ });
2997
+
2998
+ if(this.domPosition.prev) {
2999
+ $(this.domPosition.prev).after(this.currentItem);
3000
+ } else {
3001
+ $(this.domPosition.parent).prepend(this.currentItem);
3002
+ }
3003
+ }
3004
+
3005
+ return this;
3006
+
3007
+ },
3008
+
3009
+ serialize: function(o) {
3010
+
3011
+ var items = this._getItemsAsjQuery(o && o.connected);
3012
+ var str = []; o = o || {};
3013
+
3014
+ $(items).each(function() {
3015
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3016
+ if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3017
+ });
3018
+
3019
+ if(!str.length && o.key) {
3020
+ str.push(o.key + '=');
3021
+ }
3022
+
3023
+ return str.join('&');
3024
+
3025
+ },
3026
+
3027
+ toArray: function(o) {
3028
+
3029
+ var items = this._getItemsAsjQuery(o && o.connected);
3030
+ var ret = []; o = o || {};
3031
+
3032
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3033
+ return ret;
3034
+
3035
+ },
3036
+
3037
+ /* Be careful with the following core functions */
3038
+ _intersectsWith: function(item) {
3039
+
3040
+ var x1 = this.positionAbs.left,
3041
+ x2 = x1 + this.helperProportions.width,
3042
+ y1 = this.positionAbs.top,
3043
+ y2 = y1 + this.helperProportions.height;
3044
+
3045
+ var l = item.left,
3046
+ r = l + item.width,
3047
+ t = item.top,
3048
+ b = t + item.height;
3049
+
3050
+ var dyClick = this.offset.click.top,
3051
+ dxClick = this.offset.click.left;
3052
+
3053
+ var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3054
+
3055
+ if( this.options.tolerance == "pointer"
3056
+ || this.options.forcePointerForContainers
3057
+ || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3058
+ ) {
3059
+ return isOverElement;
3060
+ } else {
3061
+
3062
+ return (l < x1 + (this.helperProportions.width / 2) // Right Half
3063
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
3064
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3065
+ && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3066
+
3067
+ }
3068
+ },
3069
+
3070
+ _intersectsWithPointer: function(item) {
3071
+
3072
+ var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3073
+ isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3074
+ isOverElement = isOverElementHeight && isOverElementWidth,
3075
+ verticalDirection = this._getDragVerticalDirection(),
3076
+ horizontalDirection = this._getDragHorizontalDirection();
3077
+
3078
+ if (!isOverElement)
3079
+ return false;
3080
+
3081
+ return this.floating ?
3082
+ ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3083
+ : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3084
+
3085
+ },
3086
+
3087
+ _intersectsWithSides: function(item) {
3088
+
3089
+ var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3090
+ isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3091
+ verticalDirection = this._getDragVerticalDirection(),
3092
+ horizontalDirection = this._getDragHorizontalDirection();
3093
+
3094
+ if (this.floating && horizontalDirection) {
3095
+ return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3096
+ } else {
3097
+ return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3098
+ }
3099
+
3100
+ },
3101
+
3102
+ _getDragVerticalDirection: function() {
3103
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
3104
+ return delta != 0 && (delta > 0 ? "down" : "up");
3105
+ },
3106
+
3107
+ _getDragHorizontalDirection: function() {
3108
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
3109
+ return delta != 0 && (delta > 0 ? "right" : "left");
3110
+ },
3111
+
3112
+ refresh: function(event) {
3113
+ this._refreshItems(event);
3114
+ this.refreshPositions();
3115
+ return this;
3116
+ },
3117
+
3118
+ _connectWith: function() {
3119
+ var options = this.options;
3120
+ return options.connectWith.constructor == String
3121
+ ? [options.connectWith]
3122
+ : options.connectWith;
3123
+ },
3124
+
3125
+ _getItemsAsjQuery: function(connected) {
3126
+
3127
+ var items = [];
3128
+ var queries = [];
3129
+ var connectWith = this._connectWith();
3130
+
3131
+ if(connectWith && connected) {
3132
+ for (var i = connectWith.length - 1; i >= 0; i--){
3133
+ var cur = $(connectWith[i]);
3134
+ for (var j = cur.length - 1; j >= 0; j--){
3135
+ var inst = $.data(cur[j], this.widgetName);
3136
+ if(inst && inst != this && !inst.options.disabled) {
3137
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
3138
+ }
3139
+ };
3140
+ };
3141
+ }
3142
+
3143
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
3144
+
3145
+ for (var i = queries.length - 1; i >= 0; i--){
3146
+ queries[i][0].each(function() {
3147
+ items.push(this);
3148
+ });
3149
+ };
3150
+
3151
+ return $(items);
3152
+
3153
+ },
3154
+
3155
+ _removeCurrentsFromItems: function() {
3156
+
3157
+ var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3158
+
3159
+ this.items = $.grep(this.items, function (item) {
3160
+ for (var j=0; j < list.length; j++) {
3161
+ if(list[j] == item.item[0])
3162
+ return false;
3163
+ };
3164
+ return true;
3165
+ });
3166
+
3167
+ },
3168
+
3169
+ _refreshItems: function(event) {
3170
+
3171
+ this.items = [];
3172
+ this.containers = [this];
3173
+ var items = this.items;
3174
+ var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3175
+ var connectWith = this._connectWith();
3176
+
3177
+ if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3178
+ for (var i = connectWith.length - 1; i >= 0; i--){
3179
+ var cur = $(connectWith[i]);
3180
+ for (var j = cur.length - 1; j >= 0; j--){
3181
+ var inst = $.data(cur[j], this.widgetName);
3182
+ if(inst && inst != this && !inst.options.disabled) {
3183
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3184
+ this.containers.push(inst);
3185
+ }
3186
+ };
3187
+ };
3188
+ }
3189
+
3190
+ for (var i = queries.length - 1; i >= 0; i--) {
3191
+ var targetData = queries[i][1];
3192
+ var _queries = queries[i][0];
3193
+
3194
+ for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3195
+ var item = $(_queries[j]);
3196
+
3197
+ item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3198
+
3199
+ items.push({
3200
+ item: item,
3201
+ instance: targetData,
3202
+ width: 0, height: 0,
3203
+ left: 0, top: 0
3204
+ });
3205
+ };
3206
+ };
3207
+
3208
+ },
3209
+
3210
+ refreshPositions: function(fast) {
3211
+
3212
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3213
+ if(this.offsetParent && this.helper) {
3214
+ this.offset.parent = this._getParentOffset();
3215
+ }
3216
+
3217
+ for (var i = this.items.length - 1; i >= 0; i--){
3218
+ var item = this.items[i];
3219
+
3220
+ //We ignore calculating positions of all connected containers when we're not over them
3221
+ if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3222
+ continue;
3223
+
3224
+ var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3225
+
3226
+ if (!fast) {
3227
+ item.width = t.outerWidth();
3228
+ item.height = t.outerHeight();
3229
+ }
3230
+
3231
+ var p = t.offset();
3232
+ item.left = p.left;
3233
+ item.top = p.top;
3234
+ };
3235
+
3236
+ if(this.options.custom && this.options.custom.refreshContainers) {
3237
+ this.options.custom.refreshContainers.call(this);
3238
+ } else {
3239
+ for (var i = this.containers.length - 1; i >= 0; i--){
3240
+ var p = this.containers[i].element.offset();
3241
+ this.containers[i].containerCache.left = p.left;
3242
+ this.containers[i].containerCache.top = p.top;
3243
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3244
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3245
+ };
3246
+ }
3247
+
3248
+ return this;
3249
+ },
3250
+
3251
+ _createPlaceholder: function(that) {
3252
+ that = that || this;
3253
+ var o = that.options;
3254
+
3255
+ if(!o.placeholder || o.placeholder.constructor == String) {
3256
+ var className = o.placeholder;
3257
+ o.placeholder = {
3258
+ element: function() {
3259
+
3260
+ var el = $(document.createElement(that.currentItem[0].nodeName))
3261
+ .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
3262
+ .removeClass("ui-sortable-helper")[0];
3263
+
3264
+ if(!className)
3265
+ el.style.visibility = "hidden";
3266
+
3267
+ return el;
3268
+ },
3269
+ update: function(container, p) {
3270
+
3271
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3272
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3273
+ if(className && !o.forcePlaceholderSize) return;
3274
+
3275
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
3276
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
3277
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
3278
+ }
3279
+ };
3280
+ }
3281
+
3282
+ //Create the placeholder
3283
+ that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
3284
+
3285
+ //Append it after the actual current item
3286
+ that.currentItem.after(that.placeholder);
3287
+
3288
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3289
+ o.placeholder.update(that, that.placeholder);
3290
+
3291
+ },
3292
+
3293
+ _contactContainers: function(event) {
3294
+
3295
+ // get innermost container that intersects with item
3296
+ var innermostContainer = null, innermostIndex = null;
3297
+
3298
+
3299
+ for (var i = this.containers.length - 1; i >= 0; i--){
3300
+
3301
+ // never consider a container that's located within the item itself
3302
+ if($.contains(this.currentItem[0], this.containers[i].element[0]))
3303
+ continue;
3304
+
3305
+ if(this._intersectsWith(this.containers[i].containerCache)) {
3306
+
3307
+ // if we've already found a container and it's more "inner" than this, then continue
3308
+ if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
3309
+ continue;
3310
+
3311
+ innermostContainer = this.containers[i];
3312
+ innermostIndex = i;
3313
+
3314
+ } else {
3315
+ // container doesn't intersect. trigger "out" event if necessary
3316
+ if(this.containers[i].containerCache.over) {
3317
+ this.containers[i]._trigger("out", event, this._uiHash(this));
3318
+ this.containers[i].containerCache.over = 0;
3319
+ }
3320
+ }
3321
+
3322
+ }
3323
+
3324
+ // if no intersecting containers found, return
3325
+ if(!innermostContainer) return;
3326
+
3327
+ // move the item into the container if it's not there already
3328
+ if(this.containers.length === 1) {
3329
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3330
+ this.containers[innermostIndex].containerCache.over = 1;
3331
+ } else {
3332
+
3333
+ //When entering a new container, we will find the item with the least distance and append our item near it
3334
+ var dist = 10000; var itemWithLeastDistance = null;
3335
+ var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
3336
+ var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
3337
+ var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
3338
+ for (var j = this.items.length - 1; j >= 0; j--) {
3339
+ if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3340
+ if(this.items[j].item[0] == this.currentItem[0]) continue;
3341
+ var cur = this.items[j].item.offset()[posProperty];
3342
+ var nearBottom = false;
3343
+ if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
3344
+ nearBottom = true;
3345
+ cur += this.items[j][sizeProperty];
3346
+ }
3347
+
3348
+ if(Math.abs(cur - base) < dist) {
3349
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3350
+ this.direction = nearBottom ? "up": "down";
3351
+ }
3352
+ }
3353
+
3354
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3355
+ return;
3356
+
3357
+ this.currentContainer = this.containers[innermostIndex];
3358
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3359
+ this._trigger("change", event, this._uiHash());
3360
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3361
+
3362
+ //Update the placeholder
3363
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
3364
+
3365
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3366
+ this.containers[innermostIndex].containerCache.over = 1;
3367
+ }
3368
+
3369
+
3370
+ },
3371
+
3372
+ _createHelper: function(event) {
3373
+
3374
+ var o = this.options;
3375
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3376
+
3377
+ if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3378
+ $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3379
+
3380
+ if(helper[0] == this.currentItem[0])
3381
+ this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
3382
+
3383
+ if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3384
+ if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3385
+
3386
+ return helper;
3387
+
3388
+ },
3389
+
3390
+ _adjustOffsetFromHelper: function(obj) {
3391
+ if (typeof obj == 'string') {
3392
+ obj = obj.split(' ');
3393
+ }
3394
+ if ($.isArray(obj)) {
3395
+ obj = {left: +obj[0], top: +obj[1] || 0};
3396
+ }
3397
+ if ('left' in obj) {
3398
+ this.offset.click.left = obj.left + this.margins.left;
3399
+ }
3400
+ if ('right' in obj) {
3401
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3402
+ }
3403
+ if ('top' in obj) {
3404
+ this.offset.click.top = obj.top + this.margins.top;
3405
+ }
3406
+ if ('bottom' in obj) {
3407
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3408
+ }
3409
+ },
3410
+
3411
+ _getParentOffset: function() {
3412
+
3413
+
3414
+ //Get the offsetParent and cache its position
3415
+ this.offsetParent = this.helper.offsetParent();
3416
+ var po = this.offsetParent.offset();
3417
+
3418
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
3419
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3420
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3421
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3422
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
3423
+ po.left += this.scrollParent.scrollLeft();
3424
+ po.top += this.scrollParent.scrollTop();
3425
+ }
3426
+
3427
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3428
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
3429
+ po = { top: 0, left: 0 };
3430
+
3431
+ return {
3432
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3433
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3434
+ };
3435
+
3436
+ },
3437
+
3438
+ _getRelativeOffset: function() {
3439
+
3440
+ if(this.cssPosition == "relative") {
3441
+ var p = this.currentItem.position();
3442
+ return {
3443
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3444
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3445
+ };
3446
+ } else {
3447
+ return { top: 0, left: 0 };
3448
+ }
3449
+
3450
+ },
3451
+
3452
+ _cacheMargins: function() {
3453
+ this.margins = {
3454
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3455
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3456
+ };
3457
+ },
3458
+
3459
+ _cacheHelperProportions: function() {
3460
+ this.helperProportions = {
3461
+ width: this.helper.outerWidth(),
3462
+ height: this.helper.outerHeight()
3463
+ };
3464
+ },
3465
+
3466
+ _setContainment: function() {
3467
+
3468
+ var o = this.options;
3469
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3470
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
3471
+ 0 - this.offset.relative.left - this.offset.parent.left,
3472
+ 0 - this.offset.relative.top - this.offset.parent.top,
3473
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
3474
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
3475
+ ];
3476
+
3477
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
3478
+ var ce = $(o.containment)[0];
3479
+ var co = $(o.containment).offset();
3480
+ var over = ($(ce).css("overflow") != 'hidden');
3481
+
3482
+ this.containment = [
3483
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
3484
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
3485
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
3486
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
3487
+ ];
3488
+ }
3489
+
3490
+ },
3491
+
3492
+ _convertPositionTo: function(d, pos) {
3493
+
3494
+ if(!pos) pos = this.position;
3495
+ var mod = d == "absolute" ? 1 : -1;
3496
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3497
+
3498
+ return {
3499
+ top: (
3500
+ pos.top // The absolute mouse position
3501
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3502
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
3503
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
3504
+ ),
3505
+ left: (
3506
+ pos.left // The absolute mouse position
3507
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3508
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
3509
+ - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
3510
+ )
3511
+ };
3512
+
3513
+ },
3514
+
3515
+ _generatePosition: function(event) {
3516
+
3517
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3518
+
3519
+ // This is another very weird special case that only happens for relative elements:
3520
+ // 1. If the css position is relative
3521
+ // 2. and the scroll parent is the document or similar to the offset parent
3522
+ // we have to refresh the relative offset during the scroll so there are no jumps
3523
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
3524
+ this.offset.relative = this._getRelativeOffset();
3525
+ }
3526
+
3527
+ var pageX = event.pageX;
3528
+ var pageY = event.pageY;
3529
+
3530
+ /*
3531
+ * - Position constraining -
3532
+ * Constrain the position to a mix of grid, containment.
3533
+ */
3534
+
3535
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3536
+
3537
+ if(this.containment) {
3538
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
3539
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
3540
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
3541
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
3542
+ }
3543
+
3544
+ if(o.grid) {
3545
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
3546
+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
3547
+
3548
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
3549
+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
3550
+ }
3551
+
3552
+ }
3553
+
3554
+ return {
3555
+ top: (
3556
+ pageY // The absolute mouse position
3557
+ - this.offset.click.top // Click offset (relative to the element)
3558
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
3559
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
3560
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
3561
+ ),
3562
+ left: (
3563
+ pageX // The absolute mouse position
3564
+ - this.offset.click.left // Click offset (relative to the element)
3565
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
3566
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
3567
+ + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
3568
+ )
3569
+ };
3570
+
3571
+ },
3572
+
3573
+ _rearrange: function(event, i, a, hardRefresh) {
3574
+
3575
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
3576
+
3577
+ //Various things done here to improve the performance:
3578
+ // 1. we create a setTimeout, that calls refreshPositions
3579
+ // 2. on the instance, we have a counter variable, that get's higher after every append
3580
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
3581
+ // 4. this lets only the last addition to the timeout stack through
3582
+ this.counter = this.counter ? ++this.counter : 1;
3583
+ var counter = this.counter;
3584
+
3585
+ this._delay(function() {
3586
+ if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3587
+ });
3588
+
3589
+ },
3590
+
3591
+ _clear: function(event, noPropagation) {
3592
+
3593
+ this.reverting = false;
3594
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
3595
+ // everything else normalized again
3596
+ var delayedTriggers = [];
3597
+
3598
+ // We first have to update the dom position of the actual currentItem
3599
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
3600
+ if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
3601
+ this._noFinalSort = null;
3602
+
3603
+ if(this.helper[0] == this.currentItem[0]) {
3604
+ for(var i in this._storedCSS) {
3605
+ if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3606
+ }
3607
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3608
+ } else {
3609
+ this.currentItem.show();
3610
+ }
3611
+
3612
+ if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3613
+ if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
3614
+
3615
+ // Check if the items Container has Changed and trigger appropriate
3616
+ // events.
3617
+ if (this !== this.currentContainer) {
3618
+ if(!noPropagation) {
3619
+ delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
3620
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
3621
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
3622
+ }
3623
+ }
3624
+
3625
+
3626
+ //Post events to containers
3627
+ for (var i = this.containers.length - 1; i >= 0; i--){
3628
+ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3629
+ if(this.containers[i].containerCache.over) {
3630
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3631
+ this.containers[i].containerCache.over = 0;
3632
+ }
3633
+ }
3634
+
3635
+ //Do what was originally in plugins
3636
+ if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
3637
+ if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
3638
+ if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
3639
+
3640
+ this.dragging = false;
3641
+ if(this.cancelHelperRemoval) {
3642
+ if(!noPropagation) {
3643
+ this._trigger("beforeStop", event, this._uiHash());
3644
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3645
+ this._trigger("stop", event, this._uiHash());
3646
+ }
3647
+
3648
+ this.fromOutside = false;
3649
+ return false;
3650
+ }
3651
+
3652
+ if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
3653
+
3654
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3655
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3656
+
3657
+ if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
3658
+
3659
+ if(!noPropagation) {
3660
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3661
+ this._trigger("stop", event, this._uiHash());
3662
+ }
3663
+
3664
+ this.fromOutside = false;
3665
+ return true;
3666
+
3667
+ },
3668
+
3669
+ _trigger: function() {
3670
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
3671
+ this.cancel();
3672
+ }
3673
+ },
3674
+
3675
+ _uiHash: function(_inst) {
3676
+ var inst = _inst || this;
3677
+ return {
3678
+ helper: inst.helper,
3679
+ placeholder: inst.placeholder || $([]),
3680
+ position: inst.position,
3681
+ originalPosition: inst.originalPosition,
3682
+ offset: inst.positionAbs,
3683
+ item: inst.currentItem,
3684
+ sender: _inst ? _inst.element : null
3685
+ };
3686
+ }
3687
+
3688
+ });
3689
+
3690
+ })(jQuery);
3691
+ (function( $, undefined ) {
3692
+
3693
+ // used to prevent race conditions with remote data sources
3694
+ var requestIndex = 0;
3695
+
3696
+ $.widget( "ui.autocomplete", {
3697
+ version: "1.9.1",
3698
+ defaultElement: "<input>",
3699
+ options: {
3700
+ appendTo: "body",
3701
+ autoFocus: false,
3702
+ delay: 300,
3703
+ minLength: 1,
3704
+ position: {
3705
+ my: "left top",
3706
+ at: "left bottom",
3707
+ collision: "none"
3708
+ },
3709
+ source: null,
3710
+
3711
+ // callbacks
3712
+ change: null,
3713
+ close: null,
3714
+ focus: null,
3715
+ open: null,
3716
+ response: null,
3717
+ search: null,
3718
+ select: null
3719
+ },
3720
+
3721
+ pending: 0,
3722
+
3723
+ _create: function() {
3724
+ // Some browsers only repeat keydown events, not keypress events,
3725
+ // so we use the suppressKeyPress flag to determine if we've already
3726
+ // handled the keydown event. #7269
3727
+ // Unfortunately the code for & in keypress is the same as the up arrow,
3728
+ // so we use the suppressKeyPressRepeat flag to avoid handling keypress
3729
+ // events when we know the keydown event was used to modify the
3730
+ // search term. #7799
3731
+ var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
3732
+
3733
+ this.isMultiLine = this._isMultiLine();
3734
+ this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
3735
+ this.isNewMenu = true;
3736
+
3737
+ this.element
3738
+ .addClass( "ui-autocomplete-input" )
3739
+ .attr( "autocomplete", "off" );
3740
+
3741
+ this._on( this.element, {
3742
+ keydown: function( event ) {
3743
+ if ( this.element.prop( "readOnly" ) ) {
3744
+ suppressKeyPress = true;
3745
+ suppressInput = true;
3746
+ suppressKeyPressRepeat = true;
3747
+ return;
3748
+ }
3749
+
3750
+ suppressKeyPress = false;
3751
+ suppressInput = false;
3752
+ suppressKeyPressRepeat = false;
3753
+ var keyCode = $.ui.keyCode;
3754
+ switch( event.keyCode ) {
3755
+ case keyCode.PAGE_UP:
3756
+ suppressKeyPress = true;
3757
+ this._move( "previousPage", event );
3758
+ break;
3759
+ case keyCode.PAGE_DOWN:
3760
+ suppressKeyPress = true;
3761
+ this._move( "nextPage", event );
3762
+ break;
3763
+ case keyCode.UP:
3764
+ suppressKeyPress = true;
3765
+ this._keyEvent( "previous", event );
3766
+ break;
3767
+ case keyCode.DOWN:
3768
+ suppressKeyPress = true;
3769
+ this._keyEvent( "next", event );
3770
+ break;
3771
+ case keyCode.ENTER:
3772
+ case keyCode.NUMPAD_ENTER:
3773
+ // when menu is open and has focus
3774
+ if ( this.menu.active ) {
3775
+ // #6055 - Opera still allows the keypress to occur
3776
+ // which causes forms to submit
3777
+ suppressKeyPress = true;
3778
+ event.preventDefault();
3779
+ this.menu.select( event );
3780
+ }
3781
+ break;
3782
+ case keyCode.TAB:
3783
+ if ( this.menu.active ) {
3784
+ this.menu.select( event );
3785
+ }
3786
+ break;
3787
+ case keyCode.ESCAPE:
3788
+ if ( this.menu.element.is( ":visible" ) ) {
3789
+ this._value( this.term );
3790
+ this.close( event );
3791
+ // Different browsers have different default behavior for escape
3792
+ // Single press can mean undo or clear
3793
+ // Double press in IE means clear the whole form
3794
+ event.preventDefault();
3795
+ }
3796
+ break;
3797
+ default:
3798
+ suppressKeyPressRepeat = true;
3799
+ // search timeout should be triggered before the input value is changed
3800
+ this._searchTimeout( event );
3801
+ break;
3802
+ }
3803
+ },
3804
+ keypress: function( event ) {
3805
+ if ( suppressKeyPress ) {
3806
+ suppressKeyPress = false;
3807
+ event.preventDefault();
3808
+ return;
3809
+ }
3810
+ if ( suppressKeyPressRepeat ) {
3811
+ return;
3812
+ }
3813
+
3814
+ // replicate some key handlers to allow them to repeat in Firefox and Opera
3815
+ var keyCode = $.ui.keyCode;
3816
+ switch( event.keyCode ) {
3817
+ case keyCode.PAGE_UP:
3818
+ this._move( "previousPage", event );
3819
+ break;
3820
+ case keyCode.PAGE_DOWN:
3821
+ this._move( "nextPage", event );
3822
+ break;
3823
+ case keyCode.UP:
3824
+ this._keyEvent( "previous", event );
3825
+ break;
3826
+ case keyCode.DOWN:
3827
+ this._keyEvent( "next", event );
3828
+ break;
3829
+ }
3830
+ },
3831
+ input: function( event ) {
3832
+ if ( suppressInput ) {
3833
+ suppressInput = false;
3834
+ event.preventDefault();
3835
+ return;
3836
+ }
3837
+ this._searchTimeout( event );
3838
+ },
3839
+ focus: function() {
3840
+ this.selectedItem = null;
3841
+ this.previous = this._value();
3842
+ },
3843
+ blur: function( event ) {
3844
+ if ( this.cancelBlur ) {
3845
+ delete this.cancelBlur;
3846
+ return;
3847
+ }
3848
+
3849
+ clearTimeout( this.searching );
3850
+ this.close( event );
3851
+ this._change( event );
3852
+ }
3853
+ });
3854
+
3855
+ this._initSource();
3856
+ this.menu = $( "<ul>" )
3857
+ .addClass( "ui-autocomplete" )
3858
+ .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
3859
+ .menu({
3860
+ // custom key handling for now
3861
+ input: $(),
3862
+ // disable ARIA support, the live region takes care of that
3863
+ role: null
3864
+ })
3865
+ .zIndex( this.element.zIndex() + 1 )
3866
+ .hide()
3867
+ .data( "menu" );
3868
+
3869
+ this._on( this.menu.element, {
3870
+ mousedown: function( event ) {
3871
+ // prevent moving focus out of the text field
3872
+ event.preventDefault();
3873
+
3874
+ // IE doesn't prevent moving focus even with event.preventDefault()
3875
+ // so we set a flag to know when we should ignore the blur event
3876
+ this.cancelBlur = true;
3877
+ this._delay(function() {
3878
+ delete this.cancelBlur;
3879
+ });
3880
+
3881
+ // clicking on the scrollbar causes focus to shift to the body
3882
+ // but we can't detect a mouseup or a click immediately afterward
3883
+ // so we have to track the next mousedown and close the menu if
3884
+ // the user clicks somewhere outside of the autocomplete
3885
+ var menuElement = this.menu.element[ 0 ];
3886
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
3887
+ this._delay(function() {
3888
+ var that = this;
3889
+ this.document.one( "mousedown", function( event ) {
3890
+ if ( event.target !== that.element[ 0 ] &&
3891
+ event.target !== menuElement &&
3892
+ !$.contains( menuElement, event.target ) ) {
3893
+ that.close();
3894
+ }
3895
+ });
3896
+ });
3897
+ }
3898
+ },
3899
+ menufocus: function( event, ui ) {
3900
+ // #7024 - Prevent accidental activation of menu items in Firefox
3901
+ if ( this.isNewMenu ) {
3902
+ this.isNewMenu = false;
3903
+ if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
3904
+ this.menu.blur();
3905
+
3906
+ this.document.one( "mousemove", function() {
3907
+ $( event.target ).trigger( event.originalEvent );
3908
+ });
3909
+
3910
+ return;
3911
+ }
3912
+ }
3913
+
3914
+ // back compat for _renderItem using item.autocomplete, via #7810
3915
+ // TODO remove the fallback, see #8156
3916
+ var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
3917
+ if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3918
+ // use value to match what will end up in the input, if it was a key event
3919
+ if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3920
+ this._value( item.value );
3921
+ }
3922
+ } else {
3923
+ // Normally the input is populated with the item's value as the
3924
+ // menu is navigated, causing screen readers to notice a change and
3925
+ // announce the item. Since the focus event was canceled, this doesn't
3926
+ // happen, so we update the live region so that screen readers can
3927
+ // still notice the change and announce it.
3928
+ this.liveRegion.text( item.value );
3929
+ }
3930
+ },
3931
+ menuselect: function( event, ui ) {
3932
+ // back compat for _renderItem using item.autocomplete, via #7810
3933
+ // TODO remove the fallback, see #8156
3934
+ var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
3935
+ previous = this.previous;
3936
+
3937
+ // only trigger when focus was lost (click on menu)
3938
+ if ( this.element[0] !== this.document[0].activeElement ) {
3939
+ this.element.focus();
3940
+ this.previous = previous;
3941
+ // #6109 - IE triggers two focus events and the second
3942
+ // is asynchronous, so we need to reset the previous
3943
+ // term synchronously and asynchronously :-(
3944
+ this._delay(function() {
3945
+ this.previous = previous;
3946
+ this.selectedItem = item;
3947
+ });
3948
+ }
3949
+
3950
+ if ( false !== this._trigger( "select", event, { item: item } ) ) {
3951
+ this._value( item.value );
3952
+ }
3953
+ // reset the term after the select event
3954
+ // this allows custom select handling to work properly
3955
+ this.term = this._value();
3956
+
3957
+ this.close( event );
3958
+ this.selectedItem = item;
3959
+ }
3960
+ });
3961
+
3962
+ this.liveRegion = $( "<span>", {
3963
+ role: "status",
3964
+ "aria-live": "polite"
3965
+ })
3966
+ .addClass( "ui-helper-hidden-accessible" )
3967
+ .insertAfter( this.element );
3968
+
3969
+ if ( $.fn.bgiframe ) {
3970
+ this.menu.element.bgiframe();
3971
+ }
3972
+
3973
+ // turning off autocomplete prevents the browser from remembering the
3974
+ // value when navigating through history, so we re-enable autocomplete
3975
+ // if the page is unloaded before the widget is destroyed. #7790
3976
+ this._on( this.window, {
3977
+ beforeunload: function() {
3978
+ this.element.removeAttr( "autocomplete" );
3979
+ }
3980
+ });
3981
+ },
3982
+
3983
+ _destroy: function() {
3984
+ clearTimeout( this.searching );
3985
+ this.element
3986
+ .removeClass( "ui-autocomplete-input" )
3987
+ .removeAttr( "autocomplete" );
3988
+ this.menu.element.remove();
3989
+ this.liveRegion.remove();
3990
+ },
3991
+
3992
+ _setOption: function( key, value ) {
3993
+ this._super( key, value );
3994
+ if ( key === "source" ) {
3995
+ this._initSource();
3996
+ }
3997
+ if ( key === "appendTo" ) {
3998
+ this.menu.element.appendTo( this.document.find( value || "body" )[0] );
3999
+ }
4000
+ if ( key === "disabled" && value && this.xhr ) {
4001
+ this.xhr.abort();
4002
+ }
4003
+ },
4004
+
4005
+ _isMultiLine: function() {
4006
+ // Textareas are always multi-line
4007
+ if ( this.element.is( "textarea" ) ) {
4008
+ return true;
4009
+ }
4010
+ // Inputs are always single-line, even if inside a contentEditable element
4011
+ // IE also treats inputs as contentEditable
4012
+ if ( this.element.is( "input" ) ) {
4013
+ return false;
4014
+ }
4015
+ // All other element types are determined by whether or not they're contentEditable
4016
+ return this.element.prop( "isContentEditable" );
4017
+ },
4018
+
4019
+ _initSource: function() {
4020
+ var array, url,
4021
+ that = this;
4022
+ if ( $.isArray(this.options.source) ) {
4023
+ array = this.options.source;
4024
+ this.source = function( request, response ) {
4025
+ response( $.ui.autocomplete.filter( array, request.term ) );
4026
+ };
4027
+ } else if ( typeof this.options.source === "string" ) {
4028
+ url = this.options.source;
4029
+ this.source = function( request, response ) {
4030
+ if ( that.xhr ) {
4031
+ that.xhr.abort();
4032
+ }
4033
+ that.xhr = $.ajax({
4034
+ url: url,
4035
+ data: request,
4036
+ dataType: "json",
4037
+ success: function( data ) {
4038
+ response( data );
4039
+ },
4040
+ error: function() {
4041
+ response( [] );
4042
+ }
4043
+ });
4044
+ };
4045
+ } else {
4046
+ this.source = this.options.source;
4047
+ }
4048
+ },
4049
+
4050
+ _searchTimeout: function( event ) {
4051
+ clearTimeout( this.searching );
4052
+ this.searching = this._delay(function() {
4053
+ // only search if the value has changed
4054
+ if ( this.term !== this._value() ) {
4055
+ this.selectedItem = null;
4056
+ this.search( null, event );
4057
+ }
4058
+ }, this.options.delay );
4059
+ },
4060
+
4061
+ search: function( value, event ) {
4062
+ value = value != null ? value : this._value();
4063
+
4064
+ // always save the actual value, not the one passed as an argument
4065
+ this.term = this._value();
4066
+
4067
+ if ( value.length < this.options.minLength ) {
4068
+ return this.close( event );
4069
+ }
4070
+
4071
+ if ( this._trigger( "search", event ) === false ) {
4072
+ return;
4073
+ }
4074
+
4075
+ return this._search( value );
4076
+ },
4077
+
4078
+ _search: function( value ) {
4079
+ this.pending++;
4080
+ this.element.addClass( "ui-autocomplete-loading" );
4081
+ this.cancelSearch = false;
4082
+
4083
+ this.source( { term: value }, this._response() );
4084
+ },
4085
+
4086
+ _response: function() {
4087
+ var that = this,
4088
+ index = ++requestIndex;
4089
+
4090
+ return function( content ) {
4091
+ if ( index === requestIndex ) {
4092
+ that.__response( content );
4093
+ }
4094
+
4095
+ that.pending--;
4096
+ if ( !that.pending ) {
4097
+ that.element.removeClass( "ui-autocomplete-loading" );
4098
+ }
4099
+ };
4100
+ },
4101
+
4102
+ __response: function( content ) {
4103
+ if ( content ) {
4104
+ content = this._normalize( content );
4105
+ }
4106
+ this._trigger( "response", null, { content: content } );
4107
+ if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
4108
+ this._suggest( content );
4109
+ this._trigger( "open" );
4110
+ } else {
4111
+ // use ._close() instead of .close() so we don't cancel future searches
4112
+ this._close();
4113
+ }
4114
+ },
4115
+
4116
+ close: function( event ) {
4117
+ this.cancelSearch = true;
4118
+ this._close( event );
4119
+ },
4120
+
4121
+ _close: function( event ) {
4122
+ if ( this.menu.element.is( ":visible" ) ) {
4123
+ this.menu.element.hide();
4124
+ this.menu.blur();
4125
+ this.isNewMenu = true;
4126
+ this._trigger( "close", event );
4127
+ }
4128
+ },
4129
+
4130
+ _change: function( event ) {
4131
+ if ( this.previous !== this._value() ) {
4132
+ this._trigger( "change", event, { item: this.selectedItem } );
4133
+ }
4134
+ },
4135
+
4136
+ _normalize: function( items ) {
4137
+ // assume all items have the right format when the first item is complete
4138
+ if ( items.length && items[0].label && items[0].value ) {
4139
+ return items;
4140
+ }
4141
+ return $.map( items, function( item ) {
4142
+ if ( typeof item === "string" ) {
4143
+ return {
4144
+ label: item,
4145
+ value: item
4146
+ };
4147
+ }
4148
+ return $.extend({
4149
+ label: item.label || item.value,
4150
+ value: item.value || item.label
4151
+ }, item );
4152
+ });
4153
+ },
4154
+
4155
+ _suggest: function( items ) {
4156
+ var ul = this.menu.element
4157
+ .empty()
4158
+ .zIndex( this.element.zIndex() + 1 );
4159
+ this._renderMenu( ul, items );
4160
+ this.menu.refresh();
4161
+
4162
+ // size and position menu
4163
+ ul.show();
4164
+ this._resizeMenu();
4165
+ ul.position( $.extend({
4166
+ of: this.element
4167
+ }, this.options.position ));
4168
+
4169
+ if ( this.options.autoFocus ) {
4170
+ this.menu.next();
4171
+ }
4172
+ },
4173
+
4174
+ _resizeMenu: function() {
4175
+ var ul = this.menu.element;
4176
+ ul.outerWidth( Math.max(
4177
+ // Firefox wraps long text (possibly a rounding bug)
4178
+ // so we add 1px to avoid the wrapping (#7513)
4179
+ ul.width( "" ).outerWidth() + 1,
4180
+ this.element.outerWidth()
4181
+ ) );
4182
+ },
4183
+
4184
+ _renderMenu: function( ul, items ) {
4185
+ var that = this;
4186
+ $.each( items, function( index, item ) {
4187
+ that._renderItemData( ul, item );
4188
+ });
4189
+ },
4190
+
4191
+ _renderItemData: function( ul, item ) {
4192
+ return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
4193
+ },
4194
+
4195
+ _renderItem: function( ul, item ) {
4196
+ return $( "<li>" )
4197
+ .append( $( "<a>" ).text( item.label ) )
4198
+ .appendTo( ul );
4199
+ },
4200
+
4201
+ _move: function( direction, event ) {
4202
+ if ( !this.menu.element.is( ":visible" ) ) {
4203
+ this.search( null, event );
4204
+ return;
4205
+ }
4206
+ if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
4207
+ this.menu.isLastItem() && /^next/.test( direction ) ) {
4208
+ this._value( this.term );
4209
+ this.menu.blur();
4210
+ return;
4211
+ }
4212
+ this.menu[ direction ]( event );
4213
+ },
4214
+
4215
+ widget: function() {
4216
+ return this.menu.element;
4217
+ },
4218
+
4219
+ _value: function() {
4220
+ return this.valueMethod.apply( this.element, arguments );
4221
+ },
4222
+
4223
+ _keyEvent: function( keyEvent, event ) {
4224
+ if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
4225
+ this._move( keyEvent, event );
4226
+
4227
+ // prevents moving cursor to beginning/end of the text field in some browsers
4228
+ event.preventDefault();
4229
+ }
4230
+ }
4231
+ });
4232
+
4233
+ $.extend( $.ui.autocomplete, {
4234
+ escapeRegex: function( value ) {
4235
+ return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
4236
+ },
4237
+ filter: function(array, term) {
4238
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
4239
+ return $.grep( array, function(value) {
4240
+ return matcher.test( value.label || value.value || value );
4241
+ });
4242
+ }
4243
+ });
4244
+
4245
+
4246
+ // live region extension, adding a `messages` option
4247
+ // NOTE: This is an experimental API. We are still investigating
4248
+ // a full solution for string manipulation and internationalization.
4249
+ $.widget( "ui.autocomplete", $.ui.autocomplete, {
4250
+ options: {
4251
+ messages: {
4252
+ noResults: "No search results.",
4253
+ results: function( amount ) {
4254
+ return amount + ( amount > 1 ? " results are" : " result is" ) +
4255
+ " available, use up and down arrow keys to navigate.";
4256
+ }
4257
+ }
4258
+ },
4259
+
4260
+ __response: function( content ) {
4261
+ var message;
4262
+ this._superApply( arguments );
4263
+ if ( this.options.disabled || this.cancelSearch ) {
4264
+ return;
4265
+ }
4266
+ if ( content && content.length ) {
4267
+ message = this.options.messages.results( content.length );
4268
+ } else {
4269
+ message = this.options.messages.noResults;
4270
+ }
4271
+ this.liveRegion.text( message );
4272
+ }
4273
+ });
4274
+
4275
+
4276
+ }( jQuery ));
4277
+ (function( $, undefined ) {
4278
+
4279
+ var mouseHandled = false;
4280
+
4281
+ $.widget( "ui.menu", {
4282
+ version: "1.9.1",
4283
+ defaultElement: "<ul>",
4284
+ delay: 300,
4285
+ options: {
4286
+ icons: {
4287
+ submenu: "ui-icon-carat-1-e"
4288
+ },
4289
+ menus: "ul",
4290
+ position: {
4291
+ my: "left top",
4292
+ at: "right top"
4293
+ },
4294
+ role: "menu",
4295
+
4296
+ // callbacks
4297
+ blur: null,
4298
+ focus: null,
4299
+ select: null
4300
+ },
4301
+
4302
+ _create: function() {
4303
+ this.activeMenu = this.element;
4304
+ this.element
4305
+ .uniqueId()
4306
+ .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
4307
+ .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
4308
+ .attr({
4309
+ role: this.options.role,
4310
+ tabIndex: 0
4311
+ })
4312
+ // need to catch all clicks on disabled menu
4313
+ // not possible through _on
4314
+ .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
4315
+ if ( this.options.disabled ) {
4316
+ event.preventDefault();
4317
+ }
4318
+ }, this ));
4319
+
4320
+ if ( this.options.disabled ) {
4321
+ this.element
4322
+ .addClass( "ui-state-disabled" )
4323
+ .attr( "aria-disabled", "true" );
4324
+ }
4325
+
4326
+ this._on({
4327
+ // Prevent focus from sticking to links inside menu after clicking
4328
+ // them (focus should always stay on UL during navigation).
4329
+ "mousedown .ui-menu-item > a": function( event ) {
4330
+ event.preventDefault();
4331
+ },
4332
+ "click .ui-state-disabled > a": function( event ) {
4333
+ event.preventDefault();
4334
+ },
4335
+ "click .ui-menu-item:has(a)": function( event ) {
4336
+ var target = $( event.target ).closest( ".ui-menu-item" );
4337
+ if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4338
+ mouseHandled = true;
4339
+
4340
+ this.select( event );
4341
+ // Open submenu on click
4342
+ if ( target.has( ".ui-menu" ).length ) {
4343
+ this.expand( event );
4344
+ } else if ( !this.element.is( ":focus" ) ) {
4345
+ // Redirect focus to the menu
4346
+ this.element.trigger( "focus", [ true ] );
4347
+
4348
+ // If the active item is on the top level, let it stay active.
4349
+ // Otherwise, blur the active item since it is no longer visible.
4350
+ if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
4351
+ clearTimeout( this.timer );
4352
+ }
4353
+ }
4354
+ }
4355
+ },
4356
+ "mouseenter .ui-menu-item": function( event ) {
4357
+ var target = $( event.currentTarget );
4358
+ // Remove ui-state-active class from siblings of the newly focused menu item
4359
+ // to avoid a jump caused by adjacent elements both having a class with a border
4360
+ target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
4361
+ this.focus( event, target );
4362
+ },
4363
+ mouseleave: "collapseAll",
4364
+ "mouseleave .ui-menu": "collapseAll",
4365
+ focus: function( event, keepActiveItem ) {
4366
+ // If there's already an active item, keep it active
4367
+ // If not, activate the first item
4368
+ var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
4369
+
4370
+ if ( !keepActiveItem ) {
4371
+ this.focus( event, item );
4372
+ }
4373
+ },
4374
+ blur: function( event ) {
4375
+ this._delay(function() {
4376
+ if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
4377
+ this.collapseAll( event );
4378
+ }
4379
+ });
4380
+ },
4381
+ keydown: "_keydown"
4382
+ });
4383
+
4384
+ this.refresh();
4385
+
4386
+ // Clicks outside of a menu collapse any open menus
4387
+ this._on( this.document, {
4388
+ click: function( event ) {
4389
+ if ( !$( event.target ).closest( ".ui-menu" ).length ) {
4390
+ this.collapseAll( event );
4391
+ }
4392
+
4393
+ // Reset the mouseHandled flag
4394
+ mouseHandled = false;
4395
+ }
4396
+ });
4397
+ },
4398
+
4399
+ _destroy: function() {
4400
+ // Destroy (sub)menus
4401
+ this.element
4402
+ .removeAttr( "aria-activedescendant" )
4403
+ .find( ".ui-menu" ).andSelf()
4404
+ .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
4405
+ .removeAttr( "role" )
4406
+ .removeAttr( "tabIndex" )
4407
+ .removeAttr( "aria-labelledby" )
4408
+ .removeAttr( "aria-expanded" )
4409
+ .removeAttr( "aria-hidden" )
4410
+ .removeAttr( "aria-disabled" )
4411
+ .removeUniqueId()
4412
+ .show();
4413
+
4414
+ // Destroy menu items
4415
+ this.element.find( ".ui-menu-item" )
4416
+ .removeClass( "ui-menu-item" )
4417
+ .removeAttr( "role" )
4418
+ .removeAttr( "aria-disabled" )
4419
+ .children( "a" )
4420
+ .removeUniqueId()
4421
+ .removeClass( "ui-corner-all ui-state-hover" )
4422
+ .removeAttr( "tabIndex" )
4423
+ .removeAttr( "role" )
4424
+ .removeAttr( "aria-haspopup" )
4425
+ .children().each( function() {
4426
+ var elem = $( this );
4427
+ if ( elem.data( "ui-menu-submenu-carat" ) ) {
4428
+ elem.remove();
4429
+ }
4430
+ });
4431
+
4432
+ // Destroy menu dividers
4433
+ this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
4434
+ },
4435
+
4436
+ _keydown: function( event ) {
4437
+ var match, prev, character, skip, regex,
4438
+ preventDefault = true;
4439
+
4440
+ function escape( value ) {
4441
+ return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
4442
+ }
4443
+
4444
+ switch ( event.keyCode ) {
4445
+ case $.ui.keyCode.PAGE_UP:
4446
+ this.previousPage( event );
4447
+ break;
4448
+ case $.ui.keyCode.PAGE_DOWN:
4449
+ this.nextPage( event );
4450
+ break;
4451
+ case $.ui.keyCode.HOME:
4452
+ this._move( "first", "first", event );
4453
+ break;
4454
+ case $.ui.keyCode.END:
4455
+ this._move( "last", "last", event );
4456
+ break;
4457
+ case $.ui.keyCode.UP:
4458
+ this.previous( event );
4459
+ break;
4460
+ case $.ui.keyCode.DOWN:
4461
+ this.next( event );
4462
+ break;
4463
+ case $.ui.keyCode.LEFT:
4464
+ this.collapse( event );
4465
+ break;
4466
+ case $.ui.keyCode.RIGHT:
4467
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
4468
+ this.expand( event );
4469
+ }
4470
+ break;
4471
+ case $.ui.keyCode.ENTER:
4472
+ case $.ui.keyCode.SPACE:
4473
+ this._activate( event );
4474
+ break;
4475
+ case $.ui.keyCode.ESCAPE:
4476
+ this.collapse( event );
4477
+ break;
4478
+ default:
4479
+ preventDefault = false;
4480
+ prev = this.previousFilter || "";
4481
+ character = String.fromCharCode( event.keyCode );
4482
+ skip = false;
4483
+
4484
+ clearTimeout( this.filterTimer );
4485
+
4486
+ if ( character === prev ) {
4487
+ skip = true;
4488
+ } else {
4489
+ character = prev + character;
4490
+ }
4491
+
4492
+ regex = new RegExp( "^" + escape( character ), "i" );
4493
+ match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
4494
+ return regex.test( $( this ).children( "a" ).text() );
4495
+ });
4496
+ match = skip && match.index( this.active.next() ) !== -1 ?
4497
+ this.active.nextAll( ".ui-menu-item" ) :
4498
+ match;
4499
+
4500
+ // If no matches on the current filter, reset to the last character pressed
4501
+ // to move down the menu to the first item that starts with that character
4502
+ if ( !match.length ) {
4503
+ character = String.fromCharCode( event.keyCode );
4504
+ regex = new RegExp( "^" + escape( character ), "i" );
4505
+ match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
4506
+ return regex.test( $( this ).children( "a" ).text() );
4507
+ });
4508
+ }
4509
+
4510
+ if ( match.length ) {
4511
+ this.focus( event, match );
4512
+ if ( match.length > 1 ) {
4513
+ this.previousFilter = character;
4514
+ this.filterTimer = this._delay(function() {
4515
+ delete this.previousFilter;
4516
+ }, 1000 );
4517
+ } else {
4518
+ delete this.previousFilter;
4519
+ }
4520
+ } else {
4521
+ delete this.previousFilter;
4522
+ }
4523
+ }
4524
+
4525
+ if ( preventDefault ) {
4526
+ event.preventDefault();
4527
+ }
4528
+ },
4529
+
4530
+ _activate: function( event ) {
4531
+ if ( !this.active.is( ".ui-state-disabled" ) ) {
4532
+ if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
4533
+ this.expand( event );
4534
+ } else {
4535
+ this.select( event );
4536
+ }
4537
+ }
4538
+ },
4539
+
4540
+ refresh: function() {
4541
+ // Initialize nested menus
4542
+ var menus,
4543
+ icon = this.options.icons.submenu,
4544
+ submenus = this.element.find( this.options.menus + ":not(.ui-menu)" )
4545
+ .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
4546
+ .hide()
4547
+ .attr({
4548
+ role: this.options.role,
4549
+ "aria-hidden": "true",
4550
+ "aria-expanded": "false"
4551
+ });
4552
+
4553
+ // Don't refresh list items that are already adapted
4554
+ menus = submenus.add( this.element );
4555
+
4556
+ menus.children( ":not(.ui-menu-item):has(a)" )
4557
+ .addClass( "ui-menu-item" )
4558
+ .attr( "role", "presentation" )
4559
+ .children( "a" )
4560
+ .uniqueId()
4561
+ .addClass( "ui-corner-all" )
4562
+ .attr({
4563
+ tabIndex: -1,
4564
+ role: this._itemRole()
4565
+ });
4566
+
4567
+ // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
4568
+ menus.children( ":not(.ui-menu-item)" ).each(function() {
4569
+ var item = $( this );
4570
+ // hyphen, em dash, en dash
4571
+ if ( !/[^\-—–\s]/.test( item.text() ) ) {
4572
+ item.addClass( "ui-widget-content ui-menu-divider" );
4573
+ }
4574
+ });
4575
+
4576
+ // Add aria-disabled attribute to any disabled menu item
4577
+ menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
4578
+
4579
+ submenus.each(function() {
4580
+ var menu = $( this ),
4581
+ item = menu.prev( "a" ),
4582
+ submenuCarat = $( "<span>" )
4583
+ .addClass( "ui-menu-icon ui-icon " + icon )
4584
+ .data( "ui-menu-submenu-carat", true );
4585
+
4586
+ item
4587
+ .attr( "aria-haspopup", "true" )
4588
+ .prepend( submenuCarat );
4589
+ menu.attr( "aria-labelledby", item.attr( "id" ) );
4590
+ });
4591
+
4592
+ // If the active item has been removed, blur the menu
4593
+ if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4594
+ this.blur();
4595
+ }
4596
+ },
4597
+
4598
+ _itemRole: function() {
4599
+ return {
4600
+ menu: "menuitem",
4601
+ listbox: "option"
4602
+ }[ this.options.role ];
4603
+ },
4604
+
4605
+ focus: function( event, item ) {
4606
+ var nested, focused;
4607
+ this.blur( event, event && event.type === "focus" );
4608
+
4609
+ this._scrollIntoView( item );
4610
+
4611
+ this.active = item.first();
4612
+ focused = this.active.children( "a" ).addClass( "ui-state-focus" );
4613
+ // Only update aria-activedescendant if there's a role
4614
+ // otherwise we assume focus is managed elsewhere
4615
+ if ( this.options.role ) {
4616
+ this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
4617
+ }
4618
+
4619
+ // Highlight active parent menu item, if any
4620
+ this.active
4621
+ .parent()
4622
+ .closest( ".ui-menu-item" )
4623
+ .children( "a:first" )
4624
+ .addClass( "ui-state-active" );
4625
+
4626
+ if ( event && event.type === "keydown" ) {
4627
+ this._close();
4628
+ } else {
4629
+ this.timer = this._delay(function() {
4630
+ this._close();
4631
+ }, this.delay );
4632
+ }
4633
+
4634
+ nested = item.children( ".ui-menu" );
4635
+ if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
4636
+ this._startOpening(nested);
4637
+ }
4638
+ this.activeMenu = item.parent();
4639
+
4640
+ this._trigger( "focus", event, { item: item } );
4641
+ },
4642
+
4643
+ _scrollIntoView: function( item ) {
4644
+ var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
4645
+ if ( this._hasScroll() ) {
4646
+ borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
4647
+ paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
4648
+ offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
4649
+ scroll = this.activeMenu.scrollTop();
4650
+ elementHeight = this.activeMenu.height();
4651
+ itemHeight = item.height();
4652
+
4653
+ if ( offset < 0 ) {
4654
+ this.activeMenu.scrollTop( scroll + offset );
4655
+ } else if ( offset + itemHeight > elementHeight ) {
4656
+ this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
4657
+ }
4658
+ }
4659
+ },
4660
+
4661
+ blur: function( event, fromFocus ) {
4662
+ if ( !fromFocus ) {
4663
+ clearTimeout( this.timer );
4664
+ }
4665
+
4666
+ if ( !this.active ) {
4667
+ return;
4668
+ }
4669
+
4670
+ this.active.children( "a" ).removeClass( "ui-state-focus" );
4671
+ this.active = null;
4672
+
4673
+ this._trigger( "blur", event, { item: this.active } );
4674
+ },
4675
+
4676
+ _startOpening: function( submenu ) {
4677
+ clearTimeout( this.timer );
4678
+
4679
+ // Don't open if already open fixes a Firefox bug that caused a .5 pixel
4680
+ // shift in the submenu position when mousing over the carat icon
4681
+ if ( submenu.attr( "aria-hidden" ) !== "true" ) {
4682
+ return;
4683
+ }
4684
+
4685
+ this.timer = this._delay(function() {
4686
+ this._close();
4687
+ this._open( submenu );
4688
+ }, this.delay );
4689
+ },
4690
+
4691
+ _open: function( submenu ) {
4692
+ var position = $.extend({
4693
+ of: this.active
4694
+ }, this.options.position );
4695
+
4696
+ clearTimeout( this.timer );
4697
+ this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
4698
+ .hide()
4699
+ .attr( "aria-hidden", "true" );
4700
+
4701
+ submenu
4702
+ .show()
4703
+ .removeAttr( "aria-hidden" )
4704
+ .attr( "aria-expanded", "true" )
4705
+ .position( position );
4706
+ },
4707
+
4708
+ collapseAll: function( event, all ) {
4709
+ clearTimeout( this.timer );
4710
+ this.timer = this._delay(function() {
4711
+ // If we were passed an event, look for the submenu that contains the event
4712
+ var currentMenu = all ? this.element :
4713
+ $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
4714
+
4715
+ // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
4716
+ if ( !currentMenu.length ) {
4717
+ currentMenu = this.element;
4718
+ }
4719
+
4720
+ this._close( currentMenu );
4721
+
4722
+ this.blur( event );
4723
+ this.activeMenu = currentMenu;
4724
+ }, this.delay );
4725
+ },
4726
+
4727
+ // With no arguments, closes the currently active menu - if nothing is active
4728
+ // it closes all menus. If passed an argument, it will search for menus BELOW
4729
+ _close: function( startMenu ) {
4730
+ if ( !startMenu ) {
4731
+ startMenu = this.active ? this.active.parent() : this.element;
4732
+ }
4733
+
4734
+ startMenu
4735
+ .find( ".ui-menu" )
4736
+ .hide()
4737
+ .attr( "aria-hidden", "true" )
4738
+ .attr( "aria-expanded", "false" )
4739
+ .end()
4740
+ .find( "a.ui-state-active" )
4741
+ .removeClass( "ui-state-active" );
4742
+ },
4743
+
4744
+ collapse: function( event ) {
4745
+ var newItem = this.active &&
4746
+ this.active.parent().closest( ".ui-menu-item", this.element );
4747
+ if ( newItem && newItem.length ) {
4748
+ this._close();
4749
+ this.focus( event, newItem );
4750
+ }
4751
+ },
4752
+
4753
+ expand: function( event ) {
4754
+ var newItem = this.active &&
4755
+ this.active
4756
+ .children( ".ui-menu " )
4757
+ .children( ".ui-menu-item" )
4758
+ .first();
4759
+
4760
+ if ( newItem && newItem.length ) {
4761
+ this._open( newItem.parent() );
4762
+
4763
+ // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
4764
+ this._delay(function() {
4765
+ this.focus( event, newItem );
4766
+ });
4767
+ }
4768
+ },
4769
+
4770
+ next: function( event ) {
4771
+ this._move( "next", "first", event );
4772
+ },
4773
+
4774
+ previous: function( event ) {
4775
+ this._move( "prev", "last", event );
4776
+ },
4777
+
4778
+ isFirstItem: function() {
4779
+ return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
4780
+ },
4781
+
4782
+ isLastItem: function() {
4783
+ return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
4784
+ },
4785
+
4786
+ _move: function( direction, filter, event ) {
4787
+ var next;
4788
+ if ( this.active ) {
4789
+ if ( direction === "first" || direction === "last" ) {
4790
+ next = this.active
4791
+ [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
4792
+ .eq( -1 );
4793
+ } else {
4794
+ next = this.active
4795
+ [ direction + "All" ]( ".ui-menu-item" )
4796
+ .eq( 0 );
4797
+ }
4798
+ }
4799
+ if ( !next || !next.length || !this.active ) {
4800
+ next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
4801
+ }
4802
+
4803
+ this.focus( event, next );
4804
+ },
4805
+
4806
+ nextPage: function( event ) {
4807
+ var item, base, height;
4808
+
4809
+ if ( !this.active ) {
4810
+ this.next( event );
4811
+ return;
4812
+ }
4813
+ if ( this.isLastItem() ) {
4814
+ return;
4815
+ }
4816
+ if ( this._hasScroll() ) {
4817
+ base = this.active.offset().top;
4818
+ height = this.element.height();
4819
+ this.active.nextAll( ".ui-menu-item" ).each(function() {
4820
+ item = $( this );
4821
+ return item.offset().top - base - height < 0;
4822
+ });
4823
+
4824
+ this.focus( event, item );
4825
+ } else {
4826
+ this.focus( event, this.activeMenu.children( ".ui-menu-item" )
4827
+ [ !this.active ? "first" : "last" ]() );
4828
+ }
4829
+ },
4830
+
4831
+ previousPage: function( event ) {
4832
+ var item, base, height;
4833
+ if ( !this.active ) {
4834
+ this.next( event );
4835
+ return;
4836
+ }
4837
+ if ( this.isFirstItem() ) {
4838
+ return;
4839
+ }
4840
+ if ( this._hasScroll() ) {
4841
+ base = this.active.offset().top;
4842
+ height = this.element.height();
4843
+ this.active.prevAll( ".ui-menu-item" ).each(function() {
4844
+ item = $( this );
4845
+ return item.offset().top - base + height > 0;
4846
+ });
4847
+
4848
+ this.focus( event, item );
4849
+ } else {
4850
+ this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
4851
+ }
4852
+ },
4853
+
4854
+ _hasScroll: function() {
4855
+ return this.element.outerHeight() < this.element.prop( "scrollHeight" );
4856
+ },
4857
+
4858
+ select: function( event ) {
4859
+ // TODO: It should never be possible to not have an active item at this
4860
+ // point, but the tests don't trigger mouseenter before click.
4861
+ this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
4862
+ var ui = { item: this.active };
4863
+ if ( !this.active.has( ".ui-menu" ).length ) {
4864
+ this.collapseAll( event, true );
4865
+ }
4866
+ this._trigger( "select", event, ui );
4867
+ }
4868
+ });
4869
+
4870
+ }( jQuery ));