Medium editor

Medium.com WYSIWYG editor clone. Uses contenteditable API to implement a ri...

README

medium-editor needs help!

If you would be interested in helping to maintain one of the most successful WYSIWYG text editors on github, let us know!  (See issue #1503)

MediumEditor


This is a clone of medium.com inline editor toolbar.

MediumEditor has been written using vanilla JavaScript, no additional frameworks required.
screenshot
Join the chat at https://gitter.im/yabwe/medium-editor

Browser Support

Saucelabs Build Status

Supported Browsers
NPM info
Travis build status Dependency Status devDependency Status Coverage Status

Basic usage


Demo



Installation


Via npm:

Run in your console: npm install medium-editor

Via bower:

bower install medium-editor

Via an external CDN

Using jsDelivr.

For the latest version:

  1. ``` html
  2.  <script src="//cdn.jsdelivr.net/npm/medium-editor@latest/dist/js/medium-editor.min.js"></script>
  3.  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/medium-editor@latest/dist/css/medium-editor.min.css" type="text/css" media="screen" charset="utf-8">
  4. ```

For a custom one:

  1. ``` html
  2.  <script src="//cdn.jsdelivr.net/npm/medium-editor@5.23.2/dist/js/medium-editor.min.js"></script>
  3.  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/medium-editor@5.23.2/dist/css/medium-editor.min.css" type="text/css" media="screen" charset="utf-8">
  4. ```

Using CDNJS.

Manual installation:

Download the latest release and attach medium editor's stylesheets to your page:

Find the files to below mentioned linking in the dist folder. (./medium-editor/dist/...)

  1. ``` html
  2. <link rel="stylesheet" href="css/medium-editor.css"> 
  3. <link rel="stylesheet" href="css/themes/default.css"> 
  4. ```

Usage


The next step is to reference the editor's script

  1. ``` html
  2. <script src="js/medium-editor.js"></script>
  3. ```

You can now instantiate a new MediumEditor object:
  1. ``` html
  2. <script>var editor = new MediumEditor('.editable');</script>
  3. ```

The above code will transform all the elements with the .editable class into HTML5 editable contents and add the medium editor toolbar to them.

You can also pass a list of HTML elements:

  1. ``` js
  2. var elements = document.querySelectorAll('.editable'),
  3.     editor = new MediumEditor(elements);
  4. ```

MediumEditor also supports textarea. If you provide a textarea element, the script will create a new div with contentEditable=true, hide the textarea and link the textarea value to the div HTML content.

Integrating with various frameworks

People have contributed wrappers around MediumEditor for integrating with different frameworks and tech stacks.  Take a look at the list of existing Wrappers and Integrations that have already been written for MediumEditor!

MediumEditor Options


View the MediumEditor Options documentation on all the various options for MediumEditor.

Options to customize medium-editor are passed as the second argument to the MediumEditor constructor.  Example:

  1. ``` js
  2. var editor = new MediumEditor('.editor', {
  3.     // options go here
  4. });
  5. ```

Core options

__activeButtonClass__: CSS class added to active buttons in the toolbar. Default: 'medium-editor-button-active'
__buttonLabels__: type of labels on the buttons. Values: false | 'fontawesome'.  Default: false

NOTE:

Using 'fontawesome' as the buttonLabels requires version 4.1.0 of the fontawesome css to be on the page to ensure all icons will be displayed correctly

__delay__: time in milliseconds to show the toolbar or anchor tag preview. Default: 0
__disableReturn__:  enables/disables the use of the return-key. You can also set specific element behavior by using setting a data-disable-return attribute. Default: false
__disableDoubleReturn__:  allows/disallows two (or more) empty new lines. You can also set specific element behavior by using setting a data-disable-double-return attribute. Default: false
__disableExtraSpaces__:  when set to true, it disallows spaces at the beginning and end of the element. Also it disallows entering 2 consecutive spaces between 2 words. Default: false
__disableEditing__: enables/disables adding the contenteditable behavior. Useful for using the toolbar with customized buttons/actions. You can also set specific element behavior by using setting a data-disable-editing attribute. Default: false
__elementsContainer__: specifies a DOM node to contain MediumEditor's toolbar and anchor preview elements. Default: document.body
__extensions__: extension to use (see Custom Buttons and Extensions) for more. Default:{}
__spellcheck__: Enable/disable native contentEditable automatic spellcheck. Default: true
__targetBlank__: enables/disables target="\_blank" for anchor tags. Default: false

Toolbar options


The toolbar for MediumEditor is implemented as a built-in extension which automatically displays whenever the user selects some text.  The toolbar can hold any set of defined built-in buttons, but can also hold any custom buttons passed in as extensions.

Options for the toolbar are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     toolbar: {
  4.         /* These are the default options for the toolbar,
  5.            if nothing is passed this is what is used */
  6.         allowMultiParagraphSelection: true,
  7.         buttons: ['bold', 'italic', 'underline', 'anchor', 'h2', 'h3', 'quote'],
  8.         diffLeft: 0,
  9.         diffTop: -10,
  10.         firstButtonClass: 'medium-editor-button-first',
  11.         lastButtonClass: 'medium-editor-button-last',
  12.         relativeContainer: null,
  13.         standardizeSelectionStart: false,
  14.         static: false,
  15.         /* options which only apply when static is true */
  16.         align: 'center',
  17.         sticky: false,
  18.         updateOnEmptySelection: false
  19.     }
  20. });
  21. ```

__allowMultiParagraphSelection__: enables/disables whether the toolbar should be displayed when selecting multiple paragraphs/block elements. Default: true
__buttons__: the set of buttons to display on the toolbar. Default: ['bold', 'italic', 'underline', 'anchor', 'h2', 'h3', 'quote']
  See Button Options for details on more button options
__diffLeft__: value in pixels to be added to the X axis positioning of the toolbar. Default: 0
__diffTop__: value in pixels to be added to the Y axis positioning of the toolbar. Default: -10
__firstButtonClass__: CSS class added to the first button in the toolbar. Default: 'medium-editor-button-first'
__lastButtonClass__: CSS class added to the last button in the toolbar. Default: 'medium-editor-button-last'
__relativeContainer__: DOMElement to append the toolbar to instead of the body.  When passed, the toolbar will also be positioned relative instead of absolute. Default: null
__standardizeSelectionStart__: enables/disables standardizing how the beginning of a range is decided between browsers whenever the selected text is analyzed for updating toolbar buttons status. Default: false
__static__: enable/disable the toolbar always displaying in the same location relative to the medium-editor element. Default: false

Options which only apply when the static option is being used:
__align__: left|center|right - When the __static__ option is true, this aligns the static toolbar relative to the medium-editor element. Default: center
__sticky__: When the __static__ option is true, this enables/disables the toolbar "sticking" to the viewport and staying visible on the screen while the page scrolls. Default: false
__updateOnEmptySelection__: When the __static__ option is true, this enables/disables updating the state of the toolbar buttons even when the selection is collapsed (there is no selection, just a cursor). Default: false

To disable the toolbar (which also disables the anchor-preview extension), set the value of the toolbar option to false:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     toolbar: false
  4. });
  5. ```

Button Options


Button behavior can be modified by passing an object into the buttons array instead of a string. This allow for overriding some of the default behavior of buttons. The following options are some of the basic parts of buttons that you may override, but any part of the MediumEditor.Extension.prototype can be overridden via these button options. (Check out the source code for buttons to see what all can be overridden).

__name__: name of the button being overridden
__action__: argument to pass to MediumEditor.execAction() when the button is clicked.
__aria__: value to add as the aria-label attribute of the button element displayed in the toolbar. This is also used as the tooltip for the button.
__tagNames__: array of element tag names that would indicate that this button has already been applied. If this action has already been applied, the button will be displayed as 'active' in the toolbar.
* _Example_: For 'bold', if the text is ever within a `` or `` tag that indicates the text is already bold. So the array of tagNames for bold would be: `['b', 'strong']`
  __NOTE__: This is not used if useQueryState is set to true.
__style__: A pair of css property & value(s) that indicate that this button has already been applied. If this action has already been applied, the button will be displayed as 'active' in the toolbar.
  _Example_: For 'bold', if the text is ever within an element with a 'font-weight' style property set to 700 or 'bold', that indicates the text is already bold.  So the style object for bold would be { prop: 'font-weight', value: '700|bold' }
  __NOTE__: This is not used if useQueryState is set to true.
  Properties of the __style__ object:
    __prop__: name of the css property
    __value__: value(s) of the css property (multiple values can be separated by a '|')
__useQueryState__: Enables/disables whether this button should use the built-in document.queryCommandState() method to determine whether the action has already been applied.  If the action has already been applied, the button will be displayed as 'active' in the toolbar
  _Example_: For 'bold', if this is set to true, the code will call document.queryCommandState('bold') which will return true if the browser thinks the text is already bold, and false otherwise
__contentDefault__: Default innerHTML to put inside the button
__contentFA__: The innerHTML to use for the content of the button if the __buttonLabels__ option for MediumEditor is set to 'fontawesome'
__classList__: An array of classNames (strings) to be added to the button
__attrs__: A set of key-value pairs to add to the button as custom attributes to the button element.

Example of overriding buttons (here, the goal is to mimic medium by having H1 and H2 buttons which actually produce `

` and `

` tags respectively):
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     toolbar: {
  4.         buttons: [
  5.             'bold',
  6.             'italic',
  7.             {
  8.                 name: 'h1',
  9.                 action: 'append-h2',
  10.                 aria: 'header type 1',
  11.                 tagNames: ['h2'],
  12.                 contentDefault: '<b>H1</b>',
  13.                 classList: ['custom-class-h1'],
  14.                 attrs: {
  15.                     'data-custom-attr': 'attr-value-h1'
  16.                 }
  17.             },
  18.             {
  19.                 name: 'h2',
  20.                 action: 'append-h3',
  21.                 aria: 'header type 2',
  22.                 tagNames: ['h3'],
  23.                 contentDefault: '<b>H2</b>',
  24.                 classList: ['custom-class-h2'],
  25.                 attrs: {
  26.                     'data-custom-attr': 'attr-value-h2'
  27.                 }
  28.             },
  29.             'justifyCenter',
  30.             'quote',
  31.             'anchor'
  32.         ]
  33.     }
  34. });
  35. ```

Anchor Preview options


The anchor preview is a built-in extension which automatically displays a 'tooltip' when the user is hovering over a link in the editor.  The tooltip will display the href of the link, and when clicked, will open the anchor editing form in the toolbar.

Options for the anchor preview 'tooltip' are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     anchorPreview: {
  4.         /* These are the default options for anchor preview,
  5.            if nothing is passed this is what it used */
  6.         hideDelay: 500,
  7.         previewValueSelector: 'a'
  8.     }
  9. }
  10. });
  11. ```

__hideDelay__: time in milliseconds to show the anchor tag preview after the mouse has left the anchor tag. Default: 500
__previewValueSelector__: the default selector to locate where to put the activeAnchor value in the preview. You should only need to override this if you've modified the way in which the anchor-preview extension renders. Default: 'a'
__showWhenToolbarIsVisible__: determines whether the anchor tag preview shows up when the toolbar is visible. You should set this value to true if the static option for the toolbar is true and you want the preview to show at the same time. Default: false
__showOnEmptyLinks__: determines whether the anchor tag preview shows up on link with href as '' or '#something'. You should set this value to false if you do not want the preview to show up in such use cases. Default: true

To disable the anchor preview, set the value of the anchorPreview option to false:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     anchorPreview: false
  4. });
  5. ```
NOTE:
If the toolbar is disabled (via toolbar: false option or data-disable-toolbar attribute) the anchor-preview is automatically disabled.
If the anchor editing form is not enabled, clicking on the anchor-preview will not allow the href of the link to be edited

Placeholder Options


The placeholder handler is a built-in extension which displays placeholder text when the editor is empty.

Options for placeholder are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     placeholder: {
  4.         /* This example includes the default options for placeholder,
  5.            if nothing is passed this is what it used */
  6.         text: 'Type your text',
  7.         hideOnClick: true
  8.     }
  9. });
  10. ```

__text__: Defines the default placeholder for empty contenteditables when __placeholder__ is not set to false. You can overwrite it by setting a data-placeholder attribute on the editor elements. Default: 'Type your text'

__hideOnClick__: Causes the placeholder to disappear as soon as the field gains focus. Default: true.
To hide the placeholder only after starting to type, and to show it again as soon as field is empty, set this option to false.


To disable the placeholder, set the value of the placeholder option to false:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     placeholder: false
  4. });
  5. ```

Anchor Form options


The anchor form is a built-in button extension which allows the user to add/edit/remove links from within the editor.  When 'anchor' is passed in as a button in the list of buttons, this extension will be enabled and can be triggered by clicking the corresponding button in the toolbar.

Options for the anchor form are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     toolbar: {
  4.         buttons: ['bold', 'italic', 'underline', 'anchor']
  5.     },
  6.     anchor: {
  7.         /* These are the default options for anchor form,
  8.            if nothing is passed this is what it used */
  9.         customClassOption: null,
  10.         customClassOptionText: 'Button',
  11.         linkValidation: false,
  12.         placeholderText: 'Paste or type a link',
  13.         targetCheckbox: false,
  14.         targetCheckboxText: 'Open in new window'
  15.     }
  16. }
  17. });
  18. ```

__customClassOption__: custom class name the user can optionally have added to their created links (ie 'button').  If passed as a non-empty string, a checkbox will be displayed allowing the user to choose whether to have the class added to the created link or not. Default: null
__customClassOptionText__: text to be shown in the checkbox when the __customClassOption__ is being used. Default: 'Button'
__linkValidation__: enables/disables check for common URL protocols on anchor links. Converts invalid url characters (ie spaces) to valid characters using encodeURI. Default: false
__placeholderText__: text to be shown as placeholder of the anchor input. Default: 'Paste or type a link'
__targetCheckbox__: enables/disables displaying a "Open in new window" checkbox, which when checked changes the target attribute of the created link. Default: false
__targetCheckboxText__: text to be shown in the checkbox enabled via the __targetCheckbox__ option. Default: 'Open in new window'

Paste Options


The paste handler is a built-in extension which attempts to filter the content when the user pastes.  How the paste handler filters is configurable via specific options.

Options for paste handling are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     paste: {
  4.         /* This example includes the default options for paste,
  5.            if nothing is passed this is what it used */
  6.         forcePlainText: true,
  7.         cleanPastedHTML: false,
  8.         cleanReplacements: [],
  9.         cleanAttrs: ['class', 'style', 'dir'],
  10.         cleanTags: ['meta'],
  11.         unwrapTags: []
  12.     }
  13. });
  14. ```

__forcePlainText__: Forces pasting as plain text. Default: true
__cleanPastedHTML__: cleans pasted content from different sources, like google docs etc. Default: false
__preCleanReplacements__: custom pairs (2 element arrays) of RegExp and replacement text to use during paste when __forcePlainText__ or __cleanPastedHTML__ are true OR when calling cleanPaste(text) helper method.  These replacements are executed _before_ builtin replacements.  Default: []
__cleanReplacements__: custom pairs (2 element arrays) of RegExp and replacement text to use during paste when __forcePlainText__ or __cleanPastedHTML__ are true OR when calling cleanPaste(text) helper method.  These replacements are executed _after_ builtin replacements.  Default: []
__cleanAttrs__: list of element attributes to remove during paste when __cleanPastedHTML__ is true or when calling cleanPaste(text) or pasteHTML(html,options) helper methods. Default: ['class', 'style', 'dir']
__cleanTags__: list of element tag names to remove during paste when __cleanPastedHTML__ is true or when calling cleanPaste(text) or pasteHTML(html,options) helper methods. Default: ['meta']
__unwrapTags__: list of element tag names to unwrap (remove the element tag but retain its child elements) during paste when __cleanPastedHTML__ is true or when calling cleanPaste(text) or pasteHTML(html,options) helper methods. Default: []

KeyboardCommands Options


The keyboard commands handler is a built-in extension for mapping key-combinations to actions to execute in the editor.

Options for KeyboardCommands are passed as an object that is a member of the outer options object. Example:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     keyboardCommands: {
  4.         /* This example includes the default options for keyboardCommands,
  5.            if nothing is passed this is what it used */
  6.         commands: [
  7.             {
  8.                 command: 'bold',
  9.                 key: 'B',
  10.                 meta: true,
  11.                 shift: false,
  12.                 alt: false
  13.             },
  14.             {
  15.                 command: 'italic',
  16.                 key: 'I',
  17.                 meta: true,
  18.                 shift: false,
  19.                 alt: false
  20.             },
  21.             {
  22.                 command: 'underline',
  23.                 key: 'U',
  24.                 meta: true,
  25.                 shift: false,
  26.                 alt: false
  27.             }
  28.         ],
  29.     }
  30. });
  31. ```

__commands__: Array of objects describing each command and the combination of keys that will trigger it.  Required for each object:
  _command_: argument passed to editor.execAction() when key-combination is used
    if defined as false, the shortcut will be disabled
  _key_: keyboard character that triggers this command
  _meta_: whether the ctrl/meta key has to be active or inactive
  _shift_: whether the shift key has to be active or inactive
  _alt_: whether the alt key has to be active or inactive

To disable the keyboard commands, set the value of the keyboardCommands option to false:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     keyboardCommands: false
  4. });
  5. ```

Auto Link Options


The auto-link handler is a built-in extension which automatically turns URLs entered into the text field into HTML anchor tags (similar to the functionality of Markdown).  This feature is OFF by default.

To enable built-in auto-link support, set the value of the autoLink option to true:

  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     autoLink: true
  4. });
  5. ```

Image Dragging Options


The image dragging handler is a built-in extension for handling dragging & dropping images into the contenteditable.  This feature is ON by default.

To disable built-in image dragging, set the value of the imageDragging option to false:
  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     imageDragging: false
  4. });
  5. ```

Disable File Dragging

To stop preventing drag & drop events and disable file dragging in general, provide a dummy ImageDragging extension.
  1. ``` js
  2. var editor = new MediumEditor('.editor', {
  3.     extensions: {
  4.         'imageDragging': {}
  5.     }
  6. });
  7. ```
Due to the state of code in 5.0.0, the editorALWAYS prevented any drag and drop actions.
We will have a better way to disable file dragging in 6.*

Options Example:


  1. ``` js
  2. var editor = new MediumEditor('.editable', {
  3.     delay: 1000,
  4.     targetBlank: true,
  5.     toolbar: {
  6.         buttons: ['bold', 'italic', 'quote'],
  7.         diffLeft: 25,
  8.         diffTop: 10,
  9.     },
  10.     anchor: {
  11.         placeholderText: 'Type a link',
  12.         customClassOption: 'btn',
  13.         customClassOptionText: 'Create Button'
  14.     },
  15.     paste: {
  16.         cleanPastedHTML: true,
  17.         cleanAttrs: ['style', 'dir'],
  18.         cleanTags: ['label', 'meta'],
  19.         unwrapTags: ['sub', 'sup']
  20.     },
  21.     anchorPreview: {
  22.         hideDelay: 300
  23.     },
  24.     placeholder: {
  25.         text: 'Click to edit'
  26.     }
  27. });
  28. ```

Buttons


By default, MediumEditor supports buttons for most of the commands for document.execCommand() that are well-supported across all its supported browsers.

Default buttons.


MediumEditor, by default, will show only the buttons listed here to avoid a huge toolbar:

__bold__
__italic__
__underline__
__anchor__ _(built-in support for collecting a URL via the anchor extension)_
__h2__
__h3__
__quote__

All buttons.


These are all the built-in buttons supported by MediumEditor.

__bold__
__italic__
__underline__
__strikethrough__
__subscript__
__superscript__
__anchor__
__image__ (this simply converts selected text to an image tag)
__quote__
__pre__
__orderedlist__
__unorderedlist__
__indent__ (moves the selected text up one level)
__outdent__ (moves the selected text down one level)
__justifyLeft__
__justifyCenter__
__justifyRight__
__justifyFull__
__h1__
__h2__
__h3__
__h4__
__h5__
__h6__
__removeFormat__ (clears inline style formatting, preserves blocks)
__html__ (parses selected html and converts into actual html elements)

Themes


Check out the Wiki page for a list of available themes: https://github.com/yabwe/medium-editor/wiki/Themes

API


View the MediumEditor Object API documentation on the Wiki for details on all the methods supported on the MediumEditor object.

Initialization methods

__MediumEditor(elements, options)__:  Creates an instance of MediumEditor
__.destroy()__: tears down the editor if already setup, removing all DOM elements and event handlers
__.setup()__: rebuilds the editor if it has already been destroyed, recreating DOM elements and attaching event handlers
__.addElements()__: add elements to an already initialized instance of MediumEditor
__.removeElements()__: remove elements from an already initialized instance of MediumEditor

Event Methods

__.on(target, event, listener, useCapture)__: attach a listener to a DOM event which will be detached when MediumEditor is deactivated
__.off(target, event, listener, useCapture)__: detach a listener to a DOM event that was attached via on()
__.subscribe(event, listener)__: attaches a listener to a custom medium-editor event
__.unsubscribe(event, listener)__: detaches a listener from a custom medium-editor event
__.trigger(name, data, editable)__: manually triggers a custom medium-editor event

Selection Methods

__.checkSelection()__: manually trigger an update of the toolbar and extensions based on the current selection
__.exportSelection()__: return a data representation of the selected text, which can be applied via importSelection()
__.importSelection(selectionState)__: restore the selection using a data representation of previously selected text (ie value returned by exportSelection())
__.getFocusedElement()__: returns an element if any contenteditable element monitored by MediumEditor currently has focused
__.getSelectedParentElement(range)__: get the parent contenteditable element that contains the current selection
__.restoreSelection()__: restore the selection to what was selected when saveSelection() was called
__.saveSelection()__: internally store the set of selected text
__.selectAllContents()__: expands the selection to contain all text within the focused contenteditable
__.selectElement(element)__: change selection to be a specific element and update the toolbar to reflect the selection
__.stopSelectionUpdates()__: stop the toolbar from updating to reflect the state of the selected text
__.startSelectionUpdates()__: put the toolbar back into its normal updating state

Editor Action Methods

__.cleanPaste(text)__: convert text to plaintext and replace current selection with result
__.createLink(opts)__: creates a link via the native document.execCommand('createLink') command
__.execAction(action, opts)__: executes an built-in action via document.execCommand
__.pasteHTML(html, options)__: replace the current selection with html
__.queryCommandState(action)__: wrapper around the browser's built in document.queryCommandState(action) for checking whether a specific action has already been applied to the selection.

Helper Methods

__.delay(fn)__: delay any function from being executed by the amount of time passed as the delay option
__.getContent(index)__: gets the trimmed innerHTML of the element at index
__.getExtensionByName(name)__: get a reference to an extension with the specified name
__.resetContent(element)__: reset the content of all elements or a specific element to its value when added to the editor initially
__.serialize()__: returns a JSON object with elements contents
__.setContent(html, index)__: sets the innerHTML to html of the element at index

Static Methods/Properties

__.getEditorFromElement(element)__: retrieve the instance of MediumEditor that is monitoring the provided editor element
__.version__: the version information for the MediumEditor library

Dynamically add/remove elements to your instance


It is possible to dynamically add new elements to your existing MediumEditor instance:

  1. ``` js
  2. var editor = new MediumEditor('.editable');
  3. editor.subscribe('editableInput', this._handleEditableInput.bind(this));

  4. // imagine an ajax fetch/any other dynamic functionality which will add new '.editable' elements to the DOM

  5. editor.addElements('.editable');
  6. // OR editor.addElements(document.getElementsByClassName('editable'));
  7. // OR editor.addElements(document.querySelectorAll('.editable'));
  8. ```

Passing an elements or array of elements to addElements(elements) will:
Add the given element or array of elements to the internal this.elements array.
Ensure the element(s) are initialized with the proper attributes and event handlers as if the element had been passed during instantiation of the editor.
* For any `