/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ describe('TtmlTextParser', () => { const Cue = shaka.text.Cue; const CueRegion = shaka.text.CueRegion; const Util = shaka.test.Util; const anyString = jasmine.any(String); it('supports no cues', () => { verifyHelper([], '', {periodStart: 0, segmentStart: 0, segmentEnd: 10, vttOffset: 0}, {}); }); it('supports empty text string', () => { verifyHelper([], '', {periodStart: 0, segmentStart: 0, segmentEnd: 10, vttOffset: 0}, {}); }); it('supports div with no cues but whitespace', () => { verifyHelper( [], '
\r\n
', {periodStart: 0, segmentStart: 0, segmentEnd: 10, vttOffset: 0}, {}); }); it('supports xml:space', () => { const ttBody = '
\n' + '

\n' + ' A B C \n' + '

\n' + '
\n'; // When xml:space="default", ignore whitespace outside tags. verifyHelper( [ { startTime: 62.03, endTime: 62.05, nestedCues: [{ payload: ' A B C ', startTime: 62.03, endTime: 62.05, }], payload: '', }, ], '' + ttBody + '', {periodStart: 0, segmentStart: 60, segmentEnd: 70, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // When xml:space="preserve", take them into account. verifyHelper( [ { startTime: 62.03, endTime: 62.05, nestedCues: [{ // anonymous span payload: '\n ', startTime: 62.03, endTime: 62.05, }, { payload: ' A B C ', startTime: 62.03, endTime: 62.05, }, { // anonymous span payload: '\n ', startTime: 62.03, endTime: 62.05, }], }, ], '' + ttBody + '', {periodStart: 0, segmentStart: 60, segmentEnd: 70, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // The default value for xml:space is "default". verifyHelper( [ { startTime: 62.03, endTime: 62.05, nestedCues: [{ payload: ' A B C ', startTime: 62.03, endTime: 62.05, }], }, ], '' + ttBody + '', {periodStart: 0, segmentStart: 60, segmentEnd: 70, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // Any other value is rejected as an error. errorHelper(shaka.util.Error.Code.INVALID_XML, '' + ttBody + '', jasmine.any(String)); }); it('supports xml:space overriding default at span level', () => { const ttBody = '\n' + '
\n' + '

\n' + ' A B C \n' + '

\n' + '
\n'; // When xml:space="preserve", take them into account. verifyHelper( [ { startTime: 62.03, endTime: 62.05, nestedCues: [{ payload: ' A B C ', startTime: 62.03, endTime: 62.05, }], }, ], '' + ttBody + '', {periodStart: 0, segmentStart: 60, segmentEnd: 70, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); }); it('rejects invalid ttml', () => { errorHelper(shaka.util.Error.Code.INVALID_XML, '', anyString); }); it('rejects ttml with body>p instead of body>div', () => { errorHelper( shaka.util.Error.Code.INVALID_TEXT_CUE, '

', anyString); }); it('rejects ttml with div>span instead of div>p', () => { errorHelper( shaka.util.Error.Code.INVALID_TEXT_CUE, '
', anyString); }); it('rejects invalid time format', () => { const wrap = (ttmlCue) => { return `
${ttmlCue}
`; }; errorHelper( shaka.util.Error.Code.INVALID_TEXT_CUE, wrap('

My very own cue

'), anyString); errorHelper( shaka.util.Error.Code.INVALID_TEXT_CUE, wrap('

An invalid cue

'), anyString); }); it('supports spans as nestedCues of paragraphs', () => { verifyHelper( [ { startTime: 62.05, endTime: 3723.2, payload: '', nestedCues: [ { payload: 'First cue', startTime: 62.05, endTime: 3723.2, }, { payload: '', lineBreak: true, startTime: 62.05, endTime: 3723.2, }, { payload: 'Second cue', startTime: 62.05, endTime: 3723.2, }, ], }, ], '
' + '

' + 'First cue
Second cue' + '

' + '
', {periodStart: 0, segmentStart: 60, segmentEnd: 3730, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); it('supports anonymous spans as nestedCues of paragraphs', () => { verifyHelper( [ { startTime: 62.05, endTime: 3723.2, payload: '', nestedCues: [ { payload: 'First cue', startTime: 62.05, endTime: 3723.2, }, { payload: '', lineBreak: true, startTime: 62.05, endTime: 3723.2, }, { payload: 'Second cue', startTime: 62.05, endTime: 3723.2, }, ], }, ], '
' + '

' + 'First cue
Second cue' + '

' + '
', {periodStart: 0, segmentStart: 60, segmentEnd: 3730, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); it('supports multiple levels of nestedCues', () => { verifyHelper( [ { startTime: 62.05, endTime: 3723.2, payload: '', color: 'black', // cues in p container. nestedCues: [ // anonymous span in p container. { payload: 'First cue', startTime: 62.05, endTime: 3723.2, }, // container for Second cue and Third cue. { payload: '', startTime: 62.05, endTime: 3723.2, color: 'blue', nestedCues: [ { payload: 'Second cue', startTime: 62.05, endTime: 3723.2, color: '', }, { payload: 'Third cue', startTime: 62.05, endTime: 3723.2, color: 'green', }, ], }, ], }, ], '' + '' + '