Custom WYSIWYG Buttons

Discussion corner for Developers of Serendipity.
User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Custom WYSIWYG Buttons

Post by judebert » Mon Dec 15, 2008 5:51 pm

Thanks to everyone's help, I've solved the JavaScript reference problem. My plugin now emits its custom JavaScript as expected, and it transforms the document as expected.

However, users need to mark parts of the document with a special class. That's no problem for us advanced/HTML editing types, but there are other people who just don't have the time or inclination to learn HTML.

So I want to add a button to the editor. There are multiple examples of this for the non-WYSIWYG editor, but none that I can find for the WYSIWYG editor. I found the spot in the core where we add the media button for Xinha/HTMLArea, but it isn't expandable.

I do see, however, a backend_wysiwyg hook getting called. I'd like to propose allowing plugins to add a "buttons" array to the $eventData from that hook, providing a name, image, toolbar name, css, and JavaScript function that returns plain HTML. The core would then add the button to the appropriate toolbar if a non-wysiwyg or Xinha editor was created; plugins would be responsible for adding the button for other editors.

I also recommend naming the toolbars "formatting", "media", and "web". Of course, editors would be allowed to ignore the toolbar name and just dump the button anywhere they wanted, but it seems those are the common functionality for HTML editing, and using them would improve the user experience.

Obviously this can't be completed and tested for 1.4 before Christmas (sorry, Don). But I thought I would stimulate some discussion before I went mucking around with any truly important code.
Judebert
---
Website | Wishlist | PayPal

User avatar
garvinhicking
Core Developer
Posts: 30015
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Custom WYSIWYG Buttons

Post by garvinhicking » Mon Dec 15, 2008 6:47 pm

Hi!

That's a good idea; currently, if editors had their own buttons, those options were usually already put into the appropriate event plugin. Only for the internal s9y editor it was not found necessary until now to add more custom buttons than the s9y one.

So I think adding a new event hook to the core at this place would be a good improvement, and then existing wysiwyg-editor plugins could choose to make use of it and implement it in their plugin cores as well, or leave it at that if the correspondig editor doesn'T need it.

Regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/

User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert » Wed Dec 17, 2008 6:43 pm

I've modified the functions_entries_admin.inc.php to allow buttons to be added to the HTMLArea / Xinha and non-WYSIWYG editors. That part was easy; it even supports specifying toolbars.

Making it compatible with multiple editors is going to require some Javascript standardization, though. Each editor uses its own method to retrieve and set text. For the media editor, we solved this problem by adding Javascript for all the known editors (HTMLArea, Xinha, TinyMCE, FCKEdit, and plain textarea) to the main editor script (serendipity_editor.js). While this works, it's a maintenance nightmare: every time we add a new editor, we need to update the script. Worse, we add dependencies on third-party code: every time one of those editors updates, we need to update that script, which resides in core code.

I think a better solution would be restricting the Javascript that a button can safely use to some standardized functions, and requiring each editor plugin to provide implementations of those functions. Then, any editor can be added with only plugin changes.

I've examined the media library, the typeset button plugin, and the buttons I'm planning to make. Most buttons simply want to either insert new HTML at the current caret location, or wrap the current selection in tags.

Usually the editor would be passed as an object, but if we want to allow database lookups (like to retrieve media, or other entries) we need to pass IDs so the PHP can do the heavy lifting and call the editor's Javascript with the result.

All things considered, this is the minimal subset that I believe will fit Serendipity's current needs:

serendipity_editor_getSelected(eid)
Returns the raw equivalent of the currently selected string, or an empty string if nothing is selected.

serendipity_editor_replaceSelected(eid, str)
Replaces the currently selected text with the provided string. If nothing is selected, the text is inserted at the current caret location.

serendipity_editor_getAll(eid)
Returns the raw equivalent of the entire text. Useful for buttons that want to spellcheck or perform other complicated processing.

serendipity_editor_setAll(eid, str)
Replaces the entire text with the provided string.

The functions should work in either HTML or raw modes; it's up to the editor to decide what mode it's in and how to retrieve or set the text.

Future buttons may require more advanced editing, however. Consider a "border" button, for instance. This function may support only block-level elements, and therefore may wish to determine the parent block of the currently-selected location. It may not support nested borders; in that case, it would want to "unwrap" the current block before wrapping it again... but only if it's currently wrapped.

While both of those actions could be implemented with the proposed interface, the solution would be inelegant. (The simplest way would be to 'mark' the current selection by wrapping it with markers, then get the entire text and process it to replace currently wrapped elements, or find and modify parent elements.)

However, the only elegant solution I can imagine involves adding additional standardized functions for retrieving and manipulating the selection, and for navigating HTML by tags and possibly even attributes.

So much for the preamble (whew!).

Is that minimal subset sufficient? Should we add other standard functions? Can you think of anything I've missed?

Next up: adding CSS for text marked by custom buttons.
Judebert
---
Website | Wishlist | PayPal

User avatar
Don Chambers
Regular
Posts: 3612
Joined: Mon Feb 13, 2006 3:40 am
Location: Chicago, IL, USA
Contact:

Post by Don Chambers » Thu Dec 18, 2008 8:39 pm

Garvin - what do you think?

User avatar
garvinhicking
Core Developer
Posts: 30015
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking » Fri Dec 19, 2008 2:42 pm

Hi!

That's some tough things to consider...currently I can't wrap my head around this for future compatibility. For now this sounds reasonable, and we might need to change the API in some other 1.4.x or 1.5 release - but that's fine with me, considering the usage scneario is currently only for a few people.

Regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/

User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert » Mon Dec 22, 2008 9:38 pm

The BC is always the problem. I've used only existing hooks, but the Javascript is still different for WYSIWYG and non-WYSIWYG buttons. Since they're using different hooks, that's no big deal (beyond the duplication of code).

I'd like to solve that, but I think it's going to require an additional hook, and a long look at the serendipity_editor.js and other editors' Javascript.

Garvin, is the performance hit for another hook very big?
Judebert
---
Website | Wishlist | PayPal

User avatar
Don Chambers
Regular
Posts: 3612
Joined: Mon Feb 13, 2006 3:40 am
Location: Chicago, IL, USA
Contact:

Post by Don Chambers » Mon Dec 22, 2008 9:42 pm

Judebert - I have prototype buttons for you when you are ready for that.

User avatar
garvinhicking
Core Developer
Posts: 30015
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking » Tue Dec 23, 2008 1:17 am

Hi!

Garvin, is the performance hit for another hook very big?


No, it would be fine for the backend screen. The benefit is much higher than the performance implications.

Regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/

User avatar
konus
Regular
Posts: 334
Joined: Mon Jun 16, 2008 1:57 pm
Location: Dresden, Germany
Contact:

Post by konus » Fri Jan 16, 2009 2:11 pm

Hi,
I am very interested in this, are there any news on this issue?
konus

User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert » Fri Jan 16, 2009 4:44 pm

Yes, the news is that my hard drive crashed in the middle of implementation. I'm demoralized, and I've stopped work temporarily while I regain my wits.

Before the crash, I implemented some pull-quote custom buttons. I only tested with the HTMLArea/Xinha editors and the non-wysiwyg editor (TinyMCE and other WYSIWYG editors will have to provide their own API wrappers; I'll probably implement one for TinyMCE before I declare the feature complete). The buttons worked with no problem.

However, I needed to use different code to add the buttons to the non-wysiwyg editor than to add them to the wywsiwyg editors. That's unacceptable to me.

The 1.4 release has the changes to serendipity_editor.js and other files that allow the custom buttons to work. It's likely the interface will change in the near future, however, when I manage to make it all gel.

To regain my confidence, I'm working on other things and letting the custom buttons take a temporary back seat. Once I've got my fitness/Amazing Race site up and running, I'll get back to the buttons.
Judebert
---
Website | Wishlist | PayPal

User avatar
konus
Regular
Posts: 334
Joined: Mon Jun 16, 2008 1:57 pm
Location: Dresden, Germany
Contact:

Post by konus » Fri Jan 16, 2009 10:48 pm

I am sad to hear the bad news about your disk crash. Was it a seagate Barracuda 7200.11.?
EDIT: I read your posting on your blog about it.

Anyway I hope, you recover soon :-) :-) :-)

User avatar
konus
Regular
Posts: 334
Joined: Mon Jun 16, 2008 1:57 pm
Location: Dresden, Germany
Contact:

Re: Custom WYSIWYG Buttons

Post by konus » Thu Feb 19, 2009 10:50 am

Hi judebert,
are there any news on this? I am starting a new project right now and could use the new buttons :-)

User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Re: Custom WYSIWYG Buttons

Post by judebert » Thu Feb 19, 2009 7:37 pm

Sorry, Konus, I've been a little swamped. I keep trying to do something with it, and then I get sidetracked.

The big problem at the moment is that there's no hook that will get called for both the WYSIWYG and non-WYSIWYG editors. It occurs to me that the *correct* solution is for both editor types to call the same s9y function, just like the WYSIWYG editor does now. The templates shouldn't be worried about what type it is, any more than the plugins should.

Only the default template uses the entry form, anyway. But Garvin did just point out that custom templates are not always in the repository, so if I make the change I want to, I could mess up someone's custom admin templates.

I hope to get back on the ball later today. Maybe Garvin will say it's okay to re-implement the entry form prinout. That would make things easier.
Judebert
---
Website | Wishlist | PayPal

User avatar
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Re: Custom WYSIWYG Buttons

Post by judebert » Thu Feb 19, 2009 10:06 pm

Hmmm... we've got this idea of "advanced" WYSIWYG. What it really means is, "If the browser's user agent contains Mozilla, IE, or Opera, the browser can handle advanced Javascript for WYSIWYG editors."

Isn't that all of them? I mean, it doesn't even distinguish between early Netscape browsers and the latest FireFox. If there's a browser that handles Javascript differently, I'd like to know about it.

Cleaning up that variable and the related Javascript would help reduce this problem's complexity. And it might even reduce our resource usage.

User avatar
yellowled
Regular
Posts: 6930
Joined: Fri Jan 13, 2006 12:46 pm
Location: Eutin, Germany
Contact:

Re: Custom WYSIWYG Buttons

Post by yellowled » Thu Feb 19, 2009 10:12 pm

judebert wrote:"If the browser's user agent contains Mozilla, IE, or Opera, the browser can handle advanced Javascript for WYSIWYG editors."

Isn't that all of them?

I'm really no expert on this, but there's always the WebKit browsers, i.e. (most notably) Safari and Konqueror. However, I have no idea whatsoever if and how they handle advanced JS. One would expect fine, but who knows?

YL
amazon Wishlist - Serendipity-Podcast (German only, sorry)

Post Reply