alchemy_cms 3.0.0.rc7 → 3.0.0.rc8
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +1 -1
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -2
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +26 -2
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +22 -0
- data/app/assets/stylesheets/alchemy/base.scss +1 -5
- data/app/assets/stylesheets/alchemy/elements.scss +11 -61
- data/app/assets/stylesheets/alchemy/frame.scss +1 -1
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +1 -1
- data/app/controllers/alchemy/admin/attachments_controller.rb +1 -1
- data/app/controllers/alchemy/admin/base_controller.rb +7 -13
- data/app/controllers/alchemy/admin/clipboard_controller.rb +15 -10
- data/app/controllers/alchemy/admin/elements_controller.rb +15 -11
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +8 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +95 -22
- data/app/controllers/alchemy/admin/tags_controller.rb +1 -1
- data/app/controllers/alchemy/pictures_controller.rb +33 -32
- data/app/helpers/alchemy/admin/base_helper.rb +3 -16
- data/app/models/alchemy/element.rb +1 -1
- data/app/models/alchemy/page/page_naming.rb +4 -2
- data/app/models/alchemy/page/page_natures.rb +1 -1
- data/app/models/alchemy/page.rb +20 -1
- data/app/models/alchemy/picture.rb +1 -0
- data/app/models/alchemy/tree_node.rb +4 -0
- data/app/views/alchemy/admin/contents/destroy.js.erb +4 -0
- data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +11 -12
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +0 -3
- data/app/views/alchemy/admin/elements/create.js.erb +3 -3
- data/app/views/alchemy/admin/elements/index.html.erb +4 -19
- data/app/views/alchemy/admin/elements/new.html.erb +0 -3
- data/app/views/alchemy/admin/elements/trash.js.erb +12 -16
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +36 -30
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +1 -1
- data/app/views/alchemy/admin/trash/clear.js.erb +4 -0
- data/config/locales/alchemy.de.yml +56 -84
- data/config/locales/alchemy.en.yml +326 -105
- data/config/locales/alchemy.fr.yml +942 -0
- data/config/locales/alchemy.nl.yml +111 -137
- data/config/locales/simple_form.fr.yml +26 -0
- data/lib/alchemy/engine.rb +7 -1
- data/lib/alchemy/i18n.rb +7 -1
- data/lib/alchemy/middleware/rescue_old_cookies.rb +27 -0
- data/lib/alchemy/permissions.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/spec/controllers/admin/clipboard_controller_spec.rb +16 -19
- data/spec/controllers/admin/elements_controller_spec.rb +20 -23
- data/spec/controllers/admin/essence_pictures_controller_spec.rb +22 -6
- data/spec/controllers/admin/pages_controller_spec.rb +94 -5
- data/spec/controllers/pictures_controller_spec.rb +44 -3
- data/spec/features/admin/link_overlay_spec.rb +1 -0
- data/spec/features/admin/locale_select_feature_spec.rb +22 -0
- data/spec/libraries/i18n_spec.rb +30 -0
- data/spec/libraries/permissions_spec.rb +1 -1
- data/spec/models/element_spec.rb +5 -4
- data/spec/models/page_spec.rb +137 -8
- data/spec/spec_helper.rb +23 -19
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +9 -3
- metadata +12 -10
- data/app/models/alchemy/clipboard.rb +0 -74
- data/app/views/alchemy/admin/contents/destroy.js.coffee +0 -4
- data/app/views/alchemy/admin/elements/_add_element_button.html.erb +0 -18
- data/app/views/alchemy/admin/trash/clear.js.coffee +0 -4
- data/spec/models/clipboard_spec.rb +0 -111
- data/spec/support/phantomjs_mavericks_fix.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcb7647a1797d45f8881a956cde924671bc30f2d
|
4
|
+
data.tar.gz: 7b9dee0e4b299543fe51364f7c3be41b70e6e2e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d184d7e8aac2c27eea62560fa1ff1140500ee0b59a07a6009fbcf4ec33ca2926c5a789953e7bb70bd9ed8bc0da662394bde3d8692ba9e6afacac8107fcd08a8
|
7
|
+
data.tar.gz: ec05398a5321e6a0e709329aec857b6bc4b3031eb8f160a59ea39d66b0e95ac1b52c7fa0043aa4751dbc0ce4dd52bed366444ceaf18570ce5b5052e3376ea90d
|
data/Gemfile
CHANGED
@@ -12,12 +12,13 @@ gem 'coveralls', require: false
|
|
12
12
|
# Fixes issues with wrong exit codes. See: https://github.com/colszowka/simplecov/issues/269
|
13
13
|
gem 'simplecov', '0.7.1'
|
14
14
|
|
15
|
+
gem 'database_cleaner'
|
16
|
+
|
15
17
|
group :test do
|
16
18
|
gem 'sqlite3' if ENV['DB'].nil? || ENV['DB'] == 'sqlite'
|
17
19
|
gem 'mysql2' if ENV['DB'] == 'mysql'
|
18
20
|
gem 'pg' if ENV['DB'] == 'postgresql'
|
19
21
|
gem 'poltergeist'
|
20
|
-
gem 'connection_pool' # https://gist.github.com/mperham/3049152
|
21
22
|
unless ENV['CI']
|
22
23
|
gem 'launchy'
|
23
24
|
end
|
data/README.md
CHANGED
@@ -47,11 +47,9 @@ $.extend Alchemy,
|
|
47
47
|
Alchemy.TrashWindow.refresh page_id
|
48
48
|
|
49
49
|
start: (event, ui) ->
|
50
|
-
ui.helper.find('.insert-element-button').hide()
|
51
50
|
Alchemy.Tinymce.remove getTinymceIDs(ui)
|
52
51
|
|
53
52
|
stop: (event, ui) ->
|
54
|
-
ui.item.find('.insert-element-button').show()
|
55
53
|
Alchemy.Tinymce.init getTinymceIDs(ui)
|
56
54
|
|
57
55
|
SortableContents: (selector, token) ->
|
@@ -39,7 +39,7 @@ Alchemy.ElementEditors =
|
|
39
39
|
#
|
40
40
|
onClickElement: (e) ->
|
41
41
|
self = Alchemy.ElementEditors
|
42
|
-
$element = $(this).
|
42
|
+
$element = $(this).parent(".element_editor")
|
43
43
|
id = $element.attr("id").replace(/\D/g, "")
|
44
44
|
e.preventDefault()
|
45
45
|
$("#element_area .element_editor").removeClass "selected"
|
@@ -1,5 +1,22 @@
|
|
1
1
|
window.Alchemy = {} if typeof(window.Alchemy) is 'undefined'
|
2
2
|
|
3
|
+
# Adds buttons into a toolbar inside of overlay windows
|
4
|
+
Alchemy.ToolbarButton = (options) ->
|
5
|
+
$btn = $('<div class="button_with_label" />')
|
6
|
+
if options.buttonId
|
7
|
+
$btn.attr(id: options.buttonId)
|
8
|
+
$lnk = $("<a title='#{options.title}' class='icon_button' href='#' />")
|
9
|
+
if options.hotkey
|
10
|
+
$lnk.attr('data-alchemy-hotkey', options.hotkey)
|
11
|
+
$lnk.click (e) ->
|
12
|
+
e.preventDefault()
|
13
|
+
options.onClick(e)
|
14
|
+
false
|
15
|
+
$lnk.append "<span class='icon #{options.iconClass}' />"
|
16
|
+
$btn.append $lnk
|
17
|
+
$btn.append "<br><label>#{options.label}</label>"
|
18
|
+
$btn
|
19
|
+
|
3
20
|
Alchemy.ElementsWindow =
|
4
21
|
|
5
22
|
init: (url, options, callback) ->
|
@@ -9,6 +26,7 @@ Alchemy.ElementsWindow =
|
|
9
26
|
@url = url
|
10
27
|
@options = options
|
11
28
|
@callback = callback
|
29
|
+
@element_window.append @createToolbar(options.toolbarButtons)
|
12
30
|
@element_window.append @element_area
|
13
31
|
@button = $('#element_window_button')
|
14
32
|
@button.click =>
|
@@ -21,12 +39,18 @@ Alchemy.ElementsWindow =
|
|
21
39
|
$('#main_content').append(@element_window)
|
22
40
|
@reload()
|
23
41
|
|
42
|
+
createToolbar: (buttons) ->
|
43
|
+
@toolbar = $('<div id="overlay_toolbar"/>')
|
44
|
+
for btn in buttons
|
45
|
+
@toolbar.append Alchemy.ToolbarButton(btn)
|
46
|
+
@toolbar
|
47
|
+
|
24
48
|
resize: ->
|
25
|
-
height = $(window).height() -
|
49
|
+
height = $(window).height() - 73
|
26
50
|
@element_window.css
|
27
51
|
height: height
|
28
52
|
@element_area.css
|
29
|
-
height: height
|
53
|
+
height: height - 46
|
30
54
|
height
|
31
55
|
|
32
56
|
reload: ->
|
@@ -66,3 +66,25 @@ Alchemy.translations =
|
|
66
66
|
'File type not allowed': 'File type not allowed'
|
67
67
|
'Maximum number of files exceeded': 'Uploadlimiet bereikt.'
|
68
68
|
'Uploaded bytes exceed file size': 'Uploaded bytes exceed file size'
|
69
|
+
|
70
|
+
|
71
|
+
# French
|
72
|
+
fr:
|
73
|
+
allowed_chars: 'von %{count} signes'
|
74
|
+
cancel: 'abandonner'
|
75
|
+
cancelled: 'annulé'
|
76
|
+
click_to_edit: 'Cliquez pour modifier'
|
77
|
+
complete: 'terminé'
|
78
|
+
element_dirty_notice: 'Cet élément a des modifications non enregistrées. Souhaitez-vous vraiment plier?'
|
79
|
+
help: 'Aide'
|
80
|
+
ok: 'Ok'
|
81
|
+
page_dirty_notice: 'Vous avez des modifications non enregistrées sur la page. Ce sera perdue si vous continuez.'
|
82
|
+
page_found: 'page trouvée'
|
83
|
+
pages_found: 'pages trouvées'
|
84
|
+
url_validation_failed: "L'URL n'est pas correctement formatée."
|
85
|
+
warning: 'Attention!'
|
86
|
+
'File is too large': 'Le fichier est trop grand.'
|
87
|
+
'File is too small': 'Le fichier est trop petit.'
|
88
|
+
'File type not allowed': 'Type de document non autorisé.'
|
89
|
+
'Maximum number of files exceeded': 'Le nombre maximum de fichiers est atteint.'
|
90
|
+
'Uploaded bytes exceed file size': 'Taille de fichier maximale autorisée atteint.'
|
@@ -542,10 +542,6 @@ select#url_protocol.medium {
|
|
542
542
|
overflow-x: hidden;
|
543
543
|
overflow-y: auto;
|
544
544
|
margin-bottom: 1em;
|
545
|
-
|
546
|
-
.insert-element-button {
|
547
|
-
display: none;
|
548
|
-
}
|
549
545
|
}
|
550
546
|
|
551
547
|
.mceEditor table {
|
@@ -560,7 +556,7 @@ div.browse {
|
|
560
556
|
@include box-sizing(border-box);
|
561
557
|
position: absolute;
|
562
558
|
left: 66px;
|
563
|
-
top:
|
559
|
+
top: 73px;
|
564
560
|
width: auto;
|
565
561
|
height: auto;
|
566
562
|
border: 0 none;
|
@@ -2,7 +2,7 @@
|
|
2
2
|
@include box-sizing(border-box);
|
3
3
|
position: absolute;
|
4
4
|
right: 0;
|
5
|
-
top:
|
5
|
+
top: 73px;
|
6
6
|
width: 400px;
|
7
7
|
height: auto;
|
8
8
|
border-left: $default-border;
|
@@ -25,50 +25,6 @@
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
|
28
|
-
.insert-element-button {
|
29
|
-
display: block;
|
30
|
-
text-align: center;
|
31
|
-
margin-bottom: 2 * $default-margin;
|
32
|
-
background-color: transparent;
|
33
|
-
border: 1px solid $medium-gray;
|
34
|
-
height: 20px;
|
35
|
-
line-height: 20px;
|
36
|
-
@extend %rounded-border;
|
37
|
-
@include transition(all 100ms ease-in-out);
|
38
|
-
|
39
|
-
&:hover, &.expanded {
|
40
|
-
height: 30px;
|
41
|
-
line-height: 30px;
|
42
|
-
background-color: darken($medium-gray, 2%);
|
43
|
-
text-decoration: none;
|
44
|
-
cursor: pointer;
|
45
|
-
border-color: darken($medium-gray, 2%);
|
46
|
-
|
47
|
-
label { display: inline-block; }
|
48
|
-
.icon { @include opacity(1) }
|
49
|
-
}
|
50
|
-
|
51
|
-
&.expanded:hover {
|
52
|
-
background-color: darken($medium-gray, 5%);
|
53
|
-
|
54
|
-
label { color: #000 }
|
55
|
-
}
|
56
|
-
|
57
|
-
label {
|
58
|
-
display: inline-block;
|
59
|
-
vertical-align: middle;
|
60
|
-
cursor: pointer;
|
61
|
-
display: none;
|
62
|
-
}
|
63
|
-
|
64
|
-
.icon {
|
65
|
-
display: inline-block;
|
66
|
-
vertical-align: text-top;
|
67
|
-
@include opacity(0.7);
|
68
|
-
@include transition(opacity 100ms ease-in-out);
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
28
|
.element_heading {
|
73
29
|
padding: 0;
|
74
30
|
z-index: 0;
|
@@ -165,7 +121,10 @@ span.preview_text_element_name {
|
|
165
121
|
}
|
166
122
|
|
167
123
|
.element_editor {
|
124
|
+
border: 1px solid $default-border-color;
|
125
|
+
@extend %rounded-border;
|
168
126
|
background-color: $light-gray;
|
127
|
+
margin-bottom: 2*$default-margin;
|
169
128
|
|
170
129
|
&.not-draggable {
|
171
130
|
@include opacity(0.5);
|
@@ -179,17 +138,14 @@ span.preview_text_element_name {
|
|
179
138
|
}
|
180
139
|
}
|
181
140
|
|
182
|
-
&.selected
|
141
|
+
&.selected {
|
183
142
|
border-color: $blue;
|
184
143
|
@include box-shadow(0 0 4px $blue);
|
185
144
|
}
|
186
145
|
|
187
146
|
form {
|
188
147
|
margin: 0;
|
189
|
-
padding: 0 8px;
|
190
|
-
margin-bottom: 2*$default-margin;
|
191
|
-
border: $default-border;
|
192
|
-
@include border-radius($default-border-radius);
|
148
|
+
padding: 8px 8px 0 8px;
|
193
149
|
}
|
194
150
|
|
195
151
|
.validation_notice {
|
@@ -246,22 +202,14 @@ span.preview_text_element_name {
|
|
246
202
|
|
247
203
|
.element_head, .element_foot {
|
248
204
|
position: relative;
|
249
|
-
background-color: $medium-gray;
|
250
|
-
margin-left: -8px;
|
251
|
-
margin-right: -8px;
|
252
205
|
}
|
253
206
|
|
254
207
|
.element_head {
|
255
208
|
padding: 8px 0 6px;
|
256
|
-
margin-bottom:
|
209
|
+
margin-bottom: 0;
|
257
210
|
height: 20px;
|
211
|
+
background-color: $medium-gray;
|
258
212
|
@extend .disable-user-select;
|
259
|
-
@include border-top-radius($default-border-radius);
|
260
|
-
|
261
|
-
.folded & {
|
262
|
-
margin-bottom: 0;
|
263
|
-
@include border-bottom-radius($default-border-radius);
|
264
|
-
}
|
265
213
|
|
266
214
|
.spinner {
|
267
215
|
top: 9px;
|
@@ -273,7 +221,9 @@ span.preview_text_element_name {
|
|
273
221
|
padding: 2*$default-padding;
|
274
222
|
width: 100%;
|
275
223
|
height: 29px;
|
276
|
-
|
224
|
+
margin-left: -8px;
|
225
|
+
margin-right: -8px;
|
226
|
+
background-color: $medium-gray;
|
277
227
|
|
278
228
|
.element_tools {
|
279
229
|
float: left;
|
@@ -59,21 +59,15 @@ module Alchemy
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
@notice = "You have an old style clipboard in your session. Please remove your cookies and try again."
|
67
|
-
render :action => "error_notice", :layout => false
|
62
|
+
# Returns clipboard items for given category
|
63
|
+
def get_clipboard(category)
|
64
|
+
session[:alchemy_clipboard] ||= {}
|
65
|
+
session[:alchemy_clipboard][category.to_s] ||= []
|
68
66
|
end
|
69
67
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
session[:clipboard][category.pluralize].blank?
|
74
|
-
else
|
75
|
-
false
|
76
|
-
end
|
68
|
+
# Checks if clipboard for given category is blank
|
69
|
+
def clipboard_empty?(category)
|
70
|
+
get_clipboard(category).blank?
|
77
71
|
end
|
78
72
|
|
79
73
|
def trash_empty?(category)
|
@@ -1,21 +1,23 @@
|
|
1
1
|
module Alchemy
|
2
2
|
module Admin
|
3
3
|
class ClipboardController < Alchemy::Admin::BaseController
|
4
|
-
authorize_resource class:
|
4
|
+
authorize_resource class: :alchemy_admin_clipboard
|
5
|
+
before_filter :set_clipboard
|
5
6
|
|
6
7
|
def index
|
7
|
-
@
|
8
|
-
@clipboard_items = model_class.all_from_clipboard(@clipboard.all(params[:remarkable_type]))
|
8
|
+
@clipboard_items = model_class.all_from_clipboard(@clipboard)
|
9
9
|
respond_to do |format|
|
10
10
|
format.html
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
def insert
|
15
|
-
@clipboard = get_clipboard
|
16
15
|
@item = model_class.find(params[:remarkable_id])
|
17
|
-
unless @clipboard.
|
18
|
-
@clipboard
|
16
|
+
unless @clipboard.detect { |item| item['id'] == params[:remarkable_id] }
|
17
|
+
@clipboard << {
|
18
|
+
'id' => params[:remarkable_id],
|
19
|
+
'action' => params[:remove] ? 'cut' : 'copy'
|
20
|
+
}
|
19
21
|
end
|
20
22
|
respond_to do |format|
|
21
23
|
format.js
|
@@ -23,19 +25,22 @@ module Alchemy
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def remove
|
26
|
-
@clipboard = get_clipboard
|
27
28
|
@item = model_class.find(params[:remarkable_id])
|
28
|
-
@clipboard.
|
29
|
+
@clipboard.delete_if { |item| item['id'] == params[:remarkable_id] }
|
29
30
|
respond_to do |format|
|
30
31
|
format.js
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
35
|
def clear
|
35
|
-
|
36
|
+
@clipboard.clear
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
+
private
|
40
|
+
|
41
|
+
def set_clipboard
|
42
|
+
@clipboard = get_clipboard(params[:remarkable_type])
|
43
|
+
end
|
39
44
|
|
40
45
|
def model_class
|
41
46
|
"alchemy/#{params[:remarkable_type]}".classify.constantize
|
@@ -26,7 +26,8 @@ module Alchemy
|
|
26
26
|
@page = Page.find_by_id(params[:page_id])
|
27
27
|
@element = @page.elements.build
|
28
28
|
@elements = @page.available_element_definitions
|
29
|
-
@
|
29
|
+
@clipboard = get_clipboard('elements')
|
30
|
+
@clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Creates a element as discribed in config/alchemy/elements.yml on page via AJAX.
|
@@ -44,10 +45,8 @@ module Alchemy
|
|
44
45
|
end
|
45
46
|
@element.save
|
46
47
|
end
|
47
|
-
if
|
48
|
-
@
|
49
|
-
@element.insert_at(@element_before.position + 1)
|
50
|
-
else
|
48
|
+
if @page.definition['insert_elements_at'] == 'top'
|
49
|
+
@insert_at_top = true
|
51
50
|
@element.move_to_top
|
52
51
|
end
|
53
52
|
end
|
@@ -57,7 +56,8 @@ module Alchemy
|
|
57
56
|
else
|
58
57
|
@element.page = @page
|
59
58
|
@elements = @page.available_element_definitions
|
60
|
-
@
|
59
|
+
@clipboard = get_clipboard('elements')
|
60
|
+
@clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
|
61
61
|
render :new
|
62
62
|
end
|
63
63
|
end
|
@@ -128,24 +128,28 @@ module Alchemy
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def element_from_clipboard
|
131
|
-
@
|
132
|
-
|
131
|
+
@element_from_clipboard ||= begin
|
132
|
+
@clipboard = get_clipboard('elements')
|
133
|
+
@clipboard.detect { |item| item['id'].to_i == params[:paste_from_clipboard].to_i }
|
134
|
+
end
|
133
135
|
end
|
134
136
|
|
135
137
|
def paste_element_from_clipboard
|
136
|
-
@source_element = Element.find(element_from_clipboard[
|
138
|
+
@source_element = Element.find(element_from_clipboard['id'])
|
137
139
|
new_attributes = {:page_id => @page.id}
|
138
140
|
if @page.can_have_cells?
|
139
141
|
new_attributes = new_attributes.merge({:cell_id => find_or_create_cell.try(:id)})
|
140
142
|
end
|
141
143
|
element = Element.copy(@source_element, new_attributes)
|
142
|
-
|
144
|
+
if element_from_clipboard['action'] == 'cut'
|
145
|
+
cut_element
|
146
|
+
end
|
143
147
|
element
|
144
148
|
end
|
145
149
|
|
146
150
|
def cut_element
|
147
151
|
@cutted_element_id = @source_element.id
|
148
|
-
@clipboard.
|
152
|
+
@clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
|
149
153
|
@source_element.destroy
|
150
154
|
end
|
151
155
|
|