/* eslint-disable prefer-template, quote-props */
  // brfs doesn’t play well with template strings ATM
  // jss-lite looks more elegant when all properties are quoted
const codemirror = require('codemirror');
const jssLite = require('jss-lite');
const privateParts = require('private-parts');

require('codemirror/mode/xml/xml');
require('codemirror/keymap/sublime');

const _ = privateParts.createKey();

const baseCss = require('codemirror/lib/codemirror.css');
const themeCss = require('codemirror/theme/material.css');
const styleOverrides = jssLite({
  '.CodeMirror': {
    'font-family': '"source code pro", monospace',
    'height': 'auto',
    'padding': '0.5em',
    'cursor': 'text',
  },
});


const prototype = Object.assign(Object.create(HTMLElement.prototype), {
  createdCallback() {
    const shadow = this.createShadowRoot();

    const style = document.createElement('style');
    style.textContent = baseCss + themeCss + styleOverrides;
    shadow.appendChild(style);

    const editor = _(this).editor = codemirror(shadow, {
      mode: 'xml',
      theme: 'material',
      keyMap: 'sublime',
      tabSize: 2,
      inputStyle: 'contenteditable',
      autofocus: true,
      smartIndent: false,
      scrollbarStyle: null,
      lineWrapping: true,
    });
    editor.setOption('extraKeys', {
      Tab: (cm) => {
        cm.replaceSelection('  ', 'end');
      },
    });

    const content = document.createElement('content');
    shadow.appendChild(content);

    let textarea;
    const updateTextareaValue = () => {
      if (!textarea) return;
      textarea.value = editor.getValue();

      // Dispatch “input” event
      const event = document.createEvent('Events');
      event.initEvent('input', true, true);
      textarea.dispatchEvent(event);
    };
    editor.on('change', updateTextareaValue);

    const rewireTextarea = () => {
      const nextTextarea = Array.from(this.children)
        .find(child => child.tagName === 'TEXTAREA');

      if (nextTextarea !== textarea) {
        textarea = nextTextarea;
        if (textarea === undefined) return;
        nextTextarea.style.display = 'none';
        updateTextareaValue();
      }
    };
    rewireTextarea();
    const observer = new MutationObserver(rewireTextarea);
    observer.observe(this, { childList: true });
  },

  attachedCallback() {
    _(this).editor.focus();
  },
});

document.registerElement('codemirror-editor', { prototype });

@@ -1825,24 +1825,178 @@
 reaValue);%0A%0A
+    const updateEditorValue = (event) =%3E %7B%0A      if (event.target.value === editor.getValue()) return;%0A      editor.setValue(event.target.value);%0A    %7D;%0A%0A
     const re
@@ -2161,24 +2161,141 @@
 textarea) %7B%0A
+        if (textarea !== undefined) %7B%0A          textarea.removeEventListener('input', updateEditorValue);%0A        %7D%0A%0A
         text
@@ -2359,24 +2359,25 @@
 return;%0A
+%0A
         
 nextText
@@ -2368,21 +2368,17 @@
         
-nextT
+t
 extarea.
@@ -2442,38 +2442,151 @@
     
-%7D%0A    %7D;%0A    rewireTextarea();
+  textarea.addEventListener('input', updateEditorValue);%0A      %7D%0A    %7D;%0A    rewireTextarea();%0A%0A    // Always keep the first %3Ctextarea%3E wired up
 %0A   

Make <codemirror-editor> listen to textarea changes