mirror of
https://github.com/mastodon/mastodon.git
synced 2025-05-12 04:31:11 +00:00

Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
CSS Linting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / Libvips tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.2) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
60 lines
1.5 KiB
Ruby
60 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class StatusLengthValidator < ActiveModel::Validator
|
|
MAX_CHARS = 500
|
|
URL_PLACEHOLDER_CHARS = 23
|
|
URL_PLACEHOLDER = 'x' * 23
|
|
|
|
def validate(status)
|
|
return unless status.local? && !status.reblog?
|
|
|
|
status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?(status)
|
|
end
|
|
|
|
private
|
|
|
|
def too_long?(status)
|
|
countable_length(combined_text(status)) > MAX_CHARS
|
|
end
|
|
|
|
def countable_length(str)
|
|
str.each_grapheme_cluster.size
|
|
end
|
|
|
|
def combined_text(status)
|
|
[status.spoiler_text, countable_text(status.text)].join
|
|
end
|
|
|
|
def countable_text(str)
|
|
return '' if str.blank?
|
|
|
|
# To ensure that we only give length concessions to entities that
|
|
# will be correctly parsed during formatting, we go through full
|
|
# entity extraction
|
|
|
|
entities = Extractor.remove_overlapping_entities(Extractor.extract_urls_with_indices(str, extract_url_without_protocol: false) + Extractor.extract_mentions_or_lists_with_indices(str))
|
|
|
|
rewrite_entities(str, entities) do |entity|
|
|
if entity[:url]
|
|
URL_PLACEHOLDER
|
|
elsif entity[:screen_name]
|
|
"@#{entity[:screen_name].split('@').first}"
|
|
end
|
|
end
|
|
end
|
|
|
|
def rewrite_entities(str, entities)
|
|
entities.sort_by! { |entity| entity[:indices].first }
|
|
result = +''
|
|
|
|
last_index = entities.reduce(0) do |index, entity|
|
|
result << str[index...entity[:indices].first]
|
|
result << yield(entity)
|
|
entity[:indices].last
|
|
end
|
|
|
|
result << str[last_index..]
|
|
result
|
|
end
|
|
end
|