Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

medium-editor

Package Overview
Dependencies
Maintainers
1
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

medium-editor

Medium.com WYSIWYG editor clone.

  • 1.9.7
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
16K
decreased by-19.71%
Maintainers
1
Weekly downloads
 
Created
Source

MediumEditor

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

Since I always had problems with bloated editors and I loved the simplicity of medium.com solution I've tried to implement their WYSIWYG approach with this script.

MediumEditor has been written using vanilla JavaScript, no additional frameworks required.

Browser Support

IEChromeFirefoxOperaSafari
IE 9+ ✔Latest ✔Latest ✔Latest ✔Latest ✔

NPM info

Travis build status dependencies devDependency Status

Basic usage

screenshot

demo: http://daviferreira.github.io/medium-editor/

First, you need to attach medium editor's stylesheet to your page:

<link rel="stylesheet" href="css/medium-editor.css"> <!-- Core -->
<link rel="stylesheet" href="css/themes/default.css"> <!-- or any other theme -->

The next step is to reference the editor's script and instantiate a new MediumEditor object:

<script src="js/medium-editor.js"></script>
<script>var editor = new MediumEditor('.editable');</script>

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:

var elements = document.querySelectorAll('.editable'),
    editor = new MediumEditor(elements);

IE9

If you want to support IE9, you will need to use a classList pollyfill, like Eli Gray's, available at https://github.com/eligrey/classList.js.

Initialization options

  • allowMultiParagraphSelection: enables the toolbar when selecting multiple paragraphs/block elements. Default: true
  • anchorInputPlaceholder: text to be shown as placeholder of the anchor input. Default: Paste or type a link
  • anchorPreviewHideDelay: time in milliseconds to show the anchor tag preview after the mouse has left the anchor tag. Default: 500
  • buttons: the set of buttons to display on the toolbar. Default: ['bold', 'italic', 'underline', 'anchor', 'header1', 'header2', 'quote']
  • buttonLabels: type of labels on the buttons. Values: 'fontawesome', {'bold': '<b>b</b>', 'italic': '<i>i</i>'}. Default: false
  • checkLinkFormat: enables/disables check for common URL protocols on anchor links. Default: false
  • cleanPastedHTML: cleans pasted content from different sources, like google docs etc. Default: false
  • delay: time in milliseconds to show the toolbar or anchor tag preview. Default: 0
  • 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
  • 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
  • disableToolbar: enables/disables the toolbar, adding only the contenteditable behavior. You can also set specific element behavior by using setting a data-disable-toolbar attribute. 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
  • firstHeader: HTML tag to be used as first header. Default: h3
  • forcePlainText: Forces pasting as plain text. Default: true
  • placeholder: Defines the default placeholder for empty contenteditables. You can overwrite it by setting a data-placeholder attribute on your elements. Default: 'Type your text'
  • secondHeader: HTML tag to be used as second header. Default: h4
  • targetBlank: enables/disables target="_blank" for anchor tags. Default: false
  • anchorButton: enables/disables adding class anchorButtonClass to anchor tags. Default: false
  • anchorButtonClass: class to add to anchor tags, when anchorButton is set to true. Default: btn
  • extensions: extension to use (see Extensions) for more. Default: {}
  • activeButtonClass: CSS class added to active buttons. Default: 'medium-editor-button-active'
  • firstButtonClass: CSS class added to the first button. Default: 'medium-editor-button-first'
  • lastButtonClass: CSS class added to the last button. Default: 'medium-editor-button-last'

Example:

var editor = new MediumEditor('.editable', {
    anchorInputPlaceholder: 'Type a link',
    buttons: ['bold', 'italic', 'quote'],
    diffLeft: 25,
    diffTop: 10,
    firstHeader: 'h1',
    secondHeader: 'h2',
    delay: 1000,
    targetBlank: true
});

Extra buttons

Medium Editor, by default, will show only the buttons listed above to avoid a huge toolbar. There are a couple of extra buttons you can use:

  • superscript
  • subscript
  • strikethrough
  • unorderedlist
  • orderedlist
  • pre
  • justifyLeft
  • justifyFull
  • justifyCenter
  • justifyRight
  • image (this simply converts selected text to an image tag)
  • indent (moves the selected text up one level)
  • outdent (moves the selected text down one level)

Themes

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

API

  • .deactivate(): disables the editor
  • .activate(): re-activates the editor
  • .serialize(): returns a JSON object with elements contents

Capturing DOM changes

For observing any changes on contentEditable

$('.editable').on('input', function() {
  // Do some work
});

This is handy when you need to capture modifications other thats outside of key up's scope like clicking on toolbar buttons.

input is supported by Chrome, Firefox, IE9 and other modern browsers. If you want to read more or support older browsers, check Listening to events of a contenteditable HTML element and Detect changes in the DOM

MediumButton

Patrick Stillhar developed a new and improved way to add buttons to our toolbar. Check it out at: https://stillhart.biz/project/MediumButton/

Extensions

To add additional additional functions that are not supported by the native browser API you can write extensions that are then integrated into the toolbar. The Extension API is currently unstable and very minimal.

An extension is an object that has essentially two functions getButton and checkState.

  • getButton is called when the editor is initialized and should return a element that is integrated into the toolbar. Usually this will be a <button> element like the onces Medium Editor uses. All event handling on this button is entirely up to you so you should either keep a reference or bind your eventhandlers before returning it. You can also return a HTML-String that is then integrated into the toolbar also this is not really useful.

  • checkState is called whenever a user selects some text in the area where the Medium Editor instance is running. It's responsability is to toggle the current state of the button. I.e. marking is a on or off. Again the method on how determine the state is entirely up to you. checkState will be called multiple times and will receive a DOM Element as parameter.

Properties

  • parent add this property to your extension class constructor and set it to true to be able to access the Medium Editor instance through the base property that will be set during the initialization

Examples

A simple example the uses rangy and the CSS Class Applier Module to support highlighting of text:

rangy.init();

function Highlighter() {
    this.button = document.createElement('button');
    this.button.className = 'medium-editor-action';
    this.button.innerText = 'H';
    this.button.onclick = this.onClick.bind(this);
    this.classApplier = rangy.createCssClassApplier("highlight", {
        elementTagName: 'mark',
        normalize: true
    });
}
Highlighter.prototype.onClick = function() {
    this.classApplier.toggleSelection();
};
Highlighter.prototype.getButton = function() {
    return this.button;
};
Highlighter.prototype.checkState = function (node) {
    if(node.tagName == 'MARK') {
        this.button.classList.add('medium-editor-button-active');
    }
};

var e = new MediumEditor('.editor', {
    buttons: ['highlight', 'bold', 'italic', 'underline'],
    extensions: {
        'highlight': new Highlighter()
    }
});

A simple example that uses the parent attribute:

function Extension() {
  this.parent = true;

  this.button = document.createElement('button');
  this.button.className = 'medium-editor-action';
  this.button.innerText = 'X';
  this.button.onclick = this.onClick.bind(this);
}

Extension.prototype.getButton = function() {
  return this.button;
};

Extension.prototype.onClick = function() {
  alert('This is editor: #' + this.base.id);
};

var one = new MediumEditor('.one', {
    buttons: ['extension'],
    extensions: {
      extension: new Extension()
    }
});

var two = new MediumEditor('.two', {
    buttons: ['extension'],
    extensions: {
      extension: new Extension()
    }
});

Image Upload

Pavel Linkesch has developed a jQuery plugin to upload images following Medium.com functionality. Check it out at http://orthes.github.io/medium-editor-insert-plugin/

Laravel

Zvonko Biškup has written an awesome tutorial about how to integrate MediumEditor into your Laravel Project.

Rails Gem

Ahmet Sezgin Duran gemified Medium Editor for Rails asset pipeline, check it out at https://github.com/marjinal1st/medium-editor-rails.

Angular directive

Thijs Wijnmaalen hacked together an AngularJS directive. Check it out at https://github.com/thijsw/angular-medium-editor

Development

MediumEditor development tasks are managed by Grunt. To install all the necessary packages, just invoke:

npm install

These are the available grunt tasks:

  • js: runs jslint and jasmine tests and creates minified and concatenated versions of the script;
  • css: runs autoprefixer and csslint
  • test: runs jasmine tests, jslint and csslint
  • watch: watch for modifications on script/scss files

The source files are located inside the src directory.

Contributing

Stories in Ready

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Test your changes to the best of your ability.
  4. Update the documentation to reflect your changes if they add or changes current functionality.
  5. Commit your changes (git commit -am 'Added some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new Pull Request

Contributors

 project  : medium-editor
 repo age : 11 months
 active   : 145 days
 commits  : 535
 files    : 56
 authors  :
   396	Davi Ferreira           74.0%
    20	Maxime de Visscher      3.7%
    12	Andy Yaco-Mink          2.2%
     8	Derek Odegard           1.5%
     8	Jarl Gunnar T. Flaten   1.5%
     8	Pedro Nasser            1.5%
     8	Seif                    1.5%
     5	Martin Thurau           0.9%
     5	OmniaGM                 0.9%
     4	Sebastian Zuchmanski    0.7%
     4	minikomi                0.7%
     3	Andrew Hubbs            0.6%
     3	Dmitri Cherniak         0.6%
     3	Nikita Korotaev         0.6%
     3	Troels Knak-Nielsen     0.6%
     3	arol                    0.6%
     3	ʞuıɯ-oɔɐʎ ʎpuɐ          0.6%
     2	Ethan Turkeltaub        0.4%
     2	Jacob Magnusson         0.4%
     2	mako                    0.4%
     1	Adam Mulligan           0.2%
     1	Alberto Gasparin        0.2%
     1	Bitdeli Chef            0.2%
     1	Cenk Dölek             0.2%
     1	David Collien           0.2%
     1	David Hellsing          0.2%
     1	Denis Gorbachev         0.2%
     1	Diana Liao              0.2%
     1	Jack Parker             0.2%
     1	Jeff Welch              0.2%
     1	Mark Kraemer            0.2%
     1	Max                     0.2%
     1	Maxime Dantec           0.2%
     1	Maxime De Visscher      0.2%
     1	Michael Kay             0.2%
     1	Moore Adam              0.2%
     1	Nic Malan               0.2%
     1	Noah Paessel            0.2%
     1	Pavel Linkesch          0.2%
     1	Robert Koritnik         0.2%
     1	Sarah Squire            0.2%
     1	Scott Carleton          0.2%
     1	Søren Torp Petersen     0.2%
     1	Tom MacWright           0.2%
     1	happyaccidents          0.2%
     1	mako yass               0.2%
     1	mbrookes                0.2%
     1	muescha                 0.2%
     1	shaohua                 0.2%
     1	t_kjaergaard            0.2%
     1	typify                  0.2%
     1	waffleio                0.2%
     1	zzjin                   0.2%

License

"THE BEER-WARE LICENSE" (Revision 42):

As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return.

Keywords

FAQs

Package last updated on 20 Oct 2014

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

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