About Dev |

Archive for January, 2009

Xinha4WP — Wordpress with the power of Xinha

This won’t be one of my usual blog posts, because I just want to announce the 0.96 beta release of Xinha4WP.  It’s a wordpress plugin that installs Xinha as a drop-in replacement for TinyMCE.  (For those not in the know, Xinha is a community-driven open source web WYSIWYG editor.)

At my employer (The Open Planning Project), we switched to wordpress from Blogger back in 2006 for Streetsblog.  After a short trial, our writers and editors became increasingly frustrated with the state of WYSIWYG editing (powered by TinyMCE).  At the time, TinyMCE  was almost unusable (at least as it was embedded into wordpress).  Our writers and editors were about to give up and switch back when we came across Mike Baptiste‘s wonderful plugin.

Here at TOPP, we believe in open source software not only for idealistic reasons but also for pragmatic ones.  Being in control of our stack gives us much more flexibility in terms of site design and functionality.  By using Mike’s plugin, we were able keep our writers happy while still maintaing control of our entire platform.

Well, fast forward to the beginning of 2009 and the crew over at Wordpress and Moxiecode have put an amazing amount of work and polish into TinyMCE. It is now the first class option it should be and no longer behind other platforms.  At the same time, Mike no longer has time to update the Xinha4WP plugin, and Xinha’s last stable release was over 8 months ago.

That’s where I come in.  I’m now one of the core Xinha developers and we’ve just published a new beta release (0.96 Phoenix beta).  In addition, we’ve received Mike’s blessing to take over the Xinha4WP plugin and bring it up to date.

Because of the time lapse, we’re now playing catch up to TinyMCE in terms of integration into wordpress, but we’ve added some long needed features for our first new release.

  • Autosave was added to wordpress 2.2, two years and five versions ago.  Now we sync textareas to allow this feature to work.
  • Up until recently, Xinha4WP always enabled Xinha, and required the user to disable TinyMCE.  Now we auto-disable TinyMCE and respect the users visual editing preference.

There are some outstanding issues in this release as well.  While Xinha normally supports autoresizing, our embedded version doesn’t correctly resize with the page (requiring a page refresh).  What’s worse, since TinyMCE supports user-draggable resizing, the default size of the visual editor is a bit cramped for normal use.  These two together means that this is a bit of a pain point for writers.  While we’re working on the fix, you can use Xinha’s full screen mode to provide a comfortable editing space for your blog post.

In brief, it’s been awhile, and the people over at wordpress have put a lot of effort into TinyMCE integration, and this has become a viable option.  If, however, you crave more from your users, take a look at Xinha.  We’ve got some catching up to do, but we’ve got a great alternative and we can only go up from here.

If you’re interested in finding out more, download the release and come join our mailing list!

\n” — One of the Web’s Tough Problems

So I’ve got you.  This doesn’t make much sense, does it?  All except the oldest among you used a newline in your first program.  The tough problem is not re-displaying the page as it changes, that’s easy.  Okay, maybe not easy, but at least it’s already been solved.

Imagine that you’re typing an email to a lovely lady you want to move here from St. Petersburg.  You’ve finished a paragraph about naked scuba diving, you’ve told her about your pet rock collection and now it’s time to add you’re closing line.  “Sincerely yours” is a bit too formal, and “With all my love” might scare her off.  In any case, if you can’t hit enter to type that line, than she’s never going to move here and marry you.

Well, it can’t be too tough a problem, can it?  Olav Kjær wrote a great article about the problems and inconsistencies involved.  HTML is a great language for documents (I write software for the web, they make me say that), but its rules for containing text are pretty lax.  And when you give a user a mouse and allow him to just click anywhere on the page?  That’s just crazy talk!

Why do I care?  Well, I was editing a *cough* wiki page on OpenPlans.org using the Firefox 3 Beta (took me awhile to finish off this post, eh?).  When I clicked in the middle of the page and hit enter to start typing a new paragraph, half of my page disappeared.  Expected results?  Uh, a new paragraph?  We use Xinha, the open source WYSIWYG editor, and a pretty old version at that, but there was no problem in any other browser, or in previous versions of Firefox.

So I did what any self-respecting software engineer does when the problem’s not in his code, and he can’t understand it. I blamed someone else.  I was so worried about supporting the problem for the life of Firefox 3 that I even called John Resig, Mozilla’s Javascript Evangelist.  You’ll notice that he’s removed the phone number from his site (sorry John).

After filing the bug, I started to search through snapshots of Minefield (the testing and development version of Firefox), and was able to narrow it down to one commit.  Looking at the source (in nsRange.cpp), it turns out that the change was a bugfix that caused Firefox to correctly implement the W3C Range standard.  Before the fix, trying to create a backwards selection raised an exception, and after the fix it returned an empty selection, as it was supposed to.  That meant the Xinha code depended on broken behavior; and that I had work to do.

My first job was to find out what was wrong,  That’s easy, I have access to the code, I just have to find out where things went wrong.  Eeek.  “processRng” and “processSide”.  Well, it’s pretty obvious what those two functions do.  The first processes a range, and the second processes a side.  Thanks to some helpful comments, I know that it returns a neighbor node, and insertion type, and a “roam”. What that means?  No idea.  My favorite comment?

“I do not profess to understand any of this, simply applying a patch that others say is good — ticket:446

After stepping through the code I was finally able to figure out what it was trying to do.  It divided the document into two pieces.  It cuts out everything from the current cursor to the end of the document, inserts a break, and then pastes it back in again.  It sounds like a simple enough idea, but I couldn’t for the life of me figure out what was going wrong.  So again I did what any self-respecting software engineer would do.  I decided to rewrite the algorithm from scratch.

It’s now six months later, and I’ve finally nailed this bug.  Of course, other things happened in between, but that’s always the case.  Let’s take a look at what’s so tough about newlines.

  1. The first difficult problem is determining user intent.  If the user finishes typing a heading and then hits enter, they probably want to start typing text in a new paragraph.  If however, the cursor is in the middle of two sentences in that heading, they probably want to split it into two headings.  In a table cell and they probably just want a line break.  If they’re editing a definition list, they might want to insert a new definition, a new term, or even split two sentences into two seperate definitions or terms.
  2. The second problem is cursor position.  Since a cursor is defined as a pointer to a node and an offset, in the following HTML snippet, the position just before the letter ‘T’ can be targeted with two different cursors.
    <p><em>Text</em></p>
    The first would be a pointer to the “<em>” element with an offset of zero.  This would mean we were pointed at the text node.  The second would be a pointer to the text node with a zero offset.  In this case, we are pointing at the characters of text, and not at a node.
  3. Third is what it means to break a line.  In a list, breaking a line means creating a new list item.  In a preformatted block, it means a newline character.  In a table cell, you want a “<br>” element, and in a paragraph you want a new paragraph.  I won’t even get into how this changes for shift-enter.
  4. The final tough problem is inline elements.  The formatting of the text at a given cursor position is the result of a tree of inline elements that heads up towards the containing block.  When splitting that block, you have to create a duplicate of this tree with all of the same elements, and you have to split each inline element into the parts that come before the cursor, and the parts that come after.

After having finished the majority of this back when I found the bug, I shelved the code and moved on to other things.  With the help of my colleague, Nicholas Bergson-Shilcock, I’ve picked this up again and finished it off.  This means that the new Phoenix Release (0.96) of Xinha will get a bugfix that makes Firefox 3 usable again.

All of the code for this fix is pluggable, and should be usable by anyone needing to break lines in HTML.  The only dependence is on W3C Ranges and DOM Selections.  Luckily, there’s been talk of a cross-platform W3C Range and DOM Selection library.

When the guys over at 37signals released their own super-light-weight WYSIWYG editor WysiHat, they talked about wanting to help with the problem.  Mozile, the Mozilla Inline Editor, actually has one, but it’s too tied to the editor to be able to useful elsewhere.  TinyMCE goes the other way and has an IE TextRange implementation for Firefox, and I’ve recently been told that FCKEditor has the beginnings of a usable library.  I’ve implemented the tough parts twice now (finding the DOM node and offset of the ranges start and end points) and learned the best way to do it.  For the next release of Xinha (0.97) I hope to bring my work together with the work of all other interested parties and release it as a library.  When we do that, users will finally be able to go back and forth between browsers and not have to fight to edit a document.

Until then…

Blah-blah Blog Post — Getting It Out

No more excuses, I’m publishing this.  This is a post about getting it done; something to help me write.  Something to help get over writer’s block.

I enjoy writing, and I think it’s helps me to be better organized.  When I started working for TOPP, we were encouraged to blog, which is one of the things I like about working here.  (The wild, swinging from the rafter, parties aren’t so bad either.)  Great policy, but it only helped me to keep up blogging for about five minutes (10 if you count a drunken blog post about Calimocho).  The funny thing is that I’ve always wanted to write more, and I’ve often wanted to come back and just do it.

Well, I finally found my voice this summer, and started posting about more technical issues.  (Not that I’ve been prolific.  Unless you count my drafts folder.)  I’ve done some blogging on this site as well as a couple of the work blogs, and I’m really looking forward to a guest post for my favorite political blog, Digifesto.

However, like anyone trying to start a new habit, especially one in an area of non-expertise, I found excuses not to write, or I’d start and never finish.  I knew this was going to happen.  It’s pretty well known that writing is not easy, especially keeping it up regularly.  I’d thought I’d be clever by getting started on a couple of downtime posts.  That way, when I hit a slowdown, I could just pick one and finish it.  It turns out for me, however, having a bunch of unfinished posts wasn’t helping.  When I got to a tough point in a post, I’d turn away, or start a new draft for later.  All of that “unfinished” work started to drag on me, and 50 pounds of blog posts really make your muscles sore.

Well, this is a kick in my pants.  Each line you read is one giant boot to my tookus.  (You’re still reading?  Kind of cruel, don’t you think?  What does that say about you?)

Well, I recently finished reading Pragmatic Thinking and Learning, a book about personal productivity (Thanks, Whit!).  (It’s by the same authors as The Pragmatic Progammer, which you might be familiar with.)  Something they spend a considerable amount of ink on (and carriage returns) is how to focus, and how to transition mentally from the part of your mind that sticks up roadblocks to the part that really flows and has the great ideas.

Inside is the story of a client they were trying to get started with morning writing.  (It’s a tool to harness some of the great ideas that you have and forget about, or just plain ignore.) He thought the exercise was a bit ridiculous, and so couldn’t get anything written down.  They told him to just fill a couple of pages with nonsense sentences (Blah blah blah, I’m writing a sentence) to get over the mental block.  Well, it took him a couple of weeks, but he started having some great ideas and got to actually writing.

Luckily for me, I’m not fighting this quite so overtly, but I still seem to get in my own way.  That’s why I’ve decided to take the same advice every time I want to blog.  This post started with a couple of notes (since I already had the topic) but each time I got blocked, I just wrote down a couple of paragraphs of nonsense (Blah blah, software bugs are good, people like using Windows, etc.).  It didn’t matter if I just didn’t have any ideas, or something interrupted my train of thought. I kept belting it out, and managed to make it all the way through.

So, here it is. I hope you find the idea useful as well.