FEATURE: Better handling of quotation marks in site text search

It also matches 3 dots with the ellipsis symbol.
This commit is contained in:
Gerhard Schlager 2018-11-10 01:17:07 +01:00
parent c7377e2f2d
commit 7c4d4331bc
6 changed files with 69 additions and 7 deletions

View File

@ -6,7 +6,8 @@ export default Ember.Component.extend({
@on("didInsertElement")
highlightTerm() {
const term = this.get("term");
const term = this._searchTerm();
if (term) {
this.$(".site-text-id, .site-text-value").highlight(term, {
className: "text-highlight"
@ -19,6 +20,18 @@ export default Ember.Component.extend({
this.send("edit");
},
_searchTerm() {
const regex = this.get("searchRegex");
const siteText = this.get("siteText");
if (regex && siteText) {
const matches = siteText.value.match(new RegExp(regex, "i"));
if (matches) return matches[0];
}
return this.get("term");
},
actions: {
edit() {
this.sendAction("editAction", this.get("siteText"));

View File

@ -18,6 +18,6 @@
{{/if}}
{{#each siteTexts as |siteText|}}
{{site-text-summary siteText=siteText editAction="edit" term=q}}
{{site-text-summary siteText=siteText editAction="edit" term=q searchRegex=siteTexts.extras.regex}}
{{/each}}
{{/conditional-loading-spinner}}

View File

@ -28,6 +28,10 @@ class Admin::SiteTextsController < Admin::AdminController
results << record_for(k, v)
end
unless translations.empty?
extras[:regex] = I18n::Backend::DiscourseI18n.create_search_regexp(query, as_string: true)
end
results.sort! do |x, y|
if x[:value].casecmp(query) == 0
-1

View File

@ -70,7 +70,7 @@ module I18n
target = opts[:backend] || backend
results = opts[:overridden] ? {} : target.search(config.locale, query)
regexp = /#{Regexp.escape(query)}/i
regexp = I18n::Backend::DiscourseI18n.create_search_regexp(query)
(overrides_by_locale(locale) || {}).each do |k, v|
results.delete(k)
results[k] = v if (k =~ regexp || v =~ regexp)

View File

@ -39,11 +39,22 @@ module I18n
false
end
def self.create_search_regexp(query, as_string: false)
regexp = Regexp.escape(query)
regexp.gsub!(/[']/, "[']")
regexp.gsub!(/["“”„«»]/, '["“”„«»]')
regexp.gsub!(/(?:\\\.\\\.\\\.|…)/, '(?:\.\.\.|…)')
as_string ? regexp : /#{regexp}/i
end
def search(locale, query)
results = {}
regexp = self.class.create_search_regexp(query)
fallbacks(locale).each do |fallback|
find_results(/#{Regexp.escape(query)}/i, results, translations[fallback])
find_results(regexp, results, translations[fallback])
end
results

View File

@ -33,17 +33,51 @@ RSpec.describe Admin::SiteTextsController do
end
end
context "when logged in as amin" do
context "when logged in as admin" do
before do
sign_in(admin)
end
describe '#index' do
it 'returns json' do
get "/admin/customize/site_texts.json", params: { q: 'title' }
get "/admin/customize/site_texts.json", params: { q: 'title' }
expect(response.status).to eq(200)
expect(::JSON.parse(response.body)).to be_present
expect(JSON.parse(response.body)['site_texts']).to include(include("id" => "title"))
end
it 'normalizes quotes during search' do
value = %q|“Thats a magic sock.”|
put "/admin/customize/site_texts/title.json", params: { site_text: { value: value } }
[
%q|That's a 'magic' sock.|,
%q|Thats a magic sock.|,
%q|“That's a 'magic' sock.”|,
%q|"That's a 'magic' sock."|,
%q|«That's a 'magic' sock.»|,
%q|„Thats a magic sock.“|
].each do |search_term|
get "/admin/customize/site_texts.json", params: { q: search_term }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)['site_texts']).to include(include("id" => "title", "value" => value))
end
end
it 'normalizes ellipsis' do
value = "Loading Discussion…"
put "/admin/customize/site_texts/embed.loading.json", params: { site_text: { value: value } }
[
"Loading Discussion",
"Loading Discussion...",
"Loading Discussion…"
].each do |search_term|
get "/admin/customize/site_texts.json", params: { q: search_term }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)['site_texts']).to include(include("id" => "embed.loading", "value" => value))
end
end
end
describe '#show' do