Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit bfeabff

Browse files
committed
Tests: more unit test for non-collapsed selection during composition added.
1 parent 583b958 commit bfeabff

File tree

1 file changed

+182
-3
lines changed

1 file changed

+182
-3
lines changed

tests/view/renderer.js

+182-3
Original file line numberDiff line numberDiff line change
@@ -1803,8 +1803,9 @@ describe( 'Renderer', () => {
18031803
);
18041804
} );
18051805

1806-
// Happens when `shift + up` arrow pressed during composition in Chrome on Windows.
1807-
it( 'should not delete inline filler when selection (ranged) changes without compositionend (filler on end)', () => {
1806+
// Happens when `shift + up` arrow pressed during composition (Chrome on Windows).
1807+
// https://github.com/ckeditor/ckeditor5-engine/pull/1355#issuecomment-376087328
1808+
it( 'should not delete inline filler when selection changes without compositionend (filler in styled element)', () => {
18081809
const domSelection = document.getSelection();
18091810

18101811
// 1. Render <h1>h1</h1><p>foo<b>FILLER{}</b>bar</p>.
@@ -1860,8 +1861,186 @@ describe( 'Renderer', () => {
18601861
expect( domSelection.getRangeAt( 0 ).collapsed ).to.be.false;
18611862
} );
18621863

1864+
// Happens when `shift + up` arrow pressed during composition after unbolding text (Chrome on Windows).
1865+
// https://github.com/ckeditor/ckeditor5-engine/pull/1355#issuecomment-381516509
1866+
it( 'should not delete inline filler when selection changes without compositionend (filler on paragraph end with text)', () => {
1867+
const domSelection = document.getSelection();
1868+
1869+
// 1. Render <p>foo<b>FILLER{}</b></p>.
1870+
const { view: viewContent, selection: newSelection } = parse(
1871+
'<container:p>foo<attribute:b>[]</attribute:b></container:p>' );
1872+
1873+
viewRoot._appendChild( viewContent );
1874+
selection._setTo( newSelection );
1875+
1876+
renderer.markToSync( 'children', viewRoot );
1877+
renderer.render();
1878+
1879+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b></b></p>' );
1880+
1881+
// 2. Start composition and edit to resulting HTML: <p>foo<b>bar</b>FILLER{}</p>.
1882+
renderer.isComposing = true;
1883+
1884+
const domP = domRoot.childNodes[ 0 ];
1885+
const domB = domP.childNodes[ 1 ];
1886+
1887+
domB.childNodes[ 0 ].data += 'bar';
1888+
1889+
const viewP = viewRoot.getChild( 0 );
1890+
const viewB = viewP.getChild( 1 );
1891+
1892+
viewB._appendChild( new ViewText( 'bar' ) );
1893+
1894+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP, 2, viewP, 2 ) );
1895+
1896+
renderer.markToSync( 'children', viewRoot );
1897+
renderer.render();
1898+
1899+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b></p>' );
1900+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1901+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1902+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER );
1903+
1904+
// 3. Edit to resulting HTML: <p>foo<b>bar</b>FILLERbaz{}</p>.
1905+
viewP._appendChild( new ViewText( 'baz' ) );
1906+
1907+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP.getChild( 2 ), 3, viewP.getChild( 2 ), 3 ) );
1908+
1909+
renderer.markToSync( 'children', viewRoot );
1910+
renderer.render();
1911+
1912+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b>baz</p>' );
1913+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1914+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1915+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER + 'baz' );
1916+
1917+
// 4. Move selection (<p>{foo<b>bar</b>FILLERbaz}</p>) and render to check if filler stays untouched.
1918+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP.getChild( 0 ), 0, viewP.getChild( 2 ), 3 ) );
1919+
1920+
renderer.markToSync( 'children', viewRoot );
1921+
renderer.render();
1922+
1923+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b>baz</p>' );
1924+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1925+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1926+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER + 'baz' );
1927+
1928+
expect( domSelection.getRangeAt( 0 ).startContainer ).to.equal( domP.childNodes[ 0 ] );
1929+
expect( domSelection.getRangeAt( 0 ).endContainer ).to.equal( domP.childNodes[ 2 ] );
1930+
expect( domSelection.getRangeAt( 0 ).collapsed ).to.be.false;
1931+
} );
1932+
1933+
// Happens when `shift + up` arrow pressed during composition after unbolding text (Chrome on Windows).
1934+
// https://github.com/ckeditor/ckeditor5-engine/pull/1355#issuecomment-381516509
1935+
it( 'should not delete inline filler when selection changes without compositionend (filler on paragraph end)', () => {
1936+
const domSelection = document.getSelection();
1937+
1938+
// 1. Render <p>foo<b>FILLER{}</b></p>.
1939+
const { view: viewContent, selection: newSelection } = parse(
1940+
'<container:p>foo<attribute:b>[]</attribute:b></container:p>' );
1941+
1942+
viewRoot._appendChild( viewContent );
1943+
selection._setTo( newSelection );
1944+
1945+
renderer.markToSync( 'children', viewRoot );
1946+
renderer.render();
1947+
1948+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b></b></p>' );
1949+
1950+
// 2. Start composition and edit to resulting HTML: <p>foo<b>bar</b>FILLER{}</p>.
1951+
renderer.isComposing = true;
1952+
1953+
const domP = domRoot.childNodes[ 0 ];
1954+
const domB = domP.childNodes[ 1 ];
1955+
1956+
domB.childNodes[ 0 ].data += 'bar';
1957+
1958+
const viewP = viewRoot.getChild( 0 );
1959+
const viewB = viewP.getChild( 1 );
1960+
1961+
viewB._appendChild( new ViewText( 'bar' ) );
1962+
1963+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP, 2, viewP, 2 ) );
1964+
1965+
renderer.markToSync( 'children', viewRoot );
1966+
renderer.render();
1967+
1968+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b></p>' );
1969+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1970+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1971+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER );
1972+
1973+
// 3. Edit to resulting HTML: <p>foo<b>bar</b>FILLER{}</p>.
1974+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP, 2, viewP, 2 ) );
1975+
1976+
renderer.markToSync( 'children', viewRoot );
1977+
renderer.render();
1978+
1979+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b></p>' );
1980+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1981+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1982+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER );
1983+
1984+
// 4. Move selection (<p>{foo<b>bar</b>FILLER}</p>) and render to check if filler stays untouched.
1985+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP.getChild( 0 ), 0, viewP, 2 ) );
1986+
1987+
renderer.markToSync( 'children', viewRoot );
1988+
renderer.render();
1989+
1990+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo<b>bar</b></p>' );
1991+
expect( domB.childNodes[ 0 ].data ).to.equal( 'bar' );
1992+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
1993+
expect( domP.childNodes[ 2 ].data ).to.equal( INLINE_FILLER );
1994+
1995+
expect( domSelection.getRangeAt( 0 ).startContainer ).to.equal( domP.childNodes[ 0 ] );
1996+
expect( domSelection.getRangeAt( 0 ).endContainer ).to.equal( domP.childNodes[ 2 ] );
1997+
expect( domSelection.getRangeAt( 0 ).collapsed ).to.be.false;
1998+
} );
1999+
2000+
// This is more theoretical situation (should not be reproducible in real world unless composition is broken).
2001+
it( 'should not add new inline filler when empty inline element was removed by selection change during composition', () => {
2002+
const domSelection = document.getSelection();
2003+
2004+
// 1. Render <p>foo bar<b>FILLER{}</b></p>.
2005+
const { view: viewContent, selection: newSelection } = parse(
2006+
'<container:p>foo bar<attribute:b>[]</attribute:b></container:p>' );
2007+
2008+
viewRoot._appendChild( viewContent );
2009+
selection._setTo( newSelection );
2010+
2011+
renderer.markToSync( 'children', viewRoot );
2012+
renderer.render();
2013+
2014+
const domP = domRoot.childNodes[ 0 ];
2015+
const domB = domP.childNodes[ 1 ];
2016+
2017+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo bar<b></b></p>' );
2018+
expect( domB.childNodes[ 0 ].data ).to.equal( INLINE_FILLER );
2019+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo bar' );
2020+
2021+
// 2. Start composition and change selection to: <p>{foo bar}</p>.
2022+
renderer.isComposing = true;
2023+
2024+
const viewP = viewRoot.getChild( 0 );
2025+
2026+
viewP.getChild( 1 )._remove(); // Simulate `<b>` removal.
2027+
2028+
selection._setTo( ViewRange.createFromParentsAndOffsets( viewP.getChild( 0 ), 0, viewP.getChild( 0 ), 7 ) );
2029+
2030+
renderer.markToSync( 'children', viewP );
2031+
renderer.render();
2032+
2033+
expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<p>foo bar</p>' );
2034+
expect( domP.childNodes[ 0 ].data ).to.equal( 'foo bar' );
2035+
expect( domP.childNodes.length ).to.equal( 1 );
2036+
2037+
expect( domSelection.getRangeAt( 0 ).startContainer ).to.equal( domP.childNodes[ 0 ] );
2038+
expect( domSelection.getRangeAt( 0 ).endContainer ).to.equal( domP.childNodes[ 0 ] );
2039+
expect( domSelection.getRangeAt( 0 ).collapsed ).to.be.false;
2040+
} );
2041+
18632042
// This is more theoretical situation (should not be reproducible in real world unless composition is broken).
1864-
it( 'should not delete inline filler when selection (ranged) changes without compositionend (filler inside)', () => {
2043+
it( 'should not delete inline filler when selection changes without compositionend (filler inside selection)', () => {
18652044
const domSelection = document.getSelection();
18662045

18672046
// 1. Render <h1>h1</h1><p>foo<b>FILLER{}</b>bar</p>.

0 commit comments

Comments
 (0)