0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2025-01-03 05:00:13 -05:00

Add accurate check for whether <br> breaks line.

When cleaning up <br> elements, we need to accurately determine whether there's
text before and after it in the block to know whether it will introduce a
visible line break.
This commit is contained in:
Neil Jenkins 2013-02-25 18:05:32 +11:00
parent 327b48b9db
commit a069e8305e
3 changed files with 40 additions and 7 deletions

File diff suppressed because one or more lines are too long

View file

@ -1209,11 +1209,44 @@
return root; return root;
}; };
var notWSTextNode = function ( node ) {
return notWS.test( node.data ) ? FILTER_ACCEPT : FILTER_SKIP;
};
var isLineBreak = function ( br ) {
var block = br.parentNode;
while ( block.isInline() ) {
block = block.parentNode;
}
var walker = new TreeWalker( block, SHOW_TEXT, notWSTextNode );
walker.currentNode = br;
if ( !walker.nextNode() ) {
return false;
}
walker.currentNode = br;
return !!walker.previousNode();
};
// <br> elements are treated specially, and differently depending on the
// browser, when in rich text editor mode. When adding HTML from external
// sources, we must remove them, replacing the ones that actually affect
// line breaks with a split of the block element containing it (and wrapping
// any not inside a block). Browsers that want <br> elements at the end of
// each block will then have them added back in a later fixCursor method
// call.
var cleanupBRs = function ( root ) { var cleanupBRs = function ( root ) {
var brs = root.querySelectorAll( 'BR' ), var brs = root.querySelectorAll( 'BR' ),
brBreaksLine = [],
l = brs.length, l = brs.length,
br, block; i, br, block;
// Must calculate whether the <br> breaks a line first, because if we
// have two <br>s next to each other, after the first one is converted
// to a block split, the second will be at the end of a block and
// therefore seem to not be a line break. But in its original context it
// was, so we should also convert it to a block split.
for ( i = 0; i < l; i += 1 ) {
brBreaksLine[i] = isLineBreak( brs[i] );
}
while ( l-- ) { while ( l-- ) {
br = brs[l]; br = brs[l];
// Cleanup may have removed it // Cleanup may have removed it
@ -1231,12 +1264,12 @@
// is actual text content in the block. Otherwise, the <br> is a // is actual text content in the block. Otherwise, the <br> is a
// placeholder to stop the block from collapsing, so we must leave // placeholder to stop the block from collapsing, so we must leave
// it. // it.
else if ( tagAfterSplit[ block.nodeName ] && else {
notWS.test( block.textContent ) ) { if ( tagAfterSplit[ block.nodeName ] && brBreaksLine[l] ) {
splitBlock( block, br.parentNode, br ); splitBlock( block, br.parentNode, br );
}
br.detach(); br.detach();
} }
// Otherwise leave the br alone.
} }
}; };

View file

@ -8,7 +8,7 @@
TreeWalker#previousNode. No way to feature detect this. TreeWalker#previousNode. No way to feature detect this.
* Some versions of Opera have a bug in TreeWalker#previousNode which makes * Some versions of Opera have a bug in TreeWalker#previousNode which makes
it skip to the wrong node. it skip to the wrong node.
Rather than risk further bugs, it's easiest just to implement our own Rather than risk further bugs, it's easiest just to implement our own
(subset) of the spec in all browsers. (subset) of the spec in all browsers.
*/ */