Change multiple mentions with same username to render with domain (#15718)
Fix #15506
This commit is contained in:
		
							parent
							
								
									b3e9094e14
								
							
						
					
					
						commit
						7183d9a113
					
				
					 3 changed files with 25 additions and 54 deletions
				
			
		|  | @ -85,7 +85,7 @@ class Formatter | |||
|   end | ||||
| 
 | ||||
|   def format_field(account, str, **options) | ||||
|     html = account.local? ? encode_and_link_urls(str, me: true) : reformat(str) | ||||
|     html = account.local? ? encode_and_link_urls(str, me: true, with_domain: true) : reformat(str) | ||||
|     html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify] | ||||
|     html.html_safe # rubocop:disable Rails/OutputSafety | ||||
|   end | ||||
|  | @ -122,7 +122,7 @@ class Formatter | |||
|       elsif entity[:hashtag] | ||||
|         link_to_hashtag(entity) | ||||
|       elsif entity[:screen_name] | ||||
|         link_to_mention(entity, accounts) | ||||
|         link_to_mention(entity, accounts, options) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | @ -264,22 +264,37 @@ class Formatter | |||
|     encode(entity[:url]) | ||||
|   end | ||||
| 
 | ||||
|   def link_to_mention(entity, linkable_accounts) | ||||
|   def link_to_mention(entity, linkable_accounts, options = {}) | ||||
|     acct = entity[:screen_name] | ||||
| 
 | ||||
|     return link_to_account(acct) unless linkable_accounts | ||||
|     return link_to_account(acct, options) unless linkable_accounts | ||||
| 
 | ||||
|     account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) } | ||||
|     account ? mention_html(account) : "@#{encode(acct)}" | ||||
|     same_username_hits = 0 | ||||
|     account = nil | ||||
|     username, domain = acct.split('@') | ||||
|     domain = nil if TagManager.instance.local_domain?(domain) | ||||
| 
 | ||||
|     linkable_accounts.each do |item| | ||||
|       same_username = item.username.casecmp(username).zero? | ||||
|       same_domain   = item.domain.nil? ? domain.nil? : item.domain.casecmp(domain).zero? | ||||
| 
 | ||||
|       if same_username && !same_domain | ||||
|         same_username_hits += 1 | ||||
|       elsif same_username && same_domain | ||||
|         account = item | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|   def link_to_account(acct) | ||||
|     account ? mention_html(account, with_domain: same_username_hits.positive? || options[:with_domain]) : "@#{encode(acct)}" | ||||
|   end | ||||
| 
 | ||||
|   def link_to_account(acct, options = {}) | ||||
|     username, domain = acct.split('@') | ||||
| 
 | ||||
|     domain  = nil if TagManager.instance.local_domain?(domain) | ||||
|     account = EntityCache.instance.mention(username, domain) | ||||
| 
 | ||||
|     account ? mention_html(account) : "@#{encode(acct)}" | ||||
|     account ? mention_html(account, with_domain: options[:with_domain]) : "@#{encode(acct)}" | ||||
|   end | ||||
| 
 | ||||
|   def link_to_hashtag(entity) | ||||
|  | @ -300,7 +315,7 @@ class Formatter | |||
|     "<a href=\"#{encode(tag_url(tag))}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{encode(tag)}</span></a>" | ||||
|   end | ||||
| 
 | ||||
|   def mention_html(account) | ||||
|     "<span class=\"h-card\"><a href=\"#{encode(ActivityPub::TagManager.instance.url_for(account))}\" class=\"u-url mention\">@<span>#{encode(account.username)}</span></a></span>" | ||||
|   def mention_html(account, with_domain: false) | ||||
|     "<span class=\"h-card\"><a href=\"#{encode(ActivityPub::TagManager.instance.url_for(account))}\" class=\"u-url mention\">@<span>#{encode(with_domain ? account.pretty_acct : account.username)}</span></a></span>" | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -22,14 +22,6 @@ class TagManager | |||
|     uri.normalized_host | ||||
|   end | ||||
| 
 | ||||
|   def same_acct?(canonical, needle) | ||||
|     return true if canonical.casecmp(needle).zero? | ||||
| 
 | ||||
|     username, domain = needle.split('@') | ||||
| 
 | ||||
|     local_domain?(domain) && canonical.casecmp(username).zero? | ||||
|   end | ||||
| 
 | ||||
|   def local_url?(url) | ||||
|     uri    = Addressable::URI.parse(url).normalize | ||||
|     domain = uri.host + (uri.port ? ":#{uri.port}" : '') | ||||
|  |  | |||
|  | @ -83,40 +83,4 @@ RSpec.describe TagManager do | |||
|       expect(TagManager.instance.local_url?('https://domainn.test/')).to eq false | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe '#same_acct?' do | ||||
|     # The following comparisons MUST be case-insensitive. | ||||
| 
 | ||||
|     it 'returns true if the needle has a correct username and domain for remote user' do | ||||
|       expect(TagManager.instance.same_acct?('username@domain.test', 'UsErNaMe@DoMaIn.Test')).to eq true | ||||
|     end | ||||
| 
 | ||||
|     it 'returns false if the needle is missing a domain for remote user' do | ||||
|       expect(TagManager.instance.same_acct?('username@domain.test', 'UsErNaMe')).to eq false | ||||
|     end | ||||
| 
 | ||||
|     it 'returns false if the needle has an incorrect domain for remote user' do | ||||
|       expect(TagManager.instance.same_acct?('username@domain.test', 'UsErNaMe@incorrect.test')).to eq false | ||||
|     end | ||||
| 
 | ||||
|     it 'returns false if the needle has an incorrect username for remote user' do | ||||
|       expect(TagManager.instance.same_acct?('username@domain.test', 'incorrect@DoMaIn.test')).to eq false | ||||
|     end | ||||
| 
 | ||||
|     it 'returns true if the needle has a correct username and domain for local user' do | ||||
|       expect(TagManager.instance.same_acct?('username', 'UsErNaMe@Cb6E6126.nGrOk.Io')).to eq true | ||||
|     end | ||||
| 
 | ||||
|     it 'returns true if the needle is missing a domain for local user' do | ||||
|       expect(TagManager.instance.same_acct?('username', 'UsErNaMe')).to eq true | ||||
|     end | ||||
| 
 | ||||
|     it 'returns false if the needle has an incorrect username for local user' do | ||||
|       expect(TagManager.instance.same_acct?('username', 'UsErNaM@Cb6E6126.nGrOk.Io')).to eq false | ||||
|     end | ||||
| 
 | ||||
|     it 'returns false if the needle has an incorrect domain for local user' do | ||||
|       expect(TagManager.instance.same_acct?('username', 'incorrect@Cb6E6126.nGrOk.Io')).to eq false | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue