Index: ForceBlocks.js =================================================================== --- ForceBlocks.js (revision 1250) +++ ForceBlocks.js (working copy) @@ -352,6 +352,37 @@ var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car; + /* See http://foswiki.org/Tasks/Item2254 - workaround. + 1) Remember where we last did insertPara. + 2a) When we lose valid selection range, check whether there's a
after the last + para we inserted, + 2b) Delete it, + 2c) Replace with

, + 2d) using mceInsertContent, which happens to magically restore a valid selection range */ + var insertParaConvertInvalid = function (ipciEd, ipciCm, ipciE) { + var ipci = { // SMELL: Do I really need to contain these in a hash to avoid aliasing? + d : ed.getDoc(), b : d.body, s : ed.selection.getSel(), ra : d.createRange(), + rb : d.createRange(), dir : rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0, + sn : dir ? s.anchorNode : s.focusNode, en : dir ? s.focusNode : s.anchorNode, + nextSibling : undefined + }; + + ed.onNodeChange.remove(insertParaConvertInvalid); + // If start and end nodes represent invalid range... + if (ipci.sn === ipci.b && ipci.en === ipci.b) { + ipci.nextSibling = ipciEd.forceBlocks.lastInsertedParaParent.nextSibling; + // if the nextSibling after last para insertion is a
+ if (ipci.nextSibling.nodeName === 'BR') { + // then delete it + ipciEd.forceBlocks.lastInsertedParaParent.parentNode.removeChild( + ipci.nextSibling); + ed.getWin().focus(); // focus the editor (caret quirk) + ed.execCommand('mceInsertContent', false, '

'); + ed.nodeChanged(); + } // sadly, if it wasn't a BR then user will get a cursor jump to top of ed + } + ipciEd.forceBlocks.lastInsertedParaParent = ipciE.parentNode; + } // If root blocks are forced then use Operas default behavior since it's really good // Removed due to bug: #1853816 // if (se.forced_root_block && isOpera) @@ -425,8 +456,13 @@ bn = sb ? sb.nodeName : se.element; // Get block name to create // Return inside list use default browser behavior - if (t.dom.getParent(sb, 'ol,ul,pre')) + if (t.dom.getParent(sb, 'ol,ul,pre')) { + if (ed.settings.moz_bullets_hack) { + ed.onNodeChange.add(insertParaConvertInvalid); + } + return true; + } // If caption or absolute layers then always generate new blocks within if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {