Skip to content

Commit

Permalink
fix: Fix enforcement of cue alignment styles
Browse files Browse the repository at this point in the history
This uses flexbox once again to get proper positioning of cues.  To
compensate for the issues that originally made us remove flexbox, this
adds a wrapper span inside the flexbox element.

Summary of screenshot changes:
 - slight change to background sizing
   - ui-basic-cue
   - ui-cue-with-controls
   - ui-duplicate-cues
   - ui-end-time-edge-case
   - ui-flat-cue-bg
   - ui-two-basic-cues
 - background fills block with literal newline in text
   - ui-cue-with-newline
 - region anchored without padding
   - ui-region-position
 - new screenshots
   - *-nested-cues-with-linebreak
   - *-region-with-display-alignment  (regression test for this issue)

Closes shaka-project#3379

Change-Id: I8c678721d96662e0f8940cda12df4f5b5e5baf1e
  • Loading branch information
joeyparrish committed Jul 9, 2021
1 parent de77787 commit 2250324
Show file tree
Hide file tree
Showing 126 changed files with 93 additions and 14 deletions.
11 changes: 11 additions & 0 deletions lib/text/cue.js
Expand Up @@ -232,6 +232,17 @@ shaka.text.Cue = class {
};
}

/**
* @param {number} start
* @param {number} end
* @return {!shaka.text.Cue}
*/
static lineBreak(start, end) {
const cue = new shaka.text.Cue(start, end, '');
cue.lineBreak = true;
return cue;
}

/**
* Create a copy of the cue with the same properties.
* @return {!shaka.text.Cue}
Expand Down
35 changes: 26 additions & 9 deletions lib/text/ui_text_displayer.js
Expand Up @@ -259,13 +259,22 @@ shaka.text.UITextDisplayer = class {

// Nested cues are inline elements. Top-level cues are block elements.
const cueElement = shaka.util.Dom.createHTMLElement(type);

if (type != 'br') {
this.setCaptionStyles_(cueElement, cue, isNested);
}

for (const nestedCue of cue.nestedCues) {
this.displayCue_(cueElement, nestedCue, /* isNested= */ true);
}
let wrapper = cueElement;
if (!isNested && cue.nestedCues.length) {
// Create a wrapper element which will serve to contain all children into
// a single item. This ensures that nested span elements appear
// horizontally and br elements occupy no vertical space.
wrapper = shaka.util.Dom.createHTMLElement('span');
wrapper.classList.add('shaka-text-wrapper');
cueElement.appendChild(wrapper);
}

for (const nestedCue of cue.nestedCues) {
this.displayCue_(wrapper, nestedCue, /* isNested= */ true);
}

container.appendChild(cueElement);
Expand Down Expand Up @@ -338,12 +347,20 @@ shaka.text.UITextDisplayer = class {
// The displayAlign attribute specifies the vertical alignment of the
// captions inside the text container. Before means at the top of the
// text container, and after means at the bottom.
if (cue.displayAlign == Cue.displayAlign.BEFORE) {
style.verticalAlign = 'top';
} else if (cue.displayAlign == Cue.displayAlign.CENTER) {
style.verticalAlign = 'middle';
if (isNested) {
style.display = 'inline';
} else {
style.verticalAlign = 'bottom';
style.display = 'flex';
style.flexDirection = 'column';
style.alignItems = 'center';

if (cue.displayAlign == Cue.displayAlign.BEFORE) {
style.justifyContent = 'flex-start';
} else if (cue.displayAlign == Cue.displayAlign.CENTER) {
style.justifyContent = 'center';
} else {
style.justifyContent = 'flex-end';
}
}

if (!isLeaf) {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Android/ui-basic-cue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Android/ui-flat-cue-bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Android/ui-region-position.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Android/ui-two-basic-cues.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-basic-cue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-cue-with-controls.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-cue-with-newline.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-duplicate-cues.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-flat-cue-bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-region-position.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Linux/ui-two-basic-cues.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-cue-with-controls.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-cue-with-newline.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-region-position.png
Binary file modified test/test/assets/screenshots/chrome-Mac/ui-two-basic-cues.png
Binary file modified test/test/assets/screenshots/chrome-Windows/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/chrome-Windows/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/chrome-Windows/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/chrome-Windows/ui-region-position.png
Binary file modified test/test/assets/screenshots/chrome-Windows/ui-two-basic-cues.png
Binary file modified test/test/assets/screenshots/firefox-Linux/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/firefox-Linux/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/firefox-Linux/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/firefox-Linux/ui-region-position.png
Binary file modified test/test/assets/screenshots/firefox-Linux/ui-two-basic-cues.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-cue-with-controls.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-cue-with-newline.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-end-time-edge-case.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-region-position.png
Binary file modified test/test/assets/screenshots/firefox-Mac/ui-two-basic-cues.png
Binary file modified test/test/assets/screenshots/firefox-Windows/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/firefox-Windows/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/msedge-Windows/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/msedge-Windows/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/msedge-Windows/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/msedge-Windows/ui-region-position.png
Binary file modified test/test/assets/screenshots/msedge-Windows/ui-two-basic-cues.png
2 changes: 2 additions & 0 deletions test/test/assets/screenshots/review.html
Expand Up @@ -45,13 +45,15 @@
'two-basic-cues',
'duplicate-cues',
'two-nested-cues',
'nested-cues-with-linebreak',
'region-position',
'cue-with-controls',
'bitmap-cue',
'nested-cue-bg',
'flat-cue-bg',
'deeply-nested-cues',
'end-time-edge-case',
'region-with-display-alignment',
];

const prefixes = [
Expand Down
Binary file modified test/test/assets/screenshots/safari-Mac/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-cue-with-controls.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-cue-with-newline.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-region-position.png
Binary file modified test/test/assets/screenshots/safari-Mac/ui-two-basic-cues.png
Binary file modified test/test/assets/screenshots/xboxone/ui-basic-cue.png
Binary file modified test/test/assets/screenshots/xboxone/ui-cue-with-controls.png
Binary file modified test/test/assets/screenshots/xboxone/ui-cue-with-newline.png
Binary file modified test/test/assets/screenshots/xboxone/ui-duplicate-cues.png
Binary file modified test/test/assets/screenshots/xboxone/ui-end-time-edge-case.png
Binary file modified test/test/assets/screenshots/xboxone/ui-flat-cue-bg.png
Binary file modified test/test/assets/screenshots/xboxone/ui-region-position.png
Binary file modified test/test/assets/screenshots/xboxone/ui-two-basic-cues.png
12 changes: 8 additions & 4 deletions test/text/ui_text_displayer_unit.js
Expand Up @@ -88,7 +88,8 @@ describe('UITextDisplayer', () => {

const textContainer =
videoContainer.querySelector('.shaka-text-container');
const captions = textContainer.querySelector('span');
const captions =
textContainer.querySelector('span:not(.shaka-text-wrapper)');
const cssObj = parseCssText(captions.style.cssText);

const expectCssObj = {
Expand Down Expand Up @@ -140,7 +141,8 @@ describe('UITextDisplayer', () => {
// Verify styles applied to the nested cues.
const textContainer =
videoContainer.querySelector('.shaka-text-container');
const captions = textContainer.querySelector('span');
const captions =
textContainer.querySelector('span:not(.shaka-text-wrapper)');
const cssObj = parseCssText(captions.style.cssText);

const expectCssObj = {
Expand Down Expand Up @@ -193,7 +195,8 @@ describe('UITextDisplayer', () => {

const textContainer =
videoContainer.querySelector('.shaka-text-container');
const captions = textContainer.querySelector('span');
const captions =
textContainer.querySelector('span:not(.shaka-text-wrapper)');
const cssObj = parseCssText(captions.style.cssText);
expect(cssObj).toEqual(
jasmine.objectContaining({
Expand Down Expand Up @@ -223,7 +226,8 @@ describe('UITextDisplayer', () => {

const textContainer =
videoContainer.querySelector('.shaka-text-container');
const captions = textContainer.querySelector('span');
const captions =
textContainer.querySelector('span:not(.shaka-text-wrapper)');
const cssObj = parseCssText(captions.style.cssText);
expect(cssObj).toEqual(
jasmine.objectContaining({'font-size': expectedFontSize}));
Expand Down
39 changes: 39 additions & 0 deletions test/ui/text_displayer_layout_unit.js
Expand Up @@ -299,6 +299,21 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
await checkScreenshot(prefix, 'two-nested-cues');
});

// Distinct from "newline" test above, which has a literal \n character in
// the text payload. This uses a nested "lineBreak" cue, which is what you
// get with <br> in TTML.
it('nested cues with linebreak', async () => {
const cue = new shaka.text.Cue(0, 1, '');
cue.nestedCues = [
new shaka.text.Cue(0, 1, 'Captain\'s log,'),
shaka.text.Cue.lineBreak(0, 1),
new shaka.text.Cue(0, 1, 'stardate 41636.9'),
];
textDisplayer.append([cue]);

await checkScreenshot(prefix, 'nested-cues-with-linebreak');
});

// Regression test for #2157 and #2584
it('region positioning', async () => {
const nestedCue = new shaka.text.Cue(
Expand All @@ -316,6 +331,30 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
await checkScreenshot(prefix, 'region-position');
});

// Regression test for #3379, in which the displayAlign was not respected,
// placing text at the top of the region instead of the bottom.
it('region with display alignment', async () => {
const cue = new shaka.text.Cue(0, 1, '');

cue.region.id = '1';
cue.region.viewportAnchorX = 10;
cue.region.viewportAnchorY = 10;
cue.region.width = 80;
cue.region.height = 80;

cue.positionAlign = shaka.text.Cue.positionAlign.CENTER;
cue.lineAlign = shaka.text.Cue.lineAlign.CENTER;
cue.displayAlign = shaka.text.Cue.displayAlign.AFTER;

cue.nestedCues = [
// For those who don't speak Unicode, \xbf is an upside down "?".
new shaka.text.Cue(0, 1, '\xbfBien?'),
];
textDisplayer.append([cue]);

await checkScreenshot(prefix, 'region-with-display-alignment');
});

// Regression test for #2188
it('bitmap-based cues', async () => {
const cue = new shaka.text.Cue(0, 1, '');
Expand Down
8 changes: 7 additions & 1 deletion ui/less/containers.less
Expand Up @@ -226,12 +226,18 @@
transition-delay: 500ms;

/* These are defaults which are overridden by JS or cue styles. */
span {
span:not(.shaka-text-wrapper) {
display: inline;
font-size: 20px;
line-height: 1.4; // relative to font size.
background-color: rgba(0, 0, 0, 0.8);
color: rgb(255, 255, 255);
}

span.shaka-text-wrapper {
display: inline;
background: none;
}
}

.shaka-controls-container[shown="true"] ~ .shaka-text-container {
Expand Down

0 comments on commit 2250324

Please sign in to comment.