Commit c43b393e authored by David Kim's avatar David Kim

Merge branch '247918-add-user-preference-to-turn-off-keystroke-formatting' into 'master'

Resolve "Add user preference to turn off keystroke formatting"

See merge request gitlab-org/gitlab!53079
parents cd255a09 482cd7d1
...@@ -283,9 +283,9 @@ function updateText({ textArea, tag, cursorOffset, blockTag, wrap, select, tagCo ...@@ -283,9 +283,9 @@ function updateText({ textArea, tag, cursorOffset, blockTag, wrap, select, tagCo
/* eslint-disable @gitlab/require-i18n-strings */ /* eslint-disable @gitlab/require-i18n-strings */
export function keypressNoteText(e) { export function keypressNoteText(e) {
if (this.selectionStart === this.selectionEnd) { if (!gon.markdown_surround_selection) return;
return; if (this.selectionStart === this.selectionEnd) return;
}
const keys = { const keys = {
'*': '**{text}**', // wraps with bold character '*': '**{text}**', // wraps with bold character
_: '_{text}_', // wraps with italic character _: '_{text}_', // wraps with italic character
......
...@@ -49,7 +49,8 @@ class Profiles::PreferencesController < Profiles::ApplicationController ...@@ -49,7 +49,8 @@ class Profiles::PreferencesController < Profiles::ApplicationController
:tab_width, :tab_width,
:sourcegraph_enabled, :sourcegraph_enabled,
:gitpod_enabled, :gitpod_enabled,
:render_whitespace_in_code :render_whitespace_in_code,
:markdown_surround_selection
] ]
end end
end end
......
...@@ -294,6 +294,7 @@ class User < ApplicationRecord ...@@ -294,6 +294,7 @@ class User < ApplicationRecord
:setup_for_company, :setup_for_company=, :setup_for_company, :setup_for_company=,
:render_whitespace_in_code, :render_whitespace_in_code=, :render_whitespace_in_code, :render_whitespace_in_code=,
:experience_level, :experience_level=, :experience_level, :experience_level=,
:markdown_surround_selection, :markdown_surround_selection=,
to: :user_preference to: :user_preference
delegate :path, to: :namespace, allow_nil: true, prefix: true delegate :path, to: :namespace, allow_nil: true, prefix: true
......
...@@ -27,6 +27,7 @@ class UserPreference < ApplicationRecord ...@@ -27,6 +27,7 @@ class UserPreference < ApplicationRecord
default_value_for :time_display_relative, value: true, allows_nil: false default_value_for :time_display_relative, value: true, allows_nil: false
default_value_for :time_format_in_24h, value: false, allows_nil: false default_value_for :time_format_in_24h, value: false, allows_nil: false
default_value_for :render_whitespace_in_code, value: false, allows_nil: false default_value_for :render_whitespace_in_code, value: false, allows_nil: false
default_value_for :markdown_surround_selection, value: true, allows_nil: false
class << self class << self
def notes_filters def notes_filters
......
...@@ -88,6 +88,15 @@ ...@@ -88,6 +88,15 @@
= s_("Preferences|Show one file at a time on merge request's Changes tab") = s_("Preferences|Show one file at a time on merge request's Changes tab")
.form-text.text-muted .form-text.text-muted
= s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.") = s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.")
.form-group.form-check
= f.check_box :markdown_surround_selection, class: 'form-check-input'
= f.label :markdown_surround_selection, class: 'form-check-label' do
= s_('Preferences|Surround text selection when typing quotes or brackets')
.form-text.text-muted
- supported_characters = %w(" ' ` \( [ { < * _).map {|char| "<code>#{char}</code>" }.join(', ')
- msg = "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: #{supported_characters}."
= s_(msg).html_safe
.form-group .form-group
= f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold' = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold'
= f.number_field :tab_width, = f.number_field :tab_width,
......
---
title: Add user preference to turn off selected text keystroke formatting
merge_request: 53079
author:
type: added
# frozen_string_literal: true
class AddMarkdownSurroundSelectionToUserPreferences < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
with_lock_retries do
add_column :user_preferences, :markdown_surround_selection, :boolean, default: true, null: false
end
end
def down
with_lock_retries do
remove_column :user_preferences, :markdown_surround_selection, :boolean
end
end
end
484751de711e873e0f0f22d5951e36bf60d4826ebc95afa45e4f6cdaa0e3c024
\ No newline at end of file
...@@ -17928,7 +17928,8 @@ CREATE TABLE user_preferences ( ...@@ -17928,7 +17928,8 @@ CREATE TABLE user_preferences (
tab_width smallint, tab_width smallint,
experience_level smallint, experience_level smallint,
view_diffs_file_by_file boolean DEFAULT false NOT NULL, view_diffs_file_by_file boolean DEFAULT false NOT NULL,
gitpod_enabled boolean DEFAULT false NOT NULL gitpod_enabled boolean DEFAULT false NOT NULL,
markdown_surround_selection boolean DEFAULT true NOT NULL
); );
CREATE SEQUENCE user_preferences_id_seq CREATE SEQUENCE user_preferences_id_seq
...@@ -7,13 +7,14 @@ module Gitlab ...@@ -7,13 +7,14 @@ module Gitlab
include WebpackHelper include WebpackHelper
def add_gon_variables def add_gon_variables
gon.api_version = 'v4' gon.api_version = 'v4'
gon.default_avatar_url = default_avatar_url gon.default_avatar_url = default_avatar_url
gon.max_file_size = Gitlab::CurrentSettings.max_attachment_size gon.max_file_size = Gitlab::CurrentSettings.max_attachment_size
gon.asset_host = ActionController::Base.asset_host gon.asset_host = ActionController::Base.asset_host
gon.webpack_public_path = webpack_public_path gon.webpack_public_path = webpack_public_path
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
gon.markdown_surround_selection = current_user&.markdown_surround_selection
if Gitlab.config.sentry.enabled if Gitlab.config.sentry.enabled
gon.sentry_dsn = Gitlab.config.sentry.clientside_dsn gon.sentry_dsn = Gitlab.config.sentry.clientside_dsn
......
...@@ -22615,6 +22615,9 @@ msgstr "" ...@@ -22615,6 +22615,9 @@ msgstr ""
msgid "Preferences|Sourcegraph" msgid "Preferences|Sourcegraph"
msgstr "" msgstr ""
msgid "Preferences|Surround text selection when typing quotes or brackets"
msgstr ""
msgid "Preferences|Syntax highlighting theme" msgid "Preferences|Syntax highlighting theme"
msgstr "" msgstr ""
......
...@@ -171,27 +171,40 @@ describe('init markdown', () => { ...@@ -171,27 +171,40 @@ describe('init markdown', () => {
expect(textArea.value).toEqual(text.replace(selected, `[${selected}](url)`)); expect(textArea.value).toEqual(text.replace(selected, `[${selected}](url)`));
}); });
it.each` describe('surrounds selected text with matching character', () => {
key | expected it.each`
${'['} | ${`[${selected}]`} key | expected
${'*'} | ${`**${selected}**`} ${'['} | ${`[${selected}]`}
${"'"} | ${`'${selected}'`} ${'*'} | ${`**${selected}**`}
${'_'} | ${`_${selected}_`} ${"'"} | ${`'${selected}'`}
${'`'} | ${`\`${selected}\``} ${'_'} | ${`_${selected}_`}
${'"'} | ${`"${selected}"`} ${'`'} | ${`\`${selected}\``}
${'{'} | ${`{${selected}}`} ${'"'} | ${`"${selected}"`}
${'('} | ${`(${selected})`} ${'{'} | ${`{${selected}}`}
${'<'} | ${`<${selected}>`} ${'('} | ${`(${selected})`}
`('generates $expected when $key is pressed', ({ key, expected }) => { ${'<'} | ${`<${selected}>`}
const event = new KeyboardEvent('keydown', { key }); `('generates $expected when $key is pressed', ({ key, expected }) => {
const event = new KeyboardEvent('keydown', { key });
textArea.addEventListener('keydown', keypressNoteText); gon.markdown_surround_selection = true;
textArea.dispatchEvent(event);
textArea.addEventListener('keydown', keypressNoteText);
expect(textArea.value).toEqual(text.replace(selected, expected)); textArea.dispatchEvent(event);
expect(textArea.value).toEqual(text.replace(selected, expected));
// cursor placement should be after selection + 2 tag lengths
expect(textArea.selectionStart).toBe(selectedIndex + expected.length);
});
// cursor placement should be after selection + 2 tag lengths it('does nothing if user preference disabled', () => {
expect(textArea.selectionStart).toBe(selectedIndex + expected.length); const event = new KeyboardEvent('keydown', { key: '[' });
gon.markdown_surround_selection = false;
textArea.addEventListener('keydown', keypressNoteText);
textArea.dispatchEvent(event);
expect(textArea.value).toEqual(text);
});
}); });
describe('and text to be selected', () => { describe('and text to be selected', () => {
......
...@@ -41,6 +41,9 @@ RSpec.describe User do ...@@ -41,6 +41,9 @@ RSpec.describe User do
it { is_expected.to delegate_method(:show_whitespace_in_diffs).to(:user_preference) } it { is_expected.to delegate_method(:show_whitespace_in_diffs).to(:user_preference) }
it { is_expected.to delegate_method(:show_whitespace_in_diffs=).to(:user_preference).with_arguments(:args) } it { is_expected.to delegate_method(:show_whitespace_in_diffs=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:view_diffs_file_by_file).to(:user_preference) }
it { is_expected.to delegate_method(:view_diffs_file_by_file=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:tab_width).to(:user_preference) } it { is_expected.to delegate_method(:tab_width).to(:user_preference) }
it { is_expected.to delegate_method(:tab_width=).to(:user_preference).with_arguments(:args) } it { is_expected.to delegate_method(:tab_width=).to(:user_preference).with_arguments(:args) }
...@@ -59,6 +62,9 @@ RSpec.describe User do ...@@ -59,6 +62,9 @@ RSpec.describe User do
it { is_expected.to delegate_method(:experience_level).to(:user_preference) } it { is_expected.to delegate_method(:experience_level).to(:user_preference) }
it { is_expected.to delegate_method(:experience_level=).to(:user_preference).with_arguments(:args) } it { is_expected.to delegate_method(:experience_level=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:markdown_surround_selection).to(:user_preference) }
it { is_expected.to delegate_method(:markdown_surround_selection=).to(:user_preference).with_arguments(:args) }
it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil } it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil } it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment