This repository has been archived on 2025-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
drupalcampbristol/web/modules/contrib/webform/js/webform.element.codemirror.js
2019-01-24 08:00:03 +00:00

123 lines
4.3 KiB
JavaScript

/**
* @file
* JavaScript behaviors for CodeMirror integration.
*/
(function ($, Drupal) {
'use strict';
// @see http://codemirror.net/doc/manual.html#config
Drupal.webform = Drupal.webform || {};
Drupal.webform.codeMirror = Drupal.webform.codeMirror || {};
Drupal.webform.codeMirror.options = Drupal.webform.codeMirror.options || {};
/**
* Initialize CodeMirror editor.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.webformCodeMirror = {
attach: function (context) {
if (!window.CodeMirror) {
return;
}
// Webform CodeMirror editor.
$(context).find('textarea.js-webform-codemirror').once('webform-codemirror').each(function () {
var $input = $(this);
// Open all closed details, so that editor height is correctly calculated.
var $details = $(this).parents('details:not([open])');
$details.attr('open', 'open');
// #59 HTML5 required attribute breaks hack for webform submission.
// https://github.com/marijnh/CodeMirror-old/issues/59
$(this).removeAttr('required');
var options = $.extend({
mode: $(this).attr('data-webform-codemirror-mode'),
lineNumbers: true,
c: ($(this).attr('wrap') === 'off') ? false : true,
viewportMargin: Infinity,
readOnly: ($(this).prop('readonly') || $(this).prop('disabled')) ? true : false,
extraKeys: {
// Setting for using spaces instead of tabs - https://github.com/codemirror/CodeMirror/issues/988
Tab: function (cm) {
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
cm.replaceSelection(spaces, 'end', '+element');
},
// On 'Escape' move to the next tabbable input.
// @see http://bgrins.github.io/codemirror-accessible/
Esc: function (cm) {
// Must show and then textarea so that we can determine
// its tabindex.
var textarea = $(cm.getTextArea());
$(textarea).show().addClass('visually-hidden');
var $tabbable = $(':tabbable');
var tabindex = $tabbable.index(textarea);
$(textarea).hide().removeClass('visually-hidden');
// Tabindex + 2 accounts for the CodeMirror's iframe.
$tabbable.eq(tabindex + 2).focus();
}
}
}, Drupal.webform.codeMirror.options);
var editor = CodeMirror.fromTextArea(this, options);
// Now, close details.
$details.removeAttr('open');
// Issue #2764443: CodeMirror is not setting submitted value when
// rendered within a webform UI dialog.
editor.on('blur', function (event) {
editor.save();
});
// Update CodeMirror when the textarea's value has changed.
// @see webform.states.js
$input.on('change', function () {
editor.getDoc().setValue($input.val());
});
// Set CodeMirror to be readonly when the textarea is disabled.
// @see webform.states.js
$input.on('webform:disabled', function () {
editor.setOption('readOnly', $input.is(':disabled'));
});
// Delay refreshing CodeMirror for 10 millisecond while the dialog is
// still being rendered.
// @see http://stackoverflow.com/questions/8349571/codemirror-editor-is-not-loading-content-until-clicked
setTimeout(function () {
// Show tab panel and open details.
var $tabPanel = $input.parents('.ui-tabs-panel:hidden');
var $details = $input.parents('details:not([open])');
if (!$tabPanel.length && $details.length) {
return;
}
$tabPanel.show();
$details.attr('open', 'open');
editor.refresh();
// Hide tab panel and close details.
$tabPanel.hide();
$details.removeAttr('open');
}, 10);
});
// Webform CodeMirror syntax coloring.
$(context).find('.js-webform-codemirror-runmode').once('webform-codemirror-runmode').each(function () {
// Mode Runner - http://codemirror.net/demo/runmode.html
CodeMirror.runMode($(this).addClass('cm-s-default').text(), $(this).attr('data-webform-codemirror-mode'), this);
});
}
};
})(jQuery, Drupal);