From 883856d4afdfa9470e12669997c088548d7429a0 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 25 Jun 2020 15:54:06 -0500 Subject: [PATCH] simple form: refactor DText form fields to use SimpleForm. * Refactors DText form fields to use a custom SimpleForm input instead of manually generated html. This fixes it so that DText fields use the same markup as normal SimpleForm fields, which lets us apply browser maxlength validations to DText input fields. * Fixes autocomplete for @-mentions only working in comments and forum posts. Now @-mention autocomplete works in all DText fields, including dmails. Known bug: it applies in artist commentary fields when it shouldn't. --- app/helpers/application_helper.rb | 17 ++--------- .../src/javascripts/autocomplete.js.erb | 2 +- app/javascript/src/javascripts/dtext.js | 7 +++-- .../src/styles/common/simple_form.scss | 2 +- app/logical/dtext_input.rb | 30 +++++++++++++++++++ app/views/bulk_update_requests/_form.html.erb | 4 +-- app/views/comments/_form.html.erb | 4 +-- app/views/dmails/_form.html.erb | 4 +-- app/views/dtext/_form.html.erb | 19 ------------ .../forum_posts/partials/edit/_form.html.erb | 4 +-- .../forum_posts/partials/new/_form.html.erb | 4 +-- app/views/forum_topics/_form.html.erb | 4 +-- app/views/moderation_reports/_new.html.erb | 8 ++--- app/views/pools/edit.html.erb | 4 +-- app/views/pools/new.html.erb | 4 +-- app/views/post_appeals/_new.html.erb | 8 ++--- app/views/post_flags/_new.html.erb | 8 ++--- app/views/user_feedbacks/edit.html.erb | 4 +-- app/views/user_feedbacks/new.html.erb | 4 +-- app/views/wiki_pages/_form.html.erb | 4 +-- app/views/wiki_pages/new.html.erb | 4 +-- config/initializers/simple_form.rb | 3 ++ 22 files changed, 75 insertions(+), 77 deletions(-) create mode 100644 app/logical/dtext_input.rb delete mode 100644 app/views/dtext/_form.html.erb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 26a4a0b59..7c010de1d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -217,21 +217,8 @@ module ApplicationHelper tag.div(text, class: "prose", **options) end - def dtext_field(object, name, options = {}) - options[:name] ||= name.capitalize - options[:input_id] ||= "#{object}_#{name}" - options[:input_name] ||= "#{object}[#{name}]" - options[:value] ||= instance_variable_get("@#{object}").try(name) - options[:preview_id] ||= "dtext-preview" - options[:classes] ||= "" - options[:hint] ||= "" - options[:type] ||= "text" - - render "dtext/form", options - end - - def dtext_preview_button(object, name, input_id: "#{object}_#{name}", preview_id: "dtext-preview") - tag.input value: "Preview", type: "button", class: "dtext-preview-button", "data-input-id": input_id, "data-preview-id": preview_id + def dtext_preview_button(preview_field) + tag.input value: "Preview", type: "button", class: "dtext-preview-button", "data-preview-field": preview_field end def quick_search_form_for(attribute, url, name, autocomplete: nil, redirect: false, &block) diff --git a/app/javascript/src/javascripts/autocomplete.js.erb b/app/javascript/src/javascripts/autocomplete.js.erb index 49e9abee4..afe3a854a 100644 --- a/app/javascript/src/javascripts/autocomplete.js.erb +++ b/app/javascript/src/javascripts/autocomplete.js.erb @@ -38,7 +38,7 @@ Autocomplete.initialize_all = function() { }); this.initialize_tag_autocomplete(); - this.initialize_mention_autocomplete($(".autocomplete-mentions textarea")); + this.initialize_mention_autocomplete($("form div.input.dtext textarea")); this.initialize_fields($('[data-autocomplete="tag"]'), Autocomplete.tag_source); this.initialize_fields($('[data-autocomplete="artist"]'), Autocomplete.artist_source); this.initialize_fields($('[data-autocomplete="pool"]'), Autocomplete.pool_source); diff --git a/app/javascript/src/javascripts/dtext.js b/app/javascript/src/javascripts/dtext.js index 94d708f79..8b9edbb60 100644 --- a/app/javascript/src/javascripts/dtext.js +++ b/app/javascript/src/javascripts/dtext.js @@ -39,8 +39,11 @@ Dtext.call_edit = function(e, $button, $input, $preview) { Dtext.click_button = function(e) { var $button = $(e.target); - var $input = $("#" + $button.data("input-id")); - var $preview = $("#" + $button.data("preview-id")); + var $form = $button.parents("form"); + var fieldName = $button.data("preview-field"); + var $inputContainer = $form.find(`div.input.${fieldName} .dtext-previewable`); + var $input = $inputContainer.find("> input, > textarea"); + var $preview = $inputContainer.find("div.dtext-preview"); if ($button.val().match(/preview/i)) { Dtext.call_preview(e, $button, $input, $preview); diff --git a/app/javascript/src/styles/common/simple_form.scss b/app/javascript/src/styles/common/simple_form.scss index 9d39c3a05..2b1706df4 100644 --- a/app/javascript/src/styles/common/simple_form.scss +++ b/app/javascript/src/styles/common/simple_form.scss @@ -39,7 +39,7 @@ form.simple_form { padding-left: 1em; } - &.text { + &.text, &.dtext { .hint { padding-left: 0; display: block; diff --git a/app/logical/dtext_input.rb b/app/logical/dtext_input.rb new file mode 100644 index 000000000..a1910e933 --- /dev/null +++ b/app/logical/dtext_input.rb @@ -0,0 +1,30 @@ +# A custom SimpleForm input for DText fields. +# +# Usage: +# +# <%= f.input :body, as: :dtext %> +# <%= f.input :reason, as: :dtext, inline: true %> +# +# https://github.com/heartcombo/simple_form/wiki/Custom-inputs-examples +# https://github.com/heartcombo/simple_form/blob/master/lib/simple_form/inputs/string_input.rb +# https://github.com/heartcombo/simple_form/blob/master/lib/simple_form/inputs/text_input.rb + +class DtextInput < SimpleForm::Inputs::Base + enable :placeholder, :maxlength, :minlength + + def input(wrapper_options) + t = template + merged_input_options = merge_wrapper_options(input_html_options, wrapper_options) + + t.tag.div(class: "dtext-previewable") do + if options[:inline] + t.concat @builder.text_field(attribute_name, merged_input_options) + else + t.concat @builder.text_area(attribute_name, { rows: 20, cols: 30 }.merge(merged_input_options)) + end + + t.concat t.tag.div(id: "dtext-preview", class: "dtext-preview prose") + t.concat t.tag.span(t.link_to("Formatting help", t.dtext_help_path, remote: true, method: :get), class: "hint dtext-hint") + end + end +end diff --git a/app/views/bulk_update_requests/_form.html.erb b/app/views/bulk_update_requests/_form.html.erb index 8d48d16ea..acf886b59 100644 --- a/app/views/bulk_update_requests/_form.html.erb +++ b/app/views/bulk_update_requests/_form.html.erb @@ -24,7 +24,7 @@ <% if @bulk_update_request.new_record? %>
- <%= dtext_field "bulk_update_request", "reason", :name => "Reason" %> + <%= f.input :reason, as: :dtext %>
<% end %> @@ -44,5 +44,5 @@ <% end %> <%= f.submit value: "Submit" %> - <%= dtext_preview_button "bulk_update_request", "reason" %> + <%= dtext_preview_button "bulk_update_request_reason" %> <% end %> diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb index fbf255f5e..72f6185a6 100644 --- a/app/views/comments/_form.html.erb +++ b/app/views/comments/_form.html.erb @@ -4,9 +4,9 @@ <% if comment.new_record? %> <%= f.hidden_field :post_id %> <% end %> - <%= dtext_field "comment", "body", classes: "autocomplete-mentions", value: comment.body, input_id: "comment_body_for_#{comment.id}", preview_id: "dtext-preview-for-#{comment.id}", hint: link_to_wiki("Comment rules", "howto:comment").html_safe %> + <%= f.input :body, as: :dtext %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "comment", "body", :input_id => "comment_body_for_#{comment.id}", :preview_id => "dtext-preview-for-#{comment.id}" %> + <%= dtext_preview_button "comment_body" %> <% if comment.new_record? %> <%= f.input :do_not_bump_post, :label => "No bump" %> <% end %> diff --git a/app/views/dmails/_form.html.erb b/app/views/dmails/_form.html.erb index f3efb498c..2a5b2925d 100644 --- a/app/views/dmails/_form.html.erb +++ b/app/views/dmails/_form.html.erb @@ -1,7 +1,7 @@ <%= edit_form_for(dmail) do |f| %> <%= f.input :to_name, :label => "To", :input_html => { value: dmail.to.try(:name), data: { autocomplete: "user" } } %> <%= f.input :title, :as => :string %> - <%= dtext_field "dmail", "body" %> + <%= f.input :body, as: :dtext %> <%= f.button :submit, "Send", :data => { :disable_with => "Sending..." } %> - <%= dtext_preview_button "dmail", "body" %> + <%= dtext_preview_button "dmail_body" %> <% end %> diff --git a/app/views/dtext/_form.html.erb b/app/views/dtext/_form.html.erb deleted file mode 100644 index ef79e084e..000000000 --- a/app/views/dtext/_form.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -<%# name, input_id, input_name, preview_id, value, type %> -
- - -
- <% if type == "text" %> - - <% else %> - - <% end %> -
-
- - <%= link_to "Formatting help", dtext_help_path, remote: true, method: :get %>. - <% if hint.present? %> - <%= hint %>. - <% end %> - -
diff --git a/app/views/forum_posts/partials/edit/_form.html.erb b/app/views/forum_posts/partials/edit/_form.html.erb index 617219d23..3a1b641d7 100644 --- a/app/views/forum_posts/partials/edit/_form.html.erb +++ b/app/views/forum_posts/partials/edit/_form.html.erb @@ -1,8 +1,8 @@ <%= error_messages_for("forum_post") %> <%= edit_form_for(forum_post) do |f| %> - <%= dtext_field "forum_post", "body", :value => forum_post.body, :classes => "autocomplete-mentions", :input_id => "forum_post_body_for_#{forum_post.id}", :preview_id => "dtext-preview-for-#{forum_post.id}" %> + <%= f.input :body, as: :dtext %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "forum_post", "body", :input_id => "forum_post_body_for_#{forum_post.id}", :preview_id => "dtext-preview-for-#{forum_post.id}" %> + <%= dtext_preview_button "forum_post_body" %> <% end %> diff --git a/app/views/forum_posts/partials/new/_form.html.erb b/app/views/forum_posts/partials/new/_form.html.erb index 622d01056..cbfa63350 100644 --- a/app/views/forum_posts/partials/new/_form.html.erb +++ b/app/views/forum_posts/partials/new/_form.html.erb @@ -6,8 +6,8 @@ <% else %> <%= f.input :topic_id, :label => "Topic ID" %> <% end %> - <%= dtext_field "forum_post", "body", :classes => "autocomplete-mentions" %> + <%= f.input :body, as: :dtext %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "forum_post", "body" %> + <%= dtext_preview_button "forum_post_body" %> <% end %> diff --git a/app/views/forum_topics/_form.html.erb b/app/views/forum_topics/_form.html.erb index f4e78c493..468befdca 100644 --- a/app/views/forum_topics/_form.html.erb +++ b/app/views/forum_topics/_form.html.erb @@ -10,7 +10,7 @@ <%= f.simple_fields_for :original_post do |pf| %> - <%= dtext_field "forum_post", "body", :classes => "autocomplete-mentions", :input_name => "forum_topic[original_post_attributes][body]", :value => forum_topic.original_post.body, :input_id => "forum_post_body_for_#{forum_topic.original_post.id}", :preview_id => "dtext-preview-for-#{forum_topic.original_post.id}" %> + <%= pf.input :body, as: :dtext %> <% end %> <% if policy(forum_topic).moderate? %> @@ -20,6 +20,6 @@ <% end %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "forum_post", "body", :input_id => "forum_post_body_for_#{forum_topic.original_post.id}", :preview_id => "dtext-preview-for-#{forum_topic.original_post.id}" %> + <%= dtext_preview_button "forum_topic_original_post_body" %> <% end %> diff --git a/app/views/moderation_reports/_new.html.erb b/app/views/moderation_reports/_new.html.erb index 0af8a497c..f433ee805 100644 --- a/app/views/moderation_reports/_new.html.erb +++ b/app/views/moderation_reports/_new.html.erb @@ -1,12 +1,10 @@
<%= embed_wiki("help:report_notice") %> - <%# XXX dtext_field expects there to be a `moderation_report` instance variable. %> - <% @moderation_report = moderation_report %> - <%= edit_form_for(@moderation_report, format: :js, remote: true) do |f| %> + <%= edit_form_for(moderation_report, format: :js, remote: true) do |f| %> <%= f.hidden_field :model_type %> <%= f.hidden_field :model_id %> - <%= dtext_field "moderation_report", "reason", preview_id: "dtext-preview-for-moderation-report", type: "string" %> - <%= dtext_preview_button "moderation_report", "reason", preview_id: "dtext-preview-for-moderation-report" %> + <%= f.input :reason, as: :dtext, inline: true %> + <%= dtext_preview_button "moderation_report_reason" %> <% end %>
diff --git a/app/views/pools/edit.html.erb b/app/views/pools/edit.html.erb index 4202226de..2c2652d6a 100644 --- a/app/views/pools/edit.html.erb +++ b/app/views/pools/edit.html.erb @@ -6,11 +6,11 @@ <%= error_messages_for "pool" %> <%= f.input :name, :as => :string, :input_html => { :value => @pool.pretty_name } %> - <%= dtext_field "pool", "description" %> - <%= dtext_preview_button "pool", "description" %> + <%= f.input :description, as: :dtext %> <%= f.input :post_ids_string, as: :text, label: "Posts" %> <%= f.input :category, :collection => ["series", "collection"], :include_blank => false %> <%= f.button :submit %> + <%= dtext_preview_button "pool_description" %> <% end %> diff --git a/app/views/pools/new.html.erb b/app/views/pools/new.html.erb index 165ec4497..d2f595aee 100644 --- a/app/views/pools/new.html.erb +++ b/app/views/pools/new.html.erb @@ -6,11 +6,11 @@ <%= edit_form_for(@pool) do |f| %> <%= f.input :name, :as => :string, :required => true %> - <%= dtext_field "pool", "description" %> + <%= f.input :description, as: :dtext %> <%= f.input :post_ids_string, as: :text, label: "Posts" %> <%= f.input :category, :collection => ["series", "collection"], :include_blank => true, :selected => "", :required => true %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "pool", "description" %> + <%= dtext_preview_button "pool_description" %> <% end %> diff --git a/app/views/post_appeals/_new.html.erb b/app/views/post_appeals/_new.html.erb index c418a1b8e..8cee19acc 100644 --- a/app/views/post_appeals/_new.html.erb +++ b/app/views/post_appeals/_new.html.erb @@ -1,11 +1,9 @@
<%= embed_wiki("help:appeal_notice") %> - <%# XXX dtext_field expects there to be a `post_appeal` instance variable. %> - <% @post_appeal = post_appeal %> - <%= edit_form_for(@post_appeal, format: :js, remote: true) do |f| %> + <%= edit_form_for(post_appeal, format: :js, remote: true) do |f| %> <%= f.hidden_field :post_id %> - <%= dtext_field "post_appeal", "reason", preview_id: "dtext-preview-for-post-appeal", type: "string" %> - <%= dtext_preview_button "post_appeal", "reason", preview_id: "dtext-preview-for-post-appeal" %> + <%= f.input :reason, as: :dtext, inline: true %> + <%= dtext_preview_button "post_appeal_reason" %> <% end %>
diff --git a/app/views/post_flags/_new.html.erb b/app/views/post_flags/_new.html.erb index 00cc67449..1e2005ac3 100644 --- a/app/views/post_flags/_new.html.erb +++ b/app/views/post_flags/_new.html.erb @@ -1,11 +1,9 @@
<%= embed_wiki("help:flag_notice") %> - <%# XXX dtext_field expects there to be a `post_flag` instance variable. %> - <% @post_flag = post_flag %> - <%= edit_form_for(@post_flag, format: :js, remote: true) do |f| %> + <%= edit_form_for(post_flag, format: :js, remote: true) do |f| %> <%= f.hidden_field :post_id %> - <%= dtext_field "post_flag", "reason", preview_id: "dtext-preview-for-post-flag", type: "string" %> - <%= dtext_preview_button "post_flag", "reason", preview_id: "dtext-preview-for-post-flag" %> + <%= f.input :reason, as: :dtext, inline: true %> + <%= dtext_preview_button "post_flag_reason" %> <% end %>
diff --git a/app/views/user_feedbacks/edit.html.erb b/app/views/user_feedbacks/edit.html.erb index d7571c462..9758a573d 100644 --- a/app/views/user_feedbacks/edit.html.erb +++ b/app/views/user_feedbacks/edit.html.erb @@ -9,10 +9,10 @@ <%= edit_form_for(@user_feedback) do |f| %> <%= f.input :category, :collection => ["positive", "neutral", "negative"], :include_blank => false %> - <%= dtext_field "user_feedback", "body" %> + <%= f.input :body, as: :dtext %> <%= f.input :is_deleted, label: "Deleted" %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "user_feedback", "body" %> + <%= dtext_preview_button "user_feedback_body" %> <% end %> diff --git a/app/views/user_feedbacks/new.html.erb b/app/views/user_feedbacks/new.html.erb index 67a3d89d5..debad85a6 100644 --- a/app/views/user_feedbacks/new.html.erb +++ b/app/views/user_feedbacks/new.html.erb @@ -16,9 +16,9 @@ <%= edit_form_for(@user_feedback) do |f| %> <%= f.input :user_name, :label => "User", :input_html => { value: @user_feedback.user.try(:name), data: { autocomplete: "user" } } %> <%= f.input :category, :collection => ["positive", "neutral", "negative"], :include_blank => false %> - <%= dtext_field "user_feedback", "body" %> + <%= f.input :body, as: :dtext %> <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "user_feedback", "body" %> + <%= dtext_preview_button "user_feedback_body" %> <% end %> diff --git a/app/views/wiki_pages/_form.html.erb b/app/views/wiki_pages/_form.html.erb index bb0100e7d..8f5616dc7 100644 --- a/app/views/wiki_pages/_form.html.erb +++ b/app/views/wiki_pages/_form.html.erb @@ -5,7 +5,7 @@ <%= f.input :title, error: false, input_html: { data: { autocomplete: "tag" } }, hint: "Change to rename this wiki page. Update any wikis linking to this page first." %> <%= f.input :other_names_string, as: :text, input_html: { size: "30x1" }, label: "Other names (#{link_to_wiki "help", "help:translated_tags"})".html_safe, hint: "Names used for this tag on other sites such as Pixiv. Separate with spaces." %> - <%= dtext_field "wiki_page", "body" %> + <%= f.input :body, as: :dtext %> <% if policy(@wiki_page).can_edit_locked? %> <%= f.input :is_locked, label: "Locked", hint: "Locked wikis can only be edited by Builders." %> @@ -14,6 +14,6 @@ <%= f.input :is_deleted, label: "Deleted", hint: "Check to mark this wiki page as deleted." %> <%= f.submit "Submit" %> - <%= dtext_preview_button "wiki_page", "body" %> + <%= dtext_preview_button "wiki_page_body" %> <% end %> diff --git a/app/views/wiki_pages/new.html.erb b/app/views/wiki_pages/new.html.erb index 1449e530b..aa796d340 100644 --- a/app/views/wiki_pages/new.html.erb +++ b/app/views/wiki_pages/new.html.erb @@ -14,9 +14,9 @@ <%= edit_form_for(@wiki_page) do |f| %> <%= f.input :title, error: false, input_html: { data: { autocomplete: "tag" } } %> <%= f.input :other_names_string, as: :text, input_html: { size: "30x1" }, label: "Other names (#{link_to_wiki "help", "help:translated_tags"})".html_safe, hint: "Names used for this tag on other sites such as Pixiv. Separate with spaces." %> - <%= dtext_field "wiki_page", "body" %> + <%= f.input :body, as: :dtext %> <%= f.submit "Submit" %> - <%= dtext_preview_button "wiki_page", "body" %> + <%= dtext_preview_button "wiki_page_body" %> <% end %> <%= render "tag_relationships/alias_and_implication_list", tag: @wiki_page.tag %> diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 80eee625f..9fd871574 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -5,6 +5,9 @@ # See https://github.com/heartcombo/simple_form#custom-components to know # more about custom components. # Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f } + +require "dtext_input" + # # Use this setup block to configure all options available in SimpleForm. SimpleForm.setup do |config|