import { TBlockCtor } from '../../tree/TBlockCtor'; import { TNodeImpl } from '../../tree/tree-types'; import { TPhrasingCtor } from '../../tree/TPhrasingCtor'; import { TTextCtor, TTextImpl } from '../../tree/TTextCtor'; import { collapse } from '../collapse'; import { hoist } from '../hoist'; import { deeplyNestedSource, nestedHyperlinksSource, recursiveHoisting, rfc002Source } from './shared'; import { defaultInit, translateTreeTest } from './utils'; import { Text } from '../../dom/dom-utils'; function makeTTree( html: string, removeLineBreaksAroundEastAsianDiscardSet = false ): TNodeImpl { return collapse( hoist( translateTreeTest(html, { removeLineBreaksAroundEastAsianDiscardSet }) ) ); } function makeTextChildren() { return [new TTextCtor({ textNode: new Text(''), ...defaultInit })]; } describe('collapse function', () => { it('should collapse a tree such as specified in RFC002 example', () => { const ttree = makeTTree(rfc002Source); expect(ttree).toMatchSnapshot(); }); it('should collapse adjacent tags', () => { const ttree = makeTTree('foo bar'); expect(ttree).toMatchSnapshot(); }); it('should preserve boundary spaces wrapped in nested inline phrasing tags', () => { const ttree = makeTTree( 'foo bar' ); expect(ttree).toMatchSnapshot(); }); it('should collapse consecutive boundary spaces wrapped in nested inline phrasing tags', () => { const twoSpaces = makeTTree( 'foo bar' ); const oneSpace = makeTTree( 'foo bar' ); expect(twoSpaces).toEqual(oneSpace); }); it('should handle nested anchors', () => { const ttree = makeTTree(nestedHyperlinksSource); expect(ttree).toMatchSnapshot(); }); it('should handle deeply nested HTML', () => { const ttree = makeTTree(deeplyNestedSource); expect(ttree).toMatchSnapshot(); }); it('should hoist blocks recursively', () => { const ttree = makeTTree(recursiveHoisting); expect(ttree).toMatchSnapshot(); }); it('should handle body tag', () => { const html = `
Hello world!
`; const ttree = makeTTree(html); expect(ttree).toMatchSnapshot(); }); it('should remove empty children from TBlock nodes', () => { const ttree = new TBlockCtor(defaultInit); ttree.bindChildren(makeTextChildren()); expect(collapse(ttree).children).toHaveLength(0); }); it('should remove empty anonymous TText children from TPhrasing nodes', () => { const ttree = new TPhrasingCtor(defaultInit); ttree.bindChildren(makeTextChildren()); expect(collapse(ttree).children).toHaveLength(0); }); it('should remove empty anonymous TPhrasing children from TPhrasing nodes', () => { const ttree = new TPhrasingCtor(defaultInit); const tphrasing = new TPhrasingCtor(defaultInit); tphrasing.bindChildren(makeTextChildren()); ttree.bindChildren([tphrasing]); const collapsed = collapse(ttree); expect(collapsed.children).toHaveLength(0); expect(collapsed).toMatchSnapshot(); }); it('should remove children from TPhrasing nodes which are empty after timming', () => { const ttree = new TPhrasingCtor(defaultInit); ttree.bindChildren([ // This node will be empty after trimming right, and should be removed new TTextCtor({ textNode: new Text(' '), ...defaultInit }), new TTextCtor({ textNode: new Text(' Foo'), ...defaultInit }), new TTextCtor({ textNode: new Text(' Bar'), ...defaultInit }) ]); const collapsed = collapse(ttree); expect(collapsed.children).toHaveLength(2); expect(collapsed).toMatchSnapshot(); }); it('should handle direct style inheritance', () => { const ttree = makeTTree( '
This is nice!
' ); expect(ttree).toMatchSnapshot(); }); it('should handle indirect style inheritance', () => { const ttree = makeTTree( '
This is great!
' ); expect(ttree).toMatchSnapshot(); }); it('should not collapse when white-space CSS property is set to "pre"', () => { const ttree = makeTTree( '
This is great!
' ); expect(ttree).toMatchSnapshot(); }); it('should collapse when white-space CSS property is set to "normal"', () => { const ttree = makeTTree( '
This is great!
' ); expect(ttree).toMatchSnapshot(); }); it('should collapse when white-space CSS property is not set', () => { const ttree = makeTTree('
This is great!
'); expect(ttree).toMatchSnapshot(); }); it('should collapse a node with white-space set to "normal" while its parent has white-space set to "pre"', () => { const ttree = makeTTree( '
This is nice Should collapse
' ); // left space of child DOMTextNode should be spared, since left // sibling is not collapsible (tested in Mozilla Firefox and Chromium) expect(ttree).toMatchSnapshot(); }); it('should withold TEmpty nodes', () => { const ttree = makeTTree( '
Hi!
' ); expect(ttree).toMatchSnapshot(); }); it('should support removeLineBreaksAroundEastAsianDiscardSet param', () => { const span = makeTTree('\u2F00\n\u2FDA', true) as TTextImpl; expect(span).toMatchSnapshot(); expect(span.data).toBe('\u2F00\u2FDA'); }); it('should set `nodeIndex` field corresponding to the actual index relative to parent', () => { const src = `
Month Fortnight Savings
January first $50
second $80 $80
`; const ttree = makeTTree(src); expect(ttree.tagName).toBe('table'); ttree.children.forEach((child, i) => { expect(child.nodeIndex).toBe(i); }); }); it('should handle
tags', () => { const src = `

should
collapse

`; const ttree = makeTTree(src); expect(ttree).toMatchSnapshot(); }); it('should retain whitespaces between block and textual nodes', () => { const src = '
Tags:\nhello'; const ttree = makeTTree(src); expect(ttree).toMatchSnapshot(); }); });