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

Improve copying of plain text on windows

This commit is contained in:
Neil Jenkins 2016-12-11 12:30:09 +11:00
parent e3059eda9f
commit 3d8cd62edb
4 changed files with 52 additions and 16 deletions

View file

@ -28,10 +28,10 @@ var win = doc.defaultView;
var ua = navigator.userAgent; var ua = navigator.userAgent;
var isAndroid = /Android/.test( ua );
var isIOS = /iP(?:ad|hone|od)/.test( ua ); var isIOS = /iP(?:ad|hone|od)/.test( ua );
var isMac = /Mac OS X/.test( ua ); var isMac = /Mac OS X/.test( ua );
var isWin = /Windows NT/.test( ua );
var isAndroid = /Android/.test( ua );
var isGecko = /Gecko\//.test( ua ); var isGecko = /Gecko\//.test( ua );
var isIElt11 = /Trident\/[456]\./.test( ua ); var isIElt11 = /Trident\/[456]\./.test( ua );
@ -2129,13 +2129,31 @@ var cleanupBRs = function ( node, root ) {
// The (non-standard but supported enough) innerText property is based on the // The (non-standard but supported enough) innerText property is based on the
// render tree in Firefox and possibly other browsers, so we must insert the // render tree in Firefox and possibly other browsers, so we must insert the
// DOM node into the document to ensure the text part is correct. // DOM node into the document to ensure the text part is correct.
var setClipboardData = function ( clipboardData, node ) { var setClipboardData = function ( clipboardData, node, root ) {
var body = node.ownerDocument.body; var body = node.ownerDocument.body;
var html, text;
// 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.
// So we need to remove them first.
cleanupBRs( node, root );
node.setAttribute( 'style', node.setAttribute( 'style',
'position:fixed;overflow:hidden;bottom:100%;right:100%;' ); 'position:fixed;overflow:hidden;bottom:100%;right:100%;' );
body.appendChild( node ); body.appendChild( node );
clipboardData.setData( 'text/html', node.innerHTML ); html = node.innerHTML;
clipboardData.setData( 'text/plain', node.innerText || node.textContent ); text = node.innerText || node.textContent;
// Firefox (and others?) returns unix line endings (\n) even on Windows.
// If on Windows, normalise to \r\n, since Notepad and some other crappy
// apps do not understand just \n.
if ( isWin ) {
text = text.replace( /\r?\n/g, '\r\n' );
}
clipboardData.setData( 'text/html', html );
clipboardData.setData( 'text/plain', text );
body.removeChild( node ); body.removeChild( node );
}; };
@ -2155,7 +2173,7 @@ var onCut = function ( event ) {
if ( !isEdge && !isIOS && clipboardData ) { if ( !isEdge && !isIOS && clipboardData ) {
moveRangeBoundariesUpTree( range, root ); moveRangeBoundariesUpTree( range, root );
node.appendChild( deleteContentsOfRange( range, root ) ); node.appendChild( deleteContentsOfRange( range, root ) );
setClipboardData( clipboardData, node ); setClipboardData( clipboardData, node, root );
event.preventDefault(); event.preventDefault();
} else { } else {
setTimeout( function () { setTimeout( function () {
@ -2201,7 +2219,7 @@ var onCopy = function ( event ) {
} }
node.appendChild( contents ); node.appendChild( contents );
setClipboardData( clipboardData, node ); setClipboardData( clipboardData, node, root );
event.preventDefault(); event.preventDefault();
} }
}; };

File diff suppressed because one or more lines are too long

View file

@ -3,13 +3,31 @@
// The (non-standard but supported enough) innerText property is based on the // The (non-standard but supported enough) innerText property is based on the
// render tree in Firefox and possibly other browsers, so we must insert the // render tree in Firefox and possibly other browsers, so we must insert the
// DOM node into the document to ensure the text part is correct. // DOM node into the document to ensure the text part is correct.
var setClipboardData = function ( clipboardData, node ) { var setClipboardData = function ( clipboardData, node, root ) {
var body = node.ownerDocument.body; var body = node.ownerDocument.body;
var html, text;
// 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.
// So we need to remove them first.
cleanupBRs( node, root );
node.setAttribute( 'style', node.setAttribute( 'style',
'position:fixed;overflow:hidden;bottom:100%;right:100%;' ); 'position:fixed;overflow:hidden;bottom:100%;right:100%;' );
body.appendChild( node ); body.appendChild( node );
clipboardData.setData( 'text/html', node.innerHTML ); html = node.innerHTML;
clipboardData.setData( 'text/plain', node.innerText || node.textContent ); text = node.innerText || node.textContent;
// Firefox (and others?) returns unix line endings (\n) even on Windows.
// If on Windows, normalise to \r\n, since Notepad and some other crappy
// apps do not understand just \n.
if ( isWin ) {
text = text.replace( /\r?\n/g, '\r\n' );
}
clipboardData.setData( 'text/html', html );
clipboardData.setData( 'text/plain', text );
body.removeChild( node ); body.removeChild( node );
}; };
@ -29,7 +47,7 @@ var onCut = function ( event ) {
if ( !isEdge && !isIOS && clipboardData ) { if ( !isEdge && !isIOS && clipboardData ) {
moveRangeBoundariesUpTree( range, root ); moveRangeBoundariesUpTree( range, root );
node.appendChild( deleteContentsOfRange( range, root ) ); node.appendChild( deleteContentsOfRange( range, root ) );
setClipboardData( clipboardData, node ); setClipboardData( clipboardData, node, root );
event.preventDefault(); event.preventDefault();
} else { } else {
setTimeout( function () { setTimeout( function () {
@ -75,7 +93,7 @@ var onCopy = function ( event ) {
} }
node.appendChild( contents ); node.appendChild( contents );
setClipboardData( clipboardData, node ); setClipboardData( clipboardData, node, root );
event.preventDefault(); event.preventDefault();
} }
}; };

View file

@ -24,10 +24,10 @@ var win = doc.defaultView;
var ua = navigator.userAgent; var ua = navigator.userAgent;
var isAndroid = /Android/.test( ua );
var isIOS = /iP(?:ad|hone|od)/.test( ua ); var isIOS = /iP(?:ad|hone|od)/.test( ua );
var isMac = /Mac OS X/.test( ua ); var isMac = /Mac OS X/.test( ua );
var isWin = /Windows NT/.test( ua );
var isAndroid = /Android/.test( ua );
var isGecko = /Gecko\//.test( ua ); var isGecko = /Gecko\//.test( ua );
var isIElt11 = /Trident\/[456]\./.test( ua ); var isIElt11 = /Trident\/[456]\./.test( ua );