You are here: Foswiki>Tasks Web>Item2471 (21 May 2010, PaulHarvey)Edit Attach

Item2471: Add WysiwygPlugin option, classes to allow TinyMCEPlugin to run without forced_root_block: false

pencil
Priority: Normal
Current State: No Action Required
Released In: 1.1.0
Target Release: minor
Applies To: Extension
Component: WysiwygPlugin
Branches:
Reported By: PaulHarvey
Waiting For: Main.PaulHarvey, Main.MichaelTempest
Last Change By: PaulHarvey
It all began with Item1798 when we added forced_root_block: false to TinyMCEPlugin's init to solve the problem where TML2HTML <-> HTML2TML roundtrip would insert a newline after a table.

Problems

The init setting is not well supported upstream. We miss out on some browser quirk work-arounds that depend on the ForcedBlocks module default behaviour. Some other bugs that are caused by the new setting or are related to disabling it:

  • Item8274 - bullet lists separated by newline become merged
  • Item2447 - IE6 won't apply formats in vanilla TMCE setup with forced_root_blocks: false
  • Item2254 - Mozilla browsers get cursor jumping to top of document when finishing lists, etc.
  • Unable to position cursor before/after tables at beginning/end of document

Solution 1

I have attached a proof-of-concept patch attached to Item2254 which does something closer to what I think is needed, but needs much more thought/refactoring (detailed later in this task).

Solution 2

Actually, there is a much simpler work-around, which we could ship with 1.0.9: Rev 5347 not found. But this is a hack: ForcedBlocks is partially designed to ensure valid XHTML, and also partially solves a lot of browser quirks related to cursor and node selections.

By planting a <div> around our WYSIWYG content, we are "fooling" the cursor/selection tracking code when it comes to detecting whether or not the browser's DOM has lost cursor/selection tracking (it does this by checking if the currently selected node is the IFRAME's <body> element - if true, one of its strategies is to reset the cursor to the top of the document, hence Item2254). Now, when the browser's DOM faults, it will no longer report (incorrectly) the <body> tag as being the current selection, but our <div> instead. TinyMCE will regard this as a valid node selection, when it shouldn't.

On the other hand, the editor seems to behave better regardless - although some operations, notably the paste/insert link/etc. commands which rely on valid node selections will probably insert content at the wrong position.

Proposed solution

At the moment, this gets sent to TMCE in tml2html:
...<table>...</table>
some text...
Getting rid of our forced_root_block: false setting results in this being submitted back to html2tml:
...<table>...</table>
<p>some text</p>...
... as strictly speaking, XHTML-strict doesn't allow <body> to be a container for free text, and anyway this kind of things makes node selection/cursor tracking quite bonkers in some browsers.

What we need to send to TMCE in tml2html is something like this:
...<div class="WYSIWYG_FLATTEN"><table>...</table>
some text</div>...

  • Add a new (default) option to WYSIWYG editor, something like:
    • WYSIWYGPLUGIN_FOLLOWINGTEXT_FORCECOMMONBLOCKWITH = table, list
  • Formalise the fact we want some <div> discarded, by adding a class WYSIWYG_FLATTEN for HTML2TML to strip

-- PaulHarvey - 07 Dec 2009

Why not send everything wraped ina single div <body><<div>... everything else ... </div></body> ?

-- CrawfordCurrie - 07 Dec 2009

Curse my verbose writing! This is what I tried with Rev 5347 not found in Item2254. The reasons are under the heading "Solution 2", above.

Basically: Browser DOM in IE6 and FF 3.0 (haven't tested 3.5 much) still "fault" without the forced_root_block: false setting, just less often.

When it faults, it now ends up with root element, our new <div> as the current selection. So TMCE is unable to detect this condition (it's expecting a <body>) and apply corrective measures.

An invalid selection in TMCE means paste and any mceInsertContent command (insert link, attachment, etc) will insert stuff to the wrong place (in FF3.0, top of document, even though cursor position is elsewhere).

Would you prefer we ship Rev 5347 not found first (post-1.0.9, IMHO), and then act on this new feature if we find users come up against the unexpected paste/mceInsert commands enough to warrant this work?

-- PaulHarvey - 07 Dec 2009

Upgraded to urgent for 1.1; the closer to a "vanilla" TinyMCE customisation we can get, the fewer editor glitches we should experience.

-- PaulHarvey - 23 Jan 2010

As we are now at feature freeze, I suppose the best we can do is to apply Rev 5347 not found, but this is a hack that only fixes the cursor unable to get to beginning/end of document.

-- PaulHarvey - 06 Apr 2010

Foswiki rendering means that if the author intends a newline after a table, then it will spit out:
</table>
<p />
some text
Because free-text isn't allowed in the body, does that mean that TMCE will return that as:
</table>
<p />
<p>
some text
</p>
or is it smart enough to collapse the first P?

-- CrawfordCurrie - 20 Apr 2010

Actually, the only circumstance that tml2html seems to emit free text without a containing <p> tag is when it immediately follows a table (and probably a list). Obviously, this to avoid unwanted newlines where you want macros to build tables, lists etc.

tml2html seems to properly contain all text nodes in <p> tags the rest of the time.

My earlier idea is that we wrap table + text in a common <div> which html2tml would flatten out again before reaching the topic.

I can't recall the 3.2.7 behaviour, but at the moment, 3.3.3 is collapsing empty <p> tags like crazy... Somewhere along the way we're losing the &nbsp; which I assume stopped earlier TMCE from collapsing them.

There are some comprehensive options available to tweak TMCE's cleanup-before-submit code, which we could play with.

-- PaulHarvey - 20 Apr 2010

MichaelTempest has worked around this in Item2254

-- PaulHarvey - 21 May 2010

ItemTemplate edit

Summary Add WysiwygPlugin option, classes to allow TinyMCEPlugin to run without forced_root_block: false
ReportedBy PaulHarvey
Codebase 1.0.8
SVN Range
AppliesTo Extension
Component WysiwygPlugin
Priority Normal
CurrentState No Action Required
WaitingFor PaulHarvey, MichaelTempest
Checkins
TargetRelease minor
ReleasedIn 1.1.0
Topic revision: r9 - 21 May 2010, PaulHarvey
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy