alchemy_cms 2.1.rc5 → 2.1.rc6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: