locomotivecms 3.0.0.rc2 → 3.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/README.md +2 -1
- data/app/api/locomotive/api/entities/site_entity.rb +8 -0
- data/app/api/locomotive/api/exception_rescuers.rb +1 -1
- data/app/api/locomotive/api/forms/content_entry_form.rb +4 -3
- data/app/api/locomotive/api/helpers/params_helper.rb +21 -3
- data/app/api/locomotive/api/resources/current_site_resource.rb +1 -1
- data/app/api/locomotive/api/resources/site_resource.rb +2 -2
- data/app/assets/images/locomotive/deadend.png +0 -0
- data/app/assets/javascripts/locomotive/not_logged_in.js.coffee +1 -1
- data/app/assets/javascripts/locomotive/utils/core_ext.js +1 -1
- data/app/assets/javascripts/locomotive/utils/wysihtml5.js.coffee +43 -17
- data/app/assets/javascripts/locomotive/views/application_view.js.coffee +5 -1
- data/app/assets/javascripts/locomotive/views/editable_elements/edit_view.js.coffee +47 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/iframe_view.js.coffee +59 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/index_view.js.coffee +19 -92
- data/app/assets/javascripts/locomotive/views/editable_elements/page_view.js.coffee +81 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/text_highlighter_view.js.coffee +76 -0
- data/app/assets/javascripts/locomotive/views/inputs/rte/edit_table_view.js.coffee +35 -0
- data/app/assets/javascripts/locomotive/views/inputs/rte/file_view.js.coffee +14 -10
- data/app/assets/javascripts/locomotive/views/inputs/rte/link_view.js.coffee +25 -15
- data/app/assets/javascripts/locomotive/views/inputs/rte/table_view.js.coffee +82 -0
- data/app/assets/javascripts/locomotive/views/inputs/rte_view.js.coffee.erb +64 -23
- data/app/assets/javascripts/locomotive/views/inputs/text_view.js.coffee +11 -6
- data/app/assets/javascripts/locomotive.js +2 -2
- data/app/assets/stylesheets/locomotive/application.scss +1 -3
- data/app/assets/stylesheets/locomotive/base/_form.scss +2 -1
- data/app/assets/stylesheets/locomotive/base/_typography.scss +3 -2
- data/app/assets/stylesheets/locomotive/base/form/_base.scss +5 -0
- data/app/assets/stylesheets/locomotive/base/form/_rte.scss +42 -0
- data/app/assets/stylesheets/locomotive/error.scss +1 -1
- data/app/assets/stylesheets/locomotive/globals/_mixins.scss +41 -48
- data/app/assets/stylesheets/locomotive/globals/_variables.scss +202 -121
- data/app/assets/stylesheets/locomotive/layouts/_not_logged_in.scss +8 -9
- data/app/assets/stylesheets/locomotive/live_editing_error.scss +19 -0
- data/app/assets/stylesheets/locomotive/live_editing_iframe.scss +84 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_forms.scss +63 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_keyframes.scss +31 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_notify.scss +85 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_public.scss +129 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_type.scss +14 -0
- data/app/assets/stylesheets/locomotive/unauthorized/_variables.scss +54 -0
- data/app/assets/stylesheets/locomotive/unauthorized.scss +34 -0
- data/app/helpers/locomotive/dashboard_helper.rb +1 -1
- data/app/inputs/locomotive/rte_input.rb +12 -0
- data/app/models/locomotive/concerns/page/editable_elements.rb +0 -2
- data/app/models/locomotive/editable_element.rb +1 -1
- data/app/services/locomotive/content_asset_service.rb +1 -1
- data/app/services/locomotive/page_parsing_service.rb +4 -2
- data/app/views/locomotive/editable_elements/index.html.slim +1 -1
- data/app/views/locomotive/layouts/not_logged_in.html.slim +13 -9
- data/app/views/locomotive/passwords/edit.html.slim +13 -13
- data/app/views/locomotive/passwords/new.html.slim +14 -11
- data/app/views/locomotive/registrations/new.html.slim +14 -13
- data/app/views/locomotive/sessions/new.html.slim +14 -13
- data/app/views/locomotive/shared/rte/_markdown_toolbar.html.slim +0 -30
- data/app/views/locomotive/shared/rte/_table_popover.html.slim +17 -0
- data/app/views/locomotive/shared/rte/_toolbar.html.slim +48 -11
- data/config/initializers/simple_form.rb +2 -0
- data/config/locales/carrierwave.lt.yml +4 -0
- data/config/locales/carrierwave.nl.yml +4 -0
- data/config/locales/carrierwave.ru.yml +4 -0
- data/config/locales/default.nl.yml +13 -0
- data/config/locales/devise.nl.yml +61 -0
- data/config/locales/en.yml +28 -10
- data/config/locales/flash.nl.yml +79 -0
- data/config/locales/inputs.lt.yml +18 -0
- data/config/locales/inputs.nl.yml +18 -0
- data/config/locales/mongoid.nl.yml +47 -0
- data/config/locales/nl.yml +316 -0
- data/config/locales/simple_form.en.yml +6 -0
- data/config/locales/simple_form.nl.yml +148 -0
- data/lib/locomotive/carrierwave/asset.rb +5 -1
- data/lib/locomotive/dependencies.rb +0 -1
- data/lib/locomotive/engine.rb +7 -1
- data/lib/locomotive/middlewares/site.rb +14 -2
- data/lib/locomotive/mongoid/patches.rb +29 -0
- data/lib/locomotive/steam/middlewares/catch_error.rb +78 -0
- data/lib/locomotive/steam/middlewares/wysihtml_css.rb +32 -0
- data/lib/locomotive/steam_adaptor.rb +4 -7
- data/lib/locomotive/version.rb +1 -1
- data/spec/requests/locomotive/steam/cache_spec.rb +3 -3
- data/spec/requests/locomotive/steam/wysihtml_css_spec.rb +42 -0
- data/spec/requests/site_spec.rb +13 -2
- data/spec/support/features/session_helpers.rb +3 -3
- data/vendor/assets/components/locomotive/backbone/backbone.js +1894 -0
- data/vendor/assets/components/locomotive/underscore/underscore.js +1548 -0
- data/vendor/assets/components/locomotive_sources/backbone/LICENSE +22 -0
- data/vendor/assets/components/locomotive_sources/backbone/backbone-min.js +2 -0
- data/vendor/assets/components/locomotive_sources/backbone/backbone-min.map +1 -0
- data/vendor/assets/components/locomotive_sources/backbone/backbone.js +1894 -0
- data/vendor/assets/components/locomotive_sources/backbone/bower.json +8 -0
- data/vendor/assets/components/locomotive_sources/underscore/LICENSE +23 -0
- data/vendor/assets/components/locomotive_sources/underscore/README.md +22 -0
- data/vendor/assets/components/locomotive_sources/underscore/bower.json +7 -0
- data/vendor/assets/components/locomotive_sources/underscore/underscore-min.js +6 -0
- data/vendor/assets/components/locomotive_sources/underscore/underscore-min.map +1 -0
- data/vendor/assets/components/locomotive_sources/underscore/underscore.js +1548 -0
- data/vendor/assets/javascripts/locomotive/wysihtml5/parser_rules/advanced.js +22 -48
- data/vendor/assets/javascripts/locomotive/wysihtml5/parser_rules/advanced_unwrap.js +13 -12
- data/vendor/assets/javascripts/locomotive/wysihtml5x-toolbar.js +7324 -3862
- data/vendor/assets/stylesheets/locomotive/wysihtml5_editor.css +27 -1
- metadata +53 -28
- data/app/assets/stylesheets/locomotive/globals/_all.scss +0 -3
- data/app/assets/stylesheets/locomotive/globals/_bootstrap.scss +0 -841
- data/app/assets/stylesheets/locomotive/globals/_colors.scss +0 -1
- data/app/assets/stylesheets/locomotive/globals/_nprogress.scss +0 -3
- data/app/assets/stylesheets/locomotive/not_logged_in.scss +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adb0a5ebc0f40fc62072340ff10f15d6029d14bb
|
4
|
+
data.tar.gz: c7d3971de7bd5e22fc8d32b94445e3c6ff96f2cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 470554e8983fb56b3d2e88bc02dd1276b21baa7153dc9afcd8c98b29e4b4ea9ecb3cbe1eef5bba2df822da81024ac1682ec29eec4c157dd4337709bcf9499ea3
|
7
|
+
data.tar.gz: e38ef2a4463cd47412a61cc2843242e843db154d8e78f0e58486939535e6318b70453c0763fb5bd6c1eaf0884bca322f65cb35730513fd2180cf4421a732fa27
|
data/Gemfile
CHANGED
@@ -21,8 +21,8 @@ group :development do
|
|
21
21
|
# gem 'custom_fields', path: '../gems/custom_fields' # for Developers
|
22
22
|
# gem 'custom_fields', github: 'locomotivecms/custom_fields', ref: '15cceb66ed'
|
23
23
|
|
24
|
-
# gem 'locomotivecms_steam', path: '../
|
25
|
-
# gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: '
|
24
|
+
# gem 'locomotivecms_steam', path: '../gems/steam', require: false
|
25
|
+
# gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: 'c9cb7f6', require: false
|
26
26
|
|
27
27
|
# gem 'locomotive_liquid', path: '../gems/liquid' # for Developers
|
28
28
|
# gem 'locomotivecms_solid', path: '../gems/solid' # for Developers
|
data/README.md
CHANGED
@@ -65,9 +65,10 @@ Here is our Transifex portal page: [https://www.transifex.com/locomotive/locomot
|
|
65
65
|
|
66
66
|
Locomotive is an open source project, we encourage contributions. If you have found a bug and want to contribute a fix, or have a new feature you would like to add, follow the steps below to get your patch into the project:
|
67
67
|
|
68
|
-
- Install ruby and
|
68
|
+
- Install ruby, mongoDB and phantomjs
|
69
69
|
- Clone the project <code>git clone git@github.com:locomotivecms/engine.git</code>
|
70
70
|
- Setup a virtual host entry for <code>test.example.com</code> to point to localhost
|
71
|
+
- Start mongodb if it is not already running
|
71
72
|
- Run the tests <code>bundle exec rake</code>
|
72
73
|
- Write your failing tests
|
73
74
|
- Make the tests pass
|
@@ -31,6 +31,14 @@ module Locomotive
|
|
31
31
|
Locomotive::Dragonfly.resize_url site.picture.url, '100x100#'
|
32
32
|
end
|
33
33
|
|
34
|
+
expose :preview_url do |site, opts|
|
35
|
+
Locomotive::Engine.routes.url_helpers.preview_url(site, host: opts[:env]['HTTP_HOST'])
|
36
|
+
end
|
37
|
+
|
38
|
+
expose :sign_in_url do |site, opts|
|
39
|
+
Locomotive::Engine.routes.url_helpers.new_locomotive_account_session_url(host: opts[:env]['HTTP_HOST'])
|
40
|
+
end
|
41
|
+
|
34
42
|
end
|
35
43
|
|
36
44
|
end
|
@@ -8,7 +8,7 @@ module Locomotive
|
|
8
8
|
included do
|
9
9
|
|
10
10
|
rescue_from :all do |e|
|
11
|
-
Rails.logger.error "[API]" + e.message + "\"
|
11
|
+
Rails.logger.error "[API] " + e.message + "\n\t" + e.backtrace.join("\n\t")
|
12
12
|
|
13
13
|
error_response(message: { error: e.message }, status: 500)
|
14
14
|
end
|
@@ -26,12 +26,13 @@ module Locomotive
|
|
26
26
|
|
27
27
|
def set_many_to_many(field, value)
|
28
28
|
if value.blank?
|
29
|
-
dynamic_attributes[:"#{field.name}_ids"] = [] # reset it
|
29
|
+
dynamic_attributes[:"#{field.name.singularize}_ids"] = [] # reset it
|
30
30
|
else
|
31
|
-
dynamic_attributes[:"#{field.name}_ids"] = fetch_entry_ids(field.class_name, value).sort do |a, b|
|
31
|
+
dynamic_attributes[:"#{field.name.singularize}_ids"] = fetch_entry_ids(field.class_name, value).sort do |a, b|
|
32
|
+
# keep the original order
|
32
33
|
(value.index(a.first.to_s) || value.index(a.last)) <=>
|
33
34
|
(value.index(b.first.to_s) || value.index(b.last))
|
34
|
-
end
|
35
|
+
end.map(&:first)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -10,16 +10,34 @@ module Locomotive
|
|
10
10
|
# Much safer than permitted_params because it also uses the current policy
|
11
11
|
# (Pundit) to filter the parameters.
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# Examples:
|
14
14
|
#
|
15
15
|
# permitted_params_from_policy(current_site, :site)
|
16
16
|
#
|
17
|
-
|
18
|
-
|
17
|
+
# If we want to deal with ActionDispatch::Http::UploadedFile instances
|
18
|
+
# instead of hashes (which would break the permitted attributes policy).
|
19
|
+
#
|
20
|
+
# permitted_params_from_policy(current_site, :site, [:picture])
|
21
|
+
#
|
22
|
+
def permitted_params_from_policy(object_or_class, key, file_inputs = nil)
|
23
|
+
_params = permitted_params[key]
|
24
|
+
|
25
|
+
build_uploaded_files_from_params!(_params, file_inputs) if file_inputs
|
26
|
+
|
19
27
|
_attributes = policy(object_or_class).permitted_attributes
|
20
28
|
::ActionController::Parameters.new(_params).permit(*_attributes)
|
21
29
|
end
|
22
30
|
|
31
|
+
def build_uploaded_files_from_params!(hash, list)
|
32
|
+
list.each do |name|
|
33
|
+
file_hash = hash[name]
|
34
|
+
|
35
|
+
next unless file_hash.try(:has_key?, :tempfile)
|
36
|
+
|
37
|
+
hash[name] = ActionDispatch::Http::UploadedFile.new(file_hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
23
41
|
end
|
24
42
|
|
25
43
|
end
|
@@ -46,7 +46,7 @@ module Locomotive
|
|
46
46
|
put do
|
47
47
|
authorize current_site, :update?
|
48
48
|
|
49
|
-
current_site_form = Forms::SiteForm.new(permitted_params_from_policy(current_site, :site))
|
49
|
+
current_site_form = Forms::SiteForm.new(permitted_params_from_policy(current_site, :site, [:picture]))
|
50
50
|
service.update(current_site, current_site_form.serializable_hash)
|
51
51
|
|
52
52
|
present current_site, with: entity_klass
|
@@ -71,7 +71,7 @@ module Locomotive
|
|
71
71
|
post do
|
72
72
|
authorize Site, :create?
|
73
73
|
|
74
|
-
site_form = Forms::SiteForm.new(permitted_params_from_policy(Locomotive::Site, :site))
|
74
|
+
site_form = Forms::SiteForm.new(permitted_params_from_policy(Locomotive::Site, :site, [:picture]))
|
75
75
|
site = service.create!(site_form.serializable_hash)
|
76
76
|
|
77
77
|
present site, with: entity_klass
|
@@ -98,7 +98,7 @@ module Locomotive
|
|
98
98
|
site = load_site
|
99
99
|
authorize site, :update?
|
100
100
|
|
101
|
-
site_form = Forms::SiteForm.new(permitted_params_from_policy(site, :site))
|
101
|
+
site_form = Forms::SiteForm.new(permitted_params_from_policy(site, :site, [:picture]))
|
102
102
|
site.assign_attributes(site_form.serializable_hash)
|
103
103
|
site.save!
|
104
104
|
|
Binary file
|
@@ -1,33 +1,23 @@
|
|
1
|
-
# New command: strike
|
2
|
-
wysihtml5.commands.strike =
|
3
|
-
exec: (composer, command, param) ->
|
4
|
-
wysihtml5.commands.formatInline.exec(composer, command, 'strike')
|
5
|
-
|
6
|
-
state: (composer, command) ->
|
7
|
-
wysihtml5.commands.formatInline.state(composer, command, 'strike')
|
8
|
-
|
9
|
-
# New command: justify full
|
10
|
-
# https://github.com/xing/wysihtml5/blob/56960b31adc37e07797382d8e8b10109f206b19c/src/commands/justifyFull.js
|
11
1
|
((wysihtml5) ->
|
12
|
-
CLASS_NAME = "wysiwyg-text-align-justify"
|
13
|
-
REG_EXP = /wysiwyg-text-align-[0-9a-z]+/g
|
14
2
|
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
# New command: strike
|
4
|
+
wysihtml5.commands.strike =
|
5
|
+
exec: (composer, command) ->
|
6
|
+
wysihtml5.commands.formatInline.exec(composer, command, 'STRIKE')
|
18
7
|
|
19
8
|
state: (composer, command) ->
|
20
|
-
wysihtml5.commands.
|
9
|
+
wysihtml5.commands.formatInline.state(composer, command, 'STRIKE', null, null)
|
21
10
|
|
22
11
|
)(wysihtml5)
|
23
12
|
|
13
|
+
|
24
14
|
# New command: insert file
|
25
15
|
((wysihtml5) ->
|
26
16
|
|
27
17
|
wysihtml5.commands.insertFile =
|
28
18
|
exec: (composer, command, param) ->
|
29
19
|
# do nothing
|
30
|
-
console.log "[insertFile] exec(#{command}, #{param})"
|
20
|
+
# console.log "[insertFile] exec(#{command}, #{param})"
|
31
21
|
|
32
22
|
state: (composer, command) ->
|
33
23
|
# console.log "[insertFile] state(#{command})"
|
@@ -36,4 +26,40 @@ wysihtml5.commands.strike =
|
|
36
26
|
|
37
27
|
)(wysihtml5)
|
38
28
|
|
29
|
+
# Replace command: insert table
|
30
|
+
((wysihtml5) ->
|
31
|
+
|
32
|
+
buildHeader = (cols) ->
|
33
|
+
html = '<thead><tr>'
|
34
|
+
html += '<th><br></th>' for col in [0...cols]
|
35
|
+
html + '</tr></thead>'
|
36
|
+
|
37
|
+
buildBody = (cols, rows) ->
|
38
|
+
html = '<tbody>'
|
39
|
+
for row in [0...rows]
|
40
|
+
html += '<tr>'
|
41
|
+
html += '<td><br></td>' for col in [0...cols]
|
42
|
+
html += '</tr>'
|
43
|
+
html += '</tbody>'
|
44
|
+
|
45
|
+
wysihtml5.commands.createTable =
|
46
|
+
exec: (composer, command, options) ->
|
47
|
+
options = _.extend { cols: 3, rows: 3, class_name: '', head: true }, options
|
48
|
+
|
49
|
+
cols = parseInt(options.cols, 10)
|
50
|
+
rows = parseInt(options.rows, 10)
|
51
|
+
|
52
|
+
html = "<table class='#{options.class_name}'>"
|
53
|
+
html += buildHeader(cols) if options.head
|
54
|
+
html += buildBody(cols, rows)
|
55
|
+
html += '</table>'
|
56
|
+
|
57
|
+
composer.commands.exec('insertHTML', html)
|
58
|
+
|
59
|
+
state: (composer, command) ->
|
60
|
+
false
|
61
|
+
|
62
|
+
)(wysihtml5)
|
63
|
+
|
64
|
+
|
39
65
|
|
@@ -35,10 +35,14 @@ class Locomotive.Views.ApplicationView extends Backbone.View
|
|
35
35
|
Locomotive.notify couple[1], couple[0]
|
36
36
|
|
37
37
|
automatic_max_height: ->
|
38
|
-
$(window).on 'resize', =>
|
38
|
+
$(window).on 'resize', =>
|
39
|
+
height = @set_max_height()
|
40
|
+
PubSub.publish 'application_view.resize', height: height
|
39
41
|
|
40
42
|
set_max_height: ->
|
41
43
|
max_height = $(window).height()
|
42
44
|
height = max_height - @header_view.height()
|
43
45
|
|
44
46
|
@$('> .wrapper').height(height)
|
47
|
+
|
48
|
+
height
|
@@ -4,6 +4,17 @@ class Locomotive.Views.EditableElements.EditView extends Locomotive.Views.Shared
|
|
4
4
|
|
5
5
|
el: '.content > .inner'
|
6
6
|
|
7
|
+
events:
|
8
|
+
'click .form-group.rte label': 'select_editable_text'
|
9
|
+
'click .form-group.text label': 'select_editable_text'
|
10
|
+
|
11
|
+
initialize: ->
|
12
|
+
_.bindAll(@, 'highlight_form_group')
|
13
|
+
|
14
|
+
@tokens = [
|
15
|
+
PubSub.subscribe 'editable_elements.highlighted_text', @highlight_form_group
|
16
|
+
]
|
17
|
+
|
7
18
|
render: ->
|
8
19
|
super
|
9
20
|
|
@@ -14,12 +25,44 @@ class Locomotive.Views.EditableElements.EditView extends Locomotive.Views.Shared
|
|
14
25
|
@refresh_inputs $(data)
|
15
26
|
|
16
27
|
$('.info-row select[name=block]').select2().on 'change', (event) =>
|
28
|
+
PubSub.publish 'editable_elements.block_selected', name: event.val
|
17
29
|
@filter_elements_by(event.val)
|
18
30
|
|
19
31
|
# editable control elements
|
20
32
|
$('.editable-elements .form-group.input.select select').select2().on 'change', (event) =>
|
21
33
|
@need_reload = true
|
22
34
|
|
35
|
+
select_editable_text: (event) ->
|
36
|
+
element_id = $(event.target).parents('.form-group').attr('id').replace('editable-text-', '')
|
37
|
+
PubSub.publish 'editable_elements.form_group_selected', element_id: element_id
|
38
|
+
|
39
|
+
highlight_form_group: (msg, data) ->
|
40
|
+
$form_group = $(@el).find("#editable-text-#{data.element_id}")
|
41
|
+
|
42
|
+
return false if $form_group.size() == 0
|
43
|
+
|
44
|
+
@filter_elements_by('')
|
45
|
+
|
46
|
+
highlight_effect = =>
|
47
|
+
$form_group.clearQueue().queue (next) ->
|
48
|
+
$(this).addClass('highlighted')
|
49
|
+
next()
|
50
|
+
.delay(200).queue (next) ->
|
51
|
+
$(this).removeClass('highlighted').find('input[type=text],textarea').trigger('highlight')
|
52
|
+
next()
|
53
|
+
|
54
|
+
# scroll to the form group and then highlight the textarea/input/editor
|
55
|
+
$parent = @$('.scrollable')
|
56
|
+
offset = $form_group.position().top
|
57
|
+
|
58
|
+
if offset == 0
|
59
|
+
$parent.animate { scrollTop: 0 }, 500, 'swing', highlight_effect
|
60
|
+
else if offset < 0 || offset > $parent.height()
|
61
|
+
offset = $parent.scrollTop() + offset if offset < 0
|
62
|
+
$parent.animate { scrollTop: offset }, 500, 'swing', highlight_effect
|
63
|
+
else
|
64
|
+
highlight_effect()
|
65
|
+
|
23
66
|
refresh_inputs: ($html) ->
|
24
67
|
@inputs = _.map @inputs, (view) =>
|
25
68
|
return view unless view.need_refresh?
|
@@ -39,3 +82,7 @@ class Locomotive.Views.EditableElements.EditView extends Locomotive.Views.Shared
|
|
39
82
|
$el.parent().show()
|
40
83
|
else
|
41
84
|
$el.parent().hide()
|
85
|
+
|
86
|
+
remove: ->
|
87
|
+
super
|
88
|
+
_.each @tokens, (token) -> PubSub.unsubscribe(token)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
Locomotive.Views.EditableElements ||= {}
|
2
|
+
|
3
|
+
class Locomotive.Views.EditableElements.IframeView extends Backbone.View
|
4
|
+
|
5
|
+
el: '.preview iframe'
|
6
|
+
|
7
|
+
startup: true
|
8
|
+
|
9
|
+
initialize: ->
|
10
|
+
# shortcut
|
11
|
+
@window = $(@el)[0].contentWindow
|
12
|
+
|
13
|
+
# when the url of the iframe changes, process
|
14
|
+
$(@el).load (event) => @on_load(event)
|
15
|
+
|
16
|
+
reload: ->
|
17
|
+
$(@el).attr('src', @preview_url)
|
18
|
+
|
19
|
+
on_load: (event) ->
|
20
|
+
# Able to get the path to the edit form?
|
21
|
+
if (path = @edit_view_path())?
|
22
|
+
@preview_url = @window.document.location.href
|
23
|
+
|
24
|
+
if !@startup
|
25
|
+
History.replaceState({ live_editing: true, url: @preview_url }, '', path)
|
26
|
+
@options.parent_view.replace_edit_view(path)
|
27
|
+
else
|
28
|
+
@startup = false
|
29
|
+
|
30
|
+
@build_and_render_page_view()
|
31
|
+
|
32
|
+
edit_view_path: ->
|
33
|
+
# the browser might be unable to load the iframe because of
|
34
|
+
# the 'X-Frame-Options' option which is set to 'SAMEORIGIN'.
|
35
|
+
try
|
36
|
+
$document = $(@window.document)
|
37
|
+
return $document.find('meta[name=locomotive-editable-elements-path]').attr('content')
|
38
|
+
catch e
|
39
|
+
# reload the iframe with the previous url and display an error message
|
40
|
+
@reload()
|
41
|
+
Locomotive.notify $(@el).data('redirection-error'), 'warning'
|
42
|
+
return null
|
43
|
+
|
44
|
+
build_and_render_page_view: ->
|
45
|
+
@page_view.remove() if @page_view?
|
46
|
+
@page_view = new Locomotive.Views.EditableElements.PageView
|
47
|
+
el: $(@window.document.body)
|
48
|
+
parent_view: @
|
49
|
+
button_labels:
|
50
|
+
edit: $(@el).data('edit-label')
|
51
|
+
@page_view.render()
|
52
|
+
|
53
|
+
# insert the highlighter CSS (path to the CSS in the iframe data)
|
54
|
+
window.addStylesheet(@window.document, $(@el).data('style-path'))
|
55
|
+
|
56
|
+
remove: ->
|
57
|
+
super()
|
58
|
+
@page_view.remove() if @page_view?
|
59
|
+
_.each @tokens, (token) -> PubSub.unsubscribe(token)
|
@@ -8,108 +8,35 @@ class Locomotive.Views.EditableElements.IndexView extends Backbone.View
|
|
8
8
|
'click .content .expand-button': 'expand_preview'
|
9
9
|
'click .content .close-button': 'shrink_preview'
|
10
10
|
|
11
|
-
expand_preview: (event) ->
|
12
|
-
$('body').addClass('full-width-preview')
|
13
|
-
|
14
|
-
shrink_preview: (event) ->
|
15
|
-
$('body').removeClass('full-width-preview')
|
16
|
-
|
17
11
|
initialize: ->
|
18
|
-
_.bindAll(@, 'refresh_elements', 'refresh_image', 'refresh_image_on_remove', 'refresh_text', 'reload_page')
|
19
|
-
|
20
12
|
view_options = if $('body').hasClass('live-editing') then {} else { el: '.main' }
|
21
13
|
|
22
|
-
@
|
23
|
-
|
24
|
-
|
14
|
+
@tokens = [
|
15
|
+
PubSub.subscribe 'editable_elements.highlighted_text', @shrink_preview
|
16
|
+
]
|
25
17
|
|
26
|
-
|
27
|
-
@
|
28
|
-
|
29
|
-
|
30
|
-
|
18
|
+
# order is important here
|
19
|
+
@views = [
|
20
|
+
new Locomotive.Views.EditableElements.EditView(view_options),
|
21
|
+
new Locomotive.Views.EditableElements.IframeView(parent_view: @)
|
22
|
+
]
|
31
23
|
|
32
24
|
render: ->
|
33
25
|
super()
|
34
|
-
@
|
35
|
-
|
36
|
-
refresh_elements: (type, view, callback) ->
|
37
|
-
$parent_view = $(view.el).parent()
|
38
|
-
element_id = $parent_view.find('input[name*="[id]"]').val()
|
39
|
-
|
40
|
-
$iframe_document = $($('iframe')[0].contentWindow.document)
|
41
|
-
|
42
|
-
callback($iframe_document.find("*[data-element-id=#{element_id}]"), element_id, $iframe_document)
|
43
|
-
|
44
|
-
refresh_image_on_remove: (msg, data) ->
|
45
|
-
data.url = $(data.view.el).parent().find('input[name*="[default_source_url]"]').val()
|
46
|
-
@refresh_image(msg, data)
|
47
|
-
|
48
|
-
refresh_image: (msg, data) ->
|
49
|
-
@refresh_elements 'image', data.view, ($elements, element_id, $iframe_document) ->
|
50
|
-
current_image_url = data.view.$('input[name*="[content]"]').val()
|
51
|
-
image_url = data.url || current_image_url
|
26
|
+
_.invoke @views, 'render'
|
52
27
|
|
53
|
-
|
54
|
-
|
55
|
-
if this.nodeName == 'IMG'
|
56
|
-
$(this).attr('src', image_url)
|
57
|
-
else
|
58
|
-
$(this).css("background-image", "url('" + image_url + "')")
|
59
|
-
else
|
60
|
-
# looking for DIVs with background-url property matching the previous image url
|
61
|
-
$el = $iframe_document.find("*[style*='#{current_image_url}']").attr('data-element-id', element_id)
|
62
|
-
$el.css("background-image", "url('" + image_url + "')")
|
63
|
-
|
64
|
-
# looking for IMGs with src attribute matching the previous image url
|
65
|
-
$el = $iframe_document.find("img[src*='#{current_image_url}']").attr('data-element-id', element_id)
|
66
|
-
$el.attr('src', image_url)
|
67
|
-
|
68
|
-
refresh_text: (msg, data) ->
|
69
|
-
@refresh_elements 'text', data.view, ($elements) ->
|
70
|
-
$elements.each -> $(this).html(data.content)
|
71
|
-
|
72
|
-
reload_page: (event) ->
|
73
|
-
$iframe = $('.preview iframe')
|
74
|
-
$target_window = $iframe[0].contentWindow
|
75
|
-
$iframe.attr('src', @preview_url)
|
76
|
-
|
77
|
-
on_iframe_load: (event) ->
|
78
|
-
$iframe = $('.preview iframe')
|
79
|
-
$target_window = $iframe[0].contentWindow
|
80
|
-
editable_elements_path = null
|
81
|
-
|
82
|
-
# unable to display the iframe in the frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
|
83
|
-
try
|
84
|
-
$iframe_document = $($target_window.document)
|
85
|
-
editable_elements_path = $iframe_document.find('meta[name=locomotive-editable-elements-path]').attr('content')
|
86
|
-
catch e
|
87
|
-
# reload the iframe with the previous url and display an error message
|
88
|
-
$iframe.attr('src', @preview_url)
|
89
|
-
Locomotive.notify $iframe.data('redirection-error'), 'warning'
|
90
|
-
return
|
91
|
-
|
92
|
-
# store the url
|
93
|
-
@preview_url = $('.preview iframe')[0].contentWindow.document.location.href
|
28
|
+
expand_preview: (event) ->
|
29
|
+
$('body').addClass('full-width-preview')
|
94
30
|
|
95
|
-
|
96
|
-
|
97
|
-
@replace_edit_view(editable_elements_path)
|
98
|
-
else
|
99
|
-
@startup = false
|
31
|
+
shrink_preview: (event) ->
|
32
|
+
$('body').removeClass('full-width-preview')
|
100
33
|
|
101
34
|
replace_edit_view: (url) ->
|
102
|
-
$(@
|
103
|
-
@
|
104
|
-
@
|
105
|
-
@edit_view.render()
|
35
|
+
$(@views[0].el).load url, =>
|
36
|
+
@views[0].remove()
|
37
|
+
(@views[0] = new Locomotive.Views.EditableElements.EditView()).render()
|
106
38
|
|
107
39
|
remove: ->
|
108
|
-
super
|
109
|
-
|
110
|
-
@
|
111
|
-
|
112
|
-
PubSub.unsubscribe(@pubsub_image_changed_token)
|
113
|
-
PubSub.unsubscribe(@pubsub_image_removed_token)
|
114
|
-
PubSub.unsubscribe(@pubsub_text_token)
|
115
|
-
PubSub.unsubscribe(@pubsub_pages_sorted_token)
|
40
|
+
super()
|
41
|
+
_.each @tokens, (token) -> PubSub.unsubscribe(token)
|
42
|
+
_.invoke @views, 'remove'
|
@@ -0,0 +1,81 @@
|
|
1
|
+
Locomotive.Views.EditableElements ||= {}
|
2
|
+
|
3
|
+
class Locomotive.Views.EditableElements.PageView extends Backbone.View
|
4
|
+
|
5
|
+
initialize: ->
|
6
|
+
_.bindAll(@, 'refresh_all', 'refresh_text', 'refresh_image', 'refresh_image_on_remove', 'scroll_to_block', 'scroll_to_element')
|
7
|
+
|
8
|
+
# Global event subscriptions
|
9
|
+
@tokens = [
|
10
|
+
PubSub.subscribe 'editable_elements.block_selected', @scroll_to_block
|
11
|
+
PubSub.subscribe 'editable_elements.form_group_selected', @scroll_to_element
|
12
|
+
PubSub.subscribe 'inputs.text_changed', @refresh_text,
|
13
|
+
PubSub.subscribe 'inputs.image_changed', @refresh_image,
|
14
|
+
PubSub.subscribe 'inputs.image_removed', @refresh_image_on_remove,
|
15
|
+
PubSub.subscribe 'pages.sorted', @refresh_all
|
16
|
+
]
|
17
|
+
|
18
|
+
# create the highlighter view
|
19
|
+
@views = [new Locomotive.Views.EditableElements.TextHighLighterView(el: @el, button_labels: @options.button_labels)]
|
20
|
+
|
21
|
+
render: ->
|
22
|
+
# render the highlighter view
|
23
|
+
_.invoke @views, 'render'
|
24
|
+
|
25
|
+
scroll_to_block: (msg, data) ->
|
26
|
+
@_scroll_to @$("span.locomotive-block-anchor[data-element-id=\"#{data.name}\"]")
|
27
|
+
|
28
|
+
scroll_to_element: (msg, data) ->
|
29
|
+
@_scroll_to @$("span.locomotive-editable-text[data-element-id=\"#{data.element_id}\"]")
|
30
|
+
|
31
|
+
_scroll_to: (element) ->
|
32
|
+
return false if element.size() == 0
|
33
|
+
$(@el).animate({ scrollTop: element.offset().top }, 500)
|
34
|
+
|
35
|
+
refresh_all: (msg, data) ->
|
36
|
+
@options.parent_view.reload()
|
37
|
+
|
38
|
+
refresh_text: (msg, data) ->
|
39
|
+
@refresh_elements 'text', data.view, ($elements) ->
|
40
|
+
$elements.each -> $(this).html(data.content)
|
41
|
+
|
42
|
+
refresh_image_on_remove: (msg, data) ->
|
43
|
+
data.url = $(data.view.el).parent().find('input[name*="[default_source_url]"]').val()
|
44
|
+
@refresh_image(msg, data)
|
45
|
+
|
46
|
+
refresh_image: (msg, data) ->
|
47
|
+
@refresh_elements 'image', data.view, ($elements, element_id) =>
|
48
|
+
current_image_url = data.view.$('input[name*="[content]"]').val()
|
49
|
+
image_url = data.url || current_image_url
|
50
|
+
|
51
|
+
if $elements.size() > 0
|
52
|
+
@replace_images($elements, image_url)
|
53
|
+
else
|
54
|
+
@replace_images_identified_by_url(current_image_url, image_url, element_id)
|
55
|
+
|
56
|
+
refresh_elements: (type, view, callback) ->
|
57
|
+
$form_view = $(view.el).parent()
|
58
|
+
element_id = $form_view.find('input[name*="[id]"]').val()
|
59
|
+
|
60
|
+
callback($(@el).find("*[data-element-id=#{element_id}]"), element_id)
|
61
|
+
|
62
|
+
replace_images: (images, new_image_url) ->
|
63
|
+
images.each ->
|
64
|
+
if this.nodeName == 'IMG'
|
65
|
+
$(this).attr('src', new_image_url)
|
66
|
+
else
|
67
|
+
$(this).css("background-image", "url('" + new_image_url + "')")
|
68
|
+
|
69
|
+
replace_images_identified_by_url: (current_image_url, new_image_url, element_id) ->
|
70
|
+
# looking for DIVs with background-url property matching the previous image url
|
71
|
+
$el = $(@el).find("*[style*='#{current_image_url}']").attr('data-element-id', element_id)
|
72
|
+
$el.css("background-image", "url('" + new_image_url + "')")
|
73
|
+
|
74
|
+
# looking for IMGs with src attribute matching the previous image url
|
75
|
+
$el = $(@el).find("img[src*='#{current_image_url}']").attr('data-element-id', element_id)
|
76
|
+
$el.attr('src', new_image_url)
|
77
|
+
|
78
|
+
remove: ->
|
79
|
+
super()
|
80
|
+
_.each @tokens, (token) -> PubSub.unsubscribe(token)
|
81
|
+
_.invoke @views, 'remove'
|