MediumEditor

repository·master·Indexed 12 days ago

https://github.com/yabwe/medium-editor

A lightweight, framework-agnostic vanilla JavaScript WYSIWYG inline editor that clones the toolbar functionality of medium.com. Version 5.23.3 supports custom toolbar buttons, anchor previews, paste handling, and keyboard commands.

Tokens
21.2K
Snippets
57
Records
77
Agent score
96%

What's inside MediumEditor

  1. What are Extensions in MediumEditor?

    master

    Extensions are custom actions or commands that can be passed into the extensions option during MediumEditor initialization. They allow you to:

    1. Add new functionality: Implement features like auto-link detection, keyboard shortcuts, or image drag-and-drop.
    2. Replace existing features: If an extension shares the same name as a built-in feature, it will replace the default implementation.

    New extensions should be created by extending the MediumEditor.Extension object using MediumEditor.Extension.extend().

  2. How to use custom event listeners in extensions

    master

    Extensions can subscribe to MediumEditor's custom events using this.subscribe(eventName, handler).

    When handling custom events like editableKeyDown, the handler receives two arguments:

    1. event: The standard DOM event object.
    2. editable: A reference to the specific editor element that triggered the event.

    Using the editable argument is preferred over event.currentTarget when you need to explicitly target a specific element, especially for complex events like focus or blur, or when triggering events manually.

    var MyExtension = MediumEditor.Extension.extend({
      name: 'custom-event-extension',
    
      init: function () {
        // Subscribe to the custom 'editableKeyDown' event
        this.subscribe('editableKeyDown', this.handleKeydown.bind(this));
      },
    
      handleKeydown: function (event, editable) {
        // 'editable' is the specific element that triggered the event
        if (event.key === 'Escape') {
          editable.setAttribute('data-custom-state', 'active');
        }
      }
    });
  3. Create a Button Extension

    master

    A Button Extension is a specific type of extension that renders a button into the MediumEditor toolbar. To define an extension as a Button Extension, you must implement the getButton() method.

    Once implemented, you must include the extension's name in the toolbar.buttons option during MediumEditor initialization. The toolbar will call getButton() and append the returned HTMLElement to the toolbar in the order specified in the configuration.

    // The presence of getButton() defines it as a Button Extension
    MediumEditor.extensions.myCustomButton = MediumEditor.Extension.extend({
      name: 'my-custom-button',
      getButton: function () {
        var button = document.createElement('button');
        button.innerHTML = 'Click Me';
        return button;
      }
    });
    
    // Usage in configuration:
    // toolbar: { buttons: ['my-custom-button'] }
  4. What are Buttons and Form Extensions?

    master

    MediumEditor uses a hierarchy of extensions to manage UI and user interaction:

    Buttons

    Buttons are a specific type of Extension designed to work with the MediumEditor toolbar. They follow a contract that allows them to:

    • Display a clickable element in the toolbar.
    • Execute actions on the editor text (e.g., bold, italic).
    • Update their visual state (active/inactive) based on the current user selection.

    Form Extensions

    Form Extensions are a specialized type of Button Extension. They inherit all Button lifecycle methods but add the ability to collect user input via the toolbar (e.g., prompting for a URL in the anchor button or selecting a size in the fontsize button).

  5. Develop custom MediumEditor extensions in v5.0.0

    master

    Version 5.0.0 introduced a new model for extensions and buttons. Key changes for developers:

    • Accessing Instance: Extensions no longer use .parent. Instead, they access the MediumEditor instance via the .base property (which is populated before .init() is called).
    • Initialization: The .init() method no longer receives the instance as an argument; use .base instead.
    • Lifecycle: .deactivate() is no longer called by MediumEditor. Use .destroy() for cleanup when the editor is destroyed.
    • Options: The .options property has been removed from built-in extensions/buttons. Access and set properties directly on the object prototype (e.g., use this.action instead of this.options.action).
  6. Disable Anchor Preview

    master

    To disable the anchor preview extension, set the anchorPreview option to false.

    Note:

    • The anchor preview is automatically disabled if the toolbar is disabled (via toolbar: false or data-disable-toolbar).
    • If the anchor editing form is not enabled, clicking the preview will not allow editing the link's href.
    var editor = new MediumEditor('.editable', {
        anchorPreview: false
    });
  7. Customize button appearance with FontAwesome and tooltips

    master

    You can enhance button appearance in two ways:

    1. Icons: Set the innerHTML of the button to a FontAwesome <i> tag in the init() method.
    2. Tooltips: Set the title attribute of the button element.

    To ensure all built-in buttons also use FontAwesome, set the buttonLabels: 'fontawesome' option in the MediumEditor configuration.

    var MyExtension = MediumEditor.Extension.extend({
      name: 'my-extension',
    
      init: function () {
        this.button = this.document.createElement('button');
        this.button.classList.add('medium-editor-action');
        this.button.innerHTML = '<i class="fa fa-paint-brush"></i>';
        this.button.title = 'Highlight';
      },
    
      getButton: function () {
        return this.button;
      }
    });
    
    var editor = new MediumEditor('.editable', {
      toolbar: {
        buttons: ['bold', 'my-extension']
      },
      buttonLabels: 'fontawesome',
      extensions: {
        'my-extension': new MyExtension()
      }
    });
  8. Create a custom button extension

    master

    To add a new button to the MediumEditor toolbar, you must create an extension by extending MediumEditor.Extension.

    1. Define the extension: Use MediumEditor.Extension.extend({ name: 'your-extension-name' }).
    2. Register the extension: Pass the extension instance into the extensions object in the MediumEditor configuration.
    3. Add to toolbar: Include the extension's name in the toolbar.buttons array.

    Note: The name used in the extension definition must match the string used in the toolbar.buttons array for the toolbar to find and display it.

    var MyExtension = MediumEditor.Extension.extend({
      name: 'my-extension'
    });
    
    var editor = new MediumEditor('.editable', {
      toolbar: {
        buttons: ['bold', 'my-extension']
      },
      extensions: {
        'my-extension': new MyExtension()
      }
    });