diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue index 1036b6552d1a5b53578f9984212fe8b8e57fc054..25c03496a7619e262113dc4dc63a72e3f624b1b2 100644 --- a/app/assets/javascripts/content_editor/components/content_editor.vue +++ b/app/assets/javascripts/content_editor/components/content_editor.vue @@ -193,9 +193,12 @@ export default { } }, focus() { + this.contentEditor.tiptapEditor.commands.focus(); + }, + onFocus() { this.focused = true; }, - blur() { + onBlur() { this.focused = false; }, notifyLoading() { @@ -230,8 +233,8 @@ export default { <div class="md-area gl-overflow-hidden"> <editor-state-observer @docUpdate="notifyChange" - @focus="focus" - @blur="blur" + @focus="onFocus" + @blur="onBlur" @keydown="$emit('keydown', $event)" /> <content-editor-alert /> diff --git a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue index 8b8247a5b2cb4b4dde38a0febb2c0c474e3e61be..493b329f1b101062be09e6e5ec271ab0b0ad0ddb 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue @@ -13,6 +13,22 @@ import { import MarkdownField from './field.vue'; import eventHub from './eventhub'; +async function sleep(t = 10) { + return new Promise((resolve) => { + setTimeout(resolve, t); + }); +} + +async function waitFor(getEl, interval = 10, timeout = 2000) { + if (timeout <= 0) return null; + + const el = getEl(); + if (el) return el; + + await sleep(interval); + return waitFor(getEl, timeout - interval); +} + export default { components: { LocalStorageSync, @@ -190,8 +206,15 @@ export default { this.$emit(editingMode); this.notifyEditingModeChange(editingMode); }, - notifyEditingModeChange(editingMode) { + async notifyEditingModeChange(editingMode) { this.$emit(editingMode); + + const componentToFocus = + editingMode === EDITING_MODE_CONTENT_EDITOR + ? () => this.$refs.contentEditor + : () => this.$refs.textarea; + + (await waitFor(componentToFocus)).focus(); }, autofocusTextarea() { if (this.autofocus && this.editingMode === EDITING_MODE_MARKDOWN_FIELD) { diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index 0938f9c7d128690c2f95ed67ab365ff2f5215028..01781ceedc082ec98f14e429f56e0934b8cf728a 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -130,7 +130,7 @@ def click_edit_issue_description click_button("Switch to rich text editing") end - expect(issuable_form).not_to have_selector(content_editor_focused_selector) + expect(issuable_form).to have_selector(content_editor_focused_selector) refresh @@ -142,7 +142,7 @@ def click_edit_issue_description click_button("Switch to plain text editing") end - expect(issuable_form).not_to have_selector(markdown_field_focused_selector) + expect(issuable_form).to have_selector(markdown_field_focused_selector) end end diff --git a/spec/support/helpers/content_editor_helpers.rb b/spec/support/helpers/content_editor_helpers.rb index a6cc2560d0be12a7709dcd32636ab1469d800994..7597a13e475464995ff3447b84a83115eee865b7 100644 --- a/spec/support/helpers/content_editor_helpers.rb +++ b/spec/support/helpers/content_editor_helpers.rb @@ -9,6 +9,10 @@ def close_rich_text_promo_popover_if_present end end + def switch_to_markdown_editor + click_button("Switch to plain text editing") + end + def switch_to_content_editor click_button("Switch to rich text editing") end diff --git a/spec/support/shared_examples/features/content_editor_shared_examples.rb b/spec/support/shared_examples/features/content_editor_shared_examples.rb index 254bc3c83acaf1954d3244003d5342e4e15bd20d..fff8ef915ebf6fae4dc73071ff41ee98f6084153 100644 --- a/spec/support/shared_examples/features/content_editor_shared_examples.rb +++ b/spec/support/shared_examples/features/content_editor_shared_examples.rb @@ -27,6 +27,19 @@ expect(page).to have_text('Typing text in the content editor') end + it 'autofocuses the rich text editor when switching to rich text' do + switch_to_content_editor + + expect(page).to have_css("#{content_editor_testid}:focus") + end + + it 'autofocuses the plain text editor when switching back to markdown' do + switch_to_content_editor + switch_to_markdown_editor + + expect(page).to have_css("textarea:focus") + end + describe 'creating and editing links' do before do switch_to_content_editor