I've been looking into creating a Rich Text editor, and at first I was planning on using contentEditable, but it turns out the results are extremely inconsistent and that the output HTML is often broken.
I was wondering if there are any alternatives to using contentEditable, such as the way Google Docs does it (they created there own engine).
Even Google Docs are built on contentEditable. They, however, use it in a different way most editors out there do.
When you focus the document area, it just seems like it is focused because of the fake caret. The actual focus goes to an <iframe> with keyboard event listeners set up. The engine (kix) then modifies the document area based on the keys you press.
This is awesome because there are really no serious cross-browser inconsistencies as the browser is not the one modifying the DOM.
The only alternative I can think of might be a simple text input instead of a contentEditable element but why bother with issues like max length when you can just take advantage of contentEditable ;-)
Why not give TinyMCE a go? It is quite good and fairly refined - just need to combine it with PHP and you can save the contents :)
Related
I'm trying to force spell check on a contenteditable element that is not being directly modified by the user's keystrokes (i.e. I'm translating events and performing content changes, selections, etc, via Javascript). This is an issue, as Webkit browsers only attempt to spell check content that is from the user, of which I have none via the event translations.
Element.forceSpellCheck() remains unsupported everywhere which should be the right way to do this.
The technique for dealing with this on inputs was to mimic a selection on each word as discussed here.
I haven't had any luck in getting this technique working on contenteditable elements. The only behavior that will reliably result in the spellchecker's red underline is using the arrow keys and not overriding the events - only when the cursor is placed directly on a misspelled word will the visual red line appear.
Is there another strategy to try out for dealing with this?
I need to build a wysiwyg editor for a project I am working on and need some guidance. Some of my key points of confusion are the following:
iframe docs vs. contenteditable divs: which one should I use and why? I hate iframes, is there a clear advantage to using iframes?
cross browser styling: execCommand seems to apply different styles in different browsers. Are there any tricks to making this cross-browser compatible? Should I not use execCommand at all and instead apply my own styles?.
adding items to the undo chain: how can run my own script, such as inserting an image, and allow cntrl+z (undo) to remove it? Is there an array of undo/redo items for contenteditable that I can push items into?
keeping the text selection: how I can maintain text selection while making operations such as selecting the font style, where the focus will leave and remove my selection. Rangy? Google closure? Are there other range/selection libraries worth looking at?
Any tips on these items or anything else related to building a rich text editor would be greatly appreciated!
From personal experience, I recommend against doing this unless your aim is to provide a very limited amount of functionality. The sheer number of browser differences and the complexity of their workarounds makes this a very tricky and time-consuming task if you want to do it well.
If that hasn't put you off, here's my thoughts on your individual questions:
iframe docs vs. contenteditable divs
I recommend the iframe approach, for two main reasons:
You have complete control over the document type, CSS and script within the iframe. This is essential if you want consistent behaviour and appearance and want to use your editor within different pages.
Firefox in particular is quite buggy with contenteditable elements, which they only introduced relatively recently (version 3.0) while designMode has existed on documents for many years (since pre-1.0; around 0.6, if memory serves) and works pretty well.
cross browser styling
If it's important for you to have uniform results from applying styles in different browsers then in general you will need to write your own styling code. However, doing this will break the built-in undo stack and you will need to implement your own undo/redo system.
adding items to the undo chain
There's no programmatic way to interact with the built-in browser undo stack. You'll need to write your own.
Update November 2012
There is a spec in the works for custom undo/redo so this is likely to be possible eventually. Here are the relevant bugs for Mozilla and WebKit.
keeping the text selection
I have to declare my interests here, since I wrote Rangy. I don't think there's a better library out there that does a similar job; Google Closure does have a range/selection API but I think it uses their own proprietary interface rather than emulating DOM Range and common browser Selection objects. IERange is another library that is similar in idea to Rangy but much less fully realized and seemingly abandoned immediately after release by its author.
Don't, seriously don't.
What you are suggesting is a major undertaking. You really should be looking at TinyMCE, http://tinymce.moxiecode.com/, or CKEditor, http://ckeditor.com/. Getting what you are after is a massive amount of effort to get working for one version of one browser, to make it portable will take man-years of investment.
A better solution is to look at things like TinyMCE's plugins, http://tinymce.moxiecode.com/plugins.php. You can get your basics the basics (and portability for free) and concentrate on adding the specific value-add items you need to.
I dont know whether I am reiventing the wheel.
I need to design an online WYSIWYG where users can make one/two/three-column layout page.The WYSIWYG should adjactly show the contents in design mode as well as preview mode.Therefore, the WYSIWYG should also have the supports for Header and Footer too.Therefore, the WYSIWYG will have at least three boxes(Header, Content,Footer) and in max it may contain six boxes.
IFRAME supports designmode (on/off) and it has content editable property and it also supported by most browsers. Though DIV also has the content editable properly in the latest browsers. Since there are many users who use IE6 still, probably choosing IFRAME is better(need your kind advice).
Now the question is whether I should use 6 IFrames or only one Ifrmae or no Iframe at all? Please suggest.
Thanks.
It sounds to me like you are trying to reinvent the wheel. You should be able to use one of the existing WYSIWYG editors with template support built-in. So I'd suggest you have a look at CKEditor, which probably has all the features you need.
Choose whatever existing editor that you like, but don't try to recreate one yourself, you'll become crazy.
I don't even know what do you understand as different between WYSIWYG and "Rich Text Editor", the main difference might be that no web-based editor can be really "What You Get", because there are lots of little problems.
Anyway, it seems that you want to create a page with one toolbar and several editing instances, I think that all the main editors does support that, but I would avoid using one based on a framework (YUI or Google closure) unless you are already using that framework.
Check instead the features of stand alone editors like CKEditor or TinyMCE. You'll hardly get anything better that those ones.
Don't reinvent the wheel! If you decide that you need to support designmode iframes as well as contenteditable, Google Closure Editor has a very performant implementation of multiple editing surfaces that only creates one iframe at a time.
I would look at YUI Editor from Yahoo, The YUI stuff does support a drag and drop column editing. I would say reuse in this case.
EDIT: Since you say you want to edit multiple areas per page you should also check out the YUI Editor's Multi edit example page
I'm wanting to provide a resizing textarea control for users. I've given this a go and looked at a number of other implementations, but I can't seem to find one that meets all my requirements. Specifically I want a control that:
Works in IE6, IE7, IE8 on Windows and Firefox 3 and 3.5 on Windows and OS X when the page is rendered in standards compliant mode (i.e. not in quirks mode).
Does not mess up the undo buffer/undo stack. This is a particularly nasty issue with IE - adding nodes, removing nodes and some other DOM operations will reset the input buffer meaning that if an implementation relies on these techniques an undo will not behave like it does in a standard textarea control. I haven't been able to find much information about this bug except for this note. Implementations like the jQuery Auto Growing Plugin suffer from this problem - try undoing changes in IE and compare how this works to a standard textarea. I've added an example page demonstrating this problem to JSBin.
Has a maximum height beyond which the control cannot grow.
Shrinks appropriately when content is deleted.
Does not flicker or act strangely on keypress. e.g. jQuery Auto Growing Textarea control behaves strangely with, at least IE7, when the control has grown beyond it's initial size.
Does not require the control to use a fixed-width/monospace font.
The closest I've seen to something that works like this is Facebook's status update field, which is implemented as a content editable div element, but I have some reservations about using such an element because using a div means:
Need to explicitly style the border which means we could end up with a border that looks different to a native textarea.
Need to sync content with the real textarea (possibly in both directions?).
Adds complexity when placing hints and other elements relative to position of a textarea.
While this approach works for something like a Facebook status update, how well would it work in a form containing hundreds of standard input elements?
What I've set out above represents the "ultimate resizing textarea" - addressing what I perceive to be issues with existing approaches. Does such a control exist? Is it possible to write such a control?
Check out DOJO tools text area control
see more on this demo page (text area At the end of the form )
This closely come to your requirements.
You may need to roll your own to meet those requirements.
These could be a start.
http://tuckey.org/textareasizer/ (though try and avoid eval() in yours)
http://www.felgall.com/jstip45.htm
http://viralpatel.net/blogs/2009/06/textarea-resize-javascript-jquery-plugin-resize-textarea-html.html
This actually seems like a good jQuery plugin. I might have a tackle at developing something like this. If I get it done, I'll post it here.
I spent a few hours developing something, but then I found this one that seems to be really good.
http://www.aclevercookie.com/demos/autogrow_textarea.html
You want to auto-size the display? but leave the content the same?
That is all the scripts can do, adjust the display, and let you see more of your own text...
This A List Apart post contains an implementation that looks pretty close to meeting your criteria and contains a good explanation of what's going on.
Are any of these useful?
Textarea Resize JavaScript: Resize textarea using jQuery plugin
Smart Area: A Lightweight Resizing Text Area Plugin for jQuery
How to Build an Auto-Expanding Textarea jQuery Plugin, Part 1
How to Build an Auto-Expanding Textarea jQuery Plugin, Part 2
How to Build an Auto-Expanding Textarea jQuery Plugin, Part 3
Resizable Body
I have been using nicEdit. It seems to have all that you need and the script is only 1700 lines with an MIT license so you could make any changes you need.
I am aware that Javascript WYSIWYG editors use the inbuilt editor mode of the browser to function, but that comes up with various problems and issues.
Can an editor be built from scratch in JS, something like what Buzzword people have done with flash/flex? I came across this blog post recently and I am just wondering if this can be built (atleast to a moderate extent) using Javascript?
It depends what you mean by "from scratch". Google Docs provides a pretty good text editor in JS. Is that what you mean ?
Of course you can do it and it is not very difficult.
But before reinventing the wheel please take a look at all the existing ones.
Many of them are really very well written and open source.
Almost anything can be done with JavaScript. You have the basic building tools right there - you can intercept all mouse events and nearly all keyboard events. You can use a GIF animation for simulating the caret. The trickier part might be measuring the size of text so that you can position your caret where you need to. I'm not exactly sure how you could do that. But if you figure that out, the rest is doable. Although it will really require tons of wheel-reinventing code.
Reminds me of a little experiment I did sometime back... I basically tried to create a primitive editor by simply listening to keypresses on a DIV and to insert them into the DIV as a new node. So imagine, each character would be wrapped in a tag! It actually worked. But, once it reaches a couple of paragraphs, node insertion and deletion becomes rather slow. You will type a character, and it would only appear after a slight delay, and this simply unacceptable, and eventually I just gave up. Anyway it was just a random thing I wanted to try out..
Coming back to your question, I wonder if this can be replicated in JS alone as frankly the flash has superior raw processing power compared to JS. Even if it's technically feasible, I doubt whether it will be fast enough to actually work well. My two cents!
Atwood's Law:
Any application that can be written in JavaScript, will eventually be
written in JavaScript.