alchemy_cms 3.0.0.rc7 → 3.0.0.rc8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|