You are here

class AceFilter in Ace Code Editor 8

Filters implementation for Ace Editor.

Plugin annotation


@Filter(
  id = "ace_filter",
  title = @Translation("Ace Filter"),
  description = @Translation("Use <ace> and </ace> tags to show it with syntax highlighting.
Add attributes to <ace> tag to control formatting."),
  type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
  settings = {
          "theme" = "cobalt",
          "syntax" = "html",
          "height" = "500px",
          "width" = "700px",
          "font_size" = "12pt",
          "line_numbers" = TRUE,
          "show_invisibles" = FALSE,
          "print_margins" = TRUE,
          "auto_complete" = TRUE,
          "use_wrap_mode" = TRUE,
    }
)

Hierarchy

Expanded class hierarchy of AceFilter

File

src/Plugin/Filter/AceFilter.php, line 32

Namespace

Drupal\ace_editor\Plugin\Filter
View source
class AceFilter extends FilterBase {

  /**
   * Setting form for filters.
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $settings = $this->settings;
    $config = \Drupal::config('ace_editor.settings');
    return [
      'theme' => [
        '#type' => 'select',
        '#title' => t('Theme'),
        '#options' => $config
          ->get('theme_list'),
        '#attributes' => [
          'style' => 'width: 150px;',
        ],
        '#default_value' => $settings['theme'],
      ],
      'syntax' => [
        '#type' => 'select',
        '#title' => t('Syntax'),
        '#description' => t('The syntax that will be highlighted.'),
        '#options' => $config
          ->get('syntax_list'),
        '#attributes' => [
          'style' => 'width: 150px;',
        ],
        '#default_value' => $settings['syntax'],
      ],
      'height' => [
        '#type' => 'textfield',
        '#title' => t('Height'),
        '#description' => t('The height of the editor in either pixels or percents.'),
        '#attributes' => [
          'style' => 'width: 100px;',
        ],
        '#default_value' => $settings['height'],
      ],
      'width' => [
        '#type' => 'textfield',
        '#title' => t('Width'),
        '#description' => t('The width of the editor in either pixels or percents.'),
        '#attributes' => [
          'style' => 'width: 100px;',
        ],
        '#default_value' => $settings['width'],
      ],
      'font_size' => [
        '#type' => 'textfield',
        '#title' => t('Font size'),
        '#description' => t('The the font size of the editor.'),
        '#attributes' => [
          'style' => 'width: 100px;',
        ],
        '#default_value' => $settings['font_size'],
      ],
      'line_numbers' => [
        '#type' => 'checkbox',
        '#title' => t('Show line numbers'),
        '#default_value' => $settings['line_numbers'],
      ],
      'print_margins' => [
        '#type' => 'checkbox',
        '#title' => t('Show print margin (80 chars)'),
        '#default_value' => $settings['print_margins'],
      ],
      'show_invisibles' => [
        '#type' => 'checkbox',
        '#title' => t('Show invisible characters (whitespaces, EOL...)'),
        '#default_value' => $settings['show_invisibles'],
      ],
      'use_wrap_mode' => [
        '#type' => 'checkbox',
        '#title' => t('Toggle word wrapping'),
        '#default_value' => $settings['use_wrap_mode'],
      ],
    ];
  }

  /**
   * Processing the filters and return the processed result.
   */
  public function process($text, $langcode) {
    $text = html_entity_decode($text);
    if (preg_match_all("/<ace.*?>(.*?)\\s*<\\/ace>/s", $text, $match)) {
      $js_settings = [
        'instances' => [],
        'theme_settings' => $this
          ->getConfiguration()['settings'],
      ];
      foreach ($match[0] as $key => $value) {
        $element_id = 'ace-editor-inline' . $key;
        $content = trim($match[1][$key], "\n\r\0\v");
        $replace = '<pre id="' . $element_id . '"></pre>';

        // Override settings with attributes on the tag.
        $settings = $this
          ->getConfiguration()['settings'];
        $attach_lib = [];
        foreach ($this
          ->tagAttributes('ace', $value) as $attribute_key => $attribute_value) {
          $settings[$attribute_key] = $attribute_value;
          if ($attribute_key == "theme" && \Drupal::service('library.discovery')
            ->getLibraryByName('ace_editor', 'theme.' . $attribute_value)) {
            $attach_lib[] = "ace_editor/theme." . $attribute_value;
          }
          if ($attribute_key == "syntax" && \Drupal::service('library.discovery')
            ->getLibraryByName('ace_editor', 'mode.' . $attribute_value)) {
            $attach_lib[] = "ace_editor/mode." . $attribute_value;
          }
        }
        $js_settings['instances'][] = [
          'id' => $element_id,
          'content' => $content,
          'settings' => $settings,
        ];
        $text = $this
          ->strReplaceOnce($value, $replace, $text);
      }
      $result = new FilterProcessResult($text);
      $attach_lib[] = 'ace_editor/filter';
      $result
        ->setAttachments([
        'library' => $attach_lib,
        'drupalSettings' => [
          // Pass settings variable ace_formatter to javascript.
          'ace_filter' => $js_settings,
        ],
      ]);
      return $result;
    }
    $result = new FilterProcessResult($text);
    return $result;
  }

  /**
   * Get all attributes of an <ace> tag in key/value pairs.
   */
  public function tagAttributes($element_name, $xml) {

    // Grab the string of attributes inside the editor tag.
    $found = preg_match('#<' . $element_name . '\\s+([^>]+(?:"|\'))\\s?/?>#', $xml, $matches);
    if ($found == 1) {
      $attribute_array = [];
      $attribute_string = $matches[1];

      // Match attribute-name attribute-value pairs.
      $found = preg_match_all('#([^\\s=]+)\\s*=\\s*(\'[^<\']*\'|"[^<"]*")#', $attribute_string, $matches, PREG_SET_ORDER);
      if ($found != 0) {

        // Create an associative array that matches attribute names
        // with their values.
        foreach ($matches as $attribute) {
          $value = substr($attribute[2], 1, -1);
          if ($value == "1" || $value == "0" || $value == "TRUE" || $value == "FALSE") {
            $value = intval($value);
          }
          $attribute_array[str_replace('-', '_', $attribute[1])] = $value;
        }
        return $attribute_array;
      }
    }

    // Attributes either weren't found, or couldn't be extracted
    // by the regular expression.
    return FALSE;
  }

  /**
   * Custom function to replace the code only once.
   *
   * Probably not the most efficient way, but at least it works.
   */
  public function strReplaceOnce($needle, $replace, $haystack) {

    // Looks for the first occurence of $needle in $haystack
    // and replaces it with $replace.
    $pos = strpos($haystack, $needle);
    if ($pos === FALSE) {

      // Nothing found.
      return $haystack;
    }
    return substr_replace($haystack, $replace, $pos, strlen($needle));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AceFilter::process public function Processing the filters and return the processed result. Overrides FilterInterface::process
AceFilter::settingsForm public function Setting form for filters. Overrides FilterBase::settingsForm
AceFilter::strReplaceOnce public function Custom function to replace the code only once.
AceFilter::tagAttributes public function Get all attributes of an <ace> tag in key/value pairs.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FilterBase::$provider public property The name of the provider that owns this filter.
FilterBase::$settings public property An associative array containing the configured settings of this filter.
FilterBase::$status public property A Boolean indicating whether this filter is enabled.
FilterBase::$weight public property The weight of this filter compared to others in a filter collection.
FilterBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 1
FilterBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides ConfigurableInterface::defaultConfiguration
FilterBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
FilterBase::getDescription public function Returns the administrative description for this filter plugin. Overrides FilterInterface::getDescription
FilterBase::getHTMLRestrictions public function Returns HTML allowed by this filter's configuration. Overrides FilterInterface::getHTMLRestrictions 4
FilterBase::getLabel public function Returns the administrative label for this filter plugin. Overrides FilterInterface::getLabel
FilterBase::getType public function Returns the processing type of this filter plugin. Overrides FilterInterface::getType
FilterBase::prepare public function Prepares the text for processing. Overrides FilterInterface::prepare
FilterBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration 1
FilterBase::tips public function Generates a filter's tip. Overrides FilterInterface::tips 9
FilterBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase::__construct 4
FilterInterface::TYPE_HTML_RESTRICTOR constant HTML tag and attribute restricting filters to prevent XSS attacks.
FilterInterface::TYPE_MARKUP_LANGUAGE constant Non-HTML markup language filters that generate HTML.
FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE constant Irreversible transformation filters.
FilterInterface::TYPE_TRANSFORM_REVERSIBLE constant Reversible transformation filters.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.