Thursday, August 16th, 2007

Tales of the Rich Text Editor and Safari Support

Category: Yahoo!

>I love to hear the stories behind the technology. This way you have a chance of learning from a fellow developers trials and tribulations.

Dav Glass of the YUI team was in charge of building the new Rich Text Editor that was just released, and has documented part of the journey which includes how he managed to get this puppy working on Safari 2:

My development approach was to bend Safari first. I built it to work in Safari 2 before retrofitting it back to Opera, then Firefox and lastly Internet Explorer. I figured that if I could make Safari do what I wanted, the other three would fall into place nicely. And they did. By choosing to make Safari work first I was able to make the others do things in a standard way as well. I hope that Safari will eventually catch up to its A-grade peers and add support for the things that I have “emulated”, so I took that into consideration too.

How did he hack around Safari 2?

Safari 2 is a really good browser, but it was also the most challenging browser to support with the RTE project. It lacks some serious and critical features when it comes to editing HTML content from JavaScript. I will try to explain the main hurdles that Safari presents:

Iframe Focus – One of the biggest issues was actually quite simple to solve. Safari (and Internet Explorer) has an issue with selecting text inside of an embedded iframe. If you select text within the editor’s iframe then click/focus the parent document, the selection within the iframe is lost. Clearly, this makes it rather difficult for a button click to take action on the selection (because the selection is lost when you click the button!). It also makes it difficult to use, say, a YUI Menu Control for a drop down. As I investigated this problem, I determined that if you stop the mousedown event on the button/href the selection doesn’t get lost. However, if something else (say a href in a dropdown menu) gets focus, the selection will still get lost. This leads me to the next Safari trick.

Selection Object – The selection object in Safari is very limited (to say the least). To work around its limitations, the YUI RTE caches a copy of the current selection in the _getSelection method. Then, the next time _getSelection is called I check to see if a cache existed. If the cache is there, I “rebuild” the selection and destroy the cached copy. This little trick is what lets Safari use a YUI Overlay as a menu instead of the more classic approach of a select element. It’s roundabout, but it works.

execCommand limitations – This is the mother of all hacks for Safari (and the others). My biggest problem with the native execCommand method (in all browsers) is that the browser doesn’t tell you what it applied the command to. So there is no real way to get an element reference back after running a command on a selection. The world of JavaScript editors would be so much more civilized if this would happen (hint, hint, nudge, nudge). So what I had to do was implement this feature myself. My current approach may not be the best way to do it (I have some other ideas that I am working through), but it does the job for now. The method is named _createCurrentElement and basically it runs execCommand('fontname', false, 'yui-tmp'); on the given selection (since fontname is supported on all A-Grade browsers). It will then search the document for an element with the font-family/name set to yui-tmp and replace that with a span that has other information in it (attributes about the element that we wanted to create), then it will add the new span to the this.currentElement array, so we now have element references to the elements that were just modified. At this point we can use standard DOM manipulation to change them as we see fit. In short, I’m using the iframe’s DOM to store metadata during editing as a way to enrich the communication that’s possible between the editor and the iframe.

Thanks for sharing the story.

Related Content:

Posted by Dion Almaer at 10:05 am
6 Comments

+++--
3.3 rating from 79 votes

6 Comments »

Comments feed TrackBack URI

yep,i’ve also spent good hours with that damn safari,and ended up with my own simple safari-only editor (for others i used FCK), based on some free text editor (don’t remember thename).
The biggest challenge is tabbed layouts. Safari has some kind “optimization”. If IFRAME not visible, it unloads it’s content. So imagine, you have 2 tabs, one of them with editor. User first edit some html, then switch to another tab and then back. What the… editor is gone?! Yep… it is. You need to re-initialize editor each time you want to show it. Also you need to wait some time before editor document will be available afrer IFRAME refreshes on showing.
I don’t remember all hacks i needed to apply to my code, but Safari is really pain in the ass. I hope 3.0 will be much more coding friendly

Comment by anonymous — August 16, 2007

The rich text editor support in Safari is quite limited and has many errors, which need to be worked around for more than very basic rich text editing and formatting.

We have actually fully supported Safari in our Asbru Web Content Editor (editor.abrusoft.com) since September 2005! It has been and still is a lot of hard work and many other developers have given up – but it is doable.

Comment by Soren Vejrum — August 16, 2007

You think we will ever be able to just say this?


<textarea rich="true"></textarea>

Comment by Mike — August 16, 2007

The main problem on Safari 2.x is the lack of a proper selection object there is no way to get a DOM Range of the currently selected contents in Safari 2.x. But in 3.x they have implemented this possibility, this was a major show stopper to get TinyMCE to work properly on Safari and it’s kind of hard to fake if there isn’t an API available for it.

Another missing thing is that Safari doesn’t provide image selection support there is no visual representation when you select them. This shortcoming is reported to the Safari guys so I hope they fix it soon and that they focus more on the RTE support.

Safari might be ahead on the CSS implementation but they are still behind when it comes to JS APIs.

Comment by Spocke — August 16, 2007

The problem with rich text editors is that they allow users to add arbitrary formatting to content rather than adhering to the css styles which a site designer has set up.

So there’s a need for another kind of embedded editor also — one that only allows formatting by defined CSS styles. That means no font menu, or font size menu in particular. Since many people get bamboozled by lots of buttons, the editor needs to be visually very simple — just the minimum of controls to select allowable CSS styles.

Comment by Paul Howson — August 30, 2007

And the solution is:

Don’t use text editor!

In a great CMS there is no Rich Editor needed.

Want long documents? That’s not what web is for! Give ‘em PDF!

Want short info about products, employees, etc.? Create template and save data in JSON! The customers will enter: Name of the product, Price, etc. And template will do ALL formatting!

I don’t know if there is a CMS like this, but I AM GOING TO DEVELOP it and sell it and buy a Macbook :P:P:P

Have a great day Ajax-guys!

Comment by zero0x — January 5, 2008

Leave a comment

You must be logged in to post a comment.