quasi random (kaolinfire) wrote,
quasi random

Yahoo's new HTML Editor...

Pretty spiff. Spent about four six hours adding a "raw html" mode to it. Wish I could turn on syntax highlighting in this thing, but first the code, and then discussion:

var fancy_editor = new YAHOO.widget.Editor(el.id, {
animate: true,
toolbar: {
buttons: [
{group: 'stuff2', label: 'TEXT', buttons: [ ]},
{ type: 'separator' },
{group: 'stuff', label: 'Simple HTML Menu:', buttons: [
{ type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
{ type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
{ type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
{ type: 'separator' },
{ type: 'push', label: 'Subscript', value: 'subscript', disabled: true },
{ type: 'push', label: 'Superscript', value: 'superscript', disabled: true },
{ type: 'separator' },
{ type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
{ type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' },
{ type: 'separator' },
{ type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
{ type: 'push', label: 'Remove Formatting', value: 'removeformat', disabled: true },


//Use the toolbarLoaded Custom Event; when that event fires,
//we will execute a function that adds or custom button:
fancy_editor.on('toolbarLoaded', function() {
//Simple button config
var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event;
var button = {
type: 'push',
label: 'HTML',
value: 'togglehtml',
disabled: false

var state='on';
var htmlgroup = Dom.getElementsByClassName("yui-toolbar-group-stuff","div",this.toolbar);
var htmllabel = Dom.getElementsByClassName("yui-toolbar-group-stuff2","div",this.toolbar)[0];
htmllabel = Dom.getFirstChild(htmllabel);

//Add the button to the toolbar; "this"
//refers to fancy_editor, our RTE instance:

//Now listen for the new buttons click and do something with it.
//Note that "togglehtml" is an event synthesized for us
//automatically because that's the value we gave our button
var toggleFunction = function(o) {
if (state == 'on') {
state = 'off';
this.setEditorHTML(this.get('textarea').value.replace(/<br>/gi, '\n').replace(/\&/gi,"&amp;").replace(/</gi,"&lt;").replace(/>/gi,"&gt;").replace(/\n/gi,"<br>"));
} else {
state = 'on';
var stripHTML = /<\S[^><]*>/g;
this.setEditorHTML(this.get('textarea').value.replace(/<br>/gi, '\n').replace(stripHTML,'').replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/\&amp;/gi,"&").replace(/\n/gi,"<br>"));

this.toolbar.on('togglehtmlClick', toggleFunction, this, true);

var form = document.getElementById(el.id).form;

YAHOO.util.Event.on(form,'submit',function(ev) {
if (state == 'on') {
//all happy
} else if (state == 'off') {
//need to fire a togglehtmlClick event to the toolbar
} else {
alert("ERROR: UNKNOWN STATE for editor '"+el.id+"': '"+state+"'");
fancy_editor.saveHTML(); // Save the HTML -- BAD if state is on! EEP!

}, fancy_editor, true);


This was taken heavily from two examples they gave (though not as heavily as I would have liked ;) ):

  • http://developer.yahoo.com/yui/examples/editor/switch_editor.html

  • http://developer.yahoo.com/yui/editor/

I've set up two groups of buttons, stuff and stuff2, so that I can hide one of the groups... the first group (stuff2) I dynamically add my "toggle HTML" button to. In the second group, stuff, I put some basic and relatively sane html controls.

I hide those controls when showing the "raw" markup so that confused users don't mark up the "raw" markup ((though the code can handle that, too, just to be safe))

I automatically link the onsubmit events for the form the textareas happen to be in, and they clean themselves up (according to state) so that the data doesn't get submitted in the pseudo-raw form. :)

If you're curious, I'm doing all of this in behaviour just based on a class "fancy" being set on a textarea.  That is happiness, I tell you!

Tags: editor, html, yui

  • Post a new comment


    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.