alchemy_cms 2.1.rc5 → 2.1.rc6

Sign up to get free protection for your applications and to get access to all the features.
@@ -45,10 +45,13 @@ if (typeof(Alchemy) === 'undefined') {
45
45
  },
46
46
 
47
47
  destroy : function() {
48
- Alchemy.ImageCropper.api.destroy();
49
- Alchemy.ImageCropper.initialized = false;
48
+ try {
49
+ Alchemy.ImageCropper.api.destroy();
50
+ } catch(e) {} finally {
51
+ Alchemy.ImageCropper.initialized = false;
52
+ }
50
53
  }
51
54
 
52
- }
55
+ }
53
56
 
54
57
  })(jQuery);
@@ -3,12 +3,12 @@ if (typeof(Alchemy) === 'undefined') {
3
3
  }
4
4
 
5
5
  (function($) {
6
-
6
+
7
7
  var PageSorter = {};
8
8
  $.extend(Alchemy, PageSorter);
9
-
9
+
10
10
  Alchemy.PageSorter = {
11
-
11
+
12
12
  init : function () {
13
13
  $('ul#sitemap').nestedSortable({
14
14
  disableNesting: 'no-nest',
@@ -22,21 +22,26 @@ if (typeof(Alchemy) === 'undefined') {
22
22
  tolerance: 'pointer',
23
23
  toleranceElement: '> div'
24
24
  });
25
- $('#save_page_order').click(function(){
26
- var params = $('ul#sitemap').nestedSortable('serialize');
25
+ $('#save_page_order').click(function(e){
26
+ Alchemy.pleaseWaitOverlay();
27
+ e.preventDefault();
28
+ var params = {
29
+ set: JSON.stringify($('ul#sitemap').nestedSortable('toHierarchy'))
30
+ };
27
31
  $.post(Alchemy.routes.order_admin_pages_path, params);
32
+ return false;
28
33
  });
29
34
  Alchemy.PageSorter.disableButton();
30
35
  Alchemy.resizeFrame();
31
36
  },
32
-
37
+
33
38
  disableButton : function() {
34
39
  var $buttonLink = $('#page_sorting_button a');
35
40
  $buttonLink.removeAttr('onclick');
36
41
  $('#page_sorting_button').addClass('active');
37
42
  $buttonLink.css({cursor: 'default'});
38
43
  }
39
-
44
+
40
45
  }
41
-
46
+
42
47
  })(jQuery);
@@ -221,7 +221,7 @@ div.pagination span.gap {
221
221
  #login_box {
222
222
  height: 310px;
223
223
  width: 394px;
224
- margin-top: -210px;
224
+ margin-top: -230px;
225
225
  margin-left: -197px;
226
226
  position: absolute;
227
227
  top: 50%;
@@ -980,8 +980,11 @@ ul#layoutpages li {
980
980
  }
981
981
 
982
982
  ul#sitemap li {
983
- padding-left: 22px;
984
- padding-right: 0;
983
+ padding-left: 0;
984
+ li {
985
+ padding-left: 22px;
986
+ padding-right: 0;
987
+ }
985
988
  }
986
989
 
987
990
  ul#layoutpages li {
@@ -192,17 +192,17 @@ module Alchemy
192
192
 
193
193
  def order
194
194
  @page_root = Page.language_root_for(session[:language_id])
195
- pages_from_raw_request.each do |page|
196
- page_id = page.first[0]
197
- parent_id = page.first[1]
198
- if parent_id == 'root'
199
- parent = @page_root
200
- else
201
- parent = Page.find(parent_id)
202
- end
203
- page = Page.find(page_id)
204
- page.move_to_child_of(parent)
195
+
196
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
197
+ neworder = JSON.parse(params[:set])
198
+ prev_item = nil
199
+ neworder.each do |item|
200
+ dbitem = Page.find(item['id'])
201
+ prev_item.nil? ? dbitem.move_to_child_of(Page.root) : dbitem.move_to_right_of(prev_item)
202
+ sort_children(item, dbitem) unless item['children'].nil?
203
+ prev_item = dbitem.reload
205
204
  end
205
+
206
206
  flash[:notice] = t("Pages order saved")
207
207
  @redirect_url = admin_pages_path
208
208
  render :action => :redirect
@@ -258,6 +258,17 @@ module Alchemy
258
258
  ).path)
259
259
  end
260
260
 
261
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
262
+ def sort_children(element,dbitem)
263
+ prevchild = nil
264
+ element['children'].each do |child|
265
+ childitem = Page.find(child['id'])
266
+ prevchild.nil? ? childitem.move_to_child_of(dbitem) : childitem.move_to_right_of(prevchild)
267
+ sort_children(child, childitem) unless child['children'].nil?
268
+ prevchild = childitem
269
+ end
270
+ end
271
+
261
272
  end
262
273
  end
263
274
  end
@@ -78,11 +78,11 @@ module Alchemy
78
78
  end
79
79
 
80
80
  def all_contents_by_name(name)
81
- self.contents.find_all_by_name(name)
81
+ self.contents.where(:name => name)
82
82
  end
83
83
 
84
84
  def all_contents_by_type(essence_type)
85
- self.contents.find_all_by_essence_type(Content.normalize_essence_type(essence_type))
85
+ self.contents.where(:essence_type => Content.normalize_essence_type(essence_type))
86
86
  end
87
87
 
88
88
  # Returns the content that is marked as rss title.
@@ -10,7 +10,7 @@
10
10
  Alchemy.ImageCropper.destroy();
11
11
  Alchemy.closeCurrentWindow();
12
12
  Alchemy.reloadPreview();
13
- <%- if @content.element.contents.find_all_by_essence_type("Alchemy::EssencePicture").size > 1 -%>
13
+ <%- if @content.element.all_contents_by_type("Alchemy::EssencePicture").count > 1 -%>
14
14
  Alchemy.SortableContents('<%= form_authenticity_token -%>');
15
15
  <%- end -%>
16
16
 
@@ -1,114 +1,114 @@
1
1
  <li id="page_<%= page.id %>" class="page_level_<%= page.level %>">
2
- <div class="sitemap_page<%= page.locked ? ' locked' : '' %>">
3
- <div class="sitemap_left_images">
4
- <%= sitemapFolderLink(page) unless page.children.blank? || @sorting %>
5
- <span class="site_status <%= @sorting ? 'handle' : nil %> tooltip"></span>
6
- <div class="tooltip_content" style="display: none;">
7
- <h1><%= t("page_type") %>: <%= page.layout_display_name %></h1>
8
- <p>
9
- <%= page.humanized_status %>
10
- </p>
11
- <p>
12
- <strong><%= t("created_at") %>:</strong>
13
- <%= l(page.created_at) %> von <%= page.creator %>
14
- </p>
15
- <p>
16
- <strong><%= t("updated_at") %>:</strong>
17
- <%= l(page.updated_at) %> durch <%= page.updater %>
18
- </p>
19
- <%- if page.locked? -%>
20
- <p>
21
- <%= t("currently_edited_by") %>: <span style="font-weight: bold;"><%= page.current_editor %></span>
22
- </p>
23
- <%- end -%>
24
- </div>
25
- </div>
26
- <div class="sitemap_right_tools">
27
- <%- unless @sorting -%>
28
- <%- permitted_to?(:configure, :alchemy_admin_pages) do -%>
29
- <%= link_to_overlay_window(
30
- render_icon('configure_page'),
31
- alchemy.configure_admin_page_path(page),
32
- {
33
- :title => t('edit_page_properties'),
34
- :size => page.redirects_to_external? ? '410x270' : '410x620'
35
- },
36
- :class => '',
37
- :title => t('edit_page_properties')
38
- ) -%>
39
- <%- end -%>
40
- <%- permitted_to?([:new, :destroy, :copy], :alchemy_admin_pages) do -%>
41
- <span class="sitemap_sitetools">
42
- <%- permitted_to?(:copy, :alchemy_admin_pages) do -%>
43
- <%= link_to(
44
- render_icon("copy_page"),
45
- alchemy.insert_admin_clipboard_path(
46
- :remarkable_type => page.class.name.demodulize.underscore,
47
- :remarkable_id => page.id
48
- ),
49
- :remote => true,
50
- :method => :post,
51
- :class => "",
52
- :title => t("copy_page")
53
- ) %>
54
- <%- end -%>
55
- <%- permitted_to?(:destroy, :alchemy_admin_pages) do -%>
56
- <%= link_to_confirmation_window(
57
- render_icon('delete_page'),
58
- t("confirm_to_delete_page"),
59
- url_for(
60
- :controller => 'pages',
61
- :action => 'destroy',
62
- :id => page.id
63
- ),
64
- {
65
- :class => "",
66
- :title => t("delete_page")
67
- }
68
- ) -%>
69
- <%- end -%>
70
- <%- permitted_to?(:new, :alchemy_admin_pages) do -%>
71
- <%= link_to_overlay_window(
72
- render_icon('add_page'),
73
- alchemy.new_admin_page_path(:parent_id => page.id),
74
- {
75
- :title => t('create_page'),
76
- :size => '340x150',
77
- :overflow => true
78
- },
79
- :class => '',
80
- :title => t('create_page')
81
- ) -%>
82
- <%- end -%>
83
- </span>
84
- <%- end -%>
85
- <%- end -%>
86
- </div>
87
- <div class="page_infos" id="page_<%= page.id %>_infos">
88
- <%= render :partial => 'page_infos', :locals => {:page => page} %>
89
- </div>
90
- <div class="sitemap_sitename">
91
- <%- if page.redirects_to_external? -%>
92
- <span class="sitemap_pagename_link <%= cycle('even', 'odd') %> inactive"><%= page.name %></span>
93
- <span class="redirect_url">
94
- &raquo; <%= t('Redirects to') %>:
95
- <%= h page.urlname %>
96
- </span>
97
- <%- else -%>
98
- <%- cycle_class = cycle('even', 'odd') -%>
99
- <%= link_to_unless(
100
- @sorting,
101
- page.name,
102
- alchemy.edit_admin_page_path(page),
103
- :title => t("edit_page"),
104
- :class => "sitemap_pagename_link #{cycle_class}"
105
- ) { content_tag('span', page.name, :class => "sitemap_pagename_link #{cycle_class}") } -%>
106
- <%- end -%>
107
- </div>
108
- </div>
109
- <%- if @sorting || (!page.folded?(current_user) && !page.children.empty?) -%>
110
- <ul id="page_<%= page.id %>_children">
111
- <%= render :partial => 'page', :collection => page.children %>
112
- </ul>
113
- <%- end -%>
2
+ <div class="sitemap_page<%= page.locked ? ' locked' : '' %>">
3
+ <div class="sitemap_left_images">
4
+ <%= sitemapFolderLink(page) unless page.children.blank? || @sorting %>
5
+ <span class="site_status <%= @sorting ? 'handle' : nil %> tooltip"></span>
6
+ <div class="tooltip_content" style="display: none;">
7
+ <h1><%= t("page_type") %>: <%= page.layout_display_name %></h1>
8
+ <p>
9
+ <%= page.humanized_status %>
10
+ </p>
11
+ <p>
12
+ <strong><%= t("created_at") %>:</strong>
13
+ <%= l(page.created_at) %> von <%= page.creator %>
14
+ </p>
15
+ <p>
16
+ <strong><%= t("updated_at") %>:</strong>
17
+ <%= l(page.updated_at) %> durch <%= page.updater %>
18
+ </p>
19
+ <%- if page.locked? -%>
20
+ <p>
21
+ <%= t("currently_edited_by") %>: <span style="font-weight: bold;"><%= page.current_editor %></span>
22
+ </p>
23
+ <%- end -%>
24
+ </div>
25
+ </div>
26
+ <div class="sitemap_right_tools">
27
+ <%- unless @sorting -%>
28
+ <%- permitted_to?(:configure, :alchemy_admin_pages) do -%>
29
+ <%= link_to_overlay_window(
30
+ render_icon('configure_page'),
31
+ alchemy.configure_admin_page_path(page),
32
+ {
33
+ :title => t('edit_page_properties'),
34
+ :size => page.redirects_to_external? ? '410x270' : '410x620'
35
+ },
36
+ :class => '',
37
+ :title => t('edit_page_properties')
38
+ ) -%>
39
+ <%- end -%>
40
+ <%- permitted_to?([:new, :destroy, :copy], :alchemy_admin_pages) do -%>
41
+ <span class="sitemap_sitetools">
42
+ <%- permitted_to?(:copy, :alchemy_admin_pages) do -%>
43
+ <%= link_to(
44
+ render_icon("copy_page"),
45
+ alchemy.insert_admin_clipboard_path(
46
+ :remarkable_type => page.class.name.demodulize.underscore,
47
+ :remarkable_id => page.id
48
+ ),
49
+ :remote => true,
50
+ :method => :post,
51
+ :class => "",
52
+ :title => t("copy_page")
53
+ ) %>
54
+ <%- end -%>
55
+ <%- permitted_to?(:destroy, :alchemy_admin_pages) do -%>
56
+ <%= link_to_confirmation_window(
57
+ render_icon('delete_page'),
58
+ t("confirm_to_delete_page"),
59
+ url_for(
60
+ :controller => 'pages',
61
+ :action => 'destroy',
62
+ :id => page.id
63
+ ),
64
+ {
65
+ :class => "",
66
+ :title => t("delete_page")
67
+ }
68
+ ) -%>
69
+ <%- end -%>
70
+ <%- permitted_to?(:new, :alchemy_admin_pages) do -%>
71
+ <%= link_to_overlay_window(
72
+ render_icon('add_page'),
73
+ alchemy.new_admin_page_path(:parent_id => page.id),
74
+ {
75
+ :title => t('create_page'),
76
+ :size => '340x150',
77
+ :overflow => true
78
+ },
79
+ :class => '',
80
+ :title => t('create_page')
81
+ ) -%>
82
+ <%- end -%>
83
+ </span>
84
+ <%- end -%>
85
+ <%- end -%>
86
+ </div>
87
+ <div class="page_infos" id="page_<%= page.id %>_infos">
88
+ <%= render :partial => 'page_infos', :locals => {:page => page} %>
89
+ </div>
90
+ <div class="sitemap_sitename">
91
+ <%- if page.redirects_to_external? -%>
92
+ <span class="sitemap_pagename_link <%= cycle('even', 'odd') %> inactive"><%= page.name %></span>
93
+ <span class="redirect_url">
94
+ &raquo; <%= t('Redirects to') %>:
95
+ <%= h page.urlname %>
96
+ </span>
97
+ <%- else -%>
98
+ <%- cycle_class = cycle('even', 'odd') -%>
99
+ <%= link_to_unless(
100
+ @sorting,
101
+ page.name,
102
+ alchemy.edit_admin_page_path(page),
103
+ :title => t("edit_page"),
104
+ :class => "sitemap_pagename_link #{cycle_class}"
105
+ ) { content_tag('span', page.name, :class => "sitemap_pagename_link #{cycle_class}") } -%>
106
+ <%- end -%>
107
+ </div>
108
+ </div>
109
+ <%- if @sorting || (!page.folded?(current_user) && !page.children.empty?) -%>
110
+ <ul id="page_<%= page.id %>_children">
111
+ <%= render :partial => 'page', :collection => page.children %>
112
+ </ul>
113
+ <%- end -%>
114
114
  </li>
@@ -1,99 +1,3 @@
1
1
  <ul id="sitemap" class="list">
2
- <div class="page_root">
3
- <div class="sitemap_page<%= @page_root.locked ? ' locked' : '' %>">
4
- <div class="sitemap_left_images">
5
- <span class="site_status tooltip"></span>
6
- <div class="tooltip_content" style="display: none;">
7
- <h1><%= t("page_type") %>: <%= @page_root.layout_display_name %></h1>
8
- <p>
9
- <%= @page_root.humanized_status %>
10
- </p>
11
- <p>
12
- <strong><%= t("created_at") %>:</strong>
13
- <%= l(@page_root.created_at) %> von <%= @page_root.creator %>
14
- </p>
15
- <p>
16
- <strong><%= t("updated_at") %>:</strong>
17
- <%= l(@page_root.updated_at) %> durch <%= @page_root.updater %>
18
- </p>
19
- <%- if @page_root.locked? -%>
20
- <p>
21
- <%= t("currently_edited_by") %>: <span style="font-weight: bold;"><%= @page_root.current_editor %></span>
22
- </p>
23
- <%- end -%>
24
- </div>
25
- </div>
26
- <div class="sitemap_right_tools">
27
- <%- unless @sorting -%>
28
- <%- permitted_to?(:configure, :alchemy_admin_pages) do -%>
29
- <%= link_to_overlay_window(
30
- render_icon('configure_page'),
31
- alchemy.configure_admin_page_path(@page_root),
32
- {
33
- :title => t('edit_page_properties'),
34
- :size => @page_root.redirects_to_external? ? '410x270' : '410x620'
35
- },
36
- :class => '',
37
- :title => t('edit_page_properties')
38
- ) -%>
39
- <%- end -%>
40
- <%- permitted_to?([:new, :destroy], :alchemy_admin_pages) do -%>
41
- <span class="sitemap_sitetools">
42
- <%= render_icon('blank') %>
43
- <%- permitted_to?(:destroy, :alchemy_admin_pages) do -%>
44
- <%= link_to_confirmation_window(
45
- render_icon('delete_page'),
46
- t("confirm_to_delete_page"),
47
- url_for(
48
- :controller => 'pages',
49
- :action => 'destroy',
50
- :id => @page_root.id
51
- ),
52
- {
53
- :class => "",
54
- :title => t("delete_page")
55
- }
56
- ) -%>
57
- <%- end -%>
58
- <%- permitted_to?(:new, :alchemy_admin_pages) do -%>
59
- <%= link_to_overlay_window(
60
- render_icon('add_page'),
61
- alchemy.new_admin_page_path(:parent_id => @page_root.id),
62
- {
63
- :title => t('create_page'),
64
- :size => '340x150',
65
- :overflow => true
66
- },
67
- :class => '',
68
- :title => t('create_page')
69
- ) -%>
70
- <%- end -%>
71
- </span>
72
- <%- end -%>
73
- <%- end -%>
74
- </div>
75
- <div class="page_infos" id="page_<%= @page_root.id %>_infos">
76
- <%= render :partial => 'page_infos', :locals => {:page => @page_root} %>
77
- </div>
78
- <div class="sitemap_sitename">
79
- <%- if @page_root.redirects_to_external? -%>
80
- <span class="sitemap_pagename_link <%= cycle('even', 'odd') %> inactive"><%= @page_root.name %></span>
81
- <span class="redirect_url">
82
- &raquo; <%= t('Redirects to') %>:
83
- <%= h @page_root.urlname %>
84
- </span>
85
- <%- else -%>
86
- <%- cycle_class = cycle('even', 'odd') -%>
87
- <%= link_to_unless(
88
- @sorting,
89
- @page_root.name,
90
- alchemy.edit_admin_page_path(@page_root),
91
- :title => t("edit_page"),
92
- :class => "sitemap_pagename_link #{cycle_class}"
93
- ) { content_tag('span', @page_root.name, :class => "sitemap_pagename_link #{cycle_class}") } -%>
94
- <%- end -%>
95
- </div>
96
- </div>
97
- </div>
98
- <%= render :partial => 'page', :collection => @page_root.children %>
2
+ <%= render :partial => 'page', :object => @page_root %>
99
3
  </ul>
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
2
 
3
- VERSION = "2.1.rc5"
3
+ VERSION = "2.1.rc6"
4
4
 
5
5
  end
@@ -1,15 +1,15 @@
1
1
  /*
2
- * jQuery UI Nested Sortable 1.2.1
3
- *
4
- * Copyright 2010, Manuele J Sarfatti
5
- *
2
+ * jQuery UI Nested Sortable
3
+ * v 1.3.4 / 28 apr 2011
6
4
  * http://mjsarfatti.com/sandbox/nestedSortable
7
5
  *
8
6
  * Depends:
9
- * jquery.ui.core.js 1.8+
10
- * jquery.ui.widget.js 1.8+
11
7
  * jquery.ui.sortable.js 1.8+
8
+ *
9
+ * License CC BY-SA 3.0
10
+ * Copyright 2010-2011, Manuele J Sarfatti
12
11
  */
12
+
13
13
  (function($) {
14
14
 
15
15
  $.widget("ui.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
@@ -18,14 +18,23 @@
18
18
  tabSize: 20,
19
19
  disableNesting: 'ui-nestedSortable-no-nesting',
20
20
  errorClass: 'ui-nestedSortable-error',
21
- listType: 'ol'
21
+ listType: 'ol',
22
+ maxLevels: 0,
23
+ revertOnError: 1
22
24
  },
23
25
 
24
- _create: function(){
25
- this.element.data('sortable', this.element.data('sortableTree'));
26
+ _create: function() {
27
+ this.element.data('sortable', this.element.data('nestedSortable'));
26
28
  return $.ui.sortable.prototype._create.apply(this, arguments);
27
29
  },
28
30
 
31
+ destroy: function() {
32
+ this.element
33
+ .removeData("nestedSortable")
34
+ .unbind(".nestedSortable");
35
+ return $.ui.sortable.prototype.destroy.apply(this, arguments);
36
+ },
37
+
29
38
  _mouseDrag: function(event) {
30
39
 
31
40
  //Compute the helpers position
@@ -85,14 +94,17 @@
85
94
 
86
95
  if(itemElement != this.currentItem[0] //cannot intersect with itself
87
96
  && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
88
- && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
89
- && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
97
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
98
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
90
99
  //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
91
100
  ) {
92
101
 
102
+ $(itemElement).mouseenter();
103
+
93
104
  this.direction = intersection == 1 ? "down" : "up";
94
105
 
95
106
  if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
107
+ $(itemElement).mouseleave();
96
108
  this._rearrange(event, item);
97
109
  } else {
98
110
  break;
@@ -106,44 +118,46 @@
106
118
  }
107
119
  }
108
120
 
109
- // Get the real previous item
110
- itemBefore = this.placeholder[0].previousSibling;
111
- while (itemBefore != null) {
112
- if (itemBefore.nodeType == 1 && itemBefore != this.currentItem[0]) {
113
- break;
114
- } else {
115
- itemBefore = itemBefore.previousSibling;
121
+ var parentItem = (this.placeholder[0].parentNode.parentNode
122
+ && $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
123
+ ? $(this.placeholder[0].parentNode.parentNode)
124
+ : null,
125
+ level = this._getLevel(this.placeholder),
126
+ childLevels = this._getChildLevels(this.helper),
127
+ previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
128
+
129
+ if (previousItem != null) {
130
+ while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0]) {
131
+ if (previousItem[0].previousSibling) {
132
+ previousItem = $(previousItem[0].previousSibling);
133
+ } else {
134
+ previousItem = null;
135
+ break;
136
+ }
116
137
  }
117
138
  }
118
139
 
119
- parentItem = this.placeholder[0].parentNode.parentNode;
120
140
  newList = document.createElement(o.listType);
121
141
 
122
- // Make/delete nested ul's/ol's
123
- if (parentItem != null && parentItem.nodeName == 'LI' && this.positionAbs.left < $(parentItem).offset().left) {
124
- $(parentItem).after(this.placeholder[0]);
125
- this._clearEmpty(parentItem);
126
- } else if (itemBefore != null && itemBefore.nodeName == 'LI' && this.positionAbs.left > $(itemBefore).offset().left + this.options.tabSize) {
127
- if (!($(itemBefore).hasClass(this.options.disableNesting))) {
128
- if ($(this.placeholder[0]).hasClass(this.options.errorClass)) {
129
- $(this.placeholder[0]).css('marginLeft', 0).removeClass(this.options.errorClass);
130
- }
131
- if (itemBefore.children[1] == null) {
132
- itemBefore.appendChild(newList);
133
- }
134
- itemBefore.children[1].appendChild(this.placeholder[0]);
135
- } else {
136
- $(this.placeholder[0]).addClass(this.options.errorClass).css('marginLeft', this.options.tabSize);
137
- }
138
- } else if (itemBefore != null) {
139
- if ($(this.placeholder[0]).hasClass(this.options.errorClass)) {
140
- $(this.placeholder[0]).css('marginLeft', 0).removeClass(this.options.errorClass);
141
- }
142
- $(itemBefore).after(this.placeholder[0]);
143
- } else {
144
- if ($(this.placeholder[0]).hasClass(this.options.errorClass)) {
145
- $(this.placeholder[0]).css('marginLeft', 0).removeClass(this.options.errorClass);
142
+ this.beyondMaxLevels = 0;
143
+
144
+ // If the item is moved to the left, send it to its parent level
145
+ if (parentItem != null && this.positionAbs.left < parentItem.offset().left) {
146
+ parentItem.after(this.placeholder[0]);
147
+ this._clearEmpty(parentItem[0]);
148
+ this._trigger("change", event, this._uiHash());
149
+ }
150
+ // If the item is below another one and is moved to the right, make it a children of it
151
+ else if (previousItem != null && this.positionAbs.left > previousItem.offset().left + o.tabSize) {
152
+ this._isAllowed(previousItem, level+childLevels+1);
153
+ if (!previousItem.children(o.listType).length) {
154
+ previousItem[0].appendChild(newList);
146
155
  }
156
+ previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
157
+ this._trigger("change", event, this._uiHash());
158
+ }
159
+ else {
160
+ this._isAllowed(parentItem, level+childLevels);
147
161
  }
148
162
 
149
163
  //Post events to containers
@@ -160,15 +174,61 @@
160
174
 
161
175
  },
162
176
 
177
+ _mouseStop: function(event, noPropagation) {
178
+
179
+ // If the item is in a position not allowed, send it back
180
+ if (this.beyondMaxLevels) {
181
+
182
+ this.placeholder.removeClass(this.options.errorClass);
183
+
184
+ if (this.options.revertOnError) {
185
+ if (this.domPosition.prev) {
186
+ $(this.domPosition.prev).after(this.placeholder);
187
+ } else {
188
+ $(this.domPosition.parent).prepend(this.placeholder);
189
+ }
190
+ this._trigger("revert", event, this._uiHash());
191
+ } else {
192
+ var parent = this.placeholder.parent().closest(this.options.items);
193
+
194
+ for (var i = this.beyondMaxLevels - 1; i > 0; i--) {
195
+ parent = parent.parent().closest(this.options.items);
196
+ }
197
+
198
+ parent.after(this.placeholder);
199
+ this._trigger("change", event, this._uiHash());
200
+ }
201
+
202
+ }
203
+
204
+ // Clean last empty ul/ol
205
+ for (var i = this.items.length - 1; i >= 0; i--) {
206
+ var item = this.items[i].item[0];
207
+ this._clearEmpty(item);
208
+ }
209
+
210
+ $.ui.sortable.prototype._mouseStop.apply(this, arguments);
211
+
212
+ },
213
+
163
214
  serialize: function(o) {
164
215
 
165
- var items = this._getItemsAsjQuery(o && o.connected);
166
- var str = []; o = o || {};
216
+ var items = this._getItemsAsjQuery(o && o.connected),
217
+ str = []; o = o || {};
167
218
 
168
219
  $(items).each(function() {
169
- var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
170
- var pid = ($(o.item || this).parent(o.listType).parent('li').attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
171
- if(res) str.push((o.key || res[1]+'['+(o.key && o.expression ? res[1] : res[2])+']')+'='+(pid ? (o.key && o.expression ? pid[1] : pid[2]) : 'root'));
220
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '')
221
+ .match(o.expression || (/(.+)[-=_](.+)/)),
222
+ pid = ($(o.item || this).parent(o.listType)
223
+ .parent('li')
224
+ .attr(o.attribute || 'id') || '')
225
+ .match(o.expression || (/(.+)[-=_](.+)/));
226
+
227
+ if (res) {
228
+ str.push((o.key || res[1] + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
229
+ + '='
230
+ + (pid ? (o.key && o.expression ? pid[1] : pid[2]) : 'root'));
231
+ }
172
232
  });
173
233
 
174
234
  if(!str.length && o.key) {
@@ -179,113 +239,153 @@
179
239
 
180
240
  },
181
241
 
182
- toArray: function(o) {
242
+ toHierarchy: function(o) {
183
243
 
184
244
  o = o || {};
185
- var sDepth = o.startDepthCount || 0;
186
- var ret = [];
187
- var left = 2;
245
+ var sDepth = o.startDepthCount || 0,
246
+ ret = [];
247
+
248
+ $(this.element).children('li').each(function () {
249
+ var level = _recursiveItems($(this));
250
+ ret.push(level);
251
+ });
252
+
253
+ return ret;
254
+
255
+ function _recursiveItems(li) {
256
+ var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
257
+ if (id) {
258
+ var item = {"id" : id[2]};
259
+ if ($(li).children(o.listType).children('li').length > 0) {
260
+ item.children = [];
261
+ $(li).children(o.listType).children('li').each(function() {
262
+ var level = _recursiveItems($(this));
263
+ item.children.push(level);
264
+ });
265
+ }
266
+ return item;
267
+ }
268
+ }
269
+ },
188
270
 
189
- ret.push({"item_id": 'root', "parent_id": 'none', "depth": sDepth, "left": '1', "right": ($('li', this.element).length + 1) * 2});
271
+ toArray: function(o) {
272
+
273
+ o = o || {};
274
+ var sDepth = o.startDepthCount || 0,
275
+ ret = [],
276
+ left = 2;
277
+
278
+ ret.push({
279
+ "item_id": 'root',
280
+ "parent_id": 'none',
281
+ "depth": sDepth,
282
+ "left": '1',
283
+ "right": ($('li', this.element).length + 1) * 2
284
+ });
190
285
 
191
- $(this.element).children('li').each(function() {
192
- left = _recursiveArray($(this), sDepth + 1, left);
286
+ $(this.element).children('li').each(function () {
287
+ left = _recursiveArray(this, sDepth + 1, left);
193
288
  });
194
289
 
290
+ ret = ret.sort(function(a,b){ return (a.left - b.left); });
291
+
195
292
  return ret;
196
293
 
197
294
  function _recursiveArray(item, depth, left) {
198
295
 
199
- right = left + 1;
296
+ var right = left + 1,
297
+ id,
298
+ pid;
200
299
 
201
300
  if ($(item).children(o.listType).children('li').length > 0) {
202
301
  depth ++;
203
- $(item).children(o.listType).children('li').each(function() {
302
+ $(item).children(o.listType).children('li').each(function () {
204
303
  right = _recursiveArray($(this), depth, right);
205
304
  });
206
305
  depth --;
207
306
  }
208
307
 
209
- id = $(item).attr('id').match(o.expression || (/(.+)[-=_](.+)/));
308
+ id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
210
309
 
211
- if (depth === sDepth + 1) pid = 'root';
212
- else {
213
- parentItem = $(item).parent(o.listType).parent('li').attr('id').match(o.expression || (/(.+)[-=_](.+)/));
310
+ if (depth === sDepth + 1) {
311
+ pid = 'root';
312
+ } else {
313
+ var parentItem = ($(item).parent(o.listType)
314
+ .parent('li')
315
+ .attr(o.attribute || 'id'))
316
+ .match(o.expression || (/(.+)[-=_](.+)/));
214
317
  pid = parentItem[2];
215
318
  }
216
319
 
217
- ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
320
+ if (id) {
321
+ ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
322
+ }
218
323
 
219
- return left = right + 1;
324
+ left = right + 1;
325
+ return left;
220
326
  }
221
327
 
222
328
  },
223
329
 
224
- _createPlaceholder: function(that) {
225
-
226
- var self = that || this, o = self.options;
227
-
228
- if(!o.placeholder || o.placeholder.constructor == String) {
229
- var className = o.placeholder;
230
- o.placeholder = {
231
- element: function() {
330
+ _clearEmpty: function(item) {
232
331
 
233
- var el = $(document.createElement(self.currentItem[0].nodeName))
234
- .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
235
- .removeClass("ui-sortable-helper")[0];
332
+ var emptyList = $(item).children(this.options.listType);
333
+ if (emptyList.length && !emptyList.children().length) {
334
+ emptyList.remove();
335
+ }
236
336
 
237
- if(!className)
238
- el.style.visibility = "hidden";
337
+ },
239
338
 
240
- return el;
241
- },
242
- update: function(container, p) {
339
+ _getLevel: function(item) {
243
340
 
244
- // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
245
- // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
246
- if(className && !o.forcePlaceholderSize) return;
341
+ var level = 1;
247
342
 
248
- //If the element doesn't have an actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
249
- if(!p.height() || p.css('height') == 'auto') { p.height(self.currentItem.height()); };
250
- if(!p.width()) { p.width(self.currentItem.width()); };
251
- }
252
- };
343
+ if (this.options.listType) {
344
+ var list = item.closest(this.options.listType);
345
+ while (!list.is('.ui-sortable')) {
346
+ level++;
347
+ list = list.parent().closest(this.options.listType);
348
+ }
253
349
  }
254
350
 
255
- //Create the placeholder
256
- self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
257
-
258
- //Append it after the actual current item
259
- self.currentItem.after(self.placeholder);
260
-
261
- //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
262
- o.placeholder.update(self, self.placeholder);
263
-
351
+ return level;
264
352
  },
265
353
 
266
- _clear: function(event, noPropagation) {
354
+ _getChildLevels: function(parent, depth) {
355
+ var self = this,
356
+ o = this.options,
357
+ result = 0;
358
+ depth = depth || 0;
267
359
 
268
- $.ui.sortable.prototype._clear.apply(this, arguments);
269
-
270
- // Clean last empty ul/ol
271
- for (var i = this.items.length - 1; i >= 0; i--) {
272
- var item = this.items[i].item[0];
273
- this._clearEmpty(item);
274
- }
275
- return true;
360
+ $(parent).children(o.listType).children(o.items).each(function (index, child) {
361
+ result = Math.max(self._getChildLevels(child, depth + 1), result);
362
+ });
276
363
 
364
+ return depth ? result + 1 : result;
277
365
  },
278
366
 
279
- _clearEmpty: function(item) {
280
-
281
- if (item.children[1] && item.children[1].children.length == 0) {
282
- item.removeChild(item.children[1]);
367
+ _isAllowed: function(parentItem, levels) {
368
+ var o = this.options;
369
+ // Are we trying to nest under a no-nest or are we nesting too deep?
370
+ if (parentItem == null || !(parentItem.hasClass(o.disableNesting))) {
371
+ if (o.maxLevels < levels && o.maxLevels != 0) {
372
+ this.placeholder.addClass(o.errorClass);
373
+ this.beyondMaxLevels = levels - o.maxLevels;
374
+ } else {
375
+ this.placeholder.removeClass(o.errorClass);
376
+ this.beyondMaxLevels = 0;
377
+ }
378
+ } else {
379
+ this.placeholder.addClass(o.errorClass);
380
+ if (o.maxLevels < levels && o.maxLevels != 0) {
381
+ this.beyondMaxLevels = levels - o.maxLevels;
382
+ } else {
383
+ this.beyondMaxLevels = 1;
384
+ }
283
385
  }
284
-
285
386
  }
286
387
 
287
388
  }));
288
389
 
289
390
  $.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
290
-
291
391
  })(jQuery);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.rc5
4
+ version: 2.1.rc6
5
5
  prerelease: 4
6
6
  platform: ruby
7
7
  authors:
@@ -15,7 +15,7 @@ date: 2012-01-20 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
18
- requirement: &70208029023740 !ruby/object:Gem::Requirement
18
+ requirement: &70135245578000 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '3.1'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70208029023740
26
+ version_requirements: *70135245578000
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: authlogic
29
- requirement: &70208029023320 !ruby/object:Gem::Requirement
29
+ requirement: &70135245577560 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70208029023320
37
+ version_requirements: *70135245577560
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: awesome_nested_set
40
- requirement: &70208029022760 !ruby/object:Gem::Requirement
40
+ requirement: &70135245576980 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ~>
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '2.0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70208029022760
48
+ version_requirements: *70135245576980
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: declarative_authorization
51
- requirement: &70208029022240 !ruby/object:Gem::Requirement
51
+ requirement: &70135245576460 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ~>
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: 0.5.4
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70208029022240
59
+ version_requirements: *70135245576460
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: tvdeyen-fleximage
62
- requirement: &70208029021740 !ruby/object:Gem::Requirement
62
+ requirement: &70135245575980 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ~>
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: 1.0.9
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70208029021740
70
+ version_requirements: *70135245575980
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: will_paginate
73
- requirement: &70208029021260 !ruby/object:Gem::Requirement
73
+ requirement: &70135245575500 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ~>
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '3.0'
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *70208029021260
81
+ version_requirements: *70135245575500
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: acts_as_ferret
84
- requirement: &70208029020780 !ruby/object:Gem::Requirement
84
+ requirement: &70135245575020 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ~>
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: '0.5'
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70208029020780
92
+ version_requirements: *70135245575020
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: acts_as_list
95
- requirement: &70208029020300 !ruby/object:Gem::Requirement
95
+ requirement: &70135245574540 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ~>
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: '0.1'
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *70208029020300
103
+ version_requirements: *70135245574540
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: magiclabs-userstamp
106
- requirement: &70208029019820 !ruby/object:Gem::Requirement
106
+ requirement: &70135245574060 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ~>
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: 2.0.2
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *70208029019820
114
+ version_requirements: *70135245574060
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: dynamic_form
117
- requirement: &70208029035700 !ruby/object:Gem::Requirement
117
+ requirement: &70135245573580 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ~>
@@ -122,10 +122,10 @@ dependencies:
122
122
  version: '1.1'
123
123
  type: :runtime
124
124
  prerelease: false
125
- version_requirements: *70208029035700
125
+ version_requirements: *70135245573580
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: jquery-rails
128
- requirement: &70208029035220 !ruby/object:Gem::Requirement
128
+ requirement: &70135245573100 !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ~>
@@ -133,10 +133,10 @@ dependencies:
133
133
  version: 1.0.16
134
134
  type: :runtime
135
135
  prerelease: false
136
- version_requirements: *70208029035220
136
+ version_requirements: *70135245573100
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: attachment_magic
139
- requirement: &70208029034740 !ruby/object:Gem::Requirement
139
+ requirement: &70135245572620 !ruby/object:Gem::Requirement
140
140
  none: false
141
141
  requirements:
142
142
  - - ~>
@@ -144,10 +144,10 @@ dependencies:
144
144
  version: 0.2.1
145
145
  type: :runtime
146
146
  prerelease: false
147
- version_requirements: *70208029034740
147
+ version_requirements: *70135245572620
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: rspec-rails
150
- requirement: &70208029034200 !ruby/object:Gem::Requirement
150
+ requirement: &70135245572120 !ruby/object:Gem::Requirement
151
151
  none: false
152
152
  requirements:
153
153
  - - ~>
@@ -155,10 +155,10 @@ dependencies:
155
155
  version: '2.8'
156
156
  type: :development
157
157
  prerelease: false
158
- version_requirements: *70208029034200
158
+ version_requirements: *70135245572120
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: sqlite3
161
- requirement: &70208029033660 !ruby/object:Gem::Requirement
161
+ requirement: &70135245571740 !ruby/object:Gem::Requirement
162
162
  none: false
163
163
  requirements:
164
164
  - - ! '>='
@@ -166,7 +166,7 @@ dependencies:
166
166
  version: '0'
167
167
  type: :development
168
168
  prerelease: false
169
- version_requirements: *70208029033660
169
+ version_requirements: *70135245571740
170
170
  description: Alchemy is an awesome Rails CMS with an extremely flexible content storing
171
171
  architecture.
172
172
  email:
@@ -793,7 +793,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
793
793
  version: '0'
794
794
  segments:
795
795
  - 0
796
- hash: -607147014317575995
796
+ hash: -4092920375307944882
797
797
  required_rubygems_version: !ruby/object:Gem::Requirement
798
798
  none: false
799
799
  requirements: