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