soundcite-1.1.2/js/ckeditor5_plugins/soundcite/src/soundciteediting.js

js/ckeditor5_plugins/soundcite/src/soundciteediting.js
import { Plugin } from "ckeditor5/src/core";
import { toWidget, toWidgetEditable } from "ckeditor5/src/widget";
import { Widget } from "ckeditor5/src/widget";
import InsertSoundciteCommand from "./insertsoundcitecommand";

// cSpell:ignore Soundcite insertsoundcitecommand

/**
 * 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 Soundcite as this model:
 * <Soundcite url="" start="" end="" plays="" text="">
 * </Soundcite>
 *
 * Which is converted for the browser/user as this markup
 * <span class="coundcite" data-url="" data-start="" data-end="" data-plays="">
 *   // Link Text
 * </span>
 *
 * This file has the logic for defining the Soundcite model, and for how it is
 * converted to standard DOM markup.
 */
export default class SoundciteEditing extends Plugin {
  static get requires() {
    return [Widget];
  }

  init() {
    this._defineSchema();
    this._defineConverters();
    this.editor.commands.add(
      "insertSoundcite",
      new InsertSoundciteCommand(this.editor)
    );
  }

  /*
   * This registers the structure that will be seen by CKEditor 5 as
   * <Soundcite>
   * </Soundcite>
   *
   * 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("Soundcite", {
      // 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).
      isInline: true,
      allowWhere: "$text",
      allowAttributes: [
        "data-url",
        "data-start",
        "data-end",
        "data-plays",
        "text",
      ],
    });

    schema.addChildCheck((context, childDefinition) => {
      // Disallow Soundcite inside Soundcite.
      if (
        context.endsWith("Soundcite") &&
        childDefinition.name === "Soundcite"
      ) {
        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 <span class="soundcite"> is present in the existing markup
    // processed by CKEditor, then CKEditor recognizes and loads it as a
    // <Soundcite> model.
    conversion.for("upcast").elementToElement({
      model: (viewElement, { writer: modelWriter }) => {
        return modelWriter.createElement("Soundcite", {
          "data-url": viewElement.getAttribute("data-url"),
          "data-start": viewElement.getAttribute("data-start"),
          "data-end": viewElement.getAttribute("data-end"),
          "data-plays": viewElement.getAttribute("data-plays"),
          text: viewElement.getChild(0).data,
        });
      },
      view: {
        name: "span",
        classes: "soundcite",
      },
    });

    conversion.for("downcast").elementToElement({
      model: "Soundcite",
      view: (modelElement, { writer: viewWriter }) => {
        const span = viewWriter.createContainerElement("span", {
          class: "soundcite",
          "data-url": modelElement.getAttribute("data-url"),
          "data-start": modelElement.getAttribute("data-start"),
          "data-end": modelElement.getAttribute("data-end"),
          "data-plays": modelElement.getAttribute("data-plays"),
        });

        const text = viewWriter.createText(modelElement.getAttribute("text"));
        viewWriter.insert(viewWriter.createPositionAt(span, 0), text);

        return toWidget(span, viewWriter, { label: "Soundcite widget" });
      },
    });
  }
}

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

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