From 4866b9ac19dd8bad01d10b5e9a3cf7a8a41a4b46 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Mon, 15 Jun 2020 16:05:00 +0200 Subject: [PATCH 01/13] Initialize Monaco for blobs when FF is on Updated translation --- app/assets/javascripts/blob_edit/constants.js | 4 ++ app/assets/javascripts/blob_edit/edit_blob.js | 68 +++++++++++++++---- app/views/projects/blob/_editor.html.haml | 2 +- locale/gitlab.pot | 3 + .../maintainer_edits_fork_spec.rb | 2 +- 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 app/assets/javascripts/blob_edit/constants.js diff --git a/app/assets/javascripts/blob_edit/constants.js b/app/assets/javascripts/blob_edit/constants.js new file mode 100644 index 00000000000000..8f81f216b98b12 --- /dev/null +++ b/app/assets/javascripts/blob_edit/constants.js @@ -0,0 +1,4 @@ +import { __ } from '~/locale'; + +export const BLOB_EDITOR_ERROR = __('An error occurred while rendering the editor'); +export const BLOB_PREVIEW_ERROR = __(__('An error occurred previewing the blob')); diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 011898a5e7ab3a..96fbe1eaed8016 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -3,7 +3,7 @@ import $ from 'jquery'; import axios from '~/lib/utils/axios_utils'; import createFlash from '~/flash'; -import { __ } from '~/locale'; +import { BLOB_EDITOR_ERROR, BLOB_PREVIEW_ERROR } from './constants'; import TemplateSelectorMediator from '../blob/file_template_mediator'; import getModeByFileExtension from '~/lib/utils/ace_utils'; import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown'; @@ -13,29 +13,71 @@ export default class EditBlob { // assetsPath, filePath, currentAction, projectId, isMarkdown constructor(options) { this.options = options; - this.configureAceEditor(); - this.initModePanesAndLinks(); - this.initSoftWrap(); - this.initFileSelectors(); + const { isMarkdown } = this.options; + const bootstrap = () => { + this.initModePanesAndLinks(); + this.initSoftWrap(); + this.initFileSelectors(); + this.editorPostHandling(isMarkdown); + }; + if (window?.gon?.features?.monacoBlobs) { + this.configureMonacoEditor() + .then(() => { + bootstrap(); + }) + .catch(() => createFlash(BLOB_EDITOR_ERROR)); + } else { + this.configureAceEditor(); + bootstrap(); + } + } + + editorPostHandling(isMarkdown) { + if (isMarkdown) { + addEditorMarkdownListeners(this.editor); + } + this.editor.focus(); + } + + configureMonacoEditor() { + return import(/* webpackChunkName: 'monaco_editor_lite' */ '~/editor/editor_lite').then( + EditorModule => { + const EditorLite = EditorModule.default; + const editorEl = document.getElementById('editor'); + const fileNameEl = document.getElementById('file_path'); + const fileContentEl = document.getElementById('file-content'); + const form = document.querySelector('.js-edit-blob-form'); + + this.editor = new EditorLite(); + + this.editor.createInstance({ + el: editorEl, + blobPath: fileNameEl.value, + blobContent: editorEl.innerText, + }); + + fileNameEl.addEventListener('change', () => { + this.editor.updateModelLanguage(fileNameEl.value); + }); + + form.addEventListener('submit', () => { + fileContentEl.value = this.editor.getValue(); + }); + }, + ); } configureAceEditor() { - const { filePath, assetsPath, isMarkdown } = this.options; + const { filePath, assetsPath } = this.options; ace.config.set('modePath', `${assetsPath}/ace`); ace.config.loadModule('ace/ext/searchbox'); ace.config.loadModule('ace/ext/modelist'); this.editor = ace.edit('editor'); - if (isMarkdown) { - addEditorMarkdownListeners(this.editor); - } - // This prevents warnings re: automatic scrolling being logged this.editor.$blockScrolling = Infinity; - this.editor.focus(); - if (filePath) { this.editor.getSession().setMode(getModeByFileExtension(filePath)); } @@ -81,7 +123,7 @@ export default class EditBlob { currentPane.empty().append(data); currentPane.renderGFM(); }) - .catch(() => createFlash(__('An error occurred previewing the blob'))); + .catch(() => createFlash(BLOB_PREVIEW_ERROR)); } this.$toggleButton.show(); diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml index 032df24a6039c1..67c78620f15640 100644 --- a/app/views/projects/blob/_editor.html.haml +++ b/app/views/projects/blob/_editor.html.haml @@ -40,7 +40,7 @@ = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2', tabindex: '-1' .file-editor.code - %pre.js-edit-mode-pane.qa-editor#editor= params[:content] || local_assigns[:blob_data] + %pre.js-edit-mode-pane.qa-editor#editor{ data: { 'editor-loading': true } }= params[:content] || local_assigns[:blob_data] - if local_assigns[:path] .js-edit-mode-pane#preview.hide .center diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8fea777c0bfb22..da7a4038b2c2b0 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2443,6 +2443,9 @@ msgstr "" msgid "An error occurred while rendering preview broadcast message" msgstr "" +msgid "An error occurred while rendering the editor" +msgstr "" + msgid "An error occurred while reordering issues." msgstr "" diff --git a/spec/features/merge_request/maintainer_edits_fork_spec.rb b/spec/features/merge_request/maintainer_edits_fork_spec.rb index 4db1633abe68aa..1d5e6e5560143a 100644 --- a/spec/features/merge_request/maintainer_edits_fork_spec.rb +++ b/spec/features/merge_request/maintainer_edits_fork_spec.rb @@ -37,7 +37,7 @@ end it 'allows committing to the source branch' do - find('.ace_text-input', visible: false).send_keys('Updated the readme') + execute_script("monaco.editor.getModels()[0].setValue('Updated the readme')") click_button 'Commit changes' wait_for_requests -- GitLab From bf02f30812d51fac6c70624286fc2dff05182e9c Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Mon, 15 Jun 2020 16:06:00 +0200 Subject: [PATCH 02/13] Do not load ACE when FF is ON To not waste the resources, we load ACE only when we know Monaco is not going to be requested --- app/views/projects/blob/edit.html.haml | 5 +++-- app/views/projects/blob/new.html.haml | 6 ++++-- spec/features/projects/blobs/edit_spec.rb | 3 +-- .../blobs/user_creates_new_blob_in_new_project_spec.rb | 3 +-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index 870e37488cfd56..3d84adbc49a213 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -1,7 +1,8 @@ - breadcrumb_title "Repository" - page_title "Edit", @blob.path, @ref -- content_for :page_specific_javascripts do - = page_specific_javascript_tag('lib/ace.js') +- unless Feature.enabled?(:monaco_blobs) + - content_for :page_specific_javascripts do + = page_specific_javascript_tag('lib/ace.js') - if @conflict .alert.alert-danger diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index 8f166e9aa16e85..f9abcffeeb42c5 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -1,7 +1,9 @@ - breadcrumb_title "Repository" - page_title "New File", @path.presence, @ref -- content_for :page_specific_javascripts do - = page_specific_javascript_tag('lib/ace.js') +- unless Feature.enabled?(:monaco_blobs) + - content_for :page_specific_javascripts do + = page_specific_javascript_tag('lib/ace.js') + .editor-title-row %h3.page-title.blob-new-page-title New file diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index 56bf31f24ba5f3..d1d448f840a207 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -36,8 +36,7 @@ def edit_and_commit(commit_changes: true) def fill_editor(content: 'class NextFeature\\nend\\n') wait_for_requests - find('#editor') - execute_script("ace.edit('editor').setValue('#{content}')") + execute_script("monaco.editor.getModels()[0].setValue('#{content}')") end context 'from MR diff' do diff --git a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb index f54bceec2b3dfb..8d107e52db2247 100644 --- a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb +++ b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb @@ -16,8 +16,7 @@ it 'allows the user to add a new file' do click_link 'New file' - find('#editor') - execute_script('ace.edit("editor").setValue("Hello world")') + execute_script("monaco.editor.getModels()[0].setValue('Hello world')") fill_in(:file_name, with: 'dummy-file') -- GitLab From 3c51ad4d3d37627cfcdae71b8a1d910adf58f2d3 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Tue, 16 Jun 2020 23:55:01 +0200 Subject: [PATCH 03/13] Make "soft wrap"/"no wrap" button functional for Monaco --- app/assets/javascripts/blob_edit/edit_blob.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 96fbe1eaed8016..8034a9fdff7090 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -16,8 +16,8 @@ export default class EditBlob { const { isMarkdown } = this.options; const bootstrap = () => { this.initModePanesAndLinks(); - this.initSoftWrap(); this.initFileSelectors(); + this.initSoftWrap(); this.editorPostHandling(isMarkdown); }; if (window?.gon?.features?.monacoBlobs) { @@ -44,7 +44,8 @@ export default class EditBlob { EditorModule => { const EditorLite = EditorModule.default; const editorEl = document.getElementById('editor'); - const fileNameEl = document.getElementById('file_path'); + const fileNameEl = + document.getElementById('file_path') || document.getElementById('file_name'); const fileContentEl = document.getElementById('file-content'); const form = document.querySelector('.js-edit-blob-form'); @@ -132,14 +133,19 @@ export default class EditBlob { } initSoftWrap() { - this.isSoftWrapped = false; + this.isSoftWrapped = Boolean(window?.gon?.features?.monacoBlobs); this.$toggleButton = $('.soft-wrap-toggle'); + this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped); this.$toggleButton.on('click', () => this.toggleSoftWrap()); } toggleSoftWrap() { this.isSoftWrapped = !this.isSoftWrapped; this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped); - this.editor.getSession().setUseWrapMode(this.isSoftWrapped); + if (window?.gon?.features?.monacoBlobs) { + this.editor.updateOptions({ wordWrap: this.isSoftWrapped ? 'on' : 'off' }); + } else { + this.editor.getSession().setUseWrapMode(this.isSoftWrapped); + } } } -- GitLab From 61b443393b5ce49b29c9e86640b6d33e9597bef7 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Wed, 17 Jun 2020 00:06:18 +0200 Subject: [PATCH 04/13] Proxy some needed methods to match ACE API --- app/assets/javascripts/editor/editor_lite.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/editor/editor_lite.js b/app/assets/javascripts/editor/editor_lite.js index 020ed6dc867dcd..6db24a1b7efecf 100644 --- a/app/assets/javascripts/editor/editor_lite.js +++ b/app/assets/javascripts/editor/editor_lite.js @@ -1,4 +1,4 @@ -import { editor as monacoEditor, languages as monacoLanguages, Uri } from 'monaco-editor'; +import { editor as monacoEditor, languages as monacoLanguages, Position, Uri } from 'monaco-editor'; import { DEFAULT_THEME, themes } from '~/ide/lib/themes'; import languages from '~/ide/lib/languages'; import { defaultEditorOptions } from '~/ide/lib/editor_options'; @@ -70,6 +70,22 @@ export default class Editor { } getValue() { - return this.model.getValue(); + return this.instance.getValue(); + } + + setValue(val) { + this.instance.setValue(val); + } + + focus() { + this.instance.focus(); + } + + navigateFileStart() { + this.instance.setPosition(new Position(1, 1)); + } + + updateOptions(options = {}) { + this.instance.updateOptions(options); } } -- GitLab From d21134063bb7bbc4539d454eb9200f0d785bcdc3 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 00:55:25 +0200 Subject: [PATCH 05/13] Fixed the specs --- ...ser_follows_pipeline_suggest_nudge_spec.rb | 2 ++ .../files/edit_file_soft_wrap_spec.rb | 24 +++++++++++-------- .../projects/files/gitignore_dropdown_spec.rb | 2 +- .../projects/files/user_creates_files_spec.rb | 14 +++++------ .../projects/files/user_edits_files_spec.rb | 18 +++++++------- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb index 5270774b54141f..8b43687c71cfd1 100644 --- a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb +++ b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb @@ -32,6 +32,8 @@ end it 'displays suggest_gitlab_ci_yml popover' do + page.find(:css, '.gitlab-ci-yml-selector').click + popover_selector = '.suggest-gitlab-ci-yml' expect(page).to have_css(popover_selector, visible: true) diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index ede22204dbdf20..fda024e893dcd7 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -8,8 +8,9 @@ user = project.owner sign_in user visit project_new_blob_path(project, 'master', file_name: 'test_file-name') + page.within('.file-editor.code') do - find('.ace_text-input', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then + find('.inputarea', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then run away chase the pig around the house eat owner\'s food, and knock dish off table head butt cant eat out of my own dish. Cat is love, cat is life rub face on everything poop on grasses so meow. Playing with @@ -26,17 +27,20 @@ it 'user clicks the "Soft wrap" button and then "No wrap" button' do wrapped_content_width = get_content_width - toggle_button.click - expect(toggle_button).to have_content 'No wrap' - unwrapped_content_width = get_content_width - expect(unwrapped_content_width).to be < wrapped_content_width - - toggle_button.click - expect(toggle_button).to have_content 'Soft wrap' - expect(get_content_width).to be > unwrapped_content_width + + toggle_button.click do + expect(toggle_button).to have_content 'Soft wrap' + unwrapped_content_width = get_content_width + expect(unwrapped_content_width).to be > wrapped_content_width + end + + toggle_button.click do + expect(toggle_button).to have_content 'No wrap' + expect(get_content_width).to be < unwrapped_content_width + end end def get_content_width - find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/).to_i + find('.view-lines', visible: false)[:style].slice!(/width: \d+/).slice!(/\d+/).to_i end end diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index dae1164f7f23bb..5a39f2bcd98488 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -25,6 +25,6 @@ expect(page).to have_css('.gitignore-selector .dropdown-toggle-text', text: 'Apply a template') expect(page).to have_content('/.bundle') - expect(page).to have_content('# Gemfile.lock, .ruby-version, .ruby-gemset') + expect(page).to have_content('config/initializers/secret_token.rb') end end diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb index 7d41273011577e..9c86f2dd190e65 100644 --- a/spec/features/projects/files/user_creates_files_spec.rb +++ b/spec/features/projects/files/user_creates_files_spec.rb @@ -67,7 +67,7 @@ def submit_new_file(options) file_name = find('#file_name') file_name.set options[:file_name] || 'README.md' - find('.ace_text-input', visible: false).send_keys.native.send_keys options[:file_content] || 'Some content' + find('.monaco-editor textarea').send_keys.native.send_keys options[:file_content] || 'Some content' click_button 'Commit changes' end @@ -89,7 +89,7 @@ def submit_new_file(options) it 'creates and commit a new file' do find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -105,7 +105,7 @@ def submit_new_file(options) it 'creates and commit a new file with new lines at the end of file' do find('#editor') - execute_script('ace.edit("editor").setValue("Sample\n\n\n")') + execute_script('monaco.editor.getModels()[0].setValue("Sample\n\n\n")') fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -117,7 +117,7 @@ def submit_new_file(options) find('.js-edit-blob').click find('#editor') - expect(evaluate_script('ace.edit("editor").getValue()')).to eq("Sample\n\n\n") + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq("Sample\n\n\n") end it 'creates and commit a new file with a directory name' do @@ -126,7 +126,7 @@ def submit_new_file(options) expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -141,7 +141,7 @@ def submit_new_file(options) expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) fill_in(:branch_name, with: 'new_branch_name', visible: true) @@ -176,7 +176,7 @@ def submit_new_file(options) expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index 1bb931e35ec06b..c8461468c52e38 100644 --- a/spec/features/projects/files/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -46,9 +46,9 @@ find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq('*.rbca') end it 'does not show the edit link if a file is binary' do @@ -67,7 +67,7 @@ find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -85,7 +85,7 @@ find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) fill_in(:branch_name, with: 'new_branch_name', visible: true) click_button('Commit changes') @@ -103,7 +103,7 @@ find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") click_link('Preview changes') expect(page).to have_css('.line_holder.new') @@ -148,9 +148,9 @@ def expect_fork_status find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq('*.rbca') end it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do @@ -178,7 +178,7 @@ def expect_fork_status find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -207,7 +207,7 @@ def expect_fork_status expect(page).not_to have_button('Cancel') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'Another commit', visible: true) click_button('Commit changes') -- GitLab From 85ef8b065ed12b4a14af775f5676001728eefaff Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 12:20:07 +0200 Subject: [PATCH 06/13] Added changelog entry --- changelogs/unreleased/198605-monaco-blob.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/198605-monaco-blob.yml diff --git a/changelogs/unreleased/198605-monaco-blob.yml b/changelogs/unreleased/198605-monaco-blob.yml new file mode 100644 index 00000000000000..01da3e0250e093 --- /dev/null +++ b/changelogs/unreleased/198605-monaco-blob.yml @@ -0,0 +1,5 @@ +--- +title: Replace ACE with Monaco for Blob (files) editing/creation +merge_request: 34677 +author: +type: changed -- GitLab From a08c8c834fbe734e1947fd879ec2256cbf10cab5 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 14:21:31 +0200 Subject: [PATCH 07/13] Got rid of bootstrap func --- app/assets/javascripts/blob_edit/edit_blob.js | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 8034a9fdff7090..141029c97aa4a8 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -14,22 +14,19 @@ export default class EditBlob { constructor(options) { this.options = options; const { isMarkdown } = this.options; - const bootstrap = () => { - this.initModePanesAndLinks(); - this.initFileSelectors(); - this.initSoftWrap(); - this.editorPostHandling(isMarkdown); - }; - if (window?.gon?.features?.monacoBlobs) { - this.configureMonacoEditor() - .then(() => { - bootstrap(); - }) - .catch(() => createFlash(BLOB_EDITOR_ERROR)); - } else { - this.configureAceEditor(); - bootstrap(); - } + Promise.resolve() + .then(() => { + return window?.gon?.features?.monacoBlobs + ? this.configureMonacoEditor() + : this.configureAceEditor(); + }) + .then(() => { + this.initModePanesAndLinks(); + this.initFileSelectors(); + this.initSoftWrap(); + this.editorPostHandling(isMarkdown); + }) + .catch(() => createFlash(BLOB_EDITOR_ERROR)); } editorPostHandling(isMarkdown) { -- GitLab From cb3cd6e657a2784215f55d181cf7bb338a93fb6d Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 14:21:41 +0200 Subject: [PATCH 08/13] Removed changelog entry --- changelogs/unreleased/198605-monaco-blob.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 changelogs/unreleased/198605-monaco-blob.yml diff --git a/changelogs/unreleased/198605-monaco-blob.yml b/changelogs/unreleased/198605-monaco-blob.yml deleted file mode 100644 index 01da3e0250e093..00000000000000 --- a/changelogs/unreleased/198605-monaco-blob.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Replace ACE with Monaco for Blob (files) editing/creation -merge_request: 34677 -author: -type: changed -- GitLab From 6cd2157feaf2d9913dd862ad15c1ea66ce3a3be2 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 14:38:50 +0200 Subject: [PATCH 09/13] Removed double translation --- app/assets/javascripts/blob_edit/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/blob_edit/constants.js b/app/assets/javascripts/blob_edit/constants.js index 8f81f216b98b12..a19da2098cf8a5 100644 --- a/app/assets/javascripts/blob_edit/constants.js +++ b/app/assets/javascripts/blob_edit/constants.js @@ -1,4 +1,4 @@ import { __ } from '~/locale'; export const BLOB_EDITOR_ERROR = __('An error occurred while rendering the editor'); -export const BLOB_PREVIEW_ERROR = __(__('An error occurred previewing the blob')); +export const BLOB_PREVIEW_ERROR = __('An error occurred previewing the blob'); -- GitLab From 1fd6ba665e39837eb764042dd36390f293e4c15c Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Thu, 18 Jun 2020 14:41:25 +0200 Subject: [PATCH 10/13] Inlined editorPostHandling --- app/assets/javascripts/blob_edit/edit_blob.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 141029c97aa4a8..92b6a5d42df756 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -24,18 +24,14 @@ export default class EditBlob { this.initModePanesAndLinks(); this.initFileSelectors(); this.initSoftWrap(); - this.editorPostHandling(isMarkdown); + if (isMarkdown) { + addEditorMarkdownListeners(this.editor); + } + this.editor.focus(); }) .catch(() => createFlash(BLOB_EDITOR_ERROR)); } - editorPostHandling(isMarkdown) { - if (isMarkdown) { - addEditorMarkdownListeners(this.editor); - } - this.editor.focus(); - } - configureMonacoEditor() { return import(/* webpackChunkName: 'monaco_editor_lite' */ '~/editor/editor_lite').then( EditorModule => { -- GitLab From c95f9f83796cc1aeada1a1dc8e79f6db6942da37 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 19 Jun 2020 11:09:15 +0200 Subject: [PATCH 11/13] Testing the syntax highlighting We should make sure the syntax highlighting works for blobs when a file_path gets changed --- spec/features/projects/blobs/edit_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index d1d448f840a207..8a81b666e2f473 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -66,6 +66,15 @@ def fill_editor(content: 'class NextFeature\\nend\\n') expect(find_by_id('file_path').value).to eq('ci/.gitlab-ci.yml') end + it 'updating file path updates syntax highlighting' do + visit project_edit_blob_path(project, tree_join(branch, readme_file_path)) + expect(find('#editor')['data-mode-id']).to eq('markdown') + + find('#file_path').set('foo.txt') + + expect(find('#editor')['data-mode-id']).to eq('plaintext') + end + context 'from blob file path' do before do stub_feature_flags(code_navigation: false) -- GitLab From 40e1ff4230e77512afaf1a6337aa3ac4ae4e0a63 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 19 Jun 2020 11:15:33 +0200 Subject: [PATCH 12/13] Reduce code repetition We abstract the check about whether Monaco is enabled or not into a variable that gets reused in the component. --- app/assets/javascripts/blob_edit/edit_blob.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 92b6a5d42df756..a725b3fe5d615a 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -8,6 +8,8 @@ import TemplateSelectorMediator from '../blob/file_template_mediator'; import getModeByFileExtension from '~/lib/utils/ace_utils'; import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown'; +const monacoEnabled = window?.gon?.features?.monacoBlobs; + export default class EditBlob { // The options object has: // assetsPath, filePath, currentAction, projectId, isMarkdown @@ -16,9 +18,7 @@ export default class EditBlob { const { isMarkdown } = this.options; Promise.resolve() .then(() => { - return window?.gon?.features?.monacoBlobs - ? this.configureMonacoEditor() - : this.configureAceEditor(); + return monacoEnabled ? this.configureMonacoEditor() : this.configureAceEditor(); }) .then(() => { this.initModePanesAndLinks(); @@ -126,7 +126,7 @@ export default class EditBlob { } initSoftWrap() { - this.isSoftWrapped = Boolean(window?.gon?.features?.monacoBlobs); + this.isSoftWrapped = Boolean(monacoEnabled); this.$toggleButton = $('.soft-wrap-toggle'); this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped); this.$toggleButton.on('click', () => this.toggleSoftWrap()); @@ -135,7 +135,7 @@ export default class EditBlob { toggleSoftWrap() { this.isSoftWrapped = !this.isSoftWrapped; this.$toggleButton.toggleClass('soft-wrap-active', this.isSoftWrapped); - if (window?.gon?.features?.monacoBlobs) { + if (monacoEnabled) { this.editor.updateOptions({ wordWrap: this.isSoftWrapped ? 'on' : 'off' }); } else { this.editor.getSession().setUseWrapMode(this.isSoftWrapped); -- GitLab From 4219cef106cc30cb710d984ffd423bf5adf99ac1 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 19 Jun 2020 10:21:05 +0000 Subject: [PATCH 13/13] Updated syntax highlighting test --- spec/features/projects/blobs/edit_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index 8a81b666e2f473..5851121f635782 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -70,9 +70,9 @@ def fill_editor(content: 'class NextFeature\\nend\\n') visit project_edit_blob_path(project, tree_join(branch, readme_file_path)) expect(find('#editor')['data-mode-id']).to eq('markdown') - find('#file_path').set('foo.txt') - - expect(find('#editor')['data-mode-id']).to eq('plaintext') + find('#file_path').send_keys('foo.txt') do + expect(find('#editor')['data-mode-id']).to eq('plaintext') + end end context 'from blob file path' do -- GitLab