debian-mirror-gitlab/app/assets/javascripts/gl_form.js

135 lines
4.6 KiB
JavaScript
Raw Normal View History

2018-03-27 19:54:05 +05:30
import autosize from 'autosize';
2021-03-11 19:13:27 +05:30
import $ from 'jquery';
2023-04-23 21:23:45 +05:30
import { isEmpty } from 'lodash';
2019-07-31 22:56:46 +05:30
import GfmAutoComplete, { defaultAutocompleteConfig } from 'ee_else_ce/gfm_auto_complete';
2021-03-11 19:13:27 +05:30
import { disableButtonIfEmptyField } from '~/lib/utils/common_utils';
2018-03-17 18:26:18 +05:30
import dropzoneInput from './dropzone_input';
2018-05-09 12:01:36 +05:30
import { addMarkdownListeners, removeMarkdownListeners } from './lib/utils/text_markdown';
2018-03-17 18:26:18 +05:30
export default class GLForm {
2021-01-03 14:25:43 +05:30
/**
* Create a GLForm
*
* @param {jQuery} form Root element of the GLForm
* @param {Object} enableGFM Which autocomplete features should be enabled?
* @param {Boolean} forceNew If true, treat the element as a **new** form even if `gfm-form` class already exists.
2023-04-23 21:23:45 +05:30
* @param {Object} gfmDataSources The paths of the autocomplete data sources to use for GfmAutoComplete
* By default, the backend embeds these in the global object gl.GfmAutocomplete.dataSources.
* Use this param to override them.
2021-01-03 14:25:43 +05:30
*/
2023-04-23 21:23:45 +05:30
constructor(form, enableGFM = {}, forceNew = false, gfmDataSources = {}) {
2018-03-17 18:26:18 +05:30
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
2020-05-24 23:13:21 +05:30
this.enableGFM = { ...defaultAutocompleteConfig, ...enableGFM };
2020-07-28 23:09:34 +05:30
2018-11-08 19:23:39 +05:30
// Disable autocomplete for keywords which do not have dataSources available
2023-04-23 21:23:45 +05:30
let dataSources = (gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources) || {};
if (!isEmpty(gfmDataSources)) {
dataSources = gfmDataSources;
}
2021-03-08 18:12:59 +05:30
Object.keys(this.enableGFM).forEach((item) => {
2020-07-28 23:09:34 +05:30
if (item !== 'emojis' && !dataSources[item]) {
this.enableGFM[item] = false;
2018-11-08 19:23:39 +05:30
}
});
2020-07-28 23:09:34 +05:30
2018-03-17 18:26:18 +05:30
// Before we start, we should clean up any previous data for this form
this.destroy();
2018-12-05 23:21:45 +05:30
// Set up the form
2023-04-23 21:23:45 +05:30
this.setupForm(dataSources, forceNew);
2018-03-27 19:54:05 +05:30
this.form.data('glForm', this);
2017-09-10 17:25:29 +05:30
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
destroy() {
// Clean form listeners
this.clearEventListeners();
if (this.autoComplete) {
this.autoComplete.destroy();
}
2020-05-24 23:13:21 +05:30
if (this.formDropzone) {
this.formDropzone.destroy();
}
2018-03-27 19:54:05 +05:30
this.form.data('glForm', null);
2017-08-17 22:00:37 +05:30
}
2023-04-23 21:23:45 +05:30
setupForm(dataSources, forceNew = false) {
2021-01-03 14:25:43 +05:30
const isNewForm = this.form.is(':not(.gfm-form)') || forceNew;
2018-03-17 18:26:18 +05:30
this.form.removeClass('js-new-note-form');
if (isNewForm) {
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
// remove notify commit author checkbox for non-commit notes
2020-07-28 23:09:34 +05:30
disableButtonIfEmptyField(
2018-12-13 13:39:08 +05:30
this.form.find('.js-note-text'),
this.form.find('.js-comment-button, .js-note-new-discussion'),
);
2023-04-23 21:23:45 +05:30
this.autoComplete = new GfmAutoComplete(dataSources);
2018-11-08 19:23:39 +05:30
this.autoComplete.setup(this.form.find('.js-gfm-input'), this.enableGFM);
2020-05-24 23:13:21 +05:30
this.formDropzone = dropzoneInput(this.form, { parallelUploads: 1 });
2022-07-23 23:45:48 +05:30
if (this.form.is(':not(.js-no-autosize)')) {
autosize(this.textarea);
}
2018-03-17 18:26:18 +05:30
}
// form and textarea event listeners
this.addEventListeners();
2018-05-09 12:01:36 +05:30
addMarkdownListeners(this.form);
2018-03-17 18:26:18 +05:30
this.form.show();
if (this.isAutosizeable) this.setupAutosize();
2021-03-08 18:12:59 +05:30
if (this.textarea.data('autofocus') === true) this.textarea.focus();
2018-03-17 18:26:18 +05:30
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
setupAutosize() {
2021-02-22 17:27:13 +05:30
// eslint-disable-next-line @gitlab/no-global-event-off
2018-12-13 13:39:08 +05:30
this.textarea.off('autosize:resized').on('autosize:resized', this.setHeightData.bind(this));
2017-08-17 22:00:37 +05:30
2021-02-22 17:27:13 +05:30
// eslint-disable-next-line @gitlab/no-global-event-off
2018-12-13 13:39:08 +05:30
this.textarea.off('mouseup.autosize').on('mouseup.autosize', this.destroyAutosize.bind(this));
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
setTimeout(() => {
autosize(this.textarea);
this.textarea.css('resize', 'vertical');
}, 0);
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
setHeightData() {
this.textarea.data('height', this.textarea.outerHeight());
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
destroyAutosize() {
const outerHeight = this.textarea.outerHeight();
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
if (this.textarea.data('height') === outerHeight) return;
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
autosize.destroy(this.textarea);
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
this.textarea.data('height', outerHeight);
this.textarea.outerHeight(outerHeight);
this.textarea.css('max-height', window.outerHeight);
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
clearEventListeners() {
2021-02-22 17:27:13 +05:30
// eslint-disable-next-line @gitlab/no-global-event-off
2018-03-17 18:26:18 +05:30
this.textarea.off('focus');
2021-02-22 17:27:13 +05:30
// eslint-disable-next-line @gitlab/no-global-event-off
2018-03-17 18:26:18 +05:30
this.textarea.off('blur');
2018-05-09 12:01:36 +05:30
removeMarkdownListeners(this.form);
2018-03-17 18:26:18 +05:30
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
addEventListeners() {
this.textarea.on('focus', function focusTextArea() {
2021-03-08 18:12:59 +05:30
$(this).closest('.md-area').addClass('is-focused');
2018-03-17 18:26:18 +05:30
});
this.textarea.on('blur', function blurTextArea() {
2021-03-08 18:12:59 +05:30
$(this).closest('.md-area').removeClass('is-focused');
2018-03-17 18:26:18 +05:30
});
}
2020-07-28 23:09:34 +05:30
get supportsQuickActions() {
return Boolean(this.textarea.data('supports-quick-actions'));
}
2018-03-17 18:26:18 +05:30
}