The classic approach is that you "view" a page, and then click a button to kick the page into an "edit" mode. When "edit" mode starts up, various JS editor components "camp" on the different HTML components used for input fields. When the user switches back to "view" mode, the components are closed down and a completed page is "saved". There are a number of problems with this approach:
- Usability: It is clunky to use; you have to edit the entire page to change one character in a form field, and it's painfully slow
- Implementation: the JS components can conflict and fall over eachother, and it's the very devil to configure everything so they work together.
There are other editor components as well that don't necessarily go through an "edit page" cycle. These are inline editor components. While both classes
of editor components have different requirements they also share the inner need to organize various events like initialisation and form submission.
Editor components of various kinds are specified in the Type
field of DataForms
as well, though a lot more fine-grained. Still these are "editor components".
Another example of an "editor component" would be a single button "add attachment" that triggers a flash based uploader
. This uploader would then start to upload as soon as you close the selection box, and report when it is done. This too is a kind of "editor", as you changed the
current page. The thing missing now is that views of the current page need to be refreshed, as the list of attachments at the bottom of the topic
is outdated. Other potential listeners, such as an image gallery
would like to be updated as well.
The general situation is: an (inline) editor changed some content, you don't want to do a full page refresh but some content areas need to be updated
on the page.
We currently have at least three extensions that would like to hijack the standard textarea: TinyMCEPlugin
. There is a deeper reason why these don't function properly when installed all together ... they don't know anything about each other. This is for a good reason; we don't want to create artificial dependencies between then. However there is common functionality which is currently duplicated between them, and they have similar requirements, especially in the startup and shutdown phases.
All these components need to be coordinated in a way to play together. Some of these need special treatment or even interact with each other: a client selection box interacts with a projects selection box; a group selection box constraints a members selection box; a web selection box constraints a topic selection box; a form is only valid if a certain set of selections have been made. Just to name a few quite common requirements on forms.
Starting back in the server, we need to be able to associate an editor with a particular datum or (user) event. For example, I might want to have a form field which uses a WYSIWYG editor, but stores its contents in HTML rather than TML. Or I might want to be able to (as a user) specify a preference to use a particular type of WYSIWYG editor, or maybe no WYSIWYG editor at all, but a different flavour of raw editor (natEdit or smartEdit). So we need to be able to associate an "editor profile" with an editable object in such a way that sensible defaults can be cleanly overridden by user preferences.
Have a look at drupals wysiwyg api
, i.e. their notion of editor profiles
. This is a list of configurations for various editors that application developers then can chose from in form definitions.
The editor profile approach has the attraction that it's simple to associate large sets of options with data types. For example, I might have a form definition in a macro library:
The 'text' area could use the same style of specification, but in a macro definition:
- Set TEXT_EDITOR = wysiwyg
(this is consistent with Peter Jones' proposals to the (tm)wiki project for controlling the default editor, which is nice).
in this set of editor events as handlers registered to the submit event might veto and thus block further submission.
There's a problem with events: the order when which handler is called might become important. For instance, EditChapter needs to recombine the final
input by combining content before and after the current section with the one changed by the user. Only after that step TinyMCE is allowed to do its job by first converting html to tml. The situation is a bit more complicated as TinyMCE does not change the textarea directly as it uses an iframe for the real wysiwyg interaction. So both components need to be coordinated in a way.
Another problem with the order of events; it is different depending on which browser you use, especially during startup. Some frameworks, such as Dojo, go to great lengths to create a canonical event model that users can rely on to deliver the same behaviour on all browsers, but such solutions are rarely 100% reliable.
Form validation is as complex as you want. What an EditorAPI
could then veto on the form to be submitted. A much simpler example would be a modal dialog asking "do you really want to abandon your edits - yes - -no".
There's more in the irc logs attached below. Please help to refactor this to make it more concrete.
- 14 Jul 2009
Regarding editor profiles, I have had lots of thoughts (see WysiwygContentPolicies
) about this but sadly only just found this topic.
Behind the scenes, the editor in use (assuming it's a HTML editor) has requirements on the exact way that
should work, although that's a separate (backend) issue.
Here are my thoughts:
- Editor profiles
- Choosing an editor: I am personally interested in the lightweight jwysiwyg jquery editor (7kb, but no table handling) for formfields, and Wymeditor for semantic markup applications.
- Configuring the editor: Toolbars, plugins, sizing, options...
- Content-to-editor requirements (part of editor profile )
- Solved in the back-end (does not concern the user). But we are looking at adding even more TMCE specific quirks to
TML2HTML so this needs to be formalised if we ever want to be able to have more than one editor.
- Editor-to-content policies
- The user (or rather, foswiki admin/app tinkerer) will have requirements on what should be allowed into the target content (topic or formfield)
- Strictly no HTML tables? No spans? Preserve alignment style attributes? Block even TML tables? Etc.
- I had envisaged that several profiles should be configured in
LocalSite.cfg, differing progressively in the amount of HTML pollution allowed into a topic. For topics we would
* Set CONTENT_PROFILE = liberal+onlytmltables - where the first keyword would be the profile name, followed by a comma separated list of component policies as modifiers.
I had always imagined that specifying a wysiwyg editor (profile) for a formfield would actually go in the attributes column.
But we should be able to specify what goes back in to the formfield via the Type column. Something like:
|| Tooltip message
|| name of this macro
|| blah blah...
|| blah blah...
|| blah blah...
|| blah blah...
- Set WYSIWYG_EDITOR = fckeditor
In a similar fashion to the way we do
textarea will take a series of modifiers separated by '+'.
- The first modifier is a base policy name (made up of component policy modifiers; all configured in
LocalSite.cfg hashes because Foswiki vars are too unwieldy for this)
- Subsequent named component policy modifiers are added to tune the base policy to the user's liking
- If the name is prefixed with "no", it is substractive (removes the component policy if it is included by default in the base policy)
The example above shows:
- Description field is based on the
liberal policy (don't strip/flatten anything that fails to translate to TML), but enforces TML tables and TML lists, and disables the flattening of bare (no attributes)
- It uses the default WYSIWYG editor's formfield profile, in this case the form definition topic itself would default to
fckeditor (but normally tinymce's formfield profile)
- TML field is based on the
onlytml policy, which doesn't allow any HTML tags at all.
- MiscField is based on the liberal policy
Specifies the editor by name. A default profile (toolbar layout, sizing, options etc) specific to the named editor is assumed unless a '+' selects a specific one (which will be defined for the selected editor).
key=value pairs separated by ';' are passed to the editor plugin's setup routine to do what it likes with them.
"wysiwyg+formfield" selects the formfield profile of the default
, whatever that is (normally
At the moment the idea is that the editor profile name simply matches up with a corresponding Foswiki *Plugin to be called upon for setting up the textarea for wysiwyg (or not). WysiwygPlugin
will also know which editor it's talking to, and the EditorPlugin's
will selectively enable any special requirements for the HTML to be consumed by the editor.
parts allow the user to make their customisations by overriding from base configurations defined in
They should be able to re-use their customisations by setting variables.
- 30 Dec 2009
Type column to use '+' instead of ',content=' to delimit the modifiers, keeping it consistent with the way we do
- 03 Jan 2010