rich_cms 2.1.7 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. data/{CHANGELOG → CHANGELOG.rdoc} +24 -0
  2. data/README.textile +49 -33
  3. data/Rakefile +92 -10
  4. data/VERSION +1 -1
  5. data/app/controllers/rich/cms_controller.rb +10 -39
  6. data/app/controllers/rich/cms_sessions_controller.rb +31 -0
  7. data/app/views/rich/cms/dock/_menu.html.erb +10 -8
  8. data/app/views/rich/cms/dock/_panel.html.erb +1 -1
  9. data/app/views/rich/cms/dock/panel/edit/_rails2.html.erb +5 -3
  10. data/app/views/rich/cms/dock/panel/edit/_rails3.html.erb +4 -2
  11. data/app/views/rich/cms/dock/panel/login/_rails2.html.erb +18 -12
  12. data/app/views/rich/cms/dock/panel/login/_rails3.html.erb +18 -12
  13. data/app/views/rich_cms.html.erb +1 -1
  14. data/assets/jzip/jquery/cleditor.js +1132 -1132
  15. data/assets/jzip/jquery/extensions/browser_detect.js +1 -2
  16. data/assets/jzip/native/extensions.js +41 -0
  17. data/assets/jzip/rich/cms/editor.js +41 -7
  18. data/assets/jzip/rich_cms.jz +2 -1
  19. data/assets/sass/rich_cms/_panel.sass +11 -1
  20. data/config/routes.rb +12 -11
  21. data/lib/generators/rich/cms_admin/cms_admin_generator.rb +82 -0
  22. data/lib/generators/rich/{authlogic_user/templates → cms_admin/templates/authlogic}/migration.rb +0 -0
  23. data/lib/generators/rich/{authlogic_user/templates → cms_admin/templates/authlogic}/model.rb +0 -0
  24. data/lib/generators/rich/{authlogic_user/templates → cms_admin/templates/authlogic}/session.rb +0 -0
  25. data/lib/rich/cms/actionpack/action_controller/base.rb +3 -44
  26. data/lib/rich/cms/actionpack/action_view/base.rb +32 -10
  27. data/lib/rich/cms/actionpack.rb +1 -2
  28. data/lib/rich/cms/auth.rb +110 -0
  29. data/lib/rich/cms/content/group.rb +1 -2
  30. data/lib/rich/cms/content/item.rb +2 -3
  31. data/lib/rich/cms/core/string/html_safe.rb +1 -2
  32. data/lib/rich/cms/core/string.rb +1 -2
  33. data/lib/rich/cms/engine.rb +23 -51
  34. data/lib/rich/cms/rails/engine.rb +1 -2
  35. data/lib/rich/cms/version.rb +11 -0
  36. data/lib/rich_cms.rb +2 -2
  37. data/rails_generators/rich_cms_admin/lib/devise/route_devise.rb +32 -0
  38. data/rails_generators/rich_cms_admin/rich_cms_admin_generator.rb +113 -0
  39. data/rails_generators/{rich_authlogic_user/templates → rich_cms_admin/templates/authlogic}/migration.rb +0 -0
  40. data/rails_generators/{rich_authlogic_user/templates → rich_cms_admin/templates/authlogic}/model.rb +0 -0
  41. data/rails_generators/{rich_authlogic_user/templates → rich_cms_admin/templates/authlogic}/session.rb +0 -0
  42. data/rails_generators/{rich_authlogic_user → rich_cms_admin}/templates/config.rb +0 -0
  43. data/rails_generators/rich_cms_admin/templates/devise/README +23 -0
  44. data/rails_generators/rich_cms_admin/templates/devise/devise.rb +105 -0
  45. data/rails_generators/rich_cms_admin/templates/devise/en.yml +35 -0
  46. data/rails_generators/rich_cms_admin/templates/devise/migration.rb +23 -0
  47. data/rails_generators/rich_cms_admin/templates/devise/model.rb +9 -0
  48. data/rails_generators/rich_cms_content/rich_cms_content_generator.rb +18 -12
  49. data/rich_cms.gemspec +295 -105
  50. data/test/integrator.rb +89 -0
  51. data/test/rails-2/dummy/.bundle/config +2 -0
  52. data/test/rails-2/dummy/Gemfile +15 -0
  53. data/test/rails-2/dummy/Gemfile.lock +97 -0
  54. data/test/rails-2/dummy/Rakefile +10 -0
  55. data/test/rails-2/dummy/app/controllers/application_controller.rb +10 -0
  56. data/test/rails-2/dummy/app/helpers/application_helper.rb +3 -0
  57. data/test/rails-2/dummy/config/boot.rb +124 -0
  58. data/test/rails-2/dummy/config/database.yml +23 -0
  59. data/test/rails-2/dummy/config/environment.rb +41 -0
  60. data/test/rails-2/dummy/config/environments/development.rb +17 -0
  61. data/test/rails-2/dummy/config/environments/production.rb +28 -0
  62. data/test/rails-2/dummy/config/environments/test.rb +28 -0
  63. data/test/rails-2/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/test/rails-2/dummy/config/initializers/cookie_verification_secret.rb +7 -0
  65. data/test/rails-2/dummy/config/initializers/devise.rb +105 -0
  66. data/test/rails-2/dummy/config/initializers/enrichments.rb +5 -0
  67. data/test/rails-2/dummy/config/initializers/inflections.rb +10 -0
  68. data/test/rails-2/dummy/config/initializers/mime_types.rb +5 -0
  69. data/test/rails-2/dummy/config/initializers/new_rails_defaults.rb +21 -0
  70. data/test/rails-2/dummy/config/initializers/session_store.rb +15 -0
  71. data/test/rails-2/dummy/config/locales/en.yml +5 -0
  72. data/test/rails-2/dummy/config/preinitializer.rb +20 -0
  73. data/test/rails-2/dummy/config/routes.rb +44 -0
  74. data/test/rails-2/dummy/db/schema.rb +49 -0
  75. data/test/rails-2/dummy/db/seeds.rb +10 -0
  76. data/test/rails-2/dummy/public/404.html +30 -0
  77. data/test/rails-2/dummy/public/422.html +30 -0
  78. data/test/rails-2/dummy/public/500.html +30 -0
  79. data/test/rails-2/dummy/public/favicon.ico +0 -0
  80. data/test/rails-2/dummy/public/images/rails.png +0 -0
  81. data/test/rails-2/dummy/public/images/rich/cms/cleditor/buttons.gif +0 -0
  82. data/test/rails-2/dummy/public/images/rich/cms/cleditor/toolbar.gif +0 -0
  83. data/test/rails-2/dummy/public/javascripts/jquery/core.js +158 -0
  84. data/test/rails-2/dummy/public/javascripts/jquery/ui/rich_cms/core.js +1207 -0
  85. data/test/rails-2/dummy/public/javascripts/jquery/ui/rich_cms/draggable.js +798 -0
  86. data/test/rails-2/dummy/public/javascripts/jquery/ui/rich_cms/mouse.js +950 -0
  87. data/test/rails-2/dummy/public/javascripts/jquery/ui/rich_cms/widget.js +1188 -0
  88. data/test/rails-2/dummy/public/javascripts/rich_cms.js +1746 -0
  89. data/test/rails-2/dummy/public/robots.txt +5 -0
  90. data/test/rails-2/dummy/script/about +4 -0
  91. data/test/rails-2/dummy/script/console +3 -0
  92. data/test/rails-2/dummy/script/dbconsole +3 -0
  93. data/test/rails-2/dummy/script/destroy +3 -0
  94. data/test/rails-2/dummy/script/generate +3 -0
  95. data/test/rails-2/dummy/script/performance/benchmarker +3 -0
  96. data/test/rails-2/dummy/script/performance/profiler +3 -0
  97. data/test/rails-2/dummy/script/plugin +3 -0
  98. data/test/rails-2/dummy/script/runner +3 -0
  99. data/test/rails-2/dummy/script/server +3 -0
  100. data/test/rails-2/dummy/test/fixtures/authlogic_users.yml +6 -0
  101. data/test/rails-2/dummy/test/fixtures/devise_users.yml +5 -0
  102. data/test/rails-2/pending.rb +88 -0
  103. data/test/rails-2/test_helper.rb +13 -0
  104. data/test/rails-3/dummy/.bundle/config +2 -0
  105. data/test/rails-3/dummy/Gemfile +15 -0
  106. data/test/rails-3/dummy/Gemfile.lock +139 -0
  107. data/test/rails-3/dummy/Rakefile +7 -0
  108. data/test/rails-3/dummy/app/controllers/application_controller.rb +3 -0
  109. data/test/rails-3/dummy/app/helpers/application_helper.rb +2 -0
  110. data/test/rails-3/dummy/config/application.rb +42 -0
  111. data/test/rails-3/dummy/config/boot.rb +13 -0
  112. data/test/rails-3/dummy/config/database.yml +23 -0
  113. data/test/rails-3/dummy/config/environment.rb +5 -0
  114. data/test/rails-3/dummy/config/environments/development.rb +26 -0
  115. data/test/rails-3/dummy/config/environments/production.rb +49 -0
  116. data/test/rails-3/dummy/config/environments/test.rb +35 -0
  117. data/test/rails-3/dummy/config/initializers/backtrace_silencers.rb +7 -0
  118. data/test/rails-3/dummy/config/initializers/devise.rb +142 -0
  119. data/test/rails-3/dummy/config/initializers/enrichments.rb +5 -0
  120. data/test/rails-3/dummy/config/initializers/inflections.rb +10 -0
  121. data/test/rails-3/dummy/config/initializers/mime_types.rb +5 -0
  122. data/test/rails-3/dummy/config/initializers/secret_token.rb +7 -0
  123. data/test/rails-3/dummy/config/initializers/session_store.rb +8 -0
  124. data/test/rails-3/dummy/config/locales/en.yml +5 -0
  125. data/test/rails-3/dummy/config/routes.rb +59 -0
  126. data/test/rails-3/dummy/config.ru +4 -0
  127. data/test/rails-3/dummy/db/schema.rb +49 -0
  128. data/test/rails-3/dummy/db/seeds.rb +10 -0
  129. data/test/rails-3/dummy/public/404.html +26 -0
  130. data/test/rails-3/dummy/public/422.html +26 -0
  131. data/test/rails-3/dummy/public/500.html +26 -0
  132. data/test/rails-3/dummy/public/favicon.ico +0 -0
  133. data/test/rails-3/dummy/public/images/rich/cms/cleditor/buttons.gif +0 -0
  134. data/test/rails-3/dummy/public/images/rich/cms/cleditor/toolbar.gif +0 -0
  135. data/test/rails-3/dummy/public/javascripts/jquery/core.js +158 -0
  136. data/test/rails-3/dummy/public/javascripts/jquery/ui/rich_cms/core.js +1207 -0
  137. data/test/rails-3/dummy/public/javascripts/jquery/ui/rich_cms/draggable.js +798 -0
  138. data/test/rails-3/dummy/public/javascripts/jquery/ui/rich_cms/mouse.js +950 -0
  139. data/test/rails-3/dummy/public/javascripts/jquery/ui/rich_cms/widget.js +1188 -0
  140. data/test/rails-3/dummy/public/javascripts/rich_cms.js +1746 -0
  141. data/test/rails-3/dummy/script/rails +6 -0
  142. data/test/rails-3/dummy/test/fixtures/authlogic_users.yml +6 -0
  143. data/test/rails-3/dummy/test/fixtures/devise_users.yml +5 -0
  144. data/test/rails-3/test_helper.rb +17 -0
  145. data/test/shared/dummy/db/schema.rb +49 -0
  146. data/test/shared/dummy/db/seeds.rb +10 -0
  147. data/test/shared/dummy/fixtures/authlogic_users.yml +6 -0
  148. data/test/shared/dummy/models/authlogic_user.rb +8 -0
  149. data/test/shared/dummy/models/authlogic_user_session.rb +10 -0
  150. data/test/shared/dummy/models/cms_content.rb +2 -0
  151. data/test/shared/dummy/models/devise_user.rb +3 -0
  152. data/test/shared/dummy/stylesheets/app.css +100 -0
  153. data/test/shared/dummy/stylesheets/rich_cms.css +159 -0
  154. data/test/shared/dummy/views/application/index.html.erb +13 -0
  155. data/test/shared/dummy/views/layouts/application.html.erb +12 -0
  156. data/test/shared/support/action_controller/integration.rb +55 -0
  157. data/test/shared/support/action_controller/test_case.rb +28 -0
  158. data/test/shared/support/capybara/setup.rb +14 -0
  159. data/test/shared/support/test_helper.rb +1 -0
  160. data/test/shared/tests/actionpack/action_controller/base_test.rb +14 -0
  161. data/test/shared/tests/actionpack/action_view/base_test.rb +19 -0
  162. data/test/shared/tests/activesupport/active_support/dependencies_test.rb +15 -0
  163. data/test/shared/tests/app/integration/authenticated/authlogic.rb +88 -0
  164. data/test/shared/tests/app/integration/authenticated/devise_test.rb +89 -0
  165. data/test/shared/tests/app/integration/non_authenticated.rb +63 -0
  166. data/test/shared/tests/app/routing_test.rb +31 -0
  167. data/test/shared/tests/auth_test.rb +11 -0
  168. data/test/shared/tests/content/group.rb +10 -0
  169. data/test/shared/tests/content/item.rb +10 -0
  170. data/test/shared/tests/core/string/html_safe.rb +15 -0
  171. data/test/shared/tests/dummy_app.rb +228 -0
  172. data/test/shared/tests/engine_test.rb +19 -0
  173. data/test/shared/tests/rails/engine_test.rb +13 -0
  174. data/test/shared/tests/readme_test.rb +13 -0
  175. metadata +231 -63
  176. data/.gitignore +0 -2
  177. data/lib/generators/rich/authlogic_user/authlogic_user_generator.rb +0 -64
  178. data/rails_generators/rich_authlogic_user/rich_authlogic_user_generator.rb +0 -64
  179. data/test/test_helper.rb +0 -6
@@ -0,0 +1,1188 @@
1
+
2
+ /*!
3
+ * jQuery UI Widget 1.8.4
4
+ *
5
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6
+ * Dual licensed under the MIT or GPL Version 2 licenses.
7
+ * http://jquery.org/license
8
+ *
9
+ * http://docs.jquery.com/UI/Widget
10
+ */
11
+ (function( $, undefined ) {
12
+
13
+ var _remove = $.fn.remove;
14
+
15
+ $.fn.remove = function( selector, keepData ) {
16
+ return this.each(function() {
17
+ if ( !keepData ) {
18
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
19
+ $( "*", this ).add( [ this ] ).each(function() {
20
+ $( this ).triggerHandler( "remove" );
21
+ });
22
+ }
23
+ }
24
+ return _remove.call( $(this), selector, keepData );
25
+ });
26
+ };
27
+
28
+ $.widget = function( name, base, prototype ) {
29
+ var namespace = name.split( "." )[ 0 ],
30
+ fullName;
31
+ name = name.split( "." )[ 1 ];
32
+ fullName = namespace + "-" + name;
33
+
34
+ if ( !prototype ) {
35
+ prototype = base;
36
+ base = $.Widget;
37
+ }
38
+
39
+ // create selector for plugin
40
+ $.expr[ ":" ][ fullName ] = function( elem ) {
41
+ return !!$.data( elem, name );
42
+ };
43
+
44
+ $[ namespace ] = $[ namespace ] || {};
45
+ $[ namespace ][ name ] = function( options, element ) {
46
+ // allow instantiation without initializing for simple inheritance
47
+ if ( arguments.length ) {
48
+ this._createWidget( options, element );
49
+ }
50
+ };
51
+
52
+ var basePrototype = new base();
53
+ // we need to make the options hash a property directly on the new instance
54
+ // otherwise we'll modify the options hash on the prototype that we're
55
+ // inheriting from
56
+ // $.each( basePrototype, function( key, val ) {
57
+ // if ( $.isPlainObject(val) ) {
58
+ // basePrototype[ key ] = $.extend( {}, val );
59
+ // }
60
+ // });
61
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
62
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
63
+ namespace: namespace,
64
+ widgetName: name,
65
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
66
+ widgetBaseClass: fullName
67
+ }, prototype );
68
+
69
+ $.widget.bridge( name, $[ namespace ][ name ] );
70
+ };
71
+
72
+ $.widget.bridge = function( name, object ) {
73
+ $.fn[ name ] = function( options ) {
74
+ var isMethodCall = typeof options === "string",
75
+ args = Array.prototype.slice.call( arguments, 1 ),
76
+ returnValue = this;
77
+
78
+ // allow multiple hashes to be passed on init
79
+ options = !isMethodCall && args.length ?
80
+ $.extend.apply( null, [ true, options ].concat(args) ) :
81
+ options;
82
+
83
+ // prevent calls to internal methods
84
+ if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
85
+ return returnValue;
86
+ }
87
+
88
+ if ( isMethodCall ) {
89
+ this.each(function() {
90
+ var instance = $.data( this, name ),
91
+ methodValue = instance && $.isFunction( instance[options] ) ?
92
+ instance[ options ].apply( instance, args ) :
93
+ instance;
94
+ if ( methodValue !== instance && methodValue !== undefined ) {
95
+ returnValue = methodValue;
96
+ return false;
97
+ }
98
+ });
99
+ } else {
100
+ this.each(function() {
101
+ var instance = $.data( this, name );
102
+ if ( instance ) {
103
+ if ( options ) {
104
+ instance.option( options );
105
+ }
106
+ instance._init();
107
+ } else {
108
+ $.data( this, name, new object( options, this ) );
109
+ }
110
+ });
111
+ }
112
+
113
+ return returnValue;
114
+ };
115
+ };
116
+
117
+ $.Widget = function( options, element ) {
118
+ // allow instantiation without initializing for simple inheritance
119
+ if ( arguments.length ) {
120
+ this._createWidget( options, element );
121
+ }
122
+ };
123
+
124
+ $.Widget.prototype = {
125
+ widgetName: "widget",
126
+ widgetEventPrefix: "",
127
+ options: {
128
+ disabled: false
129
+ },
130
+ _createWidget: function( options, element ) {
131
+ // $.widget.bridge stores the plugin instance, but we do it anyway
132
+ // so that it's stored even before the _create function runs
133
+ $.data( element, this.widgetName, this );
134
+ this.element = $( element );
135
+ this.options = $.extend( true, {},
136
+ this.options,
137
+ $.metadata && $.metadata.get( element )[ this.widgetName ],
138
+ options );
139
+
140
+ var self = this;
141
+ this.element.bind( "remove." + this.widgetName, function() {
142
+ self.destroy();
143
+ });
144
+
145
+ this._create();
146
+ this._init();
147
+ },
148
+ _create: function() {},
149
+ _init: function() {},
150
+
151
+ destroy: function() {
152
+ this.element
153
+ .unbind( "." + this.widgetName )
154
+ .removeData( this.widgetName );
155
+ this.widget()
156
+ .unbind( "." + this.widgetName )
157
+ .removeAttr( "aria-disabled" )
158
+ .removeClass(
159
+ this.widgetBaseClass + "-disabled " +
160
+ "ui-state-disabled" );
161
+ },
162
+
163
+ widget: function() {
164
+ return this.element;
165
+ },
166
+
167
+ option: function( key, value ) {
168
+ var options = key,
169
+ self = this;
170
+
171
+ if ( arguments.length === 0 ) {
172
+ // don't return a reference to the internal hash
173
+ return $.extend( {}, self.options );
174
+ }
175
+
176
+ if (typeof key === "string" ) {
177
+ if ( value === undefined ) {
178
+ return this.options[ key ];
179
+ }
180
+ options = {};
181
+ options[ key ] = value;
182
+ }
183
+
184
+ $.each( options, function( key, value ) {
185
+ self._setOption( key, value );
186
+ });
187
+
188
+ return self;
189
+ },
190
+ _setOption: function( key, value ) {
191
+ this.options[ key ] = value;
192
+
193
+ if ( key === "disabled" ) {
194
+ this.widget()
195
+ [ value ? "addClass" : "removeClass"](
196
+ this.widgetBaseClass + "-disabled" + " " +
197
+ "ui-state-disabled" )
198
+ .attr( "aria-disabled", value );
199
+ }
200
+
201
+ return this;
202
+ },
203
+
204
+ enable: function() {
205
+ return this._setOption( "disabled", false );
206
+ },
207
+ disable: function() {
208
+ return this._setOption( "disabled", true );
209
+ },
210
+
211
+ _trigger: function( type, event, data ) {
212
+ var callback = this.options[ type ];
213
+
214
+ event = $.Event( event );
215
+ event.type = ( type === this.widgetEventPrefix ?
216
+ type :
217
+ this.widgetEventPrefix + type ).toLowerCase();
218
+ data = data || {};
219
+
220
+ // copy original event properties over to the new event
221
+ // this would happen if we could call $.event.fix instead of $.Event
222
+ // but we don't have a way to force an event to be fixed multiple times
223
+ if ( event.originalEvent ) {
224
+ for ( var i = $.event.props.length, prop; i; ) {
225
+ prop = $.event.props[ --i ];
226
+ event[ prop ] = event.originalEvent[ prop ];
227
+ }
228
+ }
229
+
230
+ this.element.trigger( event, data );
231
+
232
+ return !( $.isFunction(callback) &&
233
+ callback.call( this.element[0], event, data ) === false ||
234
+ event.isDefaultPrevented() );
235
+ }
236
+ };
237
+
238
+ })( jQuery );
239
+
240
+ /*!
241
+ * jQuery UI Mouse 1.8.4
242
+ *
243
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
244
+ * Dual licensed under the MIT or GPL Version 2 licenses.
245
+ * http://jquery.org/license
246
+ *
247
+ * http://docs.jquery.com/UI/Mouse
248
+ *
249
+ * Depends:
250
+ * jquery.ui.widget.js
251
+ */
252
+ (function( $, undefined ) {
253
+
254
+ $.widget("ui.mouse", {
255
+ options: {
256
+ cancel: ':input,option',
257
+ distance: 1,
258
+ delay: 0
259
+ },
260
+ _mouseInit: function() {
261
+ var self = this;
262
+
263
+ this.element
264
+ .bind('mousedown.'+this.widgetName, function(event) {
265
+ return self._mouseDown(event);
266
+ })
267
+ .bind('click.'+this.widgetName, function(event) {
268
+ if(self._preventClickEvent) {
269
+ self._preventClickEvent = false;
270
+ event.stopImmediatePropagation();
271
+ return false;
272
+ }
273
+ });
274
+
275
+ this.started = false;
276
+ },
277
+
278
+ // TODO: make sure destroying one instance of mouse doesn't mess with
279
+ // other instances of mouse
280
+ _mouseDestroy: function() {
281
+ this.element.unbind('.'+this.widgetName);
282
+ },
283
+
284
+ _mouseDown: function(event) {
285
+ // don't let more than one widget handle mouseStart
286
+ // TODO: figure out why we have to use originalEvent
287
+ event.originalEvent = event.originalEvent || {};
288
+ if (event.originalEvent.mouseHandled) { return; }
289
+
290
+ // we may have missed mouseup (out of window)
291
+ (this._mouseStarted && this._mouseUp(event));
292
+
293
+ this._mouseDownEvent = event;
294
+
295
+ var self = this,
296
+ btnIsLeft = (event.which == 1),
297
+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
298
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
299
+ return true;
300
+ }
301
+
302
+ this.mouseDelayMet = !this.options.delay;
303
+ if (!this.mouseDelayMet) {
304
+ this._mouseDelayTimer = setTimeout(function() {
305
+ self.mouseDelayMet = true;
306
+ }, this.options.delay);
307
+ }
308
+
309
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
310
+ this._mouseStarted = (this._mouseStart(event) !== false);
311
+ if (!this._mouseStarted) {
312
+ event.preventDefault();
313
+ return true;
314
+ }
315
+ }
316
+
317
+ // these delegates are required to keep context
318
+ this._mouseMoveDelegate = function(event) {
319
+ return self._mouseMove(event);
320
+ };
321
+ this._mouseUpDelegate = function(event) {
322
+ return self._mouseUp(event);
323
+ };
324
+ $(document)
325
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
326
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
327
+
328
+ // preventDefault() is used to prevent the selection of text here -
329
+ // however, in Safari, this causes select boxes not to be selectable
330
+ // anymore, so this fix is needed
331
+ ($.browser.safari || event.preventDefault());
332
+
333
+ event.originalEvent.mouseHandled = true;
334
+ return true;
335
+ },
336
+
337
+ _mouseMove: function(event) {
338
+ // IE mouseup check - mouseup happened when mouse was out of window
339
+ if ($.browser.msie && !event.button) {
340
+ return this._mouseUp(event);
341
+ }
342
+
343
+ if (this._mouseStarted) {
344
+ this._mouseDrag(event);
345
+ return event.preventDefault();
346
+ }
347
+
348
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
349
+ this._mouseStarted =
350
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
351
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
352
+ }
353
+
354
+ return !this._mouseStarted;
355
+ },
356
+
357
+ _mouseUp: function(event) {
358
+ $(document)
359
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
360
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
361
+
362
+ if (this._mouseStarted) {
363
+ this._mouseStarted = false;
364
+ this._preventClickEvent = (event.target == this._mouseDownEvent.target);
365
+ this._mouseStop(event);
366
+ }
367
+
368
+ return false;
369
+ },
370
+
371
+ _mouseDistanceMet: function(event) {
372
+ return (Math.max(
373
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
374
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
375
+ ) >= this.options.distance
376
+ );
377
+ },
378
+
379
+ _mouseDelayMet: function(event) {
380
+ return this.mouseDelayMet;
381
+ },
382
+
383
+ // These are placeholder methods, to be overriden by extending plugin
384
+ _mouseStart: function(event) {},
385
+ _mouseDrag: function(event) {},
386
+ _mouseStop: function(event) {},
387
+ _mouseCapture: function(event) { return true; }
388
+ });
389
+
390
+ })(jQuery);
391
+
392
+ /*
393
+ * jQuery UI Draggable 1.8.4
394
+ *
395
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
396
+ * Dual licensed under the MIT or GPL Version 2 licenses.
397
+ * http://jquery.org/license
398
+ *
399
+ * http://docs.jquery.com/UI/Draggables
400
+ *
401
+ * Depends:
402
+ * jquery.ui.core.js
403
+ * jquery.ui.mouse.js
404
+ * jquery.ui.widget.js
405
+ */
406
+ (function( $, undefined ) {
407
+
408
+ $.widget("ui.draggable", $.ui.mouse, {
409
+ widgetEventPrefix: "drag",
410
+ options: {
411
+ addClasses: true,
412
+ appendTo: "parent",
413
+ axis: false,
414
+ connectToSortable: false,
415
+ containment: false,
416
+ cursor: "auto",
417
+ cursorAt: false,
418
+ grid: false,
419
+ handle: false,
420
+ helper: "original",
421
+ iframeFix: false,
422
+ opacity: false,
423
+ refreshPositions: false,
424
+ revert: false,
425
+ revertDuration: 500,
426
+ scope: "default",
427
+ scroll: true,
428
+ scrollSensitivity: 20,
429
+ scrollSpeed: 20,
430
+ snap: false,
431
+ snapMode: "both",
432
+ snapTolerance: 20,
433
+ stack: false,
434
+ zIndex: false
435
+ },
436
+ _create: function() {
437
+
438
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
439
+ this.element[0].style.position = 'relative';
440
+
441
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
442
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
443
+
444
+ this._mouseInit();
445
+
446
+ },
447
+
448
+ destroy: function() {
449
+ if(!this.element.data('draggable')) return;
450
+ this.element
451
+ .removeData("draggable")
452
+ .unbind(".draggable")
453
+ .removeClass("ui-draggable"
454
+ + " ui-draggable-dragging"
455
+ + " ui-draggable-disabled");
456
+ this._mouseDestroy();
457
+
458
+ return this;
459
+ },
460
+
461
+ _mouseCapture: function(event) {
462
+
463
+ var o = this.options;
464
+
465
+ // among others, prevent a drag on a resizable-handle
466
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
467
+ return false;
468
+
469
+ //Quit if we're not on a valid handle
470
+ this.handle = this._getHandle(event);
471
+ if (!this.handle)
472
+ return false;
473
+
474
+ return true;
475
+
476
+ },
477
+
478
+ _mouseStart: function(event) {
479
+
480
+ var o = this.options;
481
+
482
+ //Create and append the visible helper
483
+ this.helper = this._createHelper(event);
484
+
485
+ //Cache the helper size
486
+ this._cacheHelperProportions();
487
+
488
+ //If ddmanager is used for droppables, set the global draggable
489
+ if($.ui.ddmanager)
490
+ $.ui.ddmanager.current = this;
491
+
492
+ /*
493
+ * - Position generation -
494
+ * This block generates everything position related - it's the core of draggables.
495
+ */
496
+
497
+ //Cache the margins of the original element
498
+ this._cacheMargins();
499
+
500
+ //Store the helper's css position
501
+ this.cssPosition = this.helper.css("position");
502
+ this.scrollParent = this.helper.scrollParent();
503
+
504
+ //The element's absolute position on the page minus margins
505
+ this.offset = this.positionAbs = this.element.offset();
506
+ this.offset = {
507
+ top: this.offset.top - this.margins.top,
508
+ left: this.offset.left - this.margins.left
509
+ };
510
+
511
+ $.extend(this.offset, {
512
+ click: { //Where the click happened, relative to the element
513
+ left: event.pageX - this.offset.left,
514
+ top: event.pageY - this.offset.top
515
+ },
516
+ parent: this._getParentOffset(),
517
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
518
+ });
519
+
520
+ //Generate the original position
521
+ this.originalPosition = this.position = this._generatePosition(event);
522
+ this.originalPageX = event.pageX;
523
+ this.originalPageY = event.pageY;
524
+
525
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
526
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
527
+
528
+ //Set a containment if given in the options
529
+ if(o.containment)
530
+ this._setContainment();
531
+
532
+ //Trigger event + callbacks
533
+ if(this._trigger("start", event) === false) {
534
+ this._clear();
535
+ return false;
536
+ }
537
+
538
+ //Recache the helper size
539
+ this._cacheHelperProportions();
540
+
541
+ //Prepare the droppable offsets
542
+ if ($.ui.ddmanager && !o.dropBehaviour)
543
+ $.ui.ddmanager.prepareOffsets(this, event);
544
+
545
+ this.helper.addClass("ui-draggable-dragging");
546
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
547
+ return true;
548
+ },
549
+
550
+ _mouseDrag: function(event, noPropagation) {
551
+
552
+ //Compute the helpers position
553
+ this.position = this._generatePosition(event);
554
+ this.positionAbs = this._convertPositionTo("absolute");
555
+
556
+ //Call plugins and callbacks and use the resulting position if something is returned
557
+ if (!noPropagation) {
558
+ var ui = this._uiHash();
559
+ if(this._trigger('drag', event, ui) === false) {
560
+ this._mouseUp({});
561
+ return false;
562
+ }
563
+ this.position = ui.position;
564
+ }
565
+
566
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
567
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
568
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
569
+
570
+ return false;
571
+ },
572
+
573
+ _mouseStop: function(event) {
574
+
575
+ //If we are using droppables, inform the manager about the drop
576
+ var dropped = false;
577
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
578
+ dropped = $.ui.ddmanager.drop(this, event);
579
+
580
+ //if a drop comes from outside (a sortable)
581
+ if(this.dropped) {
582
+ dropped = this.dropped;
583
+ this.dropped = false;
584
+ }
585
+
586
+ //if the original element is removed, don't bother to continue
587
+ if(!this.element[0] || !this.element[0].parentNode)
588
+ return false;
589
+
590
+ 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))) {
591
+ var self = this;
592
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
593
+ if(self._trigger("stop", event) !== false) {
594
+ self._clear();
595
+ }
596
+ });
597
+ } else {
598
+ if(this._trigger("stop", event) !== false) {
599
+ this._clear();
600
+ }
601
+ }
602
+
603
+ return false;
604
+ },
605
+
606
+ cancel: function() {
607
+
608
+ if(this.helper.is(".ui-draggable-dragging")) {
609
+ this._mouseUp({});
610
+ } else {
611
+ this._clear();
612
+ }
613
+
614
+ return this;
615
+
616
+ },
617
+
618
+ _getHandle: function(event) {
619
+
620
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
621
+ $(this.options.handle, this.element)
622
+ .find("*")
623
+ .andSelf()
624
+ .each(function() {
625
+ if(this == event.target) handle = true;
626
+ });
627
+
628
+ return handle;
629
+
630
+ },
631
+
632
+ _createHelper: function(event) {
633
+
634
+ var o = this.options;
635
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
636
+
637
+ if(!helper.parents('body').length)
638
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
639
+
640
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
641
+ helper.css("position", "absolute");
642
+
643
+ return helper;
644
+
645
+ },
646
+
647
+ _adjustOffsetFromHelper: function(obj) {
648
+ if (typeof obj == 'string') {
649
+ obj = obj.split(' ');
650
+ }
651
+ if ($.isArray(obj)) {
652
+ obj = {left: +obj[0], top: +obj[1] || 0};
653
+ }
654
+ if ('left' in obj) {
655
+ this.offset.click.left = obj.left + this.margins.left;
656
+ }
657
+ if ('right' in obj) {
658
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
659
+ }
660
+ if ('top' in obj) {
661
+ this.offset.click.top = obj.top + this.margins.top;
662
+ }
663
+ if ('bottom' in obj) {
664
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
665
+ }
666
+ },
667
+
668
+ _getParentOffset: function() {
669
+
670
+ //Get the offsetParent and cache its position
671
+ this.offsetParent = this.helper.offsetParent();
672
+ var po = this.offsetParent.offset();
673
+
674
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
675
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
676
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
677
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
678
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
679
+ po.left += this.scrollParent.scrollLeft();
680
+ po.top += this.scrollParent.scrollTop();
681
+ }
682
+
683
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
684
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
685
+ po = { top: 0, left: 0 };
686
+
687
+ return {
688
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
689
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
690
+ };
691
+
692
+ },
693
+
694
+ _getRelativeOffset: function() {
695
+
696
+ if(this.cssPosition == "relative") {
697
+ var p = this.element.position();
698
+ return {
699
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
700
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
701
+ };
702
+ } else {
703
+ return { top: 0, left: 0 };
704
+ }
705
+
706
+ },
707
+
708
+ _cacheMargins: function() {
709
+ this.margins = {
710
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
711
+ top: (parseInt(this.element.css("marginTop"),10) || 0)
712
+ };
713
+ },
714
+
715
+ _cacheHelperProportions: function() {
716
+ this.helperProportions = {
717
+ width: this.helper.outerWidth(),
718
+ height: this.helper.outerHeight()
719
+ };
720
+ },
721
+
722
+ _setContainment: function() {
723
+
724
+ var o = this.options;
725
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
726
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
727
+ 0 - this.offset.relative.left - this.offset.parent.left,
728
+ 0 - this.offset.relative.top - this.offset.parent.top,
729
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
730
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
731
+ ];
732
+
733
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
734
+ var ce = $(o.containment)[0]; if(!ce) return;
735
+ var co = $(o.containment).offset();
736
+ var over = ($(ce).css("overflow") != 'hidden');
737
+
738
+ this.containment = [
739
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
740
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
741
+ 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,
742
+ 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
743
+ ];
744
+ } else if(o.containment.constructor == Array) {
745
+ this.containment = o.containment;
746
+ }
747
+
748
+ },
749
+
750
+ _convertPositionTo: function(d, pos) {
751
+
752
+ if(!pos) pos = this.position;
753
+ var mod = d == "absolute" ? 1 : -1;
754
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
755
+
756
+ return {
757
+ top: (
758
+ pos.top // The absolute mouse position
759
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
760
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
761
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
762
+ ),
763
+ left: (
764
+ pos.left // The absolute mouse position
765
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
766
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
767
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
768
+ )
769
+ };
770
+
771
+ },
772
+
773
+ _generatePosition: function(event) {
774
+
775
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
776
+ var pageX = event.pageX;
777
+ var pageY = event.pageY;
778
+
779
+ /*
780
+ * - Position constraining -
781
+ * Constrain the position to a mix of grid, containment.
782
+ */
783
+
784
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
785
+
786
+ if(this.containment) {
787
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
788
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
789
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
790
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
791
+ }
792
+
793
+ if(o.grid) {
794
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
795
+ 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;
796
+
797
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
798
+ 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;
799
+ }
800
+
801
+ }
802
+
803
+ return {
804
+ top: (
805
+ pageY // The absolute mouse position
806
+ - this.offset.click.top // Click offset (relative to the element)
807
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
808
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
809
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
810
+ ),
811
+ left: (
812
+ pageX // The absolute mouse position
813
+ - this.offset.click.left // Click offset (relative to the element)
814
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
815
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
816
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
817
+ )
818
+ };
819
+
820
+ },
821
+
822
+ _clear: function() {
823
+ this.helper.removeClass("ui-draggable-dragging");
824
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
825
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
826
+ this.helper = null;
827
+ this.cancelHelperRemoval = false;
828
+ },
829
+
830
+ // From now on bulk stuff - mainly helpers
831
+
832
+ _trigger: function(type, event, ui) {
833
+ ui = ui || this._uiHash();
834
+ $.ui.plugin.call(this, type, [event, ui]);
835
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
836
+ return $.Widget.prototype._trigger.call(this, type, event, ui);
837
+ },
838
+
839
+ plugins: {},
840
+
841
+ _uiHash: function(event) {
842
+ return {
843
+ helper: this.helper,
844
+ position: this.position,
845
+ originalPosition: this.originalPosition,
846
+ offset: this.positionAbs
847
+ };
848
+ }
849
+
850
+ });
851
+
852
+ $.extend($.ui.draggable, {
853
+ version: "1.8.4"
854
+ });
855
+
856
+ $.ui.plugin.add("draggable", "connectToSortable", {
857
+ start: function(event, ui) {
858
+
859
+ var inst = $(this).data("draggable"), o = inst.options,
860
+ uiSortable = $.extend({}, ui, { item: inst.element });
861
+ inst.sortables = [];
862
+ $(o.connectToSortable).each(function() {
863
+ var sortable = $.data(this, 'sortable');
864
+ if (sortable && !sortable.options.disabled) {
865
+ inst.sortables.push({
866
+ instance: sortable,
867
+ shouldRevert: sortable.options.revert
868
+ });
869
+ sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
870
+ sortable._trigger("activate", event, uiSortable);
871
+ }
872
+ });
873
+
874
+ },
875
+ stop: function(event, ui) {
876
+
877
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
878
+ var inst = $(this).data("draggable"),
879
+ uiSortable = $.extend({}, ui, { item: inst.element });
880
+
881
+ $.each(inst.sortables, function() {
882
+ if(this.instance.isOver) {
883
+
884
+ this.instance.isOver = 0;
885
+
886
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
887
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
888
+
889
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
890
+ if(this.shouldRevert) this.instance.options.revert = true;
891
+
892
+ //Trigger the stop of the sortable
893
+ this.instance._mouseStop(event);
894
+
895
+ this.instance.options.helper = this.instance.options._helper;
896
+
897
+ //If the helper has been the original item, restore properties in the sortable
898
+ if(inst.options.helper == 'original')
899
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
900
+
901
+ } else {
902
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
903
+ this.instance._trigger("deactivate", event, uiSortable);
904
+ }
905
+
906
+ });
907
+
908
+ },
909
+ drag: function(event, ui) {
910
+
911
+ var inst = $(this).data("draggable"), self = this;
912
+
913
+ var checkPos = function(o) {
914
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
915
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
916
+ var itemHeight = o.height, itemWidth = o.width;
917
+ var itemTop = o.top, itemLeft = o.left;
918
+
919
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
920
+ };
921
+
922
+ $.each(inst.sortables, function(i) {
923
+
924
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
925
+ this.instance.positionAbs = inst.positionAbs;
926
+ this.instance.helperProportions = inst.helperProportions;
927
+ this.instance.offset.click = inst.offset.click;
928
+
929
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
930
+
931
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
932
+ if(!this.instance.isOver) {
933
+
934
+ this.instance.isOver = 1;
935
+ //Now we fake the start of dragging for the sortable instance,
936
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
937
+ //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)
938
+ this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
939
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
940
+ this.instance.options.helper = function() { return ui.helper[0]; };
941
+
942
+ event.target = this.instance.currentItem[0];
943
+ this.instance._mouseCapture(event, true);
944
+ this.instance._mouseStart(event, true, true);
945
+
946
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
947
+ this.instance.offset.click.top = inst.offset.click.top;
948
+ this.instance.offset.click.left = inst.offset.click.left;
949
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
950
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
951
+
952
+ inst._trigger("toSortable", event);
953
+ inst.dropped = this.instance.element; //draggable revert needs that
954
+ //hack so receive/update callbacks work (mostly)
955
+ inst.currentItem = inst.element;
956
+ this.instance.fromOutside = inst;
957
+
958
+ }
959
+
960
+ //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
961
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
962
+
963
+ } else {
964
+
965
+ //If it doesn't intersect with the sortable, and it intersected before,
966
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
967
+ if(this.instance.isOver) {
968
+
969
+ this.instance.isOver = 0;
970
+ this.instance.cancelHelperRemoval = true;
971
+
972
+ //Prevent reverting on this forced stop
973
+ this.instance.options.revert = false;
974
+
975
+ // The out event needs to be triggered independently
976
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
977
+
978
+ this.instance._mouseStop(event, true);
979
+ this.instance.options.helper = this.instance.options._helper;
980
+
981
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
982
+ this.instance.currentItem.remove();
983
+ if(this.instance.placeholder) this.instance.placeholder.remove();
984
+
985
+ inst._trigger("fromSortable", event);
986
+ inst.dropped = false; //draggable revert needs that
987
+ }
988
+
989
+ };
990
+
991
+ });
992
+
993
+ }
994
+ });
995
+
996
+ $.ui.plugin.add("draggable", "cursor", {
997
+ start: function(event, ui) {
998
+ var t = $('body'), o = $(this).data('draggable').options;
999
+ if (t.css("cursor")) o._cursor = t.css("cursor");
1000
+ t.css("cursor", o.cursor);
1001
+ },
1002
+ stop: function(event, ui) {
1003
+ var o = $(this).data('draggable').options;
1004
+ if (o._cursor) $('body').css("cursor", o._cursor);
1005
+ }
1006
+ });
1007
+
1008
+ $.ui.plugin.add("draggable", "iframeFix", {
1009
+ start: function(event, ui) {
1010
+ var o = $(this).data('draggable').options;
1011
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1012
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1013
+ .css({
1014
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1015
+ position: "absolute", opacity: "0.001", zIndex: 1000
1016
+ })
1017
+ .css($(this).offset())
1018
+ .appendTo("body");
1019
+ });
1020
+ },
1021
+ stop: function(event, ui) {
1022
+ $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
1023
+ }
1024
+ });
1025
+
1026
+ $.ui.plugin.add("draggable", "opacity", {
1027
+ start: function(event, ui) {
1028
+ var t = $(ui.helper), o = $(this).data('draggable').options;
1029
+ if(t.css("opacity")) o._opacity = t.css("opacity");
1030
+ t.css('opacity', o.opacity);
1031
+ },
1032
+ stop: function(event, ui) {
1033
+ var o = $(this).data('draggable').options;
1034
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1035
+ }
1036
+ });
1037
+
1038
+ $.ui.plugin.add("draggable", "scroll", {
1039
+ start: function(event, ui) {
1040
+ var i = $(this).data("draggable");
1041
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1042
+ },
1043
+ drag: function(event, ui) {
1044
+
1045
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
1046
+
1047
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1048
+
1049
+ if(!o.axis || o.axis != 'x') {
1050
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1051
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1052
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1053
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1054
+ }
1055
+
1056
+ if(!o.axis || o.axis != 'y') {
1057
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1058
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1059
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1060
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1061
+ }
1062
+
1063
+ } else {
1064
+
1065
+ if(!o.axis || o.axis != 'x') {
1066
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1067
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1068
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1069
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1070
+ }
1071
+
1072
+ if(!o.axis || o.axis != 'y') {
1073
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1074
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1075
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1076
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1077
+ }
1078
+
1079
+ }
1080
+
1081
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1082
+ $.ui.ddmanager.prepareOffsets(i, event);
1083
+
1084
+ }
1085
+ });
1086
+
1087
+ $.ui.plugin.add("draggable", "snap", {
1088
+ start: function(event, ui) {
1089
+
1090
+ var i = $(this).data("draggable"), o = i.options;
1091
+ i.snapElements = [];
1092
+
1093
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1094
+ var $t = $(this); var $o = $t.offset();
1095
+ if(this != i.element[0]) i.snapElements.push({
1096
+ item: this,
1097
+ width: $t.outerWidth(), height: $t.outerHeight(),
1098
+ top: $o.top, left: $o.left
1099
+ });
1100
+ });
1101
+
1102
+ },
1103
+ drag: function(event, ui) {
1104
+
1105
+ var inst = $(this).data("draggable"), o = inst.options;
1106
+ var d = o.snapTolerance;
1107
+
1108
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1109
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1110
+
1111
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
1112
+
1113
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1114
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1115
+
1116
+ //Yes, I know, this is insane ;)
1117
+ 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))) {
1118
+ 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 })));
1119
+ inst.snapElements[i].snapping = false;
1120
+ continue;
1121
+ }
1122
+
1123
+ if(o.snapMode != 'inner') {
1124
+ var ts = Math.abs(t - y2) <= d;
1125
+ var bs = Math.abs(b - y1) <= d;
1126
+ var ls = Math.abs(l - x2) <= d;
1127
+ var rs = Math.abs(r - x1) <= d;
1128
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1129
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1130
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1131
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1132
+ }
1133
+
1134
+ var first = (ts || bs || ls || rs);
1135
+
1136
+ if(o.snapMode != 'outer') {
1137
+ var ts = Math.abs(t - y1) <= d;
1138
+ var bs = Math.abs(b - y2) <= d;
1139
+ var ls = Math.abs(l - x1) <= d;
1140
+ var rs = Math.abs(r - x2) <= d;
1141
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1142
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1143
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1144
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1145
+ }
1146
+
1147
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1148
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1149
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1150
+
1151
+ };
1152
+
1153
+ }
1154
+ });
1155
+
1156
+ $.ui.plugin.add("draggable", "stack", {
1157
+ start: function(event, ui) {
1158
+
1159
+ var o = $(this).data("draggable").options;
1160
+
1161
+ var group = $.makeArray($(o.stack)).sort(function(a,b) {
1162
+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1163
+ });
1164
+ if (!group.length) { return; }
1165
+
1166
+ var min = parseInt(group[0].style.zIndex) || 0;
1167
+ $(group).each(function(i) {
1168
+ this.style.zIndex = min + i;
1169
+ });
1170
+
1171
+ this[0].style.zIndex = min + group.length;
1172
+
1173
+ }
1174
+ });
1175
+
1176
+ $.ui.plugin.add("draggable", "zIndex", {
1177
+ start: function(event, ui) {
1178
+ var t = $(ui.helper), o = $(this).data("draggable").options;
1179
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1180
+ t.css('zIndex', o.zIndex);
1181
+ },
1182
+ stop: function(event, ui) {
1183
+ var o = $(this).data("draggable").options;
1184
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1185
+ }
1186
+ });
1187
+
1188
+ })(jQuery);