UNPKG

shaka-player

Version:
235 lines (210 loc) 8.19 kB
/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ goog.require('shaka.test.Util'); goog.require('shaka.test.UiUtils'); goog.require('shaka.text.Cue'); goog.require('shaka.text.UITextDisplayer'); describe('UITextDisplayer', () => { /** @type {!HTMLElement} */ let videoContainer; /** @type {!HTMLVideoElement} */ let video; /** @type {shaka.text.UITextDisplayer} */ let textDisplayer; /** @type {number} */ const videoContainerHeight = 450; /** * Transform a cssText to an object. * Example: * cssText: 'background-color: black; color: green; font-size: 10px;' * cssObject: { * background-color: 'black', * color: 'green', * font-size: '10px', * } * @param {string} cssStr * @return {!Object.<string, string|number>} */ function parseCssText(cssStr) { // Remove the white spaces in the string. // Split with ';' and ignore the last one. const css = cssStr.replace(/\s/g, '').substring(0, cssStr.length - 1) .split(';'); const cssObj = {}; for (const cssStyle of css) { const propertyAndValue = cssStyle.split(':'); let value = propertyAndValue[1]; value = isNaN(value) ? value : Number(value); cssObj[propertyAndValue[0]] = value; } return cssObj; } beforeAll(() => { videoContainer = /** @type {!HTMLElement} */ (document.createElement('div')); videoContainer.style.height = `${videoContainerHeight}px`; document.body.appendChild(videoContainer); video = shaka.test.UiUtils.createVideoElement(); videoContainer.appendChild(video); }); beforeEach(() => { textDisplayer = new shaka.text.UITextDisplayer(video, videoContainer); }); afterEach(async () => { await textDisplayer.destroy(); }); afterAll(() => { document.body.removeChild(videoContainer); }); it('correctly displays styles for cues', async () => { /** @type {!shaka.text.Cue} */ const cue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); cue.color = 'green'; cue.backgroundColor = 'black'; cue.direction = shaka.text.Cue.direction.HORIZONTAL_LEFT_TO_RIGHT; cue.fontSize = '10px'; cue.fontWeight = shaka.text.Cue.fontWeight.NORMAL; cue.fontStyle = 'normal'; cue.lineHeight = '2'; cue.nestedCues = []; cue.textAlign = 'center'; cue.writingMode = shaka.text.Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM; textDisplayer.setTextVisibility(true); textDisplayer.append([cue]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); const textContainer = videoContainer.querySelector('.shaka-text-container'); const captions = textContainer.querySelector('span'); const cssObj = parseCssText(captions.style.cssText); expect(cssObj).toEqual( jasmine.objectContaining({ 'color': 'green', 'background-color': 'black', 'direction': 'ltr', 'font-size': '10px', 'font-style': 'normal', 'font-weight': 400, 'line-height': 2, 'text-align': 'center', // TODO: We're not testing writing-mode since IE 11 only supports // deprecated writing-mode values partially. Add it back once we end // support for IE 11. // https://github.com/google/shaka-player/issues/2339 // 'writing-mode': 'horizontal-tb', })); }); it('correctly displays styles for nested cues', async () => { /** @type {!shaka.text.Cue} */ const cue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); const nestedCue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); cue.nestedCues = [nestedCue]; nestedCue.textAlign = 'center'; nestedCue.writingMode = shaka.text.Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM; nestedCue.color = 'green'; nestedCue.backgroundColor = 'black'; nestedCue.fontSize = '10px'; nestedCue.fontWeight = shaka.text.Cue.fontWeight.NORMAL; nestedCue.fontStyle = 'normal'; nestedCue.lineHeight = '2'; nestedCue.nestedCues = []; textDisplayer.setTextVisibility(true); textDisplayer.append([cue]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); // Verify styles applied to the nested cues. const textContainer = videoContainer.querySelector('.shaka-text-container'); const captions = textContainer.querySelector('span'); const cssObj = parseCssText(captions.style.cssText); expect(cssObj).toEqual( jasmine.objectContaining({ 'color': 'green', 'background-color': 'black', 'font-size': '10px', 'font-style': 'normal', 'font-weight': 400, 'text-align': 'center', // TODO: We're not testing writing-mode since IE 11 only supports // deprecated writing-mode values partially. Add it back once we end // support for IE 11. // https://github.com/google/shaka-player/issues/2339 // 'writing-mode': 'horizontal-tb', })); }); it('correctly displays styles for cellResolution units', async () => { /** @type {!shaka.text.Cue} */ const cue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); cue.fontSize = '0.80c'; cue.linePadding = '0.50c'; cue.cellResolution = { columns: 60, rows: 20, }; textDisplayer.setTextVisibility(true); textDisplayer.append([cue]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); // Expected value is calculated based on ttp:cellResolution="60 20" // videoContainerHeight=450px and tts:fontSize="0.80c" on the default style. const expectedFontSize = '18px'; // Expected value is calculated based on ttp:cellResolution="60 20" // videoContainerHeight=450px and ebutts:linePadding="0.5c" on the default // style. const expectedLinePadding = '11.25px'; const textContainer = videoContainer.querySelector('.shaka-text-container'); const captions = textContainer.querySelector('span'); const cssObj = parseCssText(captions.style.cssText); expect(cssObj).toEqual( jasmine.objectContaining({ 'font-size': expectedFontSize, 'padding-left': expectedLinePadding, 'padding-right': expectedLinePadding, })); }); it('correctly displays styles for percentages units', async () => { /** @type {!shaka.text.Cue} */ const cue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); cue.fontSize = '90%'; cue.cellResolution = { columns: 32, rows: 15, }; textDisplayer.setTextVisibility(true); textDisplayer.append([cue]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); // Expected value is calculated based on ttp:cellResolution="32 15" // videoContainerHeight=450px and tts:fontSize="90%" on the default style. const expectedFontSize = '27px'; const textContainer = videoContainer.querySelector('.shaka-text-container'); const captions = textContainer.querySelector('span'); const cssObj = parseCssText(captions.style.cssText); expect(cssObj).toEqual( jasmine.objectContaining({'font-size': expectedFontSize})); }); it('does not display duplicate cues', async () => { const cue = new shaka.text.Cue(0, 100, 'Captain\'s log.'); textDisplayer.setTextVisibility(true); textDisplayer.append([cue]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); /** @type {Element} */ const textContainer = videoContainer.querySelector('.shaka-text-container'); let captions = textContainer.querySelectorAll('span'); // Expect textContainer to display this cue. expect(captions.length).toBe(1); const cue2 = new shaka.text.Cue(0, 100, 'Captain\'s log.'); textDisplayer.append([cue2]); // Wait until updateCaptions_() gets called. await shaka.test.Util.delay(0.5); captions = textContainer.querySelectorAll('span'); // Expect textContainer to display one cue without duplication. expect(captions.length).toBe(1); }); });