0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2025-01-05 06:10:07 -05:00

If selection is empty, expand to current line when removing PREs.

This commit is contained in:
Gert K. Sønderby 2015-11-25 14:41:06 +01:00 committed by Gert Sønderby
parent 6ba03f6989
commit 8a8285560e
4 changed files with 210 additions and 108 deletions

View file

@ -3551,9 +3551,9 @@ var getTextFromHTMLFragment = function ( self, frag ) {
var makePreformatted = function ( frag ) {
return this.createElement( 'PRE',
this._config.tagAttributes.pre, [
this.createElement( 'DIV', { id: startSelectionId } ),
this.createElement( 'INPUT', { id: startSelectionId, type: 'hidden' } ),
getTextFromHTMLFragment( this, frag ),
this.createElement( 'DIV', { id: endSelectionId } )
this.createElement( 'INPUT', { id: endSelectionId, type: 'hidden' } )
] );
};
@ -3561,14 +3561,13 @@ var removePreformatted = function ( frag ) {
var range = this._doc.createRange();
var startRangeMarker = frag.querySelector( '#' + startSelectionId );
var endRangeMarker = frag.querySelector( '#' + endSelectionId );
if (!startRangeMarker || !endRangeMarker) { return frag; }
if ( !startRangeMarker || !endRangeMarker ) {
return frag;
}
range.setStartBefore( startRangeMarker );
range.setEndAfter( endRangeMarker );
if (!range || range.collapsed) {
return frag; // Maybe remove whole element instead? Single line?
} else {
var preElems = frag.querySelectorAll('pre');
if ( preElems.length === 0 ) {
return frag;
@ -3580,6 +3579,41 @@ var removePreformatted = function ( frag ) {
endContainer = range.endContainer,
endOffset = range.endOffset,
splitElems = [];
if ( startRangeMarker.nextSibling === endRangeMarker ) {
// Collapsed selection - expand to the whole line
var beforeStart = startRangeMarker.previousSibling,
newNode;
if ( beforeStart && beforeStart.nodeType === TEXT_NODE ) {
var lineStartOffset = beforeStart.nodeValue.lastIndexOf( '\n' );
if ( lineStartOffset !== -1 ) {
newNode = beforeStart.splitText( lineStartOffset );
beforeStart.parentNode.insertBefore( startRangeMarker, newNode );
} else {
beforeStart.parentNode.insertBefore( startRangeMarker, beforeStart );
}
range.setStartBefore( startRangeMarker );
startOffset = range.startOffset;
startContainer = range.startContainer;
}
var afterEnd = endRangeMarker.nextSibling;
if ( afterEnd && afterEnd.nodeType === TEXT_NODE ) {
var lineEndOffset = afterEnd.nodeValue.indexOf( '\n' );
if ( lineEndOffset !== -1 ) {
newNode = afterEnd.splitText( lineEndOffset + 1 );
afterEnd.parentNode.insertBefore( endRangeMarker, newNode );
} else {
if ( afterEnd.nextSibling ) {
afterEnd.parentNode.insertBefore( endRangeMarker, afterEnd.nextSibling );
} else {
afterEnd.parentNode.appendChild( endRangeMarker );
}
}
range.setEndBefore( endRangeMarker );
endOffset = range.endOffset;
endContainer = range.endContainer;
}
startContainer.normalize();
}
if ( getNearest( endContainer, 'PRE' ) === lastPre &&
endOffset < endContainer.childNodes.length - 1 ) {
splitElems.push( split( endContainer, endOffset, lastPre.parentNode ) );
@ -3605,6 +3639,7 @@ var removePreformatted = function ( frag ) {
var nodeLines = childNode.nodeValue.split( '\n' );
/*jshint loopfunc: true*/
nodeLines.forEach( function (line) {
if ( !line ) { return; }
var div = self.createDefaultBlock( [ self._doc.createTextNode ( line ) ] );
replacement.appendChild( div );
});
@ -3619,7 +3654,6 @@ var removePreformatted = function ( frag ) {
}
return frag;
}
}
};
proto._ensureBottomLine = function () {

File diff suppressed because one or more lines are too long

View file

@ -1352,9 +1352,9 @@ var getTextFromHTMLFragment = function ( self, frag ) {
var makePreformatted = function ( frag ) {
return this.createElement( 'PRE',
this._config.tagAttributes.pre, [
this.createElement( 'DIV', { id: startSelectionId } ),
this.createElement( 'INPUT', { id: startSelectionId, type: 'hidden' } ),
getTextFromHTMLFragment( this, frag ),
this.createElement( 'DIV', { id: endSelectionId } )
this.createElement( 'INPUT', { id: endSelectionId, type: 'hidden' } )
] );
};
@ -1362,14 +1362,13 @@ var removePreformatted = function ( frag ) {
var range = this._doc.createRange();
var startRangeMarker = frag.querySelector( '#' + startSelectionId );
var endRangeMarker = frag.querySelector( '#' + endSelectionId );
if (!startRangeMarker || !endRangeMarker) { return frag; }
if ( !startRangeMarker || !endRangeMarker ) {
return frag;
}
range.setStartBefore( startRangeMarker );
range.setEndAfter( endRangeMarker );
if (!range || range.collapsed) {
return frag; // Maybe remove whole element instead? Single line?
} else {
var preElems = frag.querySelectorAll('pre');
if ( preElems.length === 0 ) {
return frag;
@ -1381,6 +1380,41 @@ var removePreformatted = function ( frag ) {
endContainer = range.endContainer,
endOffset = range.endOffset,
splitElems = [];
if ( startRangeMarker.nextSibling === endRangeMarker ) {
// Collapsed selection - expand to the whole line
var beforeStart = startRangeMarker.previousSibling,
newNode;
if ( beforeStart && beforeStart.nodeType === TEXT_NODE ) {
var lineStartOffset = beforeStart.nodeValue.lastIndexOf( '\n' );
if ( lineStartOffset !== -1 ) {
newNode = beforeStart.splitText( lineStartOffset );
beforeStart.parentNode.insertBefore( startRangeMarker, newNode );
} else {
beforeStart.parentNode.insertBefore( startRangeMarker, beforeStart );
}
range.setStartBefore( startRangeMarker );
startOffset = range.startOffset;
startContainer = range.startContainer;
}
var afterEnd = endRangeMarker.nextSibling;
if ( afterEnd && afterEnd.nodeType === TEXT_NODE ) {
var lineEndOffset = afterEnd.nodeValue.indexOf( '\n' );
if ( lineEndOffset !== -1 ) {
newNode = afterEnd.splitText( lineEndOffset + 1 );
afterEnd.parentNode.insertBefore( endRangeMarker, newNode );
} else {
if ( afterEnd.nextSibling ) {
afterEnd.parentNode.insertBefore( endRangeMarker, afterEnd.nextSibling );
} else {
afterEnd.parentNode.appendChild( endRangeMarker );
}
}
range.setEndBefore( endRangeMarker );
endOffset = range.endOffset;
endContainer = range.endContainer;
}
startContainer.normalize();
}
if ( getNearest( endContainer, 'PRE' ) === lastPre &&
endOffset < endContainer.childNodes.length - 1 ) {
splitElems.push( split( endContainer, endOffset, lastPre.parentNode ) );
@ -1406,6 +1440,7 @@ var removePreformatted = function ( frag ) {
var nodeLines = childNode.nodeValue.split( '\n' );
/*jshint loopfunc: true*/
nodeLines.forEach( function (line) {
if ( !line ) { return; }
var div = self.createDefaultBlock( [ self._doc.createTextNode ( line ) ] );
replacement.appendChild( div );
});
@ -1420,7 +1455,6 @@ var removePreformatted = function ( frag ) {
}
return frag;
}
}
};
proto._ensureBottomLine = function () {

View file

@ -242,7 +242,7 @@ describe('Squire RTE', function () {
expect(editor, 'to contain HTML', startHTML);
selectAll(editor);
editor.removePreformatted();
expect(editor, 'to contain HTML', '<div>abc</div><div></div><div>one two three four five</div><div></div>');
expect(editor, 'to contain HTML', '<div>abc</div><div>one two three four five</div>');
});
it('cuts the beginning off PRE tags', function () {
@ -254,7 +254,7 @@ describe('Squire RTE', function () {
range.setEnd(doc.querySelector('pre').childNodes[0], 18);
editor.setSelection(range);
editor.removePreformatted();
expect(editor, 'to contain HTML', '<div>abc</div><div></div><div>one two three</div><pre> four five\n</pre>');
expect(editor, 'to contain HTML', '<div>abc</div><div>one two three</div><pre> four five\n</pre>');
});
it('cuts the end off PRE tags', function () {
@ -268,6 +268,40 @@ describe('Squire RTE', function () {
editor.removePreformatted();
expect(editor, 'to contain HTML', '<pre>abc\n\none two three</pre><div> four five</div>');
});
describe('with collapsed selection', function () {
beforeEach(function () {
var startHTML = '<pre>abc\n\none two three four five\nxyz</pre>';
editor.setHTML(startHTML);
});
it('expands selection to the whole line', function () {
var range = doc.createRange();
range.setStart(doc.querySelector('pre').childNodes[0], 24);
range.setEnd(doc.querySelector('pre').childNodes[0], 24);
editor.setSelection(range);
editor.removePreformatted();
expect(editor, 'to contain HTML', '<pre>abc\n</pre><div>one two three four five</div><pre>xyz</pre>');
});
it('... even when on first line of tag', function () {
var range = doc.createRange();
range.setStart(doc.querySelector('pre').childNodes[0], 2);
range.setEnd(doc.querySelector('pre').childNodes[0], 2);
editor.setSelection(range);
editor.removePreformatted();
expect(editor, 'to contain HTML', '<div>abc</div><pre>\none two three four five\nxyz</pre>');
});
it('... or on last line of tag', function () {
var range = doc.createRange();
range.setStart(doc.querySelector('pre').childNodes[0], 31);
range.setEnd(doc.querySelector('pre').childNodes[0], 31);
editor.setSelection(range);
editor.removePreformatted();
expect(editor, 'to contain HTML', '<pre>abc\n\none two three four five</pre><div>xyz</div>');
});
});
});
afterEach(function () {