language_negotiation_matrix-1.0.0-beta2/js/element.codemirror.js
js/element.codemirror.js
/**
* @file
* JavaScript behaviors for CodeMirror integration.
*/
(function ($, Drupal, once) {
'use strict';
// @see http://codemirror.net/doc/manual.html#config
Drupal.language_negotiation_matrix = Drupal.language_negotiation_matrix || {};
Drupal.language_negotiation_matrix.codeMirror = Drupal.language_negotiation_matrix.codeMirror || {};
Drupal.language_negotiation_matrix.codeMirror.options = Drupal.language_negotiation_matrix.codeMirror.options || {};
/**
* Initialize CodeMirror editor.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.codeMirror = {
attach: function (context) {
if (!window.CodeMirror) {
return;
}
// CodeMirror editor.
once('codemirror', 'textarea.js-codemirror', context).forEach(function (element) {
var $input = $(element);
// Open all closed details, so that editor height is correctly calculated.
var $details = $input.parents('details:not([open])');
$details.attr('open', 'open');
var options = $.extend({
mode: $input.attr('data-codemirror-mode'),
lineNumbers: true,
lineWrapping: ($input.attr('wrap') !== 'off'),
viewportMargin: Infinity,
readOnly: !!($input.prop('readonly') || $input.prop('disabled')),
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).trigger('focus');
}
}
}, Drupal.language_negotiation_matrix.codeMirror.options);
var editor = CodeMirror.fromTextArea(this, options);
// Now, close details.
$details.removeAttr('open');
// Apply the textarea's min/max-height to the CodeMirror editor.
if ($input.css('min-height')) {
var minHeight = $input.css('min-height');
$(editor.getWrapperElement())
.css('min-height', minHeight)
.find('.CodeMirror-scroll')
.css('min-height', minHeight);
}
if ($input.css('max-height')) {
var maxHeight = $input.css('max-height');
$(editor.getWrapperElement())
.css('max-height', maxHeight)
.find('.CodeMirror-scroll')
.css('max-height', maxHeight);
}
// Issue #2764443: CodeMirror is not setting submitted value when
// rendered within a form UI dialog or within an Ajaxified element.
var changeTimer = null;
editor.on('change', function () {
if (changeTimer) {
window.clearTimeout(changeTimer);
changeTimer = null;
}
changeTimer = setTimeout(function () {editor.save();}, 500);
});
// Update CodeMirror when the textarea's value has changed.
$input.on('change', function () {
editor.getDoc().setValue($input.val());
});
// Set CodeMirror to be readonly when the textarea is disabled.
$input.on('form:disabled', function () {
editor.setOption('readOnly', $input.is(':disabled'));
});
// Delay refreshing CodeMirror for 500 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');
}, 500);
});
// CodeMirror syntax coloring.
if (window.CodeMirror.runMode) {
once('codemirror-runmode', '.js-codemirror-runmode', context).forEach(function (element) {
// Mode Runner - http://codemirror.net/demo/runmode.html
CodeMirror.runMode($(element).addClass('cm-s-default').text(), $(element).attr('data-codemirror-mode'), element);
});
}
}
};
})(jQuery, Drupal, once);
