alchemy_cms 3.0.0.rc5 → 3.0.0.rc6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -5
  3. data/README.md +32 -5
  4. data/alchemy_cms.gemspec +1 -1
  5. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +3 -3
  6. data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +19 -0
  7. data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +5 -0
  8. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +3 -2
  9. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +2 -0
  10. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
  11. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -26
  12. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +1 -1
  13. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +2 -0
  14. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +12 -7
  15. data/app/assets/javascripts/alchemy/alchemy.js +1 -1
  16. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +33 -4
  17. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +1 -1
  18. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +2 -13
  19. data/app/assets/javascripts/alchemy/{alchemy.tinymce.js.coffee.erb → alchemy.tinymce.js.coffee} +1 -25
  20. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +63 -105
  21. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +3 -3
  22. data/app/assets/stylesheets/alchemy/_extends.scss +2 -8
  23. data/app/assets/stylesheets/alchemy/_mixins.scss +4 -9
  24. data/app/assets/stylesheets/alchemy/base.scss +6 -6
  25. data/app/assets/stylesheets/alchemy/buttons.scss +56 -29
  26. data/app/assets/stylesheets/alchemy/elements.scss +66 -14
  27. data/app/assets/stylesheets/alchemy/form_fields.scss +39 -6
  28. data/app/assets/stylesheets/alchemy/forms.scss +32 -0
  29. data/app/assets/stylesheets/alchemy/frame.scss +44 -44
  30. data/app/assets/stylesheets/alchemy/icons.scss +2 -2
  31. data/app/assets/stylesheets/alchemy/jquery-ui.scss +2 -0
  32. data/app/assets/stylesheets/alchemy/notices.scss +6 -0
  33. data/app/assets/stylesheets/alchemy/selects.scss +10 -0
  34. data/app/assets/stylesheets/alchemy/sitemap.scss +8 -10
  35. data/app/assets/stylesheets/alchemy/toolbar.scss +40 -31
  36. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +11 -22
  37. data/app/controllers/alchemy/admin/base_controller.rb +14 -1
  38. data/app/controllers/alchemy/admin/elements_controller.rb +4 -2
  39. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -0
  40. data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +39 -0
  41. data/app/controllers/alchemy/admin/pages_controller.rb +0 -3
  42. data/app/controllers/alchemy/base_controller.rb +7 -4
  43. data/app/helpers/alchemy/admin/base_helper.rb +33 -3
  44. data/app/helpers/alchemy/pages_helper.rb +1 -1
  45. data/app/models/alchemy/element.rb +6 -4
  46. data/app/models/alchemy/legacy_page_url.rb +5 -1
  47. data/app/models/alchemy/message.rb +2 -2
  48. data/app/models/alchemy/page.rb +8 -9
  49. data/app/models/alchemy/page/{cells.rb → page_cells.rb} +1 -1
  50. data/app/models/alchemy/page/{elements.rb → page_elements.rb} +1 -1
  51. data/app/models/alchemy/page/{naming.rb → page_naming.rb} +33 -18
  52. data/app/models/alchemy/page/{natures.rb → page_natures.rb} +1 -1
  53. data/app/models/alchemy/page/{scopes.rb → page_scopes.rb} +1 -1
  54. data/app/models/alchemy/page/{users.rb → page_users.rb} +13 -1
  55. data/app/views/alchemy/admin/elements/_add_element_button.html.erb +18 -0
  56. data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
  57. data/app/views/alchemy/admin/elements/_element.html.erb +12 -11
  58. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +3 -0
  59. data/app/views/alchemy/admin/elements/create.js.erb +3 -3
  60. data/app/views/alchemy/admin/elements/index.html.erb +19 -4
  61. data/app/views/alchemy/admin/elements/new.html.erb +3 -0
  62. data/app/views/alchemy/admin/elements/trash.js.erb +16 -12
  63. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +1 -1
  64. data/app/views/alchemy/admin/layoutpages/edit.html.erb +11 -0
  65. data/app/views/alchemy/admin/layoutpages/index.html.erb +4 -16
  66. data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +5 -0
  67. data/app/views/alchemy/admin/legacy_page_urls/_label.html.erb +1 -0
  68. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +13 -0
  69. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +20 -0
  70. data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +10 -0
  71. data/app/views/alchemy/admin/legacy_page_urls/destroy.js.erb +6 -0
  72. data/app/views/alchemy/admin/legacy_page_urls/update.js.erb +2 -0
  73. data/app/views/alchemy/admin/pages/_form.html.erb +58 -0
  74. data/app/views/alchemy/admin/pages/_internal_link.html.erb +9 -4
  75. data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +23 -0
  76. data/app/views/alchemy/admin/pages/_locked_page.html.erb +21 -0
  77. data/app/views/alchemy/admin/pages/_page.html.erb +2 -2
  78. data/app/views/alchemy/admin/pages/_page_status.html.erb +11 -9
  79. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +13 -0
  80. data/app/views/alchemy/admin/pages/configure.html.erb +16 -57
  81. data/app/views/alchemy/admin/pages/edit.html.erb +64 -66
  82. data/app/views/alchemy/admin/pages/index.html.erb +9 -19
  83. data/app/views/alchemy/admin/pages/update.js.erb +1 -1
  84. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +7 -12
  85. data/app/views/alchemy/admin/partials/_routes.html.erb +25 -0
  86. data/app/views/alchemy/admin/partials/_search_form.html.erb +10 -12
  87. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +53 -47
  88. data/app/views/alchemy/admin/pictures/index.html.erb +34 -29
  89. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +1 -1
  90. data/app/views/alchemy/navigation/_link.html.erb +9 -9
  91. data/app/views/alchemy/pages/show.rss.builder +2 -2
  92. data/app/views/layouts/alchemy/admin.html.erb +20 -9
  93. data/bin/alchemy +1 -1
  94. data/config/alchemy/config.yml +1 -0
  95. data/config/locales/alchemy.de.yml +15 -1
  96. data/config/locales/alchemy.en.yml +29 -19
  97. data/config/locales/alchemy.nl.yml +11 -1
  98. data/config/routes.rb +2 -1
  99. data/lib/alchemy/errors.rb +2 -2
  100. data/lib/alchemy/permissions.rb +2 -0
  101. data/lib/alchemy/resource.rb +22 -9
  102. data/lib/alchemy/tinymce.rb +13 -7
  103. data/lib/alchemy/version.rb +1 -1
  104. data/spec/controllers/admin/base_controller_spec.rb +39 -0
  105. data/spec/controllers/admin/elements_controller_spec.rb +17 -14
  106. data/spec/controllers/admin/pages_controller_spec.rb +1 -2
  107. data/spec/controllers/pages_controller_spec.rb +7 -3
  108. data/spec/dummy/app/models/dummy_user.rb +12 -2
  109. data/spec/features/admin/dashboard_spec.rb +45 -0
  110. data/spec/features/admin/legacy_page_url_management_spec.rb +62 -0
  111. data/spec/features/admin/page_editing_feature_spec.rb +66 -6
  112. data/spec/features/page_feature_spec.rb +13 -0
  113. data/spec/helpers/admin/base_helper_spec.rb +36 -0
  114. data/spec/libraries/resource_spec.rb +168 -84
  115. data/spec/libraries/tinymce_spec.rb +10 -0
  116. data/spec/models/element_spec.rb +16 -0
  117. data/spec/models/legacy_page_url_spec.rb +21 -0
  118. data/spec/models/message_spec.rb +23 -7
  119. data/spec/models/page_spec.rb +89 -12
  120. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js +1 -0
  121. data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.min.js +1 -0
  122. metadata +96 -75
  123. data/app/assets/javascripts/alchemy/alchemy.routes.js.erb +0 -38
  124. data/spec/models/resource_spec.rb +0 -159
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2c765b8cbf60627a8a7127e4c911ac5f784a0d5
4
- data.tar.gz: 64f8f25adcd982278ee427c0d8bbf2646c03ce88
3
+ metadata.gz: 46aef856d1de74f7fdd263bd44290ab72970a408
4
+ data.tar.gz: c8db252636d2e4af9b8172f89b27fc7d7ba209e9
5
5
  SHA512:
6
- metadata.gz: 7cd17ed412cce80d4929376215336d28424615c3a0897592cb14094825abf730cc22678cf4d6b8e34fa225c5e7f95d2f3683cfd62a2978439f3bff1dfeb0732b
7
- data.tar.gz: 31ceaae54f98da0e6a97106a46a317b58c0a3a93e0a6081726368fa628e08bab3682b1f809a4a9d34f085a53c3939421a34f36bab79bd15a615e2079a8a53e52
6
+ metadata.gz: 316bf6685dc74ea7a82a54a9f6f2c1f3efff0abf0ff24952fca2bb5de42315ae027cc154016dac6fc5075006f90104eaed1680b4bfba10d28e0ff10518366572
7
+ data.tar.gz: b86f3962f5e93226710495596dc5dc9ec7dd16ffbac5972b80fecd3e085b2feb812d4b11b51f260dad7c370ab03f61aa9939b1f229f4cd9af669a31f9617fc44
@@ -2,7 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.0
5
+ - 2.1
6
6
  branches:
7
7
  only:
8
8
  - master
@@ -10,7 +10,7 @@ script: rake
10
10
  env:
11
11
  - DB=mysql
12
12
  - DB=postgresql
13
- - RAILS_VERSION=4.1.0.rc2
13
+ - RAILS_VERSION=4.1.1
14
14
  notifications:
15
15
  irc:
16
16
  on_success: change
@@ -18,6 +18,3 @@ notifications:
18
18
  use_notice: true
19
19
  channels:
20
20
  - "irc.freenode.org#alchemy_cms"
21
- matrix:
22
- allow_failures:
23
- - env: RAILS_VERSION=4.1.0.rc2
data/README.md CHANGED
@@ -10,8 +10,8 @@ Alchemy is the most powerful, userfriendly and flexible Rails CMS.
10
10
 
11
11
  Read more on the [website](http://alchemy-cms.com) and in the [guidelines](http://guides.alchemy-cms.com).
12
12
 
13
- **This master branch is a development branch that can contain bugs. For productive environments you should use the [current Ruby gem version](http://rubygems.org/gems/alchemy_cms/versions/2.7.2),
14
- or the [latest stable branch (2.7-stable)](https://github.com/magiclabs/alchemy_cms/tree/2.7-stable).**
13
+ **This master branch is a development branch that can contain bugs. For productive environments you should use the [current Ruby gem version](http://rubygems.org/gems/alchemy_cms/versions/2.8.1),
14
+ or the [latest stable branch (2.8-stable)](https://github.com/magiclabs/alchemy_cms/tree/2.8-stable).**
15
15
 
16
16
  Features
17
17
  --------
@@ -37,7 +37,7 @@ Rails Version
37
37
 
38
38
  **This version of Alchemy CMS runs with Rails 4 (including 4.1)**
39
39
 
40
- If you are looking for a Rails 3.2 compatible version check the [2.7-stable branch](https://github.com/magiclabs/alchemy_cms/tree/2.7-stable).
40
+ If you are looking for a Rails 3.2 compatible version check the [2.8-stable branch](https://github.com/magiclabs/alchemy_cms/tree/2.8-stable).
41
41
 
42
42
  If you are looking for a Rails 3.1 compatible version check the [2.1-stable branch](https://github.com/magiclabs/alchemy_cms/tree/2.1-stable).
43
43
 
@@ -130,6 +130,33 @@ Example:
130
130
  end
131
131
  end
132
132
 
133
+ **Optionally** you can add a `alchemy_display_name` method that returns a name representing the currently logged in user. This is used in the admin views.
134
+
135
+ Example:
136
+
137
+ def alchemy_display_name
138
+ "#{first_name} #{last_name}".strip
139
+ end
140
+
141
+ Testing
142
+ -------
143
+
144
+ Before running tests (which refer to Alchemy), please make sure to run the rake task
145
+
146
+ bundle exec rake alchemy:spec:prepare
147
+
148
+ to set up the database for testing.
149
+
150
+ Now you can run your tests, e. g. with RSpec:
151
+
152
+ bundle exec rspec spec/...
153
+
154
+ **Alternatively** you can just run:
155
+
156
+ bundle exec rake
157
+
158
+ This default task executes the database preparations and runs all defined test cases.
159
+
133
160
  Deployment
134
161
  ----------
135
162
 
@@ -179,7 +206,7 @@ Resources
179
206
  ---------
180
207
 
181
208
  * Homepage: <http://alchemy-cms.com>
182
- * Live-Demo: <http://edge-demo.alchemy-cms.com> (user: demo, password: demo123)
209
+ * Live-Demo: <http://demo.alchemy-cms.com> (user: demo, password: demo123)
183
210
  * API Documentation: <http://rubydoc.info/github/magiclabs/alchemy_cms>
184
211
  * Issue-Tracker: <https://github.com/magiclabs/alchemy_cms/issues>
185
212
  * Sourcecode: <https://github.com/magiclabs/alchemy_cms>
@@ -199,4 +226,4 @@ Authors
199
226
  License
200
227
  -------
201
228
 
202
- * BSD: <https://raw.github.com/magiclabs/alchemy_cms/2.7-stable/LICENSE>
229
+ * BSD: <https://raw.github.com/magiclabs/alchemy_cms/master/LICENSE>
@@ -43,7 +43,7 @@ Gem::Specification.new do |gem|
43
43
  gem.add_runtime_dependency 'non-stupid-digest-assets', '~> 1.0.3'
44
44
  gem.add_runtime_dependency 'active_model_serializers', '~> 0.8.1'
45
45
 
46
- gem.add_development_dependency 'rspec-rails'
46
+ gem.add_development_dependency 'rspec-rails', '~> 2.0'
47
47
  gem.add_development_dependency 'capybara'
48
48
  gem.add_development_dependency 'factory_girl_rails'
49
49
 
@@ -15,12 +15,12 @@ Alchemy.Buttons =
15
15
  disable: (button) ->
16
16
  $button = $(button)
17
17
  spinner = Alchemy.Spinner.small()
18
- $button.data('label', $button.text())
18
+ $button.data('content', $button.html())
19
19
  $button.attr('disabled', true)
20
20
  $button.addClass('disabled')
21
21
  $button.css
22
22
  width: $button.outerWidth()
23
- $button.text('')
23
+ $button.empty()
24
24
  spinner.spin($button[0])
25
25
  return true
26
26
 
@@ -28,5 +28,5 @@ Alchemy.Buttons =
28
28
  $button = $('form :submit:disabled', scope)
29
29
  $button.removeClass('disabled')
30
30
  $button.removeAttr('disabled')
31
- $button.text($button.data('label'))
31
+ $button.html($button.data('content'))
32
32
  return true
@@ -0,0 +1,19 @@
1
+ class window.Alchemy.CharCounter
2
+
3
+ constructor: (field) ->
4
+ @$field = $(field)
5
+ @max_chars = @$field.data('alchemy-char-counter')
6
+ @text = Alchemy._t('allowed_chars', @max_chars)
7
+ @$display = $('<small class="alchemy-char-counter"/>')
8
+ @$field.after(@$display)
9
+ countChars.call(this)
10
+ @$field.keyup =>
11
+ countChars.call(this)
12
+ true
13
+
14
+ countChars = ->
15
+ char_length = @$field.val().length
16
+ @$display.removeClass('too-long')
17
+ @$display.text("#{char_length} #{@text}")
18
+ if char_length > @max_chars
19
+ @$display.addClass('too-long')
@@ -76,5 +76,10 @@ window.Alchemy.confirmToDeleteDialog = (url, opts) ->
76
76
  $.ajax
77
77
  url: url
78
78
  type: "DELETE"
79
+ error: (xhr, status, error) ->
80
+ type = if xhr.status == 403 then 'warning' else 'error'
81
+ Alchemy.pleaseWaitOverlay(false)
82
+ Alchemy.growl(xhr.responseText || error, type)
83
+
79
84
  $.extend(options, opts)
80
85
  Alchemy.openConfirmDialog options.message, options
@@ -99,9 +99,10 @@ class window.Alchemy.Dialog
99
99
  form = $('[data-remote="true"]', @dialog_body)
100
100
  form.bind "ajax:complete", (e, xhr, status) =>
101
101
  content_type = xhr.getResponseHeader('Content-Type')
102
+ Alchemy.Buttons.enable(@dialog_body)
102
103
  if status == 'success'
103
104
  if content_type.match(/javascript/)
104
- @close()
105
+ return
105
106
  else
106
107
  @dialog_body.html(xhr.responseText)
107
108
  @init()
@@ -127,7 +128,7 @@ class window.Alchemy.Dialog
127
128
  error_header = "#{xhr.statusText} (#{xhr.status})"
128
129
  error_body = "Please check log and try again."
129
130
  $errorDiv = $("<div class=\"message #{error_type}\" />")
130
- $errorDiv.append '<span class="icon warning"></span>'
131
+ $errorDiv.append "<span class=\"icon #{error_type}\" />"
131
132
  $errorDiv.append "<h1>#{error_header}</h1>"
132
133
  $errorDiv.append "<p>#{error_body}</p>"
133
134
  @dialog_body.html $errorDiv
@@ -47,9 +47,11 @@ $.extend Alchemy,
47
47
  Alchemy.TrashWindow.refresh page_id
48
48
 
49
49
  start: (event, ui) ->
50
+ ui.helper.find('.insert-element-button').hide()
50
51
  Alchemy.Tinymce.remove getTinymceIDs(ui)
51
52
 
52
53
  stop: (event, ui) ->
54
+ ui.item.find('.insert-element-button').show()
53
55
  Alchemy.Tinymce.init getTinymceIDs(ui)
54
56
 
55
57
  SortableContents: (selector, token) ->
@@ -39,7 +39,7 @@ Alchemy.ElementEditors =
39
39
  #
40
40
  onClickElement: (e) ->
41
41
  self = Alchemy.ElementEditors
42
- $element = $(this).parent(".element_editor")
42
+ $element = $(this).parents(".element_editor")
43
43
  id = $element.attr("id").replace(/\D/g, "")
44
44
  e.preventDefault()
45
45
  $("#element_area .element_editor").removeClass "selected"
@@ -1,22 +1,5 @@
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
-
20
3
  Alchemy.ElementsWindow =
21
4
 
22
5
  init: (url, options, callback) ->
@@ -26,7 +9,6 @@ Alchemy.ElementsWindow =
26
9
  @url = url
27
10
  @options = options
28
11
  @callback = callback
29
- @element_window.append @createToolbar(options.toolbarButtons)
30
12
  @element_window.append @element_area
31
13
  @button = $('#element_window_button')
32
14
  @button.click =>
@@ -39,18 +21,12 @@ Alchemy.ElementsWindow =
39
21
  $('#main_content').append(@element_window)
40
22
  @reload()
41
23
 
42
- createToolbar: (buttons) ->
43
- @toolbar = $('<div id="overlay_toolbar"/>')
44
- for btn in buttons
45
- @toolbar.append Alchemy.ToolbarButton(btn)
46
- @toolbar
47
-
48
24
  resize: ->
49
- height = $(window).height() - 80
25
+ height = $(window).height() - 75
50
26
  @element_window.css
51
27
  height: height
52
28
  @element_area.css
53
- height: height - 54
29
+ height: height
54
30
  height
55
31
 
56
32
  reload: ->
@@ -60,4 +60,4 @@ Alchemy.FileProgress::setCancelled = ->
60
60
  $(this).remove()
61
61
 
62
62
  Alchemy.FileProgress::setStatus = (status) ->
63
- @$fileProgressStatus.text status
63
+ @$fileProgressStatus.text Alchemy._t(status)
@@ -13,6 +13,8 @@ Alchemy.GUI =
13
13
  Alchemy.ListFilter(scope)
14
14
  Alchemy.Spinner.watch(scope)
15
15
  Alchemy.Autocomplete.tags(scope)
16
+ $('[data-alchemy-char-counter]', scope).each ->
17
+ new Alchemy.CharCounter(this)
16
18
 
17
19
  initElement: ($el) ->
18
20
  Alchemy.ElementDirtyObserver($el)
@@ -6,16 +6,21 @@ Alchemy.I18n =
6
6
 
7
7
  # Translates given string
8
8
  #
9
- translate: (id) ->
9
+ translate: (key, replacement) ->
10
10
  if !Alchemy.locale?
11
11
  throw 'Alchemy.locale is not set! Please set Alchemy.locale to a locale string in order to translate something.'
12
- translation = Alchemy.translations[id]
13
- if (translation)
14
- translation[Alchemy.locale]
12
+ translations = Alchemy.translations[Alchemy.locale]
13
+ if translations
14
+ translation = translations[key] || key
15
+ if replacement
16
+ translation.replace(/%\{.+\}/, replacement)
17
+ else
18
+ translation
15
19
  else
16
- id
20
+ Alchemy.debug "Translations for locale #{Alchemy.locale} not found!"
21
+ key
17
22
 
18
23
  # Global utility method for translating a given string
19
24
  #
20
- Alchemy._t = (id) ->
21
- Alchemy.I18n.translate(id)
25
+ Alchemy._t = (key, replacement) ->
26
+ Alchemy.I18n.translate(key, replacement)
@@ -16,12 +16,12 @@
16
16
  //= require requestAnimationFrame
17
17
  //= require select2
18
18
  //= require select2_locale_de
19
- //= require alchemy/alchemy.routes
20
19
  //= require alchemy/alchemy.base
21
20
  //= require alchemy/alchemy.autocomplete
22
21
  //= require alchemy/alchemy.browser
23
22
  //= require alchemy/alchemy.buttons
24
23
  //= require alchemy/alchemy.dialog
24
+ //= require alchemy/alchemy.char_counter
25
25
  //= require alchemy/alchemy.confirm_dialog
26
26
  //= require alchemy/alchemy.datepicker
27
27
  //= require alchemy/alchemy.dirty
@@ -7,23 +7,25 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
7
7
  @url = Alchemy.routes.link_admin_pages_path
8
8
  @$link_object = $(@link_object)
9
9
  @options =
10
- size: '600x540'
10
+ size: '600x320'
11
11
  title: 'Link'
12
12
  super(@url, @options)
13
13
 
14
14
  # Called from Dialog class after the url was loaded
15
15
  replace: (data) ->
16
- # let Dailog class handle the content replacement
16
+ # let Dialog class handle the content replacement
17
17
  super(data)
18
18
  # attach events we handle
19
19
  @attachEvents()
20
20
  # Store some jQuery objects for further reference
21
21
  @$page_anchor = $('#page_anchor', @dialog_body)
22
22
  @$internal_urlname = $('#internal_urlname', @dialog_body)
23
+ @$internal_anchor = $('#internal_anchor', @dialog_body)
23
24
  @$external_url = $('#external_url', @dialog_body)
24
25
  @$public_filename = $('#public_filename', @dialog_body)
25
26
  @$overlay_tabs = $('#overlay_tabs', @dialog_body)
26
27
  @$page_container = $('#page_selector_container')
28
+ @initInternalAnchors()
27
29
  # if we edit an existing link
28
30
  if @link_object
29
31
  # we select the correct tab
@@ -66,10 +68,16 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
66
68
 
67
69
  # Sets the page selected and scrolls it in the viewport.
68
70
  selectPage: (page_id) ->
69
- $('#sitemap .selected_page', @dialog_body).removeClass('selected_page')
71
+ # deselect any selected page from page tree
72
+ @deselectPage()
73
+ # reset the internal anchor select
74
+ @$internal_anchor.select2('val', '')
70
75
  $('#sitemap_sitename_' + page_id).addClass('selected_page')
71
76
  @$page_container.scrollTo("#sitemap_sitename_#{page_id}", {duration: 400, offset: -10})
72
77
 
78
+ deselectPage: ->
79
+ $('#sitemap .selected_page', @dialog_body).removeClass('selected_page')
80
+
73
81
  # Creates a link if no validation errors are present.
74
82
  # Otherwise shows an error notice.
75
83
  createLink: (options) ->
@@ -152,6 +160,11 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
152
160
  @$page_anchor.val("##{anchor}")
153
161
  # and update the url field
154
162
  @$internal_urlname.val("#{urlname}##{anchor}")
163
+ # if we linked an internal anchor
164
+ if @$internal_urlname.val().match(/^#/)
165
+ # we select the correct value from anchors select
166
+ value = @$internal_urlname.val()
167
+ @$internal_anchor.select2 'val', value.replace(/^#/, '')
155
168
  else
156
169
  @$internal_urlname.val(urlname)
157
170
  $sitemap_line = $('.sitemap_sitename').closest('[name="'+urlname+'"]')
@@ -195,7 +208,7 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
195
208
 
196
209
  # Validates url for beginning with an protocol.
197
210
  validateURLFormat: (url) ->
198
- if url.match(/^(mailto:|\/|[a-z]+:\/\/)/)
211
+ if url.match(Alchemy.link_url_regexp)
199
212
  true
200
213
  else
201
214
  false
@@ -205,6 +218,22 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
205
218
  $('#errors ul', @dialog_body).html("<li>#{Alchemy._t('url_validation_failed')}</li>")
206
219
  $('#errors', @dialog_body).show()
207
220
 
221
+ # Populates the internal anchors select
222
+ initInternalAnchors: ->
223
+ frame = document.getElementById('alchemy_preview_window')
224
+ elements = frame.contentDocument.getElementsByTagName('*')
225
+ if elements.length > 0
226
+ for element in elements
227
+ if element.id
228
+ @$internal_anchor.append("<option value='#{element.id}'>##{element.id}</option>")
229
+ else
230
+ @$internal_anchor.html("<option>#{Alchemy._t('No anchors found')}</option>")
231
+ @$internal_anchor.change (e) =>
232
+ # deselect any selected page from page tree
233
+ @deselectPage()
234
+ # store the internal anchor as urlname
235
+ $("#internal_urlname").val("##{e.target.value}")
236
+
208
237
  # Public class methods
209
238
 
210
239
  # Removes link from Essence.
@@ -19,7 +19,7 @@ Alchemy.PreviewWindow =
19
19
  width = $window.width() - 64
20
20
  else
21
21
  width = $window.width() - 466
22
- height = $window.height() - 80
22
+ height = $window.height() - 75
23
23
  width = 240 if width < 240
24
24
  @currentWidth = width
25
25
  @currentWindow.css
@@ -27,10 +27,10 @@ Alchemy.Sitemap =
27
27
  self.filter_field_clear.show()
28
28
  length = results.length
29
29
  if length == 1
30
- self.display.show().text("1 #{self._t('page_found')}")
30
+ self.display.show().text("1 #{Alchemy._t('page_found')}")
31
31
  $.scrollTo(results[0], {duration: 400, offset: -80})
32
32
  else if length > 1
33
- self.display.show().text("#{length} #{self._t('pages_found')}")
33
+ self.display.show().text("#{length} #{Alchemy._t('pages_found')}")
34
34
  else
35
35
  self.items.removeClass('no-match highlight')
36
36
  self.display.hide()
@@ -48,14 +48,3 @@ Alchemy.Sitemap =
48
48
  @filter_field_clear.click =>
49
49
  @search_field.val('')
50
50
  filter('')
51
-
52
- # Translations
53
- _t: (id) ->
54
- i18n =
55
- page_found:
56
- de: 'Seite gefunden'
57
- en: 'Page found'
58
- pages_found:
59
- de: 'Seiten gefunden'
60
- en: 'Pages found'
61
- i18n[id][Alchemy.locale]