mirror of
https://github.com/discourse/discourse.git
synced 2025-06-01 09:08:10 +08:00
FEATURE: Better handling of quotation marks in site text search
It also matches 3 dots with the ellipsis symbol.
This commit is contained in:
@ -6,7 +6,8 @@ export default Ember.Component.extend({
|
|||||||
|
|
||||||
@on("didInsertElement")
|
@on("didInsertElement")
|
||||||
highlightTerm() {
|
highlightTerm() {
|
||||||
const term = this.get("term");
|
const term = this._searchTerm();
|
||||||
|
|
||||||
if (term) {
|
if (term) {
|
||||||
this.$(".site-text-id, .site-text-value").highlight(term, {
|
this.$(".site-text-id, .site-text-value").highlight(term, {
|
||||||
className: "text-highlight"
|
className: "text-highlight"
|
||||||
@ -19,6 +20,18 @@ export default Ember.Component.extend({
|
|||||||
this.send("edit");
|
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: {
|
actions: {
|
||||||
edit() {
|
edit() {
|
||||||
this.sendAction("editAction", this.get("siteText"));
|
this.sendAction("editAction", this.get("siteText"));
|
||||||
|
@ -18,6 +18,6 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#each siteTexts as |siteText|}}
|
{{#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}}
|
{{/each}}
|
||||||
{{/conditional-loading-spinner}}
|
{{/conditional-loading-spinner}}
|
||||||
|
@ -28,6 +28,10 @@ class Admin::SiteTextsController < Admin::AdminController
|
|||||||
results << record_for(k, v)
|
results << record_for(k, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless translations.empty?
|
||||||
|
extras[:regex] = I18n::Backend::DiscourseI18n.create_search_regexp(query, as_string: true)
|
||||||
|
end
|
||||||
|
|
||||||
results.sort! do |x, y|
|
results.sort! do |x, y|
|
||||||
if x[:value].casecmp(query) == 0
|
if x[:value].casecmp(query) == 0
|
||||||
-1
|
-1
|
||||||
|
@ -70,7 +70,7 @@ module I18n
|
|||||||
target = opts[:backend] || backend
|
target = opts[:backend] || backend
|
||||||
results = opts[:overridden] ? {} : target.search(config.locale, query)
|
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|
|
(overrides_by_locale(locale) || {}).each do |k, v|
|
||||||
results.delete(k)
|
results.delete(k)
|
||||||
results[k] = v if (k =~ regexp || v =~ regexp)
|
results[k] = v if (k =~ regexp || v =~ regexp)
|
||||||
|
@ -39,11 +39,22 @@ module I18n
|
|||||||
false
|
false
|
||||||
end
|
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)
|
def search(locale, query)
|
||||||
results = {}
|
results = {}
|
||||||
|
regexp = self.class.create_search_regexp(query)
|
||||||
|
|
||||||
fallbacks(locale).each do |fallback|
|
fallbacks(locale).each do |fallback|
|
||||||
find_results(/#{Regexp.escape(query)}/i, results, translations[fallback])
|
find_results(regexp, results, translations[fallback])
|
||||||
end
|
end
|
||||||
|
|
||||||
results
|
results
|
||||||
|
@ -33,17 +33,51 @@ RSpec.describe Admin::SiteTextsController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when logged in as amin" do
|
context "when logged in as admin" do
|
||||||
before do
|
before do
|
||||||
sign_in(admin)
|
sign_in(admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#index' do
|
describe '#index' do
|
||||||
it 'returns json' 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(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
|
end
|
||||||
|
|
||||||
|
it 'normalizes quotes during search' do
|
||||||
|
value = %q|“That’s a ‘magic’ sock.”|
|
||||||
|
put "/admin/customize/site_texts/title.json", params: { site_text: { value: value } }
|
||||||
|
|
||||||
|
[
|
||||||
|
%q|That's a 'magic' sock.|,
|
||||||
|
%q|That’s a ‘magic’ sock.|,
|
||||||
|
%q|“That's a 'magic' sock.”|,
|
||||||
|
%q|"That's a 'magic' sock."|,
|
||||||
|
%q|«That's a 'magic' sock.»|,
|
||||||
|
%q|„That’s 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
|
end
|
||||||
|
|
||||||
describe '#show' do
|
describe '#show' do
|
||||||
|
Reference in New Issue
Block a user