From a058a77c079c90445173e27a70ed144557f4e57f Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 18 Feb 2018 16:09:17 -0600 Subject: [PATCH 1/4] ApplicationHelper#search_field: accept html attributes on field. Rewrite `search_field` to allow setting `data-*` attributes on the field. --- app/helpers/application_helper.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4042152fd..88a257664 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -163,14 +163,14 @@ module ApplicationHelper submit_tag("Preview", "data-input-id" => options[:input_id], "data-preview-id" => options[:preview_id]) end - def search_field(method, options = {}) - name = options[:label] || method.titleize - string = '
' - if options[:hint] - string += '

' + options[:hint] + '

' + def search_field(method, label: method.titleize, hint: nil, value: nil, **attributes) + content_tag(:div, class: "input") do + label_html = label_tag("search_#{method}", label) + input_html = text_field_tag(method, value, id: "search_#{method}", name: "search[#{method}]", **attributes) + hint_html = hint.present? ? content_tag(:p, hint, class: "hint") : "" + + label_html + input_html + hint_html end - string += '
' - string.html_safe end def body_attributes(user = CurrentUser.user) From 962842815dfedc30ff5d42a011aa91d24db0ecb6 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 18 Feb 2018 16:19:32 -0600 Subject: [PATCH 2/4] autocomplete: move artist/pool/wiki autocompletion to autocomplete.js. * Move all autocomplete code to autocomplete.js. * Mark autocompleted fields with `data-autocomplete=""` attributes, instead of hardcoding input field IDs in the javascript. --- app/assets/javascripts/artists.js | 42 -------- app/assets/javascripts/autocomplete.js.erb | 114 +++++++++++++++++++- app/assets/javascripts/pools.js | 41 ------- app/assets/javascripts/wiki_pages.js | 42 -------- app/views/artist_versions/search.html.erb | 2 +- app/views/artists/_quick_search.html.erb | 2 +- app/views/artists/_search.html.erb | 2 +- app/views/pool_elements/_new.html.erb | 2 +- app/views/pools/_quick_search.html.erb | 2 +- app/views/pools/_search.html.erb | 2 +- app/views/wiki_pages/_quick_search.html.erb | 2 +- app/views/wiki_pages/search.html.erb | 2 +- 12 files changed, 118 insertions(+), 137 deletions(-) diff --git a/app/assets/javascripts/artists.js b/app/assets/javascripts/artists.js index 2d89c5e21..878c764b3 100644 --- a/app/assets/javascripts/artists.js +++ b/app/assets/javascripts/artists.js @@ -5,10 +5,6 @@ if ($("#c-artists").length) { Danbooru.Artist.initialize_check_name(); Danbooru.Artist.initialize_shortcuts(); - - if (Danbooru.meta("enable-auto-complete") === "true") { - Danbooru.Artist.initialize_autocomplete(); - } } } @@ -43,46 +39,8 @@ }); } }; - - Danbooru.Artist.initialize_autocomplete = function() { - var $fields = $("#search_name,#quick_search_name"); - - $fields.autocomplete({ - minLength: 1, - source: function(req, resp) { - $.ajax({ - url: "/artists.json", - data: { - "search[name]": req.term + "*", - "search[is_active]": true, - "search[order]": "post_count", - "limit": 10 - }, - method: "get", - success: function(data) { - resp($.map(data, function(artist) { - return { - label: artist.name.replace(/_/g, " "), - value: artist.name - }; - })); - } - }); - } - }); - - var render_artist = function(list, artist) { - var $link = $("").addClass("tag-type-1").text(artist.label); - return $("
  • ").data("item.autocomplete", artist).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_artist; - }); - } })(); - $(document).ready(function() { Danbooru.Artist.initialize_all(); }); diff --git a/app/assets/javascripts/autocomplete.js.erb b/app/assets/javascripts/autocomplete.js.erb index f3b88c03d..f96da803f 100644 --- a/app/assets/javascripts/autocomplete.js.erb +++ b/app/assets/javascripts/autocomplete.js.erb @@ -13,7 +13,10 @@ if (Danbooru.meta("enable-auto-complete") === "true") { Danbooru.Autocomplete.enable_local_storage = this.test_local_storage(); this.initialize_tag_autocomplete(); - this.initialize_mention_autocomplete(); + this.initialize_mention_autocomplete($(".autocomplete-mentions textarea")); + this.initialize_artist_autocomplete($('[data-autocomplete="artist"]')); + this.initialize_pool_autocomplete($('[data-autocomplete="pool"]')); + this.initialize_wiki_autocomplete($('[data-autocomplete="wiki-page"]')); this.prune_local_storage(); } } @@ -43,9 +46,7 @@ } } - Danbooru.Autocomplete.initialize_mention_autocomplete = function() { - var $fields = $(".autocomplete-mentions textarea"); - + Danbooru.Autocomplete.initialize_mention_autocomplete = function($fields) { $fields.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab); $fields.autocomplete({ delay: 500, @@ -194,6 +195,111 @@ }); } + Danbooru.Autocomplete.initialize_artist_autocomplete = function($fields) { + $fields.autocomplete({ + minLength: 1, + source: function(req, resp) { + $.ajax({ + url: "/artists.json", + data: { + "search[name]": req.term + "*", + "search[is_active]": true, + "search[order]": "post_count", + "limit": 10 + }, + method: "get", + success: function(data) { + resp($.map(data, function(artist) { + return { + label: artist.name.replace(/_/g, " "), + value: artist.name + }; + })); + } + }); + } + }); + + var render_artist = function(list, artist) { + var $link = $("").addClass("tag-type-1").text(artist.label); + return $("
  • ").data("item.autocomplete", artist).append($link).appendTo(list); + }; + + $fields.each(function(i, field) { + $(field).data("uiAutocomplete")._renderItem = render_artist; + }); + }; + + Danbooru.Autocomplete.initialize_pool_autocomplete = function($fields) { + $fields.autocomplete({ + minLength: 1, + source: function(req, resp) { + $.ajax({ + url: "/pools.json", + data: { + "search[name_matches]": req.term, + "limit": 10 + }, + method: "get", + success: function(data) { + resp($.map(data, function(pool) { + return { + label: pool.name.replace(/_/g, " "), + value: pool.name, + category: pool.category + }; + })); + } + }); + } + }); + + var render_pool = function(list, pool) { + var $link = $("").addClass("pool-category-" + pool.category).text(pool.label); + return $("
  • ").data("item.autocomplete", pool).append($link).appendTo(list); + }; + + $fields.each(function(i, field) { + $(field).data("uiAutocomplete")._renderItem = render_pool; + }); + }; + + Danbooru.Autocomplete.initialize_wiki_autocomplete = function($fields) { + $fields.autocomplete({ + minLength: 1, + source: function(req, resp) { + $.ajax({ + url: "/wiki_pages.json", + data: { + "search[title]": req.term + "*", + "search[hide_deleted]": "Yes", + "search[order]": "post_count", + "limit": 10 + }, + method: "get", + success: function(data) { + resp($.map(data, function(wiki_page) { + return { + label: wiki_page.title.replace(/_/g, " "), + value: wiki_page.title, + category: wiki_page.category_name + }; + })); + } + }); + } + }); + + var render_wiki_page = function(list, wiki_page) { + var $link = $("").addClass("tag-type-" + wiki_page.category).text(wiki_page.label); + return $("
  • ").data("item.autocomplete", wiki_page).append($link).appendTo(list); + }; + + $fields.each(function(i, field) { + $(field).data("uiAutocomplete")._renderItem = render_wiki_page; + }); + }; + Danbooru.Autocomplete.normal_source = function(term, resp) { var key = "ac-" + term.replace(/\./g,'\uFFFF'); if (this.enable_local_storage) { diff --git a/app/assets/javascripts/pools.js b/app/assets/javascripts/pools.js index 5241af28d..7c69a6f01 100644 --- a/app/assets/javascripts/pools.js +++ b/app/assets/javascripts/pools.js @@ -4,9 +4,6 @@ Danbooru.Pool.initialize_all = function() { if ($("#c-pools").length) { this.initialize_shortcuts(); - if (Danbooru.meta("enable-auto-complete") === "true") { - this.initialize_autocomplete_for("#search_name_matches,#quick_search_name_matches"); - } } if ($("#c-posts").length && $("#a-show").length) { @@ -18,47 +15,9 @@ } } - Danbooru.Pool.initialize_autocomplete_for = function(selector) { - var $fields = $(selector); - - $fields.autocomplete({ - minLength: 1, - source: function(req, resp) { - $.ajax({ - url: "/pools.json", - data: { - "search[name_matches]": req.term, - "limit": 10 - }, - method: "get", - success: function(data) { - resp($.map(data, function(pool) { - return { - label: pool.name.replace(/_/g, " "), - value: pool.name, - category: pool.category - }; - })); - } - }); - } - }); - - var render_pool = function(list, pool) { - var $link = $("").addClass("pool-category-" + pool.category).text(pool.label); - return $("
  • ").data("item.autocomplete", pool).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_pool; - }); - } - Danbooru.Pool.initialize_add_to_pool_link = function() { $("#add-to-pool-dialog").dialog({autoOpen: false}); - this.initialize_autocomplete_for("#add-to-pool-dialog input[type=text]"); - $("#pool").click(function(e) { e.preventDefault(); $("#add-to-pool-dialog").dialog("open"); diff --git a/app/assets/javascripts/wiki_pages.js b/app/assets/javascripts/wiki_pages.js index b44a46ac2..e628d4ac6 100644 --- a/app/assets/javascripts/wiki_pages.js +++ b/app/assets/javascripts/wiki_pages.js @@ -3,52 +3,10 @@ Danbooru.WikiPage.initialize_all = function() { if ($("#c-wiki-pages,#c-wiki-page-versions").length) { - if (Danbooru.meta("enable-auto-complete") === "true") { - this.initialize_autocomplete(); - } - this.initialize_shortcuts(); } } - Danbooru.WikiPage.initialize_autocomplete = function() { - var $fields = $("#search_title,#quick_search_title"); - - $fields.autocomplete({ - minLength: 1, - source: function(req, resp) { - $.ajax({ - url: "/wiki_pages.json", - data: { - "search[title]": req.term + "*", - "search[hide_deleted]": "Yes", - "search[order]": "post_count", - "limit": 10 - }, - method: "get", - success: function(data) { - resp($.map(data, function(wiki_page) { - return { - label: wiki_page.title.replace(/_/g, " "), - value: wiki_page.title, - category: wiki_page.category_name - }; - })); - } - }); - } - }); - - var render_wiki_page = function(list, wiki_page) { - var $link = $("").addClass("tag-type-" + wiki_page.category).text(wiki_page.label); - return $("
  • ").data("item.autocomplete", wiki_page).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_wiki_page; - }); - } - Danbooru.WikiPage.initialize_shortcuts = function() { if ($("#a-show").length) { Danbooru.keydown("e", "edit", function(e) { diff --git a/app/views/artist_versions/search.html.erb b/app/views/artist_versions/search.html.erb index 681a7892f..e1de40803 100644 --- a/app/views/artist_versions/search.html.erb +++ b/app/views/artist_versions/search.html.erb @@ -5,7 +5,7 @@ diff --git a/app/views/artists/_quick_search.html.erb b/app/views/artists/_quick_search.html.erb index a84724e61..70bd174be 100644 --- a/app/views/artists/_quick_search.html.erb +++ b/app/views/artists/_quick_search.html.erb @@ -1,3 +1,3 @@ <%= form_tag(artists_path, :method => :get) do %> - <%= text_field "search", "name", :id => "quick_search_name", :placeholder => "Search artists" %> + <%= text_field "search", "name", id: "quick_search_name", placeholder: "Search artists", data: { autocomplete: "artist" } %> <% end %> diff --git a/app/views/artists/_search.html.erb b/app/views/artists/_search.html.erb index 17eb78526..021b4ec7b 100644 --- a/app/views/artists/_search.html.erb +++ b/app/views/artists/_search.html.erb @@ -1,5 +1,5 @@ <%= simple_form_for(:search, url: artists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> - <%= f.input :name, label: "Name", hint: "Use * for wildcard", input_html: { value: params[:search][:name] } %> + <%= f.input :name, label: "Name", hint: "Use * for wildcard", input_html: { value: params[:search][:name], data: { autocomplete: "artist" }} %> <%= f.input :url_matches, label: "URL", as: "string", input_html: { value: params[:search][:url_matches] } %> <%= f.input :creator_name, label: "Creator", input_html: { value: params[:search][:creator_name] } %> <%= f.input :is_active, label: "Active?", collection: [["Yes", true], ["No", false]], include_blank: true, selected: params[:search][:is_active] %> diff --git a/app/views/pool_elements/_new.html.erb b/app/views/pool_elements/_new.html.erb index bd9f5560d..b89299eb1 100644 --- a/app/views/pool_elements/_new.html.erb +++ b/app/views/pool_elements/_new.html.erb @@ -3,7 +3,7 @@
    - <%= text_field_tag "pool_name", "", :size => 20 %> + <%= text_field_tag "pool_name", "", :size => 20, :data => { autocomplete: "pool" } %> Search for a pool containing (<%= link_to "see full list", all_select_pool_element_path, :remote => true %>)
    diff --git a/app/views/pools/_quick_search.html.erb b/app/views/pools/_quick_search.html.erb index 40d8b1993..e53d8b366 100644 --- a/app/views/pools/_quick_search.html.erb +++ b/app/views/pools/_quick_search.html.erb @@ -1,3 +1,3 @@ <%= form_tag(pools_path, :method => :get) do %> - <%= text_field "search", "name_matches", :id => "quick_search_name_matches", :placeholder => "Search pools" %> + <%= text_field "search", "name_matches", id: "quick_search_name_matches", placeholder: "Search pools", data: { autocomplete: "pool" } %> <% end %> diff --git a/app/views/pools/_search.html.erb b/app/views/pools/_search.html.erb index a0c3f6a3e..b334c957f 100644 --- a/app/views/pools/_search.html.erb +++ b/app/views/pools/_search.html.erb @@ -5,7 +5,7 @@
    - <%= text_field "search", "name_matches", :value => params[:search][:name_matches] %> + <%= text_field "search", "name_matches", :value => params[:search][:name_matches], :data => { autocomplete: "pool" } %>
    diff --git a/app/views/wiki_pages/_quick_search.html.erb b/app/views/wiki_pages/_quick_search.html.erb index 051e01695..dad203ab9 100644 --- a/app/views/wiki_pages/_quick_search.html.erb +++ b/app/views/wiki_pages/_quick_search.html.erb @@ -1,3 +1,3 @@ <%= form_tag(wiki_pages_path, :method => :get) do %> - <%= text_field "search", "title", :id => "quick_search_title", :placeholder => "Search wiki pages" %> + <%= text_field "search", "title", id: "quick_search_title", placeholder: "Search wiki pages", data: { autocomplete: "wiki-page" } %> <% end %> diff --git a/app/views/wiki_pages/search.html.erb b/app/views/wiki_pages/search.html.erb index fee3fcee7..47b9ea058 100644 --- a/app/views/wiki_pages/search.html.erb +++ b/app/views/wiki_pages/search.html.erb @@ -1,7 +1,7 @@
  • ").data("item.autocomplete", artist).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_artist; - }); }; Danbooru.Autocomplete.initialize_pool_autocomplete = function($fields) { $fields.autocomplete({ minLength: 1, source: function(req, resp) { - $.ajax({ - url: "/pools.json", - data: { - "search[name_matches]": req.term, - "limit": 10 - }, - method: "get", - success: function(data) { - resp($.map(data, function(pool) { - return { - label: pool.name.replace(/_/g, " "), - value: pool.name, - category: pool.category - }; - })); - } - }); - } - }); - - var render_pool = function(list, pool) { - var $link = $("").addClass("pool-category-" + pool.category).text(pool.label); - return $("
  • ").data("item.autocomplete", pool).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_pool; + Danbooru.Autocomplete.pool_source(req.term, resp); + }, }); }; @@ -280,6 +248,7 @@ success: function(data) { resp($.map(data, function(wiki_page) { return { + type: "tag", label: wiki_page.title.replace(/_/g, " "), value: wiki_page.title, category: wiki_page.category_name @@ -289,15 +258,6 @@ }); } }); - - var render_wiki_page = function(list, wiki_page) { - var $link = $("").addClass("tag-type-" + wiki_page.category).text(wiki_page.label); - return $("
  • ").data("item.autocomplete", wiki_page).append($link).appendTo(list); - }; - - $fields.each(function(i, field) { - $(field).data("uiAutocomplete")._renderItem = render_wiki_page; - }); }; Danbooru.Autocomplete.normal_source = function(term, resp) { @@ -545,7 +505,7 @@ return { type: "pool", label: pool.name.replace(/_/g, " "), - value: metatag + ":" + pool.name, + value: (metatag ? (metatag + ":" + pool.name) : pool.name), post_count: pool.post_count, category: pool.category }; From d8e195d1688c140a3ecffe5c5c94e7c90aa12f05 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 18 Feb 2018 19:13:16 -0600 Subject: [PATCH 4/4] autocomplete: unify autocomplete options. Use a single set of default options so that autocomplete behaves the same way everywhere. --- app/assets/javascripts/autocomplete.js.erb | 28 ++++++++-------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/autocomplete.js.erb b/app/assets/javascripts/autocomplete.js.erb index 8b63b05c0..4d4be3b3e 100644 --- a/app/assets/javascripts/autocomplete.js.erb +++ b/app/assets/javascripts/autocomplete.js.erb @@ -12,6 +12,16 @@ Danbooru.Autocomplete.initialize_all = function() { if (Danbooru.meta("enable-auto-complete") === "true") { $.widget("ui.autocomplete", $.ui.autocomplete, { + options: { + delay: 100, + minLength: 1, + autoFocus: false, + focus: function() { return false; }, + }, + _create: function() { + this.element.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab); + this._super(); + }, _renderItem: Danbooru.Autocomplete.render_item, }); @@ -51,14 +61,7 @@ } Danbooru.Autocomplete.initialize_mention_autocomplete = function($fields) { - $fields.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab); $fields.autocomplete({ - delay: 500, - minLength: 2, - autoFocus: false, - focus: function() { - return false; - }, select: function(event, ui) { Danbooru.Autocomplete.insert_completion(this, ui.item.value); return false; @@ -96,13 +99,7 @@ var $fields_multiple = $('[data-autocomplete="tag-query"], [data-autocomplete="tag-edit"]'); var $fields_single = $('[data-autocomplete="tag"]'); - $fields_multiple.on("keydown.danbooru.autocomplete.tab", null, "tab", Danbooru.Autocomplete.on_tab); $fields_multiple.autocomplete({ - delay: 100, - autoFocus: false, - focus: function() { - return false; - }, select: function(event, ui) { // Prevent Danbooru.Upload.initialize_enter_on_tags from running if the // Enter key is used to select a tag from the autocomplete menu. @@ -187,8 +184,6 @@ }); $fields_single.autocomplete({ - minLength: 1, - autoFocus: true, source: function(req, resp) { Danbooru.Autocomplete.normal_source(req.term, resp); } @@ -197,7 +192,6 @@ Danbooru.Autocomplete.initialize_artist_autocomplete = function($fields) { $fields.autocomplete({ - minLength: 1, source: function(req, resp) { $.ajax({ url: "/artists.json", @@ -225,7 +219,6 @@ Danbooru.Autocomplete.initialize_pool_autocomplete = function($fields) { $fields.autocomplete({ - minLength: 1, source: function(req, resp) { Danbooru.Autocomplete.pool_source(req.term, resp); }, @@ -234,7 +227,6 @@ Danbooru.Autocomplete.initialize_wiki_autocomplete = function($fields) { $fields.autocomplete({ - minLength: 1, source: function(req, resp) { $.ajax({ url: "/wiki_pages.json",