ponyedit
An interface between contentEditable
and your UI.
Sample UI:
Note that the UI is entirely decoupled from this library, and is defined in the sample JS, CSS, and HTML
Install
Install with bower
.
bower install --save ponyedit
Or, using npm
.
npm install --save ponyedit
Dependencies
ponyedit
depends on EventEmitter2 because it follows the Obey and Report pattern.
Usage
Check out the example JS file, all that's needed is an element ponyedit
can turn into contentEditable
. Then it'll do most of the heavy lifting for us, sans the UI.
var something = document.querySelector('selector');
var somepony = ponyedit.init(something, options);
var samepony = ponyedit(something);
We can now use somepony
to listen for state changes on our editor, and apply changes to the content. If we want to set up a button to toggle italics, we could just use:
var button = document.querySelector('selector');
button.addEventListener('click', function () {
somepony.setBold();
});
Updating the UI state can be isolated as well. Say we want the button to say 'BOLD'
when something is bold, and 'turn bold on'
, when it isn't. That'd be pretty easy.
somepony.on('report.bold', function (value) {
button.innerText = value ? 'BOLD' : 'turn bold on';
});
Framework-less data binding! Sort of.
Use Case
This might not be as powerful as some other open-source WYSIWYG editors, but its strong point in favor is that it can be completely decoupled from its UI. This enables us to pair it with a framework such as Angular, Knockout or Backbone, and we could spread the UI all over the place, without the editor knowing any of that.
The event-driven approach also makes it easy to plug into these databinding-type frameworks.
API
All of EventEmitter2
's API is supported, as ponyedit
extends its prototype. The only option passed to EventEmitter2
is wildcard: true
.
Options
Here are the default values.
{
htmlWrap: true,
pixels: false,
pickyHeight: false
}
The pixels
option defaults to false
, using <font size='{n}'>
tags just like native contentEditable
does. Setting it to true
results in <span class='py-pixels-element' style='font-size: {n}px;'>
tags instead.
The pickyHeight
option may be used in addition to the pixels
option to set line heights relatively to the font size. Furthermore, pickyHeight
enables the .execHeight(px)
, and .setHeight(px)
API.
.focus()
Focuses the content editable at the beginning.
.html(value)
Similar to jQuery's method, gets or sets the HTML contents in our editable. If the htmlWrap
option (enabled by default) is set to true
, then the HTML will be wrapped in a <div>
(if it's not already wrapped). This is generally useful because the first line can sometimes become a text node, while the rest of our content stays in paragraphs, but that behavior can vary among browsers.
.getSelection()
Gets the current selection, only if it's inside the content editable area of our element.
.getRange()
Gets the currently selected range of text, only if the selection is inside the content editable area of our element.
.saveSelection()
Takes the selection from .getSelection
and saves it for later. It can be restored later. This also happens whenever the user selects text by hand (or unselects it).
.restoreSelection(forget)
Restores the last saved selection. If forget
is true
, then the saved selection is deleted. This helps because sometimes our UI will make the content editable lose focus, for example if we're using a <select>
to pick a font. In those cases, we can save the selection right before, and then restore it right after.
.exec
Commands
These methods just execute commands on the content editable.
-
.execBold()
Toggles bold formatting in the selection -
.execItalic()
Toggles italic formatting in the selection -
.execSize(value)
Sets font size tovalue
for the selection -
.execSizeDecrease()
Reduces font size by one for the selection -
.execSizeIncrease()
Increases font size by one for the selection -
.execType(value)
Sets the font name tovalue
for the selection. -
.execColor(value)
Sets the fore color tovalue
for the selection. -
.execAlignment(value)
Sets text alignment tovalue
for the selection,left
,center
, orright
. -
.execHeight(value)
Sets line height tovalue
for the selection. Value may be'auto'
.set
State changes
These methods restore the latest selection, execute the appropriate .exec
command, and emit an state update. All of these take two arguments. The first one is an array of arguments for the .exec
command, and the second is whether the selection should be preserved (by default, it isn't).
.setBold(args, preserveSelection)
.setItalic(args, preserveSelection)
.setSize(args, preserveSelection)
.decreaseSize(args, preserveSelection)
.increaseSize(args, preserveSelection)
.setType(args, preserveSelection)
.setColor(args, preserveSelection)
.setAlignment(args, preserveSelection)
.setHeight(args, preserveSelection)
Note that, in order to be future proof, these methods' args
should be an array of arguments to pass to the .exec
command. As such, setting the size should be invoked like this:
ponyeditor.setSize([2]);
That'll end up invoking ponyeditor.execSize(2)
.
.report
Methods
These methods emit the state each particular property is in, or all of them at once with .report()
.
.reportBold()
.reportItalic()
.reportSize()
.reportType()
.reportColor()
-
.reportAlignment()
normalized to report one ofleft
,center
,right
, or''
.reportHeight()
.report()
.meta
Object
This object provides values you could use to populate lists, such as fontSizes
, fontTypes
, and alignments
.
window.ponyedit(element)
Looks up and returns the ponyeditor
object associated to the element.
window.ponyedit.meta
Convenience shortcut to ponyeditor.meta
, without an instance.
window.ponyedit.init(element, options)
Creates a ponyeditor
for the element, and sets contentEditable
on for that element.
License
MIT