diff options
Diffstat (limited to 'app')
37 files changed, 135 insertions, 70 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index f36a0c859..4d03a04b7 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -17,6 +17,8 @@ class AccountsController < ApplicationController respond_to do |format| format.html do expires_in 0, public: true unless user_signed_in? + + @rss_url = rss_url end format.rss do diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 32f1f9a5d..e79f7a43e 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -9,9 +9,9 @@ module Admin @form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button)) @form.save rescue ActionController::ParameterMissing - flash[:alert] = I18n.t('admin.email_domain_blocks.no_domain_block_selected') + flash[:alert] = I18n.t('admin.domain_blocks.no_domain_block_selected') rescue Mastodon::NotPermittedError - flash[:alert] = I18n.t('admin.domain_blocks.created_msg') + flash[:alert] = I18n.t('admin.domain_blocks.not_permitted') else redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg') end diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb index 593457b94..a0a43de19 100644 --- a/app/controllers/admin/email_domain_blocks_controller.rb +++ b/app/controllers/admin/email_domain_blocks_controller.rb @@ -19,7 +19,7 @@ module Admin rescue ActionController::ParameterMissing flash[:alert] = I18n.t('admin.email_domain_blocks.no_email_domain_block_selected') rescue Mastodon::NotPermittedError - flash[:alert] = I18n.t('admin.custom_emojis.not_permitted') + flash[:alert] = I18n.t('admin.email_domain_blocks.not_permitted') ensure redirect_to admin_email_domain_blocks_path end diff --git a/app/controllers/api/v1/followed_tags_controller.rb b/app/controllers/api/v1/followed_tags_controller.rb index f0dfd044c..eae2bdc01 100644 --- a/app/controllers/api/v1/followed_tags_controller.rb +++ b/app/controllers/api/v1/followed_tags_controller.rb @@ -3,11 +3,11 @@ class Api::V1::FollowedTagsController < Api::BaseController TAGS_LIMIT = 100 - before_action -> { doorkeeper_authorize! :follow, :read, :'read:follows' }, except: :show + before_action -> { doorkeeper_authorize! :follow, :read, :'read:follows' } before_action :require_user! before_action :set_results - after_action :insert_pagination_headers, only: :show + after_action :insert_pagination_headers def index render json: @results.map(&:tag), each_serializer: REST::TagSerializer, relationships: TagRelationshipsPresenter.new(@results.map(&:tag), current_user&.account_id) @@ -43,7 +43,7 @@ class Api::V1::FollowedTagsController < Api::BaseController end def records_continue? - @results.size == limit_param(TAG_LIMIT) + @results.size == limit_param(TAGS_LIMIT) end def pagination_params(core_params) diff --git a/app/controllers/api/v1/tags_controller.rb b/app/controllers/api/v1/tags_controller.rb index 32f71bdce..0966ee469 100644 --- a/app/controllers/api/v1/tags_controller.rb +++ b/app/controllers/api/v1/tags_controller.rb @@ -12,7 +12,7 @@ class Api::V1::TagsController < Api::BaseController end def follow - TagFollow.create!(tag: @tag, account: current_account, rate_limit: true) + TagFollow.first_or_create!(tag: @tag, account: current_account, rate_limit: true) render json: @tag, serializer: REST::TagSerializer end diff --git a/app/controllers/statuses_cleanup_controller.rb b/app/controllers/statuses_cleanup_controller.rb index 3d4f4af02..0e7bb835f 100644 --- a/app/controllers/statuses_cleanup_controller.rb +++ b/app/controllers/statuses_cleanup_controller.rb @@ -20,6 +20,10 @@ class StatusesCleanupController < ApplicationController # Do nothing end + def require_functional! + redirect_to edit_user_registration_path unless current_user.functional_or_moved? + end + private def set_pack diff --git a/app/javascript/flavours/glitch/features/emoji/emoji.js b/app/javascript/flavours/glitch/features/emoji/emoji.js index 50a399114..4f33200b6 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji.js +++ b/app/javascript/flavours/glitch/features/emoji/emoji.js @@ -19,8 +19,6 @@ const emojiFilename = (filename) => { return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; -const domParser = new DOMParser(); - const emojifyTextNode = (node, customEmojis) => { let str = node.textContent; @@ -39,7 +37,7 @@ const emojifyTextNode = (node, customEmojis) => { } } - let rend, replacement = ''; + let rend, replacement = null; if (i === str.length) { break; } else if (str[i] === ':') { @@ -51,7 +49,14 @@ const emojifyTextNode = (node, customEmojis) => { // if you want additional emoji handler, add statements below which set replacement and return true. if (shortname in customEmojis) { const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url; - replacement = `<img draggable="false" class="emojione custom-emoji" alt="${shortname}" title="${shortname}" src="${filename}" data-original="${customEmojis[shortname].url}" data-static="${customEmojis[shortname].static_url}" />`; + replacement = document.createElement('img'); + replacement.setAttribute('draggable', false); + replacement.setAttribute('class', 'emojione custom-emoji'); + replacement.setAttribute('alt', shortname); + replacement.setAttribute('title', shortname); + replacement.setAttribute('src', filename); + replacement.setAttribute('data-original', customEmojis[shortname].url); + replacement.setAttribute('data-static', customEmojis[shortname].static_url); return true; } return false; @@ -59,7 +64,12 @@ const emojifyTextNode = (node, customEmojis) => { } else if (!useSystemEmojiFont) { // matched to unicode emoji const { filename, shortCode } = unicodeMapping[match]; const title = shortCode ? `:${shortCode}:` : ''; - replacement = `<img draggable="false" class="emojione" alt="${match}" title="${title}" src="${assetHost}/emoji/${emojiFilename(filename)}.svg" />`; + replacement = document.createElement('img'); + replacement.setAttribute('draggable', false); + replacement.setAttribute('class', 'emojione'); + replacement.setAttribute('alt', match); + replacement.setAttribute('title', title); + replacement.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename)}.svg`); rend = i + match.length; // If the matched character was followed by VS15 (for selecting text presentation), skip it. if (str.codePointAt(rend) === 65038) { @@ -69,9 +79,8 @@ const emojifyTextNode = (node, customEmojis) => { fragment.append(document.createTextNode(str.slice(0, i))); if (replacement) { - fragment.append(domParser.parseFromString(replacement, 'text/html').documentElement.getElementsByTagName('img')[0]); + fragment.append(replacement); } - node.textContent = str.slice(0, i); str = str.slice(rend); } diff --git a/app/javascript/flavours/glitch/features/explore/index.js b/app/javascript/flavours/glitch/features/explore/index.js index 24fa26eec..ba435d7e3 100644 --- a/app/javascript/flavours/glitch/features/explore/index.js +++ b/app/javascript/flavours/glitch/features/explore/index.js @@ -24,6 +24,16 @@ const mapStateToProps = state => ({ isSearching: state.getIn(['search', 'submitted']) || !showTrends, }); +// Fix strange bug on Safari where <span> (rendered by FormattedMessage) disappears +// after clicking around Explore top bar (issue #20885). +// Removing width=100% from <a> also fixes it, as well as replacing <span> with <div> +// We're choosing to wrap span with div to keep the changes local only to this tool bar. +const WrapFormattedMessage = ({ children, ...props }) => <div><FormattedMessage {...props}>{children}</FormattedMessage></div>; +WrapFormattedMessage.propTypes = { + children: PropTypes.any, +}; + + export default @connect(mapStateToProps) @injectIntl class Explore extends React.PureComponent { @@ -47,7 +57,7 @@ class Explore extends React.PureComponent { this.column = c; } - render () { + render() { const { intl, multiColumn, isSearching } = this.props; const { signedIn } = this.context.identity; @@ -70,10 +80,10 @@ class Explore extends React.PureComponent { ) : ( <React.Fragment> <div className='account__section-headline'> - <NavLink exact to='/explore'><FormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink> - <NavLink exact to='/explore/tags'><FormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink> - <NavLink exact to='/explore/links'><FormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink> - {signedIn && <NavLink exact to='/explore/suggestions'><FormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>} + <NavLink exact to='/explore'><WrapFormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink> + <NavLink exact to='/explore/tags'><WrapFormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink> + <NavLink exact to='/explore/links'><WrapFormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink> + {signedIn && <NavLink exact to='/explore/suggestions'><WrapFormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>} </div> <Switch> diff --git a/app/javascript/flavours/glitch/features/ui/components/header.js b/app/javascript/flavours/glitch/features/ui/components/header.js index 6c2fb40ba..891f7fc07 100644 --- a/app/javascript/flavours/glitch/features/ui/components/header.js +++ b/app/javascript/flavours/glitch/features/ui/components/header.js @@ -36,7 +36,7 @@ class Header extends React.PureComponent { if (signedIn) { content = ( <> - {location.pathname !== '/publish' && <Link to='/publish' className='button'><FormattedMessage id='compose_form.publish' defaultMessage='Publish' /></Link>} + {location.pathname !== '/publish' && <Link to='/publish' className='button'><FormattedMessage id='compose_form.publish_form' defaultMessage='Publish' /></Link>} <Account /> </> ); diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js index 2f19aab7e..72a732e3b 100644 --- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js +++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js @@ -88,5 +88,10 @@ describe('emoji', () => { expect(emojify('💂♀️💂♂️')) .toEqual('<img draggable="false" class="emojione" alt="💂\u200D♀️" title=":female-guard:" src="/emoji/1f482-200d-2640-fe0f_border.svg"><img draggable="false" class="emojione" alt="💂\u200D♂️" title=":male-guard:" src="/emoji/1f482-200d-2642-fe0f_border.svg">'); }); + + it('keeps ordering as expected (issue fixed by PR 20677)', () => { + expect(emojify('<p>💕 <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>')) + .toEqual('<p><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg"> <a class="hashtag" href="https://example.com/tags/foo" rel="nofollow noopener noreferrer" target="_blank">#<span>foo</span></a> test: foo.</p>'); + }); }); }); diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index 52a8458fb..bc3dd8c60 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -19,8 +19,6 @@ const emojiFilename = (filename) => { return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; -const domParser = new DOMParser(); - const emojifyTextNode = (node, customEmojis) => { let str = node.textContent; @@ -39,7 +37,7 @@ const emojifyTextNode = (node, customEmojis) => { } } - let rend, replacement = ''; + let rend, replacement = null; if (i === str.length) { break; } else if (str[i] === ':') { @@ -51,7 +49,14 @@ const emojifyTextNode = (node, customEmojis) => { // if you want additional emoji handler, add statements below which set replacement and return true. if (shortname in customEmojis) { const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url; - replacement = `<img draggable="false" class="emojione custom-emoji" alt="${shortname}" title="${shortname}" src="${filename}" data-original="${customEmojis[shortname].url}" data-static="${customEmojis[shortname].static_url}" />`; + replacement = document.createElement('img'); + replacement.setAttribute('draggable', false); + replacement.setAttribute('class', 'emojione custom-emoji'); + replacement.setAttribute('alt', shortname); + replacement.setAttribute('title', shortname); + replacement.setAttribute('src', filename); + replacement.setAttribute('data-original', customEmojis[shortname].url); + replacement.setAttribute('data-static', customEmojis[shortname].static_url); return true; } return false; @@ -59,7 +64,12 @@ const emojifyTextNode = (node, customEmojis) => { } else { // matched to unicode emoji const { filename, shortCode } = unicodeMapping[match]; const title = shortCode ? `:${shortCode}:` : ''; - replacement = `<img draggable="false" class="emojione" alt="${match}" title="${title}" src="${assetHost}/emoji/${emojiFilename(filename)}.svg" />`; + replacement = document.createElement('img'); + replacement.setAttribute('draggable', false); + replacement.setAttribute('class', 'emojione'); + replacement.setAttribute('alt', match); + replacement.setAttribute('title', title); + replacement.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename)}.svg`); rend = i + match.length; // If the matched character was followed by VS15 (for selecting text presentation), skip it. if (str.codePointAt(rend) === 65038) { @@ -69,9 +79,8 @@ const emojifyTextNode = (node, customEmojis) => { fragment.append(document.createTextNode(str.slice(0, i))); if (replacement) { - fragment.append(domParser.parseFromString(replacement, 'text/html').documentElement.getElementsByTagName('img')[0]); + fragment.append(replacement); } - node.textContent = str.slice(0, i); str = str.slice(rend); } diff --git a/app/javascript/mastodon/features/explore/index.js b/app/javascript/mastodon/features/explore/index.js index 552def142..286170c9f 100644 --- a/app/javascript/mastodon/features/explore/index.js +++ b/app/javascript/mastodon/features/explore/index.js @@ -24,6 +24,16 @@ const mapStateToProps = state => ({ isSearching: state.getIn(['search', 'submitted']) || !showTrends, }); +// Fix strange bug on Safari where <span> (rendered by FormattedMessage) disappears +// after clicking around Explore top bar (issue #20885). +// Removing width=100% from <a> also fixes it, as well as replacing <span> with <div> +// We're choosing to wrap span with div to keep the changes local only to this tool bar. +const WrapFormattedMessage = ({ children, ...props }) => <div><FormattedMessage {...props}>{children}</FormattedMessage></div>; +WrapFormattedMessage.propTypes = { + children: PropTypes.any, +}; + + export default @connect(mapStateToProps) @injectIntl class Explore extends React.PureComponent { @@ -47,7 +57,7 @@ class Explore extends React.PureComponent { this.column = c; } - render () { + render() { const { intl, multiColumn, isSearching } = this.props; const { signedIn } = this.context.identity; @@ -70,10 +80,10 @@ class Explore extends React.PureComponent { ) : ( <React.Fragment> <div className='account__section-headline'> - <NavLink exact to='/explore'><FormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink> - <NavLink exact to='/explore/tags'><FormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink> - <NavLink exact to='/explore/links'><FormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink> - {signedIn && <NavLink exact to='/explore/suggestions'><FormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>} + <NavLink exact to='/explore'><WrapFormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink> + <NavLink exact to='/explore/tags'><WrapFormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink> + <NavLink exact to='/explore/links'><WrapFormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink> + {signedIn && <NavLink exact to='/explore/suggestions'><WrapFormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>} </div> <Switch> diff --git a/app/javascript/mastodon/features/ui/components/header.js b/app/javascript/mastodon/features/ui/components/header.js index 4e109080e..bbb0ca1c6 100644 --- a/app/javascript/mastodon/features/ui/components/header.js +++ b/app/javascript/mastodon/features/ui/components/header.js @@ -35,7 +35,7 @@ class Header extends React.PureComponent { if (signedIn) { content = ( <> - {location.pathname !== '/publish' && <Link to='/publish' className='button'><FormattedMessage id='compose_form.publish' defaultMessage='Publish' /></Link>} + {location.pathname !== '/publish' && <Link to='/publish' className='button'><FormattedMessage id='compose_form.publish_form' defaultMessage='Publish' /></Link>} <Account /> </> ); diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index f7ea661d7..2b99ac502 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -3989,7 +3989,7 @@ "descriptors": [ { "defaultMessage": "Publish", - "id": "compose_form.publish" + "id": "compose_form.publish_form" }, { "defaultMessage": "Sign in", diff --git a/app/models/form/account_batch.rb b/app/models/form/account_batch.rb index 5cfcf7205..473622edf 100644 --- a/app/models/form/account_batch.rb +++ b/app/models/form/account_batch.rb @@ -115,6 +115,10 @@ class Form::AccountBatch authorize(account, :suspend?) log_action(:suspend, account) account.suspend!(origin: :local) + account.strikes.create!( + account: current_account, + action: :suspend + ) Admin::SuspensionWorker.perform_async(account.id) end diff --git a/app/models/user.rb b/app/models/user.rb index 0e8a87aea..0eb975dec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -237,6 +237,11 @@ class User < ApplicationRecord end def functional? + + functional_or_moved? + end + + def functional_or_moved? confirmed? && approved? && !disabled? && !account.suspended? && !account.memorial? end diff --git a/app/policies/email_domain_block_policy.rb b/app/policies/email_domain_block_policy.rb index 1a0ddfa87..0d167ea3e 100644 --- a/app/policies/email_domain_block_policy.rb +++ b/app/policies/email_domain_block_policy.rb @@ -5,6 +5,10 @@ class EmailDomainBlockPolicy < ApplicationPolicy role.can?(:manage_blocks) end + def show? + role.can?(:manage_blocks) + end + def create? role.can?(:manage_blocks) end diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb index 5604325be..48f3aa7a6 100644 --- a/app/serializers/manifest_serializer.rb +++ b/app/serializers/manifest_serializer.rb @@ -35,6 +35,7 @@ class ManifestSerializer < ActiveModel::Serializer src: full_pack_url("media/icons/android-chrome-#{size}x#{size}.png"), sizes: "#{size}x#{size}", type: 'image/png', + purpose: 'any maskable', } end end diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb index 0a39d7f26..7496fe2d5 100644 --- a/app/services/verify_link_service.rb +++ b/app/services/verify_link_service.rb @@ -28,7 +28,7 @@ class VerifyLinkService < BaseService links = Nokogiri::HTML(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]') - if links.any? { |link| link['href'].downcase == @link_back.downcase } + if links.any? { |link| link['href']&.downcase == @link_back.downcase } true elsif links.empty? false @@ -38,6 +38,8 @@ class VerifyLinkService < BaseService end def link_redirects_back?(test_url) + return false if test_url.blank? + redirect_to_url = Request.new(:head, test_url, follow: false).perform do |res| res.headers['Location'] end diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml index 909d9ff81..3d0e6b1da 100644 --- a/app/views/application/_card.html.haml +++ b/app/views/application/_card.html.haml @@ -13,4 +13,4 @@ %strong.emojify.p-name= display_name(account, custom_emojify: true) %span = acct(account) - = fa_icon('lock', { :data => ({hidden: true} unless account.locked?)}) + = fa_icon('lock', { data: ({hidden: true} unless account.locked?)}) diff --git a/app/views/auth/challenges/new.html.haml b/app/views/auth/challenges/new.html.haml index ff4b7a506..4f21e4af6 100644 --- a/app/views/auth/challenges/new.html.haml +++ b/app/views/auth/challenges/new.html.haml @@ -5,7 +5,7 @@ = f.input :return_to, as: :hidden .field-group - = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password', :autofocus => true }, label: t('challenge.prompt'), required: true + = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password', autofocus: true }, label: t('challenge.prompt'), required: true .actions = f.button :button, t('challenge.confirm'), type: :submit diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml index 4a1bedaa4..a294d3cb5 100644 --- a/app/views/auth/confirmations/new.html.haml +++ b/app/views/auth/confirmations/new.html.haml @@ -5,7 +5,7 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false .actions = f.button :button, t('auth.resend_confirmation'), type: :submit diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml index c7dbebe75..b95a9b676 100644 --- a/app/views/auth/passwords/edit.html.haml +++ b/app/views/auth/passwords/edit.html.haml @@ -8,9 +8,9 @@ = f.input :reset_password_token, as: :hidden .fields-group - = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, required: true + = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, required: true .fields-group - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'new-password' }, required: true + = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, required: true .actions = f.button :button, t('auth.set_new_password'), type: :submit diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml index bae5b24ba..10ad108ea 100644 --- a/app/views/auth/passwords/new.html.haml +++ b/app/views/auth/passwords/new.html.haml @@ -5,7 +5,7 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false .actions = f.button :button, t('auth.reset_password'), type: :submit diff --git a/app/views/auth/registrations/_sessions.html.haml b/app/views/auth/registrations/_sessions.html.haml index 5d993f574..c094dfd25 100644 --- a/app/views/auth/registrations/_sessions.html.haml +++ b/app/views/auth/registrations/_sessions.html.haml @@ -18,7 +18,7 @@ %tr %td %span{ title: session.user_agent }< - = fa_icon "#{session_device_icon(session)} fw", 'aria-label' => session_device_icon(session) + = fa_icon "#{session_device_icon(session)} fw", 'aria-label': session_device_icon(session) = ' ' = t 'sessions.description', browser: t("sessions.browsers.#{session.browser}", default: "#{session.browser}"), platform: t("sessions.platforms.#{session.platform}", default: "#{session.platform}") %td diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml index c642c2293..60fd1635e 100644 --- a/app/views/auth/registrations/edit.html.haml +++ b/app/views/auth/registrations/edit.html.haml @@ -11,15 +11,15 @@ - if !use_seamless_external_login? || resource.encrypted_password.present? .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :email, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended? + = f.input :email, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended? .fields-row__column.fields-group.fields-row__column-6 - = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'current-password' }, required: true, disabled: current_account.suspended?, hint: false + = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, required: true, disabled: current_account.suspended?, hint: false .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended? + = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended? .fields-row__column.fields-group.fields-row__column-6 - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'new-password' }, disabled: current_account.suspended? + = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, disabled: current_account.suspended? .actions = f.button :button, t('generic.save_changes'), type: :submit, class: 'button', disabled: current_account.suspended? diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index b1d52dd0c..0d8fd800f 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -17,13 +17,13 @@ .fields-group = f.simple_fields_for :account do |ff| - = ff.input :display_name, wrapper: :with_label, label: false, required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.display_name'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.display_name') } - = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false - = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'username' }, hint: false - = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'new-password', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: false - = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'new-password' }, hint: false - = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }, hint: false - = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' } + = ff.input :display_name, wrapper: :with_label, label: false, required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.display_name'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.display_name') } + = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false + = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false + = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false + = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false + = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, hint: false + = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' } - if approved_registrations? && !@invite.present? .fields-group diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml index 943618e39..304e3ab84 100644 --- a/app/views/auth/sessions/new.html.haml +++ b/app/views/auth/sessions/new.html.haml @@ -8,11 +8,11 @@ = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| .fields-group - if use_seamless_external_login? - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }, hint: false + = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, hint: false - else - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false .fields-group - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'current-password' }, hint: false + = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, hint: false .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml index 82f957527..094b502b1 100644 --- a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml +++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml @@ -5,7 +5,7 @@ %p.hint.authentication-hint= t('simple_form.hints.sessions.otp') .fields-group - = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'one-time-code' }, autofocus: true + = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, autofocus: true .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index c14fed56f..1a6611ceb 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -9,7 +9,7 @@ %p.hint= t('auth.setup.email_below_hint_html') .fields-group - = f.input :email, required: true, hint: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' } + = f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' } .actions = f.submit t('admin.accounts.change_email.label'), class: 'button' diff --git a/app/views/settings/deletes/show.html.haml b/app/views/settings/deletes/show.html.haml index c08ee85b0..2e9785c89 100644 --- a/app/views/settings/deletes/show.html.haml +++ b/app/views/settings/deletes/show.html.haml @@ -21,9 +21,9 @@ %hr.spacer/ - if current_user.encrypted_password.present? - = f.input :password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, hint: t('deletes.confirm_password') + = f.input :password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, hint: t('deletes.confirm_password') - else - = f.input :username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_username') + = f.input :username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, hint: t('deletes.confirm_username') .actions = f.button :button, t('deletes.proceed'), type: :submit, class: 'negative' diff --git a/app/views/settings/migration/redirects/new.html.haml b/app/views/settings/migration/redirects/new.html.haml index d7868e900..370087879 100644 --- a/app/views/settings/migration/redirects/new.html.haml +++ b/app/views/settings/migration/redirects/new.html.haml @@ -19,9 +19,9 @@ .fields-row__column.fields-group.fields-row__column-6 - if current_user.encrypted_password.present? - = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, required: true + = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, required: true - else - = f.input :current_username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, required: true + = f.input :current_username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, required: true .actions = f.button :button, t('migrations.set_redirect'), type: :submit, class: 'button button--destructive' diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml index 1ecf7302a..31f7d5e58 100644 --- a/app/views/settings/migrations/show.html.haml +++ b/app/views/settings/migrations/show.html.haml @@ -48,9 +48,9 @@ .fields-row__column.fields-group.fields-row__column-6 - if current_user.encrypted_password.present? - = f.input :current_password, wrapper: :with_block_label, input_html: { :autocomplete => 'current-password' }, required: true, disabled: on_cooldown? + = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password' }, required: true, disabled: on_cooldown? - else - = f.input :current_username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, required: true, disabled: on_cooldown? + = f.input :current_username, wrapper: :with_block_label, input_html: { autocomplete: 'off' }, required: true, disabled: on_cooldown? .actions = f.button :button, t('migrations.proceed_with_move'), type: :submit, class: 'button button--destructive', disabled: on_cooldown? diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index 671237db5..43830ac27 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -12,7 +12,7 @@ %samp.qr-alternative__code= @new_otp_secret.scan(/.{4}/).join(' ') .fields-group - = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true + = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { autocomplete: 'off' }, required: true .actions = f.button :button, t('otp_authentication.enable'), type: :submit diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml index c5a323ee5..5ec024757 100644 --- a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml +++ b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml @@ -8,7 +8,7 @@ %p.hint= t('webauthn_credentials.description_html') .fields_group - = f.input :nickname, wrapper: :with_block_label, hint: t('webauthn_credentials.nickname_hint'), input_html: { :autocomplete => 'off' }, required: true + = f.input :nickname, wrapper: :with_block_label, hint: t('webauthn_credentials.nickname_hint'), input_html: { autocomplete: 'off' }, required: true .actions = f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml index 619406d89..bf498e33d 100644 --- a/app/views/statuses/_detailed_status.html.haml +++ b/app/views/statuses/_detailed_status.html.haml @@ -15,12 +15,12 @@ = account_action_button(status.account) - .status__content.emojify{ :data => ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< + .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< - if status.spoiler_text? %p< %span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} %button.status__content__spoiler-link= t('statuses.show_more') - .e-content{ :lang => status.language } + .e-content{ lang: status.language } = prerender_custom_emojis(status_content_format(status), status.emojis) - if status.preloadable_poll diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml index 1e37b6cf3..ecbabf34c 100644 --- a/app/views/statuses/_simple_status.html.haml +++ b/app/views/statuses/_simple_status.html.haml @@ -27,12 +27,12 @@ %span.display-name__account = acct(status.account) = fa_icon('lock') if status.account.locked? - .status__content.emojify{ :data => ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< + .status__content.emojify{ data: ({ spoiler: current_account&.user&.setting_expand_spoilers ? 'expanded' : 'folded' } if status.spoiler_text?) }< - if status.spoiler_text? %p< %span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} %button.status__content__spoiler-link= t('statuses.show_more') - .e-content{ :lang => status.language }< + .e-content{ lang: status.language }< = prerender_custom_emojis(status_content_format(status), status.emojis) - if status.preloadable_poll |