2017-03-16 15:29:07 +00:00
/ * *
* @ file
2018-11-23 12:29:20 +00:00
* JavaScript behaviors for CodeMirror integration .
2017-03-16 15:29:07 +00:00
* /
( function ( $ , Drupal ) {
'use strict' ;
2018-11-23 12:29:20 +00:00
// @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 || { } ;
2017-03-16 15:29:07 +00:00
/ * *
* Initialize CodeMirror editor .
*
* @ type { Drupal ~ behavior }
* /
Drupal . behaviors . webformCodeMirror = {
attach : function ( context ) {
2018-11-23 12:29:20 +00:00
if ( ! window . CodeMirror ) {
return ;
}
2017-03-16 15:29:07 +00:00
// 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' ) ;
2018-11-23 12:29:20 +00:00
var options = $ . extend ( {
2017-03-16 15:29:07 +00:00
mode : $ ( this ) . attr ( 'data-webform-codemirror-mode' ) ,
lineNumbers : true ,
2019-01-24 08:00:03 +00:00
c : ( $ ( this ) . attr ( 'wrap' ) === 'off' ) ? false : true ,
2017-03-16 15:29:07 +00:00
viewportMargin : Infinity ,
2018-11-23 12:29:20 +00:00
readOnly : ( $ ( this ) . prop ( 'readonly' ) || $ ( this ) . prop ( 'disabled' ) ) ? true : false ,
2017-03-16 15:29:07 +00:00
extraKeys : {
2018-11-23 12:29:20 +00:00
// Setting for using spaces instead of tabs - https://github.com/codemirror/CodeMirror/issues/988
2017-03-16 15:29:07 +00:00
Tab : function ( cm ) {
var spaces = Array ( cm . getOption ( 'indentUnit' ) + 1 ) . join ( ' ' ) ;
cm . replaceSelection ( spaces , 'end' , '+element' ) ;
2018-11-23 12:29:20 +00:00
} ,
// 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 ( ) ;
2017-03-16 15:29:07 +00:00
}
2018-11-23 12:29:20 +00:00
2017-03-16 15:29:07 +00:00
}
2018-11-23 12:29:20 +00:00
} , Drupal . webform . codeMirror . options ) ;
var editor = CodeMirror . fromTextArea ( this , options ) ;
2017-03-16 15:29:07 +00:00
// 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 ( ) {
2018-11-23 12:29:20 +00:00
editor . setOption ( 'readOnly' , $input . is ( ':disabled' ) ) ;
2017-03-16 15:29:07 +00:00
} ) ;
2018-11-23 12:29:20 +00:00
// 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 ) ;
2017-03-16 15:29:07 +00:00
} ) ;
// Webform CodeMirror syntax coloring.
$ ( context ) . find ( '.js-webform-codemirror-runmode' ) . once ( 'webform-codemirror-runmode' ) . each ( function ( ) {
// Mode Runner - http://codemirror.net/demo/runmode.html
2018-11-23 12:29:20 +00:00
CodeMirror . runMode ( $ ( this ) . addClass ( 'cm-s-default' ) . text ( ) , $ ( this ) . attr ( 'data-webform-codemirror-mode' ) , this ) ;
2017-03-16 15:29:07 +00:00
} ) ;
}
} ;
} ) ( jQuery , Drupal ) ;