ckeditor_accordion-8.x-1.3/js/ckeditor5_plugins/accordion/src/accordionediting.js

js/ckeditor5_plugins/accordion/src/accordionediting.js
import { Plugin } from 'ckeditor5/src/core';
import { toWidget, toWidgetEditable } from 'ckeditor5/src/widget';
import { Widget } from 'ckeditor5/src/widget';
import InsertAccordionCommand from './insertaccordioncommand';
import InsertAccordionRowCommand from './insertaccordionrowcommand';
import DeleteAccordionRowCommand from './deleteaccordionrowcommand';

// cSpell:ignore accordion insertsimpleboxcommand

/**
 * CKEditor 5 plugins do not work directly with the DOM. They are defined as
 * plugin-specific data models that are then converted to markup that
 * is inserted in the DOM.
 *
 * CKEditor 5 internally interacts with accordion as this model:
 * <accordion>
 *    <accordionTitle></accordionTitle>
 *    <accordionContent></accordionContent>
 * </accordion>
 *
 * Which is converted for the browser/user as this markup
 * <section class="simple-box">
 *   <h2 class="simple-box-title"></h1>
 *   <div class="simple-box-description"></div>
 * </section>
 *
 * This file has the logic for defining the accordion model, and for how it is
 * converted to standard DOM markup.
 */
export default class AccordionEditing extends Plugin {
  /**
   * @inheritDoc
   */
  static get pluginName() {
    return 'AccordionEditing';
  }

  static get requires() {
    return [Widget];
  }

  init() {
    this._defineSchema();
    this._defineConverters();
    this.editor.commands.add(
      'insertAccordion',
      new InsertAccordionCommand(this.editor),
    );

    this.editor.commands.add(
      'insertAccordionRowAbove',
      new InsertAccordionRowCommand(this.editor, { order: 'above' })
    );
    this.editor.commands.add(
      'insertAccordionRowBelow',
      new InsertAccordionRowCommand( this.editor, { order: 'below' } )
    );
    this.editor.commands.add(
      'deleteAccordionRow',
      new DeleteAccordionRowCommand( this.editor, {} )
    );

  }

  /*
   * This registers the structure that will be seen by CKEditor 5 as
   * <accordion>
   *    <accordionTitle></accordionTitle>
   *    <accordionContent></accordionContent>
   * </accordion>
   *
   * The logic in _defineConverters() will determine how this is converted to
   * markup.
   */
  _defineSchema() {
    // Schemas are registered via the central `editor` object.
    const schema = this.editor.model.schema;

    schema.register('accordion', {
      // Behaves like a self-contained object (e.g. an image).
      isObject: true,
      // Allow in places where other blocks are allowed (e.g. directly in the root).
      allowWhere: '$block',
    });

    schema.register( 'accordionRow', {
      allowIn: 'accordion',
      isLimit: true
    } );

    schema.register('accordionTitle', {
      // This creates a boundary for external actions such as clicking and
      // and keypress. For example, when the cursor is inside this box, the
      // keyboard shortcut for "select all" will be limited to the contents of
      // the box.
      isLimit: true,
      // This is only to be used within accordion.
      allowIn: 'accordion',
      // Allow content that is allowed in blocks (e.g. text with attributes).
      allowContentOf: '$block',
    });

    schema.register('accordionContent', {
      isLimit: true,
      allowIn: 'accordion',
      allowContentOf: '$root',
    });

    schema.addChildCheck((context, childDefinition) => {
      // Disallow accordion inside accordionContent.
      if (
        context.endsWith('accordionContent') &&
        childDefinition.name === 'accordion'
      ) {
        return false;
      }
    });
  }

  /**
   * Converters determine how CKEditor 5 models are converted into markup and
   * vice-versa.
   */
  _defineConverters() {
    // Converters are registered via the central editor object.
    const { conversion } = this.editor;

    // Upcast Converters: determine how existing HTML is interpreted by the
    // editor. These trigger when an editor instance loads.
    //
    // If <dl class="ckeditor-accordion"> is present in the existing markup
    // processed by CKEditor, then CKEditor recognizes and loads it as a
    // <accordion> model.
    conversion.for('upcast').elementToElement({
      model: 'accordion',
      view: {
        name: 'dl',
        classes: 'ckeditor-accordion',
      },
    });

    // If <dt> is present in the existing markup
    // processed by CKEditor, then CKEditor recognizes and loads it as a
    // <accordionTitle> model, provided it is a child element of <accordion>,
    // as required by the schema.
    conversion.for('upcast').elementToElement({
      model: 'accordionTitle',
      view: {
        name: 'dt',
        classes: '',
      },
    });

    // If <dd> is present in the existing markup
    // processed by CKEditor, then CKEditor recognizes and loads it as a
    // <accordionContent> model, provided it is a child element of
    // <accordion>, as required by the schema.
    conversion.for('upcast').elementToElement({
      model: 'accordionContent',
      view: {
        name: 'dd',
        classes: '',
      },
    });

    // Data Downcast Converters: converts stored model data into HTML.
    // These trigger when content is saved.
    //
    // Instances of <accordion> are saved as
    // <dl class="ckeditor-accordion">{{inner content}}</dl>.
    conversion.for('dataDowncast').elementToElement({
      model: 'accordion',
      view: {
        name: 'dl',
        classes: 'ckeditor-accordion',
      },
    });

    // Instances of <accordionTitle> are saved as
    // <dt>{{inner content}}</dt>.
    conversion.for('dataDowncast').elementToElement({
      model: 'accordionTitle',
      view: {
        name: 'dt',
        classes: '',
      },
    });

    // Instances of <accordionContent> are saved as
    // <dd>{{inner content}}</dd>.
    conversion.for('dataDowncast').elementToElement({
      model: 'accordionContent',
      view: {
        name: 'dd',
        classes: '',
      },
    });

    // Editing Downcast Converters. These render the content to the user for
    // editing, i.e. this determines what gets seen in the editor. These trigger
    // after the Data Upcast Converters, and are re-triggered any time there
    // are changes to any of the models' properties.
    //
    // Convert the <accordion> model into a container widget in the editor UI.
    conversion.for('editingDowncast').elementToElement({
      model: 'accordion',
      view: (modelElement, { writer: viewWriter }) => {
        const div = viewWriter.createContainerElement('div', {
          class: 'ckeditor-accordion',
        });

        return toWidget(div, viewWriter);
      },
    });

    // Convert the <accordionTitle> model into an editable <h2> widget.
    conversion.for('editingDowncast').elementToElement({
      model: 'accordionTitle',
      view: (modelElement, { writer: viewWriter }) => {
        const h2 = viewWriter.createEditableElement('div', {
          class: 'ckeditor-accordion-title',
        });
        return toWidgetEditable(h2, viewWriter);
      },
    });

    // Convert the <accordionContent> model into an editable <div> widget.
    conversion.for('editingDowncast').elementToElement({
      model: 'accordionContent',
      view: (modelElement, { writer: viewWriter }) => {
        const div = viewWriter.createEditableElement('div', {
          class: 'ckeditor-accordion-content',
        });
        return toWidgetEditable(div, viewWriter);
      },
    });
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc