mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-21 13:47:16 +00:00
Change hashtags at the end of the post to render out-of-band
This commit is contained in:
parent
26eaf058e2
commit
a16299b65a
|
@ -15,7 +15,7 @@ module FormattingHelper
|
||||||
module_function :extract_status_plain_text
|
module_function :extract_status_plain_text
|
||||||
|
|
||||||
def status_content_format(status)
|
def status_content_format(status)
|
||||||
html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []))
|
html_aware_format(status.text, status.local?, strip_rich_entities: true, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []))
|
||||||
end
|
end
|
||||||
|
|
||||||
def rss_status_content_format(status)
|
def rss_status_content_format(status)
|
||||||
|
|
|
@ -20,6 +20,7 @@ class TextFormatter
|
||||||
# @option options [Boolean] :multiline
|
# @option options [Boolean] :multiline
|
||||||
# @option options [Boolean] :with_domains
|
# @option options [Boolean] :with_domains
|
||||||
# @option options [Boolean] :with_rel_me
|
# @option options [Boolean] :with_rel_me
|
||||||
|
# @option options [Boolean] :strip_rich_entities
|
||||||
# @option options [Array<Account>] :preloaded_accounts
|
# @option options [Array<Account>] :preloaded_accounts
|
||||||
def initialize(text, options = {})
|
def initialize(text, options = {})
|
||||||
@text = text
|
@text = text
|
||||||
|
@ -75,16 +76,22 @@ class TextFormatter
|
||||||
entity[:indices].first
|
entity[:indices].first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
interrupt_text_at = detect_hashtag_block if options[:strip_rich_entities]
|
||||||
result = +''
|
result = +''
|
||||||
|
|
||||||
last_index = entities.reduce(0) do |index, entity|
|
last_index = entities.reduce(0) do |index, entity|
|
||||||
indices = entity[:indices]
|
indices = entity[:indices]
|
||||||
|
|
||||||
result << h(text[index...indices.first])
|
result << h(text[index...indices.first])
|
||||||
|
|
||||||
|
break interrupt_text_at if interrupt_text_at.present? && indices.first >= interrupt_text_at
|
||||||
|
|
||||||
result << yield(entity)
|
result << yield(entity)
|
||||||
|
|
||||||
indices.last
|
indices.last
|
||||||
end
|
end
|
||||||
|
|
||||||
result << h(text[last_index..])
|
result << h(text[last_index..]) unless interrupt_text_at.present? && last_index >= interrupt_text_at
|
||||||
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
@ -163,4 +170,38 @@ class TextFormatter
|
||||||
def preloaded_accounts?
|
def preloaded_accounts?
|
||||||
preloaded_accounts.present?
|
preloaded_accounts.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def detect_hashtag_block
|
||||||
|
block_begin = nil
|
||||||
|
block_end = nil
|
||||||
|
|
||||||
|
entities.map.with_index do |entity, i|
|
||||||
|
next unless entity[:hashtag]
|
||||||
|
|
||||||
|
next_entity = entities[i + 1]
|
||||||
|
|
||||||
|
if !next_entity.nil? && !next_entity[:hashtag]
|
||||||
|
block_begin = nil
|
||||||
|
block_end = nil
|
||||||
|
next
|
||||||
|
elsif next_entity.nil?
|
||||||
|
block_begin = entity[:indices].first if block_begin.nil?
|
||||||
|
block_end = entity[:indices].last
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
entity_end = entity[:indices].last
|
||||||
|
next_entity_start = next_entity[:indices].first
|
||||||
|
|
||||||
|
if next_entity_start == entity_end + 1
|
||||||
|
block_begin = entity[:indices].first if block_begin.nil?
|
||||||
|
block_end = entity_end
|
||||||
|
else
|
||||||
|
block_begin = nil
|
||||||
|
block_end = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
block_begin if block_begin.present? && block_end.present? && text[block_end..].blank? && text[block_begin - 1] == "\n"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,9 @@ require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe TextFormatter do
|
RSpec.describe TextFormatter do
|
||||||
describe '#to_s' do
|
describe '#to_s' do
|
||||||
subject { described_class.new(text, preloaded_accounts: preloaded_accounts).to_s }
|
subject { described_class.new(text, strip_rich_entities: strip_rich_entities, preloaded_accounts: preloaded_accounts).to_s }
|
||||||
|
|
||||||
|
let(:strip_rich_entities) { false }
|
||||||
let(:preloaded_accounts) { nil }
|
let(:preloaded_accounts) { nil }
|
||||||
|
|
||||||
context 'when given text containing plain text' do
|
context 'when given text containing plain text' do
|
||||||
|
@ -273,7 +274,7 @@ RSpec.describe TextFormatter do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when given text containing a hashtag' do
|
context 'when given text containing a hashtag' do
|
||||||
let(:text) { '#hashtag' }
|
let(:text) { 'foo #hashtag' }
|
||||||
|
|
||||||
it 'creates a hashtag link' do
|
it 'creates a hashtag link' do
|
||||||
expect(subject).to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
|
expect(subject).to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
|
||||||
|
@ -281,7 +282,7 @@ RSpec.describe TextFormatter do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when given text containing a hashtag with Unicode chars' do
|
context 'when given text containing a hashtag with Unicode chars' do
|
||||||
let(:text) { '#hashtagタグ' }
|
let(:text) { 'foo #hashtagタグ' }
|
||||||
|
|
||||||
it 'creates a hashtag link' do
|
it 'creates a hashtag link' do
|
||||||
expect(subject).to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#<span>hashtagタグ</span></a>'
|
expect(subject).to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#<span>hashtagタグ</span></a>'
|
||||||
|
@ -311,5 +312,33 @@ RSpec.describe TextFormatter do
|
||||||
expect(subject).to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"'
|
expect(subject).to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with strip_rich_entities option' do
|
||||||
|
let(:strip_rich_entities) { true }
|
||||||
|
|
||||||
|
context 'when a hashtag is in the middle of a sentence' do
|
||||||
|
let(:text) { 'Hello #foo world' }
|
||||||
|
|
||||||
|
it 'keeps the hashtag in place' do
|
||||||
|
expect(subject).to include 'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a hashtag starts a line but is followed by text' do
|
||||||
|
let(:text) { '#foo Hello world' }
|
||||||
|
|
||||||
|
it 'keeps the hashtag in place' do
|
||||||
|
expect(subject).to include 'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a hashtag is on the last line in the text' do
|
||||||
|
let(:text) { "Hello world\n#foo" }
|
||||||
|
|
||||||
|
it 'strips out the hashtag' do
|
||||||
|
expect(subject).to_not include 'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue