Socket
Socket
Sign inDemoInstall

medium-editor

Package Overview
Dependencies
Maintainers
6
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

medium-editor - npm Package Compare versions

Comparing version 5.20.2 to 5.21.0

42

CUSTOM-EVENTS.md
# MediumEditor Custom Events (v5.0.0)
MediumEditor exposes a variety of custom events for convienience when using the editor with your web application. You can attach and detach listeners to these custom events, as well as manually trigger any custom events including your own custom events.
MediumEditor exposes a variety of custom events for convenience when using the editor with your web application. You can attach and detach listeners to these custom events, as well as manually trigger any custom events including your own custom events.

@@ -9,3 +9,3 @@ **NOTE:**

If you need to override the editor's bult-in behavior, try overriding the built-in extensions with your own [custom extension](src/js/extensions).
If you need to override the editor's built-in behavior, try overriding the built-in extensions with your own [custom extension](src/js/extensions).

@@ -20,2 +20,3 @@ <!-- START doctoc generated TOC please keep comment here to allow auto update -->

- [Custom Events](#custom-events)
- [`addElement`](#addelement)
- [`blur`](#blur)

@@ -25,2 +26,3 @@ - [`editableInput`](#editableinput)

- [`focus`](#focus)
- [`removeElement`](#removeelement)
- [Toolbar Custom Events](#toolbar-custom-events)

@@ -62,3 +64,3 @@ - [`hideToolbar`](#hidetoolbar)

2. _**listener(data, editable)** (`function`)_:
2. _**listener(data, editable)** (`function`)_:

@@ -87,3 +89,3 @@ * Listener method that will be called whenever the custom event is triggered.

2. _**listener** (`function`)_:
2. _**listener** (`function`)_:

@@ -117,2 +119,16 @@ * A reference to the listener to detach. This must be a match by-reference and not a copy.

### `addElement`
`addElement` is triggered whenever an element is added to the editor after the editor has been instantiated. This custom event will be triggered **after** the element has already been initialized by the editor and added to the internal array of **elements**. If the element being added was a `<textarea>`, the element passed to the listener will be the created `<div contenteditable=true>` element and not the root `<textarea>`.
**Arguments to listener**
1. _**data** (`object`)_
* Properties of data object
* `target`: element which was added to the editor
* `currentTarget`: element which was added to the editor
2. _**editable** (`HTMLElement`)_
* element which was added to the editor
***
### `blur`

@@ -149,4 +165,18 @@

`focus` is triggered whenver a `contenteditable` element within an editor receives focus. If the user interacts with any editor maintained elements (ie toolbar), `blur` is NOT triggered because focus has not been lost. Thus, `focus` will only be triggered when an `contenteditable` element (or the editor that contains it) is first interacted with.
`focus` is triggered whenever a `contenteditable` element within an editor receives focus. If the user interacts with any editor maintained elements (ie toolbar), `blur` is NOT triggered because focus has not been lost. Thus, `focus` will only be triggered when an `contenteditable` element (or the editor that contains it) is first interacted with.
***
### `removeElement`
`removeElement` is triggered whenever an element is removed from the editor after the editor has been instantiated. This custom event will be triggered **after** the element has already been removed from the editor and any events attached to it have already been removed. If the element being removed was a `<div>` created to correspond to a `<textarea>`, the element will already have been removed from the DOM.
**Arguments to listener**
1. _**data** (`object`)_
* Properties of data object
* `target`: element which was removed from the editor
* `currentTarget`: element which was removed from the editor
2. _**editable** (`HTMLElement`)_
* element which was removed from the editor
## Toolbar Custom Events

@@ -171,3 +201,3 @@

These events are triggered whenever a native browser event is triggered for any of the `contenteditable` elements monitored by this instnace of MediumEditor.
These events are triggered whenever a native browser event is triggered for any of the `contenteditable` elements monitored by this instance of MediumEditor.

@@ -174,0 +204,0 @@ For example, the `editableClick` custom event will be triggered when a native `click` event is fired on any of the `contenteditable` elements. This provides a single event listener that can get fired for all elements, and also allows for the `contenteditable` element that triggered the event to be passed to the listener.

2

package.json
{
"name": "medium-editor",
"version": "5.20.2",
"version": "5.21.0",
"author": "Davi Ferreira <hi@daviferreira.com>",

@@ -5,0 +5,0 @@ "contributors": [

@@ -118,2 +118,14 @@ /*global fireEvent */

it('should trigger addElement custom event for each element', function () {
var editor = this.newMediumEditor('.editor'),
spy = jasmine.createSpy('handler');
editor.subscribe('addElement', spy);
editor.addElements('.add-one');
expect(spy).toHaveBeenCalledWith({ target: this.addOne, currentTarget: this.addOne }, this.addOne);
editor.addElements(document.getElementsByClassName('add-two'));
expect(spy).toHaveBeenCalledWith({ target: this.addTwo, currentTarget: this.addTwo }, this.addTwo);
});
function runAddTest(inputSupported) {

@@ -239,2 +251,14 @@ it('should re-attach element properly when removed from dom, cleaned up and injected to dom again', function () {

});
it('should trigger removeElement custom event for each element', function () {
var editor = this.newMediumEditor('.editor, .add-one, .add-two'),
spy = jasmine.createSpy('handler');
editor.subscribe('removeElement', spy);
editor.removeElements('.add-one');
expect(spy).toHaveBeenCalledWith({ target: this.addOne, currentTarget: this.addOne }, this.addOne);
editor.removeElements(document.getElementsByClassName('add-two'));
expect(spy).toHaveBeenCalledWith({ target: this.addTwo, currentTarget: this.addTwo }, this.addTwo);
});
});

@@ -241,0 +265,0 @@ });

@@ -208,3 +208,3 @@ /*global selectElementContents,

jasmine.clock().tick(1);
expect(spy).toHaveBeenCalledWith({ currentTarget: this.el, target: this.el }, this.el);
expect(spy).toHaveBeenCalledWith(evt, this.el);
});

@@ -211,0 +211,0 @@

@@ -44,2 +44,8 @@ /*global fireEvent, selectElementContentsAndFire */

it('should not set a placeholder for elements with table', function () {
this.el.innerHTML = '<table></table>';
var editor = this.newMediumEditor('.editor');
expect(editor.elements[0].className).not.toContain('medium-editor-placeholder');
});
it('should set placeholder for elements with empty children', function () {

@@ -157,2 +163,11 @@ this.el.innerHTML = '<p><br></p><div class="empty"></div>';

it('should add the default placeholder text when data-placeholder is not present on dynamically added elements', function () {
var editor = this.newMediumEditor('.editor');
expect(editor.elements.length).toBe(1);
var newEl = this.createElement('div', 'other-element');
editor.addElements(newEl);
validatePlaceholderContent(newEl, MediumEditor.extensions.placeholder.prototype.text);
});
it('should remove the added data-placeholder attribute when destroyed', function () {

@@ -168,2 +183,14 @@ expect(this.el.hasAttribute('data-placeholder')).toBe(false);

it('should remove the added data-placeholder attribute when elements are removed dynamically from the editor', function () {
var editor = this.newMediumEditor('.editor'),
newEl = this.createElement('div', 'other-element');
expect(newEl.hasAttribute('other-element')).toBe(false);
editor.addElements(newEl);
expect(newEl.getAttribute('data-placeholder')).toBe(MediumEditor.extensions.placeholder.prototype.text);
editor.removeElements('.other-element');
expect(newEl.hasAttribute('data-placeholder')).toBe(false);
});
it('should not remove custom data-placeholder attribute when destroyed', function () {

@@ -170,0 +197,0 @@ var placeholderText = 'Custom placeholder';

@@ -1215,2 +1215,5 @@ (function () {

this.elements.push(element);
// Trigger event so extensions can know when an element has been added
this.trigger('addElement', { target: element, currentTarget: element }, element);
}, this);

@@ -1238,2 +1241,4 @@ },

}
// Trigger event so extensions can clean-up elements that are being removed
this.trigger('removeElement', { target: element, currentTarget: element }, element);
return false;

@@ -1240,0 +1245,0 @@ }

@@ -363,2 +363,4 @@ (function () {

break;
// TODO: We need to have a custom 'paste' event separate from 'editablePaste'
// Need to think about the way to introduce this without breaking folks
case 'editablePaste':

@@ -560,3 +562,3 @@ // Detecting paste on the contenteditables

handlePaste: function (event) {
this.triggerCustomEvent('editablePaste', { currentTarget: event.currentTarget, target: event.target }, event.currentTarget);
this.triggerCustomEvent('editablePaste', event, event.currentTarget);
},

@@ -563,0 +565,0 @@

@@ -146,7 +146,16 @@ (function () {

if (this.forcePlainText || this.cleanPastedHTML) {
this.subscribe('editablePaste', this.handlePaste.bind(this));
this.subscribe('editableKeydown', this.handleKeydown.bind(this));
// We need access to the full event data in paste
// so we can't use the editablePaste event here
this.getEditorElements().forEach(function (element) {
this.on(element, 'paste', this.handlePaste.bind(this));
}, this);
this.subscribe('addElement', this.handleAddElement.bind(this));
}
},
handleAddElement: function (event, editable) {
this.on(editable, 'paste', this.handlePaste.bind(this));
},
destroy: function () {

@@ -153,0 +162,0 @@ // Make sure pastebin is destroyed in case it's still around for some reason

@@ -27,18 +27,30 @@ (function () {

initPlaceholders: function () {
this.getEditorElements().forEach(function (el) {
if (!el.getAttribute('data-placeholder')) {
el.setAttribute('data-placeholder', this.text);
}
this.updatePlaceholder(el);
}, this);
this.getEditorElements().forEach(this.initElement, this);
},
handleAddElement: function (event, editable) {
this.initElement(editable);
},
initElement: function (el) {
if (!el.getAttribute('data-placeholder')) {
el.setAttribute('data-placeholder', this.text);
}
this.updatePlaceholder(el);
},
destroy: function () {
this.getEditorElements().forEach(function (el) {
if (el.getAttribute('data-placeholder') === this.text) {
el.removeAttribute('data-placeholder');
}
}, this);
this.getEditorElements().forEach(this.cleanupElement, this);
},
handleRemoveElement: function (event, editable) {
this.cleanupElement(editable);
},
cleanupElement: function (el) {
if (el.getAttribute('data-placeholder') === this.text) {
el.removeAttribute('data-placeholder');
}
},
showPlaceholder: function (el) {

@@ -70,3 +82,3 @@ if (el) {

// If the element has content, hide the placeholder
if (el.querySelector('img, blockquote, ul, ol') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
if (el.querySelector('img, blockquote, ul, ol, table') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
return this.hidePlaceholder(el);

@@ -91,2 +103,6 @@ }

this.subscribe('blur', this.handleBlur.bind(this));
// Need to know when elements are added/removed from the editor
this.subscribe('addElement', this.handleAddElement.bind(this));
this.subscribe('removeElement', this.handleRemoveElement.bind(this));
},

@@ -93,0 +109,0 @@

@@ -18,3 +18,3 @@ MediumEditor.parseVersionString = function (release) {

// grunt-bump looks for this:
'version': '5.20.2'
'version': '5.21.0'
}).version);
(function (root, factory) {
'use strict';
if (typeof module === 'object') {
var isElectron = typeof module === 'object' && process && process.versions && process.versions.electron;
if (!isElectron && typeof module === 'object') {
module.exports = factory;

@@ -5,0 +6,0 @@ } else if (typeof define === 'function' && define.amd) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc