View source  
  <?php
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
function insert_editor_js_settings_alter(array &$settings) {
  $config = \Drupal::config('insert.config');
  $text_formats = $config
    ->get('text_formats');
  foreach (array_keys($settings['editor']['formats']) as $text_format_id) {
    if (in_array($text_format_id, $text_formats)) {
      $settings['editor']['formats'][$text_format_id]['editorSettings']['extraAllowedContent'] = 'img[src,width,height,alt,title,data-insert-class,data-insert-type](*); span[contenteditable,data-insert-type](*); a[title,type,data-insert-type](*)';
    }
    
    if (!in_array('drupalimage', array_keys($settings['editor']['formats'][$text_format_id]['editorSettings']['drupalExternalPlugins']))) {
      $settings['editor']['formats'][$text_format_id]['editorSettings']['removePlugins'] = 'image2';
    }
  }
}
function insert_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id === 'filter_format_edit_form') {
    $text_formats = \Drupal::config('insert.config')
      ->get('text_formats');
    if (in_array($form['format']['#default_value'], $text_formats)) {
      $form['filters']['settings']['filter_html']['allowed_html']['#element_validate'][] = 'insert_allowed_html_validate';
    }
  }
}
function insert_allowed_html_validate($element, FormState &$form_state) {
  $value = $element['#value'];
  $tags = [
    'img' => null,
    'a' => null,
    'span' => null,
  ];
  $attributes = [
    'img' => [
      'class' => null,
      'src' => null,
      'width' => null,
      'height' => null,
      'alt' => null,
      'title' => null,
    ],
    'a' => [
      'class' => null,
      'title' => null,
      'type' => null,
    ],
    'span' => [
      'class' => null,
    ],
  ];
  
  $html = str_replace('>', ' />', $value);
  $star_protector = '__zqh6vxfbk3cg__';
  $html = str_replace('*', $star_protector, $html);
  $body_child_nodes = Html::load($html)
    ->getElementsByTagName('body')
    ->item(0)->childNodes;
  
  foreach ($body_child_nodes as $node) {
    if ($node->nodeType !== XML_ELEMENT_NODE) {
      continue;
    }
    $tag = $node->tagName;
    if (array_key_exists($tag, $tags)) {
      $tags[$tag] = TRUE;
    }
    else {
      continue;
    }
    
    if ($node
      ->hasAttributes()) {
      foreach ($node->attributes as $name => $attribute) {
        
        $name = str_replace($star_protector, '*', $name);
        $allowed_attribute_values = preg_split('/\\s+/', str_replace($star_protector, '*', $attribute->value), -1, PREG_SPLIT_NO_EMPTY);
        $allowed_attribute_values = array_filter($allowed_attribute_values, function ($value) use ($star_protector) {
          return $value !== '*';
        });
        
        if (array_key_exists($name, $attributes[$tag])) {
          $attributes[$tag][$name] = empty($allowed_attribute_values);
        }
      }
    }
  }
  
  foreach ($tags as $tag => $found_tag) {
    if (!$found_tag) {
      $value .= ' <' . $tag . '>';
    }
    foreach ($attributes[$tag] as $name => $found_attribute) {
      if ($found_attribute === TRUE) {
        
        continue;
      }
      elseif ($found_attribute === null) {
        
        $value = preg_replace('/<' . $tag . '/', '<' . $tag . ' ' . $name, $value);
      }
      else {
        
        $value = preg_replace('/(<' . $tag . '[^>]+' . $name . ')(=("|\')[^"\']+("|\'))/', '$1', $value);
      }
    }
  }
  $form_state
    ->setValueForElement($element, $value);
}
function insert_theme() {
  return array(
    'insert_button_widget' => array(
      'render element' => 'element',
      'template' => 'insert-button-widget',
    ),
    'insert_field_widget_settings_styles' => array(
      'render element' => 'element',
    ),
    'insert_image' => array(
      'variables' => array(
        'item' => NULL,
        'widget' => NULL,
        'style_name' => NULL,
      ),
      'template' => 'insert-image',
      'pattern' => 'insert_image__[a-z0-9_]+',
    ),
    'insert_link' => array(
      'variables' => array(
        'item' => NULL,
        'widget' => NULL,
      ),
      'template' => 'insert-link',
    ),
    'insert_icon_link' => array(
      'variables' => array(
        'item' => NULL,
        'widget' => NULL,
      ),
      'template' => 'insert-icon-link',
    ),
  );
}
function template_preprocess_insert_button_widget(&$vars) {
  $element = $vars['element'];
  $vars['insert_absolute'] = $element['#insert_absolute'];
  $vars['insert_styles'] = $element['#options'];
  $vars['default_style'] = $element['#default_value'];
  $vars['widget_type'] = $element['#widget']['type'];
  $vars['insert_rotate'] = isset($element['#insert_rotate']) ? $element['#insert_rotate'] : FALSE;
  $vars['fid'] = $element['#fid'];
  $vars['nid'] = $element['#nid'];
}
function template_preprocess_insert_image(&$vars) {
  if (count($vars['item']['fids']) === 0) {
    return;
  }
  $vars['file'] = File::load($vars['item']['fids'][0]);
  
  $image = \Drupal::service('image.factory')
    ->get($vars['file']
    ->getFileUri());
  if ($image
    ->isValid()) {
    $vars['width'] = $image
      ->getWidth();
    $vars['height'] = $image
      ->getHeight();
  }
  else {
    $vars['width'] = $variables['height'] = NULL;
  }
  if ($vars['style_name'] === 'image') {
    
    return;
  }
  $style = ImageStyle::load($vars['style_name']);
  if ($style === null) {
    return;
  }
  $style
    ->transformDimensions($vars, $vars['file']
    ->getFileUri());
}
function template_preprocess_insert_link(&$vars) {
  
  $vars['name'] = $vars['file']
    ->getFilename();
}
function template_preprocess_insert_icon_link(&$vars) {
  
  $file = $vars['file'];
  $vars['name'] = $file
    ->getFilename();
  $mime_type = $file
    ->getMimeType();
  $vars['type'] = $file
    ->getMimeType() . '; length=' . $file
    ->getSize();
  $vars['icon_classes'] = join(' ', array(
    'file',
    
    'file--mime-' . strtr($mime_type, array(
      '/' => '-',
      '.' => '-',
    )),
    
    'file--' . file_icon_class($mime_type),
  ));
}