0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2025-01-04 22:00:09 -05:00

Fix empty lines missing when copying plain text

This commit is contained in:
Neil Jenkins 2017-01-09 10:35:19 +11:00
parent 918e252500
commit e645489f5f
5 changed files with 30 additions and 28 deletions

View file

@ -2077,16 +2077,17 @@ var notWSTextNode = function ( node ) {
node.nodeName === 'BR' : node.nodeName === 'BR' :
notWS.test( node.data ); notWS.test( node.data );
}; };
var isLineBreak = function ( br ) { var isLineBreak = function ( br, isLBIfEmptyBlock ) {
var block = br.parentNode, var block = br.parentNode;
walker; var walker;
while ( isInline( block ) ) { while ( isInline( block ) ) {
block = block.parentNode; block = block.parentNode;
} }
walker = new TreeWalker( walker = new TreeWalker(
block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode ); block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode );
walker.currentNode = br; walker.currentNode = br;
return !!walker.nextNode(); return !!walker.nextNode() ||
( isLBIfEmptyBlock && !walker.previousNode() );
}; };
// <br> elements are treated specially, and differently depending on the // <br> elements are treated specially, and differently depending on the
@ -2095,11 +2096,11 @@ var isLineBreak = function ( br ) {
// line breaks by wrapping the inline text in a <div>. Browsers that want <br> // line breaks by wrapping the inline text in a <div>. Browsers that want <br>
// elements at the end of each block will then have them added back in a later // elements at the end of each block will then have them added back in a later
// fixCursor method call. // fixCursor method call.
var cleanupBRs = function ( node, root ) { var cleanupBRs = function ( node, root, keepForBlankLine ) {
var brs = node.querySelectorAll( 'BR' ), var brs = node.querySelectorAll( 'BR' );
brBreaksLine = [], var brBreaksLine = [];
l = brs.length, var l = brs.length;
i, br, parent; var i, br, parent;
// Must calculate whether the <br> breaks a line first, because if we // 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 // have two <br>s next to each other, after the first one is converted
@ -2107,7 +2108,7 @@ var cleanupBRs = function ( node, root ) {
// therefore seem to not be a line break. But in its original context it // 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. // was, so we should also convert it to a block split.
for ( i = 0; i < l; i += 1 ) { for ( i = 0; i < l; i += 1 ) {
brBreaksLine[i] = isLineBreak( brs[i] ); brBreaksLine[i] = isLineBreak( brs[i], keepForBlankLine );
} }
while ( l-- ) { while ( l-- ) {
br = brs[l]; br = brs[l];
@ -2136,7 +2137,7 @@ var setClipboardData = function ( clipboardData, node, root ) {
// Firefox will add an extra new line for BRs at the end of block when // Firefox will add an extra new line for BRs at the end of block when
// calculating innerText, even though they don't actually affect display. // calculating innerText, even though they don't actually affect display.
// So we need to remove them first. // So we need to remove them first.
cleanupBRs( node, root ); cleanupBRs( node, root, true );
node.setAttribute( 'style', node.setAttribute( 'style',
'position:fixed;overflow:hidden;bottom:100%;right:100%;' ); 'position:fixed;overflow:hidden;bottom:100%;right:100%;' );
@ -4004,7 +4005,7 @@ proto.setHTML = function ( html ) {
} }
cleanTree( frag ); cleanTree( frag );
cleanupBRs( frag, root ); cleanupBRs( frag, root, false );
fixContainer( frag, root ); fixContainer( frag, root );
@ -4180,7 +4181,7 @@ proto.insertHTML = function ( html, isPaste ) {
addLinks( frag, frag, this ); addLinks( frag, frag, this );
cleanTree( frag ); cleanTree( frag );
cleanupBRs( frag, root ); cleanupBRs( frag, root, false );
removeEmptyInlines( frag ); removeEmptyInlines( frag );
frag.normalize(); frag.normalize();

File diff suppressed because one or more lines are too long

View file

@ -307,16 +307,17 @@ var notWSTextNode = function ( node ) {
node.nodeName === 'BR' : node.nodeName === 'BR' :
notWS.test( node.data ); notWS.test( node.data );
}; };
var isLineBreak = function ( br ) { var isLineBreak = function ( br, isLBIfEmptyBlock ) {
var block = br.parentNode, var block = br.parentNode;
walker; var walker;
while ( isInline( block ) ) { while ( isInline( block ) ) {
block = block.parentNode; block = block.parentNode;
} }
walker = new TreeWalker( walker = new TreeWalker(
block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode ); block, SHOW_ELEMENT|SHOW_TEXT, notWSTextNode );
walker.currentNode = br; walker.currentNode = br;
return !!walker.nextNode(); return !!walker.nextNode() ||
( isLBIfEmptyBlock && !walker.previousNode() );
}; };
// <br> elements are treated specially, and differently depending on the // <br> elements are treated specially, and differently depending on the
@ -325,11 +326,11 @@ var isLineBreak = function ( br ) {
// line breaks by wrapping the inline text in a <div>. Browsers that want <br> // line breaks by wrapping the inline text in a <div>. Browsers that want <br>
// elements at the end of each block will then have them added back in a later // elements at the end of each block will then have them added back in a later
// fixCursor method call. // fixCursor method call.
var cleanupBRs = function ( node, root ) { var cleanupBRs = function ( node, root, keepForBlankLine ) {
var brs = node.querySelectorAll( 'BR' ), var brs = node.querySelectorAll( 'BR' );
brBreaksLine = [], var brBreaksLine = [];
l = brs.length, var l = brs.length;
i, br, parent; var i, br, parent;
// Must calculate whether the <br> breaks a line first, because if we // 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 // have two <br>s next to each other, after the first one is converted
@ -337,7 +338,7 @@ var cleanupBRs = function ( node, root ) {
// therefore seem to not be a line break. But in its original context it // 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. // was, so we should also convert it to a block split.
for ( i = 0; i < l; i += 1 ) { for ( i = 0; i < l; i += 1 ) {
brBreaksLine[i] = isLineBreak( brs[i] ); brBreaksLine[i] = isLineBreak( brs[i], keepForBlankLine );
} }
while ( l-- ) { while ( l-- ) {
br = brs[l]; br = brs[l];

View file

@ -10,7 +10,7 @@ var setClipboardData = function ( clipboardData, node, root ) {
// Firefox will add an extra new line for BRs at the end of block when // Firefox will add an extra new line for BRs at the end of block when
// calculating innerText, even though they don't actually affect display. // calculating innerText, even though they don't actually affect display.
// So we need to remove them first. // So we need to remove them first.
cleanupBRs( node, root ); cleanupBRs( node, root, true );
node.setAttribute( 'style', node.setAttribute( 'style',
'position:fixed;overflow:hidden;bottom:100%;right:100%;' ); 'position:fixed;overflow:hidden;bottom:100%;right:100%;' );

View file

@ -1592,7 +1592,7 @@ proto.setHTML = function ( html ) {
} }
cleanTree( frag ); cleanTree( frag );
cleanupBRs( frag, root ); cleanupBRs( frag, root, false );
fixContainer( frag, root ); fixContainer( frag, root );
@ -1768,7 +1768,7 @@ proto.insertHTML = function ( html, isPaste ) {
addLinks( frag, frag, this ); addLinks( frag, frag, this );
cleanTree( frag ); cleanTree( frag );
cleanupBRs( frag, root ); cleanupBRs( frag, root, false );
removeEmptyInlines( frag ); removeEmptyInlines( frag );
frag.normalize(); frag.normalize();