publify_core 10.0.1 → 10.0.2

Sign up to get free protection for your applications and to get access to all the features.
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 %>