publify_core 10.0.1 → 10.0.2

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -1
  3. data/app/assets/javascripts/markup_help_popup.js +25 -0
  4. data/app/assets/javascripts/optional_field_toggle.js +7 -0
  5. data/app/assets/javascripts/preview_comment.js +10 -0
  6. data/app/assets/javascripts/publify.js +3 -0
  7. data/app/assets/javascripts/publify_admin.js +1 -25
  8. data/app/assets/javascripts/spinnable.js +7 -2
  9. data/app/assets/stylesheets/administration_structure.css.scss +1 -1
  10. data/app/assets/stylesheets/publify.css.scss +43 -0
  11. data/app/assets/stylesheets/publify_admin.css.scss +0 -1
  12. data/app/controllers/admin/articles_controller.rb +3 -3
  13. data/app/controllers/admin/dashboard_controller.rb +0 -4
  14. data/app/controllers/admin/themes_controller.rb +1 -9
  15. data/app/controllers/articles_controller.rb +3 -1
  16. data/app/controllers/comments_controller.rb +1 -1
  17. data/app/helpers/admin/feedback_helper.rb +1 -1
  18. data/app/helpers/base_helper.rb +20 -12
  19. data/app/models/archives_sidebar.rb +1 -1
  20. data/app/models/content.rb +8 -3
  21. data/app/models/redirect.rb +2 -2
  22. data/app/models/tag_sidebar.rb +25 -3
  23. data/app/models/text_filter.rb +1 -1
  24. data/app/uploaders/resource_uploader.rb +1 -1
  25. data/app/views/admin/articles/_form.html.erb +2 -2
  26. data/app/views/admin/articles/index.html.erb +4 -5
  27. data/app/views/admin/dashboard/_comment.html.erb +1 -1
  28. data/app/views/admin/dashboard/_drafts.html.erb +1 -1
  29. data/app/views/admin/feedback/_ham.html.erb +1 -1
  30. data/app/views/admin/feedback/article.html.erb +1 -1
  31. data/app/views/admin/feedback/edit.html.erb +1 -1
  32. data/app/views/admin/feedback/index.html.erb +2 -2
  33. data/app/views/admin/migrations/show.html.erb +1 -1
  34. data/app/views/admin/notes/_form.html.erb +2 -3
  35. data/app/views/admin/notes/_note.html.erb +2 -2
  36. data/app/views/admin/notes/edit.html.erb +0 -1
  37. data/app/views/admin/pages/_pages.html.erb +1 -1
  38. data/app/views/admin/post_types/_index_and_form.html.erb +2 -2
  39. data/app/views/admin/redirects/_index_and_form.html.erb +2 -2
  40. data/app/views/admin/seo/show.html.erb +1 -1
  41. data/app/views/admin/settings/display.html.erb +1 -1
  42. data/app/views/admin/settings/feedback.html.erb +1 -1
  43. data/app/views/admin/settings/index.html.erb +1 -1
  44. data/app/views/admin/settings/write.html.erb +1 -1
  45. data/app/views/admin/tags/_index_and_form.html.erb +1 -1
  46. data/app/views/admin/users/_form.html.erb +1 -1
  47. data/app/views/articles/_comment_form.html.erb +9 -7
  48. data/app/views/articles/_comment_preview.html.erb +1 -1
  49. data/app/views/articles/_trackback.html.erb +3 -3
  50. data/app/views/articles/comment_failed.js.erb +1 -1
  51. data/app/views/articles/read.html.erb +4 -2
  52. data/app/views/comments/_comment.html.erb +1 -1
  53. data/app/views/comments/preview.js.erb +1 -1
  54. data/app/views/devise/passwords/edit.html.erb +3 -3
  55. data/app/views/devise/passwords/new.html.erb +1 -1
  56. data/app/views/devise/registrations/new.html.erb +2 -2
  57. data/app/views/devise/sessions/new.html.erb +2 -2
  58. data/app/views/devise/shared/_links.html.erb +3 -3
  59. data/app/views/layouts/accounts.html.erb +3 -3
  60. data/app/views/layouts/administration.html.erb +4 -6
  61. data/app/views/layouts/default.html.erb +1 -1
  62. data/app/views/layouts/editor.html.erb +3 -3
  63. data/app/views/notes/index.html.erb +1 -1
  64. data/app/views/notification_mailer/comment.html.erb +1 -1
  65. data/app/views/search_sidebar/_content.html.erb +2 -3
  66. data/app/views/settings/install.html.erb +2 -2
  67. data/app/views/shared/_page_header.html.erb +5 -5
  68. data/app/views/tag_sidebar/_content.html.erb +2 -2
  69. data/config/locales/ar.yml +0 -1
  70. data/config/locales/da.yml +0 -1
  71. data/config/locales/de.yml +0 -1
  72. data/config/locales/en.yml +0 -1
  73. data/config/locales/es-MX.yml +0 -1
  74. data/config/locales/fr.yml +0 -1
  75. data/config/locales/he.yml +0 -1
  76. data/config/locales/it.yml +0 -1
  77. data/config/locales/ja.yml +0 -1
  78. data/config/locales/lt.yml +0 -1
  79. data/config/locales/nb.yml +0 -1
  80. data/config/locales/nl.yml +0 -1
  81. data/config/locales/pl.yml +0 -1
  82. data/config/locales/pt-BR.yml +0 -1
  83. data/config/locales/ro.yml +0 -1
  84. data/config/locales/ru.yml +0 -1
  85. data/config/locales/zh-CN.yml +0 -1
  86. data/config/locales/zh-TW.yml +0 -1
  87. data/lib/publify_core/testing_support/feed_assertions.rb +1 -4
  88. data/lib/publify_core/version.rb +1 -1
  89. data/lib/theme.rb +18 -7
  90. metadata +30 -15
  91. data/app/assets/javascripts/datetimepicker.js +0 -1470
  92. data/app/assets/stylesheets/datetimepicker.css +0 -306
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f07659f73a5dbeb0204128c9d42e6fcec4092ed7d4e920dceac39f1d104531f3
4
- data.tar.gz: cef962bcdc17d957b1824f6e529534c48fdadb473280c910a33198cbcb49d2e7
3
+ metadata.gz: a80ae8a43965fcfb378504dd7b9d0cf6f13d5bc87df95fd9fb937caca4eb401f
4
+ data.tar.gz: d18535211810991287441d7e851786062d1ae0dea3b7835f47a102d20c0c179f
5
5
  SHA512:
6
- metadata.gz: 5f1262b50e741c94cf9bfcf2cc9d30dade5ae00fccbb5a33206789e7a900af47d280246b204b4f6671f2baaf18547fa1c98aad558d890500347ce58cf97d14f6
7
- data.tar.gz: 58e3228983425a5a802714855453184d726f351b81475c0f36f63acf19486c61c0be3f54b26a5cb205f0db48924158840a978fb83888c33cbbcaeaddc9d65b98
6
+ metadata.gz: 4154fcce63f81d06ea49c427307cebe10dec30c90dfeb16d4955fd9fca6e40be98a6d95a00b2582d0dd41d81ed82535a5f6b4ee3fc403ebfd04f924aa5e3bb59
7
+ data.tar.gz: 8dfb7191f158518c34cac975d53f89ed74539c14340db36f67fc6f5951e3f8a90004881d1a2a74c0740368040c19f424d29f0d830ddae9dcbe2b260b69c81846
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## 10.0.2 / 2024-06-28
4
+
5
+ ### Security updates
6
+
7
+ * Safely link target URLs for Redirects in admin ([#148] by [mvz])
8
+ * Upgrade jquery-ui-rails to version 7.0 ([#149] by [mvz])
9
+
10
+ ### Functional changes
11
+
12
+ * Use native datetime inputs in the Admin ([#121] by [mvz])
13
+ * Display Theme description nicely in the admin ([#151] by [mvz])
14
+
15
+ ### Internal changes
16
+
17
+ * Stop using and depending on REXML ([#123] by [mvz])
18
+ * Remove inline javascript ([#124] by [mvz])
19
+ * Switch to no-trailing-comma style ([#127] by [mvz])
20
+ * Remove inline styles assigned in ERB templates ([#128] by [mvz])
21
+ * Make Content.searchstring scope code more transparent ([#150] by [mvz])
22
+ * Add erb-lint and fix initial warnings ([#125] by [mvz])
23
+
24
+ [#121]: https://github.com/publify/publify_core/pull/121
25
+ [#123]: https://github.com/publify/publify_core/pull/123
26
+ [#124]: https://github.com/publify/publify_core/pull/124
27
+ [#125]: https://github.com/publify/publify_core/pull/125
28
+ [#127]: https://github.com/publify/publify_core/pull/127
29
+ [#128]: https://github.com/publify/publify_core/pull/128
30
+ [#148]: https://github.com/publify/publify_core/pull/148
31
+ [#149]: https://github.com/publify/publify_core/pull/149
32
+ [#150]: https://github.com/publify/publify_core/pull/150
33
+ [#151]: https://github.com/publify/publify_core/pull/151
34
+
3
35
  ## 10.0.1 / 2023-10-28
4
36
 
5
37
  * Update CarrierWave dependency to version 3.0 ([#102] by [mvz])
@@ -18,7 +50,6 @@
18
50
  [#118]: https://github.com/publify/publify_core/pull/118
19
51
  [#119]: https://github.com/publify/publify_core/pull/119
20
52
  [mvz]: https://github.com/mvz
21
- [dependabot]: https://github.com/apps/dependabot
22
53
 
23
54
  ## 10.0.0 / 2023-06-25
24
55
 
@@ -0,0 +1,25 @@
1
+ $(document).ready(function() {
2
+ $('.markup-help-popup-link').on("click", function(e){
3
+ var dialog = document.getElementById(e.target.dataset["target"]);
4
+ var url = e.target.dataset.url;
5
+
6
+ $.ajax({
7
+ url: url,
8
+ type: 'get',
9
+ dataType: 'html',
10
+ success: function(data) {
11
+ dialog.getElementsByClassName("content-target").item(0).innerHTML = data;
12
+ dialog.showModal();
13
+ }
14
+ });
15
+ e.preventDefault();
16
+ });
17
+ $('.markup-help-popup-close').on("click", function(e) {
18
+ e.target.closest('dialog').close();
19
+ });
20
+ $('.markup-help-popup').on("click", function(e) {
21
+ if (e.target == e.currentTarget) {
22
+ e.target.close();
23
+ }
24
+ });
25
+ });
@@ -0,0 +1,7 @@
1
+ $(document).ready(function() {
2
+ $('.optional_field').hide();
3
+ $('.optional-field-toggle').on("click", function(e){
4
+ $('.optional_field').fadeToggle();
5
+ e.preventDefault();
6
+ });
7
+ });
@@ -0,0 +1,10 @@
1
+ $(document).ready(function() {
2
+ $('.preview-comment-link').on("click", function(e) {
3
+ var lnk = e.currentTarget;
4
+ var preview_url = lnk.dataset.previewUrl;
5
+ var comment_form_selector = lnk.dataset.targetForm;
6
+
7
+ $.post(preview_url, $(comment_form_selector).serialize());
8
+ e.preventDefault();
9
+ });
10
+ });
@@ -6,7 +6,10 @@
6
6
  //= require set-timeago-lang
7
7
  //= require jquery_ujs
8
8
  //= require lightbox
9
+ //= require markup_help_popup
9
10
  //= require observe
11
+ //= require optional_field_toggle
12
+ //= require preview_comment
10
13
  //= require check_password
11
14
  //
12
15
  //= require_self
@@ -3,23 +3,6 @@
3
3
  //= require jquery
4
4
  //= require jquery_ujs
5
5
  //= require jquery-ui
6
- //= require jquery-ui/i18n/datepicker-da
7
- //= require jquery-ui/i18n/datepicker-de
8
- //= require jquery-ui/i18n/datepicker-es
9
- //= require jquery-ui/i18n/datepicker-fr
10
- //= require jquery-ui/i18n/datepicker-he
11
- //= require jquery-ui/i18n/datepicker-it
12
- //= require jquery-ui/i18n/datepicker-ja
13
- //= require jquery-ui/i18n/datepicker-lt
14
- //= require jquery-ui/i18n/datepicker-nb
15
- //= require jquery-ui/i18n/datepicker-nl
16
- //= require jquery-ui/i18n/datepicker-pl
17
- //= require jquery-ui/i18n/datepicker-pt-BR
18
- //= require jquery-ui/i18n/datepicker-ro
19
- //= require jquery-ui/i18n/datepicker-ru
20
- //= require jquery-ui/i18n/datepicker-zh-CN
21
- //= require jquery-ui/i18n/datepicker-zh-TW
22
- //= require datetimepicker
23
6
  //= require bootstrap-sprockets
24
7
  //= require quicktags
25
8
  //= require tagmanager
@@ -84,14 +67,7 @@ $(document).ready(function() {
84
67
  $('#article_form').each(function(e){autosave_request(e)});
85
68
  $('#article_form').submit(function(e){save_article_tags()});
86
69
  $('#article_form').each(function(e){tag_manager()});
87
-
88
- // DatePickers
89
- $('.datepicker').each(function() {
90
- $(this).datepicker($.datepicker.regional[this.dataset.locale]);
91
- });
92
-
93
- // Date time picker (not related to date picker at all!)
94
- $( "#article_published_at" ).datetimepicker();
70
+ $('#checkall').click(function(e){check_all(e.target)});
95
71
 
96
72
  // DropDown
97
73
  $(".dropdown-toggle").dropdown();
@@ -1,5 +1,10 @@
1
1
  // Show and hide spinners on Ajax requests.
2
2
  $(document).ready(function(){
3
- $('form.spinnable').on('ajax:before', function(evt, xhr, status){ $('#spinner').show();})
4
- $('form.spinnable').on('ajax:complete', function(evt, xhr, status){ $('#spinner').hide();})
3
+ $('#spinner').hide().removeClass("hidden");
4
+ $('form.spinnable').on('ajax:before', function(evt, xhr, status){
5
+ $('#spinner').show();
6
+ });
7
+ $('form.spinnable').on('ajax:complete', function(evt, xhr, status){
8
+ $('#spinner').hide();
9
+ });
5
10
  });
@@ -1,7 +1,7 @@
1
1
  /* General */
2
2
 
3
3
  body {
4
- padding-top: 40px;
4
+ padding-top: 60px;
5
5
  }
6
6
 
7
7
  footer {
@@ -7,3 +7,46 @@
7
7
  border-bottom: #eee 1px solid;
8
8
  font-size: 0.9em;
9
9
  }
10
+
11
+ .markup-help-popup {
12
+ padding: 0;
13
+ }
14
+
15
+ .markup-help-popup > div {
16
+ padding: 1em;
17
+ }
18
+
19
+ .markup-help-popup-close {
20
+ float: right;
21
+ cursor: pointer;
22
+ }
23
+
24
+ .admintools {
25
+ display: none;
26
+ }
27
+
28
+ .admin-tools-reveal:hover .admintools {
29
+ display: block;
30
+ }
31
+
32
+ .tag-sidebar-tag-cloud {
33
+ overflow: hidden;
34
+ }
35
+
36
+ .tag-sidebar-tag-67 { font-size: 0.67em; }
37
+ .tag-sidebar-tag-75 { font-size: 0.75em; }
38
+ .tag-sidebar-tag-83 { font-size: 0.83em; }
39
+ .tag-sidebar-tag-91 { font-size: 0.91em; }
40
+ .tag-sidebar-tag-100 { font-size: 1em; }
41
+ .tag-sidebar-tag-112 { font-size: 1.12em; }
42
+ .tag-sidebar-tag-125 { font-size: 1.25em; }
43
+ .tag-sidebar-tag-137 { font-size: 1.37em; }
44
+ .tag-sidebar-tag-150 { font-size: 1.50em; }
45
+ .tag-sidebar-tag-162 { font-size: 1.62em; }
46
+ .tag-sidebar-tag-175 { font-size: 1.75em; }
47
+ .tag-sidebar-tag-187 { font-size: 1.87em; }
48
+ .tag-sidebar-tag-200 { font-size: 2em; }
49
+
50
+ .hidden {
51
+ display: none;
52
+ }
@@ -3,7 +3,6 @@
3
3
  *= require jquery-ui
4
4
  *= require tagmanager
5
5
  *= require sidebar_admin
6
- *= require datetimepicker
7
6
  */
8
7
  // "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables"
9
8
  @import "bootstrap-sprockets";
@@ -123,9 +123,9 @@ class Admin::ArticlesController < Admin::BaseController
123
123
  if @article.save
124
124
  flash[:success] = I18n.t("admin.articles.autosave.success")
125
125
  @must_update_calendar =
126
- (params[:article][:published_at] and
127
- params[:article][:published_at].to_time.to_i < Time.zone.now.to_time.to_i and
128
- @article.parent_id.nil?)
126
+ params[:article][:published_at] and
127
+ params[:article][:published_at].to_time.to_i < Time.zone.now.to_time.to_i and
128
+ @article.parent_id.nil?
129
129
  respond_to do |format|
130
130
  format.js
131
131
  end
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Admin::DashboardController < Admin::BaseController
4
- require "open-uri"
5
- require "time"
6
- require "rexml/document"
7
-
8
4
  def index
9
5
  today = Time.zone.now.strftime("%Y-%m-%d 00:00")
10
6
 
@@ -1,22 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "open-uri"
4
- require "time"
5
- require "rexml/document"
6
-
7
3
  class Admin::ThemesController < Admin::BaseController
8
4
  def index
9
5
  @themes = Theme.find_all
10
- @themes.each do |theme|
11
- # TODO: Move to Theme
12
- theme.description_html = TextFilter.none.filter_text(theme.description)
13
- end
14
6
  @active = this_blog.current_theme
15
7
  end
16
8
 
17
9
  def preview
18
10
  theme = Theme.find(params[:theme])
19
- send_file File.join(theme.path, "preview.png"),
11
+ send_file theme.theme_file("preview.png"),
20
12
  type: "image/png", disposition: "inline", stream: false
21
13
  end
22
14
 
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ArticlesController < ContentController
4
+ include ActionView::Helpers::SanitizeHelper
5
+
4
6
  before_action :login_required, only: [:preview, :preview_page]
5
7
  before_action :verify_config
6
8
  before_action :auto_discovery_feed, only: [:show, :index]
@@ -127,7 +129,7 @@ class ArticlesController < ContentController
127
129
  def markup_help
128
130
  filter = TextFilter.make_filter(params[:id])
129
131
  if filter
130
- render html: filter.commenthelp
132
+ render html: sanitize(filter.commenthelp)
131
133
  else
132
134
  render plain: "Unknown filter"
133
135
  end
@@ -32,7 +32,7 @@ class CommentsController < BaseController
32
32
 
33
33
  def recaptcha_ok_for?(comment)
34
34
  use_recaptcha = comment.blog.use_recaptcha
35
- ((use_recaptcha && verify_recaptcha(model: comment)) || !use_recaptcha)
35
+ (use_recaptcha && verify_recaptcha(model: comment)) || !use_recaptcha
36
36
  end
37
37
 
38
38
  def new_comment_defaults
@@ -16,7 +16,7 @@ module Admin::FeedbackHelper
16
16
  change_status(item, context),
17
17
  button_to_edit_comment(item),
18
18
  button_to_delete_comment(item),
19
- button_to_conversation(item),
19
+ button_to_conversation(item)
20
20
  ], " "
21
21
  end
22
22
 
@@ -71,21 +71,29 @@ module BaseHelper
71
71
 
72
72
  def markup_help_popup(markup, text)
73
73
  if markup && markup.commenthelp.size > 1
74
- link_to(text,
75
- url_for(controller: "articles", action: "markup_help", id: markup.name),
76
- onclick: "return popup(this, 'Publify Markup Help')")
74
+ modal = tag.dialog id: "this_markup_help_popup_dialog", class: "markup-help-popup" do
75
+ tag.div do
76
+ close_div = tag.div tag.span("\u2a09", class: "markup-help-popup-close")
77
+ content = tag.div class: "content-target"
78
+ safe_join [close_div, content]
79
+ end
80
+ end
81
+
82
+ url = url_for(controller: "articles", action: "markup_help", id: markup.name)
83
+
84
+ link = link_to(text, "#", class: "markup-help-popup-link",
85
+ data: { target: "this_markup_help_popup_dialog",
86
+ url: url })
87
+
88
+ safe_join [modal, link]
77
89
  else
78
90
  ""
79
91
  end
80
92
  end
81
93
 
82
- def onhover_show_admin_tools(type, id = nil)
83
- admin_id = "#admin_#{[type, id].compact.join("_")}"
84
- tag = []
85
- tag << %{ onmouseover="if (getCookie('publify_user_profile') == 'admin')\
86
- { $('#{admin_id}').show(); }" }
87
- tag << %{ onmouseout="$('#{admin_id}').hide();" }
88
- safe_join(tag, " ")
94
+ # This method's original implementation was broken. Now it does nothing.
95
+ def onhover_show_admin_tools(_type, _id = nil)
96
+ ""
89
97
  end
90
98
 
91
99
  def feed_title
@@ -190,7 +198,7 @@ module BaseHelper
190
198
  end
191
199
 
192
200
  def stop_index_robots?(blog)
193
- stop = (params[:year].present? || params[:page].present?)
201
+ stop = params[:year].present? || params[:page].present?
194
202
  stop = blog.unindex_tags if controller_name == "tags"
195
203
  stop = blog.unindex_categories if controller_name == "categories"
196
204
  stop
@@ -216,7 +224,7 @@ module BaseHelper
216
224
  elsif !@article.nil?
217
225
  @article.feed_url(type)
218
226
  elsif !@auto_discovery_url_atom.nil?
219
- instance_variable_get("@auto_discovery_url_#{type}")
227
+ instance_variable_get(:"@auto_discovery_url_#{type}")
220
228
  end
221
229
  end
222
230
 
@@ -36,7 +36,7 @@ class ArchivesSidebar < Sidebar
36
36
  name: I18n.l(Date.new(year, month), format: "%B %Y"),
37
37
  month: month,
38
38
  year: year,
39
- article_count: entry.count,
39
+ article_count: entry.count
40
40
  }
41
41
  end
42
42
  end
@@ -25,10 +25,15 @@ class Content < ApplicationRecord
25
25
  scope :drafts, -> { where(state: "draft").order("created_at DESC") }
26
26
  scope :no_draft, -> { where.not(state: "draft").order("published_at DESC") }
27
27
  scope :searchstring, lambda { |search_string|
28
+ result = where(state: "published")
29
+
28
30
  tokens = search_string.split(" ").map { |c| "%#{c.downcase}%" }
29
- matcher = "(LOWER(body) LIKE ? OR LOWER(extended) LIKE ? OR LOWER(title) LIKE ?)"
30
- template = "state = ? AND #{([matcher] * tokens.size).join(" AND ")}"
31
- where(template, "published", *tokens.map { |token| [token] * 3 }.flatten)
31
+ tokens.each do |token|
32
+ result = result
33
+ .where("(LOWER(body) LIKE ? OR LOWER(extended) LIKE ? OR LOWER(title) LIKE ?)",
34
+ token, token, token)
35
+ end
36
+ result
32
37
  }
33
38
 
34
39
  scope :published_at_like, lambda { |date_at|
@@ -17,8 +17,8 @@ class Redirect < ApplicationRecord
17
17
  return path if %r{^(https?)://([^/]*)(.*)}.match?(path)
18
18
 
19
19
  url_root = blog.root_path
20
- unless url_root.nil? || path[0, url_root.length] == url_root
21
- path = File.join(url_root, path)
20
+ if url_root.length == 0 || path[0, url_root.length] != url_root
21
+ path = blog.url_for(path, only_path: true)
22
22
  end
23
23
  path
24
24
  end
@@ -18,12 +18,34 @@ class TagSidebar < Sidebar
18
18
  average = total.to_f / @tags.size
19
19
  @sizes = tags.reduce({}) do |h, tag|
20
20
  size = tag.content_counter.to_f / average
21
- h.merge tag => size.clamp(2.0 / 3.0, 2) * 100
21
+ h.merge tag => bucket(size)
22
22
  end
23
23
  end
24
24
 
25
- def font_multiplier
26
- 80
25
+ BUCKETS = [
26
+ 67,
27
+ 75,
28
+ 83,
29
+ 91,
30
+ 100,
31
+ 112,
32
+ 125,
33
+ 137,
34
+ 150,
35
+ 162,
36
+ 175,
37
+ 187,
38
+ 200
39
+ ].freeze
40
+
41
+ private
42
+
43
+ def bucket(size)
44
+ base_size = size.clamp(2.0 / 3.0, 2) * 100
45
+ BUCKETS.each do |sz|
46
+ return sz if sz >= base_size
47
+ end
48
+ BUCKETS.last
27
49
  end
28
50
  end
29
51
 
@@ -65,7 +65,7 @@ class TextFilter
65
65
  markdown,
66
66
  smartypants,
67
67
  markdown_smartypants,
68
- none,
68
+ none
69
69
  ]
70
70
  end
71
71
 
@@ -30,7 +30,7 @@ class ResourceUploader < CarrierWave::Uploader::Base
30
30
  end
31
31
 
32
32
  def dynamic_resize_to_fit(size)
33
- resize_setting = model.blog.send("image_#{size}_size").to_i
33
+ resize_setting = model.blog.send(:"image_#{size}_size").to_i
34
34
 
35
35
  resize_to_fit(resize_setting, resize_setting)
36
36
  end
@@ -9,7 +9,7 @@
9
9
  <span id="preview_link">
10
10
  <%= link_to(t('.preview'), { controller: '/articles', action: 'preview', id: @article.id }, { target: 'new', class: 'btn btn-default' }) if @article.id %>
11
11
  </span>
12
- <input id="save_draft" type="submit" value="<%= t('.save_as_draft') %>" name="article[draft]" class="btn btn-default" />
12
+ <input id="save_draft" type="submit" value="<%= t('.save_as_draft') %>" name="article[draft]" class="btn btn-default">
13
13
  <!-- Button trigger modal -->
14
14
  <button class="btn btn-success" data-toggle="modal" type="button" data-target="#publishOptions">
15
15
  <%= controller.action_name == 'new' ? t('.publish') : t('.save') %>
@@ -144,7 +144,7 @@
144
144
  <%= toggle_element('publish') %>
145
145
  </p>
146
146
  <div id="publish" class="collapse">
147
- <%= text_field 'article', 'published_at' %>
147
+ <%= datetime_field 'article', 'published_at' %>
148
148
  <p>
149
149
  <span class="btn btn-mini btn-default">
150
150
  <%= toggle_element('publish', t('.ok')) %>
@@ -8,7 +8,7 @@
8
8
  <%= form_tag({ action: 'index' }, { method: :get, name: 'article', remote: true, class: 'form-inline spinnable', "data-update-success": 'articleList' }) do %>
9
9
 
10
10
  <% if params[:search] and params[:search]['state'] %>
11
- <input type="hidden" name="search[state]" value="<%= params[:search]['state'] %>" />
11
+ <input type="hidden" name="search[state]" value="<%= params[:search]['state'] %>">
12
12
  <% end %>
13
13
 
14
14
  <p>
@@ -20,7 +20,7 @@
20
20
  </p>
21
21
 
22
22
  <div class="panel panel-default">
23
- <div class="panel-heading">
23
+ <div class="panel-heading clearfix">
24
24
  <div class="pull-right">
25
25
  <div class="form-group">
26
26
  <%= select_tag('search[user_id]', options_from_collection_for_select(User.all, 'id', 'name'), prompt: t('.select_an_author'), class: 'form-control') %>
@@ -29,14 +29,13 @@
29
29
  <%= select_tag('search[published_at]', options_for_select(Article.publication_months), prompt: t('.publication_date'), class: 'form-control') %>
30
30
  </div>
31
31
  <div class="form-group">
32
- <input id="search" type="text" name="search[searchstring]" class="form-control" />
32
+ <input id="search" type="text" name="search[searchstring]" class="form-control" autocomplete="off">
33
33
  </div>
34
34
  <div class="form-group">
35
35
  <%= submit_tag(t('.search'), class: 'btn btn-success') %>
36
- <span id="spinner" style="display:none;"><%= image_tag('spinner.gif') %></span>
36
+ <span id="spinner" class="hidden"><%= image_tag('spinner.gif') %></span>
37
37
  </div>
38
38
  </div>
39
- <br style="clear: both" />
40
39
  </div>
41
40
  </div>
42
41
  <table class="table table-hover">
@@ -12,7 +12,7 @@
12
12
  <%= comment.html.strip_html.slice(0..300) %>
13
13
  </p>
14
14
  <%= button_to_conversation(comment) %>
15
- <hr />
15
+ <hr>
16
16
  </li>
17
17
  <% end %>
18
18
  <% end %>
@@ -16,7 +16,7 @@
16
16
  <%= display_date_and_time(post.created_at) %>
17
17
  </h5>
18
18
  <p><%= post.body&.strip_html&.slice(0, 300) %></p>
19
- <hr />
19
+ <hr>
20
20
  </li>
21
21
  <% end %>
22
22
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <td>
2
- <input class="feedback_check" type="checkbox" name="feedback_check[<%= comment.id %>]" />
2
+ <input class="feedback_check" type="checkbox" name="feedback_check[<%= comment.id %>]">
3
3
  </td>
4
4
  <td>
5
5
  <%= avatar_tag(email: comment.email, url: comment.url, size: 36, class: 'img-circle') %>
@@ -16,7 +16,7 @@
16
16
  <thead>
17
17
  <tr class='noborder'>
18
18
  <th>
19
- <input type="checkbox" name="checkall" id="checkall" onclick="check_all(this);" />
19
+ <input type="checkbox" name="checkall" id="checkall">
20
20
  </th>
21
21
  <th><%= t(".author") %></th>
22
22
  <th><%= t(".created_at") %></th>
@@ -50,7 +50,7 @@
50
50
  </div>
51
51
  <div class='row'>
52
52
  <div class='form-group col-md-12'>
53
- <hr />
53
+ <hr>
54
54
  <%= t('.action_or_other_html', first_action: link_to(t('.cancel'), action: 'index'), second_action: submit_tag(t('.save'), class: 'btn btn-primary')) %>
55
55
  </div>
56
56
  </div>
@@ -27,7 +27,7 @@
27
27
  <thead>
28
28
  <tr class='noborder'>
29
29
  <th>
30
- <input type="checkbox" name="checkall" id="checkall" onclick="check_all(this);" />
30
+ <input type="checkbox" name="checkall" id="checkall">
31
31
  </th>
32
32
  <th><%= t(".author") %></th>
33
33
  <th><%= t(".created_at") %></th>
@@ -52,4 +52,4 @@
52
52
  </table>
53
53
  <% end %>
54
54
 
55
- <br class='clear' />
55
+ <br class='clear'>
@@ -29,7 +29,7 @@
29
29
  <p><strong><%= t('.you_are_up_to_date') %></strong></p>
30
30
  </div>
31
31
  <% else %>
32
- <hr />
32
+ <hr>
33
33
  <%= submit_tag(t('.update_database_now'), class: 'btn btn-success') %>
34
34
  <small><%= t('.may_take_a_moment') %></small>
35
35
  <% end %>
@@ -25,11 +25,10 @@
25
25
  </div>
26
26
  <div class='form-group'>
27
27
  <label for='note_published_at'><%= t('.publish_at') %></label>
28
- <%= n.text_field :published_at, class: 'form-control datepicker',
29
- placeholder: t('.now'), data: { locale: I18n.locale } %>
28
+ <%= n.datetime_field :published_at, class: 'form-control' %>
30
29
  </div>
31
30
  <div class='form-group'>
32
- <hr />
31
+ <hr>
33
32
  <%= link_to(t('.cancel'), action: 'index') %>
34
33
  <%= t('.or') %>
35
34
  <%= submit_tag(t('.publish'), class: 'btn btn-success') %>
@@ -3,10 +3,10 @@
3
3
  <%= h(note.body.strip_html.slice(0..140)) %>
4
4
  </td>
5
5
  <td>
6
- <%= author_link(note) %><br />
6
+ <%= author_link(note) %><br>
7
7
  </td>
8
8
  <td>
9
- <%= l(note.published_at) %>
9
+ <%= l(note.published_at) if note.published_at %>
10
10
  </td>
11
11
  <td>
12
12
  <%= note.text_filter_name %>