Thursday, August 16th, 2007
>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?
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
_getSelectionmethod. Then, the next time
_getSelectionis 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
_createCurrentElementand 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-tmpand 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.currentElementarray, 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.