mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 865407 - Part 8: Update vtt.js to latest version. r=rillian
This completes the initial implementation of the processing algorithm. The algorithm doesn't support vertical text yet, but that's not a big issue since Firefox doesn't support it.
This commit is contained in:
parent
2b1ee432d6
commit
0610cbd281
@ -52,7 +52,7 @@ WebVTTParserWrapper.prototype =
|
||||
|
||||
processCues: function(window, cues, overlay)
|
||||
{
|
||||
WebVTTParser.processCues(window, cues, null, overlay);
|
||||
WebVTTParser.processCues(window, cues, overlay);
|
||||
},
|
||||
|
||||
classDescription: "Wrapper for the JS WebVTTParser (vtt.js)",
|
||||
|
@ -8,7 +8,7 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
* Code below is vtt.js the JS WebVTTParser.
|
||||
* Current source code can be found at http://github.com/andreasgal/vtt.js
|
||||
*
|
||||
* Code taken from commit d819872e198d051dfcebcfb7ecf260462c9a9c6f
|
||||
* Code taken from commit b812cd783d4284de1bc6b0349b7bda151052a1df
|
||||
*/
|
||||
/**
|
||||
* Copyright 2013 vtt.js Contributors
|
||||
@ -101,20 +101,18 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
// Accept a setting if its a valid (signed) integer.
|
||||
integer: function(k, v) {
|
||||
if (/^-?\d+$/.test(v)) { // integer
|
||||
this.set(k, parseInt(v, 10));
|
||||
// Only take values in the range of -1000 ~ 1000
|
||||
this.set(k, Math.min(Math.max(parseInt(v, 10), -1000), 1000));
|
||||
}
|
||||
},
|
||||
// Accept a setting if its a valid percentage.
|
||||
percent: function(k, v, frac) {
|
||||
percent: function(k, v) {
|
||||
var m;
|
||||
if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
|
||||
v = v.replace("%", "");
|
||||
if (!m[2] || (m[2] && frac)) {
|
||||
v = parseFloat(v);
|
||||
if (v >= 0 && v <= 100) {
|
||||
this.set(k, v);
|
||||
return true;
|
||||
}
|
||||
v = parseFloat(v);
|
||||
if (v >= 0 && v <= 100) {
|
||||
this.set(k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -664,25 +662,59 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
return ++count * -1;
|
||||
}
|
||||
|
||||
function BoundingBox() {
|
||||
function StyleBox() {
|
||||
}
|
||||
|
||||
BoundingBox.prototype.applyStyles = function(styles) {
|
||||
var div = this.div;
|
||||
// Apply styles to a div. If there is no div passed then it defaults to the
|
||||
// div on 'this'.
|
||||
StyleBox.prototype.applyStyles = function(styles, div) {
|
||||
div = div || this.div;
|
||||
Object.keys(styles).forEach(function(style) {
|
||||
div.style[style] = styles[style];
|
||||
});
|
||||
};
|
||||
|
||||
BoundingBox.prototype.formatStyle = function(val, unit) {
|
||||
StyleBox.prototype.formatStyle = function(val, unit) {
|
||||
return val === 0 ? 0 : val + unit;
|
||||
};
|
||||
|
||||
function BasicBoundingBox(window, cue) {
|
||||
BoundingBox.call(this);
|
||||
// Constructs the computed display state of the cue (a div). Places the div
|
||||
// into the overlay which should be a block level element (usually a div).
|
||||
function CueStyleBox(window, cue, styleOptions) {
|
||||
StyleBox.call(this);
|
||||
this.cue = cue;
|
||||
|
||||
// Parse our cue's text into a DOM tree rooted at 'div'.
|
||||
this.div = parseContent(window, cue.text);
|
||||
// Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
|
||||
// have inline positioning and will function as the cue background box.
|
||||
this.cueDiv = parseContent(window, cue.text);
|
||||
this.applyStyles({
|
||||
color: "rgba(255, 255, 255, 1)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
||||
position: "relative",
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
display: "inline"
|
||||
}, this.cueDiv);
|
||||
|
||||
// Create an absolutely positioned div that will be used to position the cue
|
||||
// div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
|
||||
// mirrors of them except "middle" which is "center" in CSS.
|
||||
this.div = window.document.createElement("div");
|
||||
this.applyStyles({
|
||||
textAlign: cue.align === "middle" ? "center" : cue.align,
|
||||
direction: determineBidi(this.cueDiv),
|
||||
writingMode: cue.vertical === "" ? "horizontal-tb"
|
||||
: cue.vertical === "lr" ? "vertical-lr"
|
||||
: "vertical-rl",
|
||||
unicodeBidi: "plaintext",
|
||||
font: styleOptions.font,
|
||||
whiteSpace: "pre-line",
|
||||
position: "absolute"
|
||||
});
|
||||
|
||||
this.div.appendChild(this.cueDiv);
|
||||
|
||||
// Calculate the distance from the reference edge of the viewport to the text
|
||||
// position of the cue box. The reference edge will be resolved later when
|
||||
@ -718,149 +750,277 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
});
|
||||
}
|
||||
|
||||
// All WebVTT cue-setting alignments are equivalent to the CSS mirrors of
|
||||
// them except "middle" which is "center" in CSS.
|
||||
this.applyStyles({
|
||||
"textAlign": cue.align === "middle" ? "center" : cue.align
|
||||
});
|
||||
}
|
||||
BasicBoundingBox.prototype = Object.create(BoundingBox.prototype);
|
||||
BasicBoundingBox.prototype.constructor = BasicBoundingBox;
|
||||
|
||||
const CUE_FONT_SIZE = 2.5;
|
||||
const SCROLL_DURATION = 0.433;
|
||||
const LINE_HEIGHT = 0.0533;
|
||||
const REGION_FONT_SIZE = 1.3;
|
||||
|
||||
// Constructs the computed display state of the cue (a div). Places the div
|
||||
// into the overlay which should be a block level element (usually a div).
|
||||
function CueBoundingBox(window, cue, overlay) {
|
||||
BasicBoundingBox.call(this, window, cue);
|
||||
this.applyStyles({
|
||||
direction: determineBidi(this.div),
|
||||
writingMode: cue.vertical === "" ? "horizontal-tb"
|
||||
: cue.vertical === "lr" ? "vertical-lr"
|
||||
: "vertical-rl",
|
||||
position: "absolute",
|
||||
unicodeBidi: "plaintext",
|
||||
fontSize: CUE_FONT_SIZE + "vh",
|
||||
fontFamily: "sans-serif",
|
||||
color: "rgba(255, 255, 255, 1)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
||||
whiteSpace: "pre-line"
|
||||
});
|
||||
|
||||
// Append the div to the overlay so we can get the computed styles of the
|
||||
// element in order to position for overlap avoidance.
|
||||
overlay.appendChild(this.div);
|
||||
|
||||
// Calculate the distance from the reference edge of the viewport to the line
|
||||
// position of the cue box. The reference edge will be resolved later when
|
||||
// the box orientation styles are applied. Default if snapToLines is not set
|
||||
// is 85.
|
||||
var linePos = 85;
|
||||
if (!cue.snapToLines) {
|
||||
var computedLinePos = computeLinePos(cue),
|
||||
boxComputedStyle = window.getComputedStyle(this.div),
|
||||
size = cue.vertical === "" ? boxComputedStyle.getPropertyValue("height") :
|
||||
boxComputedStyle.getPropertyValue("width"),
|
||||
// Get the percentage value of the computed height as getPropertyValue
|
||||
// returns pixels.
|
||||
overlayHeight = window.getComputedStyle(overlay).getPropertyValue("height"),
|
||||
calculatedPercentage = (size.replace("px", "") / overlayHeight.replace("px", "")) * 100;
|
||||
|
||||
switch (cue.lineAlign) {
|
||||
case "start":
|
||||
linePos = computedLinePos;
|
||||
break;
|
||||
case "middle":
|
||||
linePos = computedLinePos - (calculatedPercentage / 2);
|
||||
break;
|
||||
case "end":
|
||||
linePos = computedLinePos - calculatedPercentage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cue.vertical) {
|
||||
case "":
|
||||
this.move = function(box) {
|
||||
this.applyStyles({
|
||||
top: this.formatStyle(linePos, "%")
|
||||
top: this.formatStyle(box.top, "px"),
|
||||
bottom: this.formatStyle(box.bottom, "px"),
|
||||
left: this.formatStyle(box.left, "px"),
|
||||
right: this.formatStyle(box.right, "px"),
|
||||
height: this.formatStyle(box.height, "px"),
|
||||
width: this.formatStyle(box.width, "px"),
|
||||
});
|
||||
break;
|
||||
case "rl":
|
||||
this.applyStyles({
|
||||
left: this.formatStyle(linePos, "%")
|
||||
});
|
||||
break;
|
||||
case "lr":
|
||||
this.applyStyles({
|
||||
right: this.formatStyle(linePos, "%")
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
cue.displayState = this.div;
|
||||
}
|
||||
CueBoundingBox.prototype = Object.create(BasicBoundingBox.prototype);
|
||||
CueBoundingBox.prototype.constuctor = CueBoundingBox;
|
||||
|
||||
function RegionBoundingBox(window, region) {
|
||||
BoundingBox.call(this);
|
||||
this.div = window.document.createElement("div");
|
||||
|
||||
var left = region.viewportAnchorX -
|
||||
region.regionAnchorX * region.width / 100,
|
||||
top = region.viewportAnchorY -
|
||||
region.regionAnchorY * region.lines * LINE_HEIGHT / 100;
|
||||
|
||||
this.applyStyles({
|
||||
position: "absolute",
|
||||
writingMode: "horizontal-tb",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
||||
wordWrap: "break-word",
|
||||
overflowWrap: "break-word",
|
||||
font: REGION_FONT_SIZE + "vh/" + LINE_HEIGHT + "vh sans-serif",
|
||||
lineHeight: LINE_HEIGHT + "vh",
|
||||
color: "rgba(255, 255, 255, 1)",
|
||||
overflow: "hidden",
|
||||
width: this.formatStyle(region.width, "%"),
|
||||
minHeight: "0",
|
||||
// TODO: This value is undefined in the spec, but I am assuming that they
|
||||
// refer to lines * line height to get the max height See issue #107.
|
||||
maxHeight: this.formatStyle(region.lines * LINE_HEIGHT, "px"),
|
||||
left: this.formatStyle(left, "%"),
|
||||
top: this.formatStyle(top, "%"),
|
||||
display: "inline-flex",
|
||||
flexFlow: "column",
|
||||
justifyContent: "flex-end"
|
||||
});
|
||||
|
||||
this.maybeAddCue = function(cue) {
|
||||
if (region.id !== cue.regionId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var basicBox = new BasicBoundingBox(window, cue);
|
||||
basicBox.applyStyles({
|
||||
position: "relative",
|
||||
unicodeBidi: "plaintext",
|
||||
width: "auto"
|
||||
});
|
||||
|
||||
if (this.div.childNodes.length === 1 && region.scroll === "up") {
|
||||
this.applyStyles({
|
||||
transitionProperty: "top",
|
||||
transitionDuration: SCROLL_DURATION + "s"
|
||||
});
|
||||
}
|
||||
|
||||
this.div.appendChild(basicBox.div);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
RegionBoundingBox.prototype = Object.create(BoundingBox.prototype);
|
||||
RegionBoundingBox.prototype.constructor = RegionBoundingBox;
|
||||
CueStyleBox.prototype = Object.create(StyleBox.prototype);
|
||||
CueStyleBox.prototype.constructor = CueStyleBox;
|
||||
|
||||
// Represents the co-ordinates of an Element in a way that we can easily
|
||||
// compute things with such as if it overlaps or intersects with another Element.
|
||||
// Can initialize it with either a StyleBox or another BoxPosition.
|
||||
function BoxPosition(obj) {
|
||||
var self = this;
|
||||
|
||||
// Either a BoxPosition was passed in and we need to copy it, or a StyleBox
|
||||
// was passed in and we need to copy the results of 'getBoundingClientRect'
|
||||
// as the object returned is readonly. All co-ordinate values are in reference
|
||||
// to the viewport origin (top left).
|
||||
var lh;
|
||||
if (obj.div) {
|
||||
var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
|
||||
rects.getClientRects && rects.getClientRects();
|
||||
obj = obj.div.getBoundingClientRect();
|
||||
// In certain cases the outter div will be slightly larger then the sum of
|
||||
// the inner div's lines. This could be due to bold text, etc, on some platforms.
|
||||
// In this case we should get the average line height and use that. This will
|
||||
// result in the desired behaviour.
|
||||
lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
|
||||
: 0;
|
||||
}
|
||||
this.left = obj.left;
|
||||
this.right = obj.right;
|
||||
this.top = obj.top;
|
||||
this.height = obj.height;
|
||||
this.bottom = obj.bottom;
|
||||
this.width = obj.width;
|
||||
this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
|
||||
}
|
||||
|
||||
// Move the box along a particular axis. If no amount to move is passed, via
|
||||
// the val parameter, then the default amount is the line height of the box.
|
||||
BoxPosition.prototype.move = function(axis, val) {
|
||||
val = val !== undefined ? val : this.lineHeight;
|
||||
switch (axis) {
|
||||
case "+x":
|
||||
this.left += val;
|
||||
this.right += val;
|
||||
break;
|
||||
case "-x":
|
||||
this.left -= val;
|
||||
this.right -= val;
|
||||
break;
|
||||
case "+y":
|
||||
this.top += val;
|
||||
this.bottom += val;
|
||||
break;
|
||||
case "-y":
|
||||
this.top -= val;
|
||||
this.bottom -= val;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Check if this box overlaps another box, b2.
|
||||
BoxPosition.prototype.overlaps = function(b2) {
|
||||
return this.left < b2.right &&
|
||||
this.right > b2.left &&
|
||||
this.top < b2.bottom &&
|
||||
this.bottom > b2.top;
|
||||
};
|
||||
|
||||
// Check if this box overlaps any other boxes in boxes.
|
||||
BoxPosition.prototype.overlapsAny = function(boxes) {
|
||||
for (var i = 0; i < boxes.length; i++) {
|
||||
if (this.overlaps(boxes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Check if this box is within another box.
|
||||
BoxPosition.prototype.within = function(container) {
|
||||
return this.top >= container.top &&
|
||||
this.bottom <= container.bottom &&
|
||||
this.left >= container.left &&
|
||||
this.right <= container.right;
|
||||
};
|
||||
|
||||
// Check if this box is entirely within the container or it is overlapping
|
||||
// on the edge opposite of the axis direction passed. For example, if "+x" is
|
||||
// passed and the box is overlapping on the left edge of the container, then
|
||||
// return true.
|
||||
BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
|
||||
switch (axis) {
|
||||
case "+x":
|
||||
return this.left < container.left;
|
||||
case "-x":
|
||||
return this.right > container.right;
|
||||
case "+y":
|
||||
return this.top < container.top;
|
||||
case "-y":
|
||||
return this.bottom > container.bottom;
|
||||
}
|
||||
};
|
||||
|
||||
// Find the percentage of the area that this box is overlapping with another
|
||||
// box.
|
||||
BoxPosition.prototype.intersectPercentage = function(b2) {
|
||||
var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
|
||||
y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
|
||||
intersectArea = x * y;
|
||||
return intersectArea / (this.height * this.width);
|
||||
};
|
||||
|
||||
// Convert the positions from this box to CSS compatible positions using
|
||||
// the reference container's positions. This has to be done because this
|
||||
// box's positions are in reference to the viewport origin, whereas, CSS
|
||||
// values are in referecne to their respective edges.
|
||||
BoxPosition.prototype.toCSSCompatValues = function(reference) {
|
||||
return {
|
||||
top: this.top - reference.top,
|
||||
bottom: reference.bottom - this.bottom,
|
||||
left: this.left - reference.left,
|
||||
right: reference.right - this.right,
|
||||
height: this.height,
|
||||
width: this.width
|
||||
};
|
||||
};
|
||||
|
||||
// Get an object that represents the box's position without anything extra.
|
||||
// Can pass a StyleBox, HTMLElement, or another BoxPositon.
|
||||
BoxPosition.getSimpleBoxPosition = function(obj) {
|
||||
obj = obj.div ? obj.div.getBoundingClientRect() :
|
||||
obj.tagName ? obj.getBoundingClientRect() : obj;
|
||||
return {
|
||||
left: obj.left,
|
||||
right: obj.right,
|
||||
top: obj.top,
|
||||
height: obj.height,
|
||||
bottom: obj.bottom,
|
||||
width: obj.width
|
||||
};
|
||||
};
|
||||
|
||||
// Move a StyleBox to its specified, or next best, position. The containerBox
|
||||
// is the box that contains the StyleBox, such as a div. boxPositions are
|
||||
// a list of other boxes that the styleBox can't overlap with.
|
||||
function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
|
||||
|
||||
// Find the best position for a cue box, b, on the video. The axis parameter
|
||||
// is a list of axis, the order of which, it will move the box along. For example:
|
||||
// Passing ["+x", "-x"] will move the box first along the x axis in the positive
|
||||
// direction. If it doesn't find a good position for it there it will then move
|
||||
// it along the x axis in the negative direction.
|
||||
function findBestPosition(b, axis) {
|
||||
var bestPosition,
|
||||
specifiedPosition = new BoxPosition(b),
|
||||
percentage = 1; // Highest possible so the first thing we get is better.
|
||||
|
||||
for (var i = 0; i < axis.length; i++) {
|
||||
while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
|
||||
(b.within(containerBox) && b.overlapsAny(boxPositions))) {
|
||||
b.move(axis[i]);
|
||||
}
|
||||
// We found a spot where we aren't overlapping anything. This is our
|
||||
// best position.
|
||||
if (b.within(containerBox)) {
|
||||
return b;
|
||||
}
|
||||
var p = b.intersectPercentage(containerBox);
|
||||
// If we're outside the container box less then we were on our last try
|
||||
// then remember this position as the best position.
|
||||
if (percentage > p) {
|
||||
bestPosition = new BoxPosition(b);
|
||||
percentage = p;
|
||||
}
|
||||
// Reset the box position to the specified position.
|
||||
b = new BoxPosition(specifiedPosition);
|
||||
}
|
||||
return bestPosition || specifiedPosition;
|
||||
}
|
||||
|
||||
function reverseAxis(axis) {
|
||||
return axis.map(function(a) {
|
||||
return a.indexOf("+") !== -1 ? a.replace("+", "-") : a.replace("-", "+");
|
||||
});
|
||||
}
|
||||
|
||||
var boxPosition = new BoxPosition(styleBox),
|
||||
cue = styleBox.cue,
|
||||
linePos = computeLinePos(cue),
|
||||
axis = [];
|
||||
|
||||
// If we have a line number to align the cue to.
|
||||
if (cue.snapToLines) {
|
||||
switch (cue.vertical) {
|
||||
case "":
|
||||
axis = [ "+y", "-y" ];
|
||||
break;
|
||||
case "rl":
|
||||
axis = [ "+x", "-x" ];
|
||||
break;
|
||||
case "lr":
|
||||
axis = [ "-x", "+x" ];
|
||||
break;
|
||||
}
|
||||
|
||||
// If computed line position returns negative then line numbers are
|
||||
// relative to the bottom of the video instead of the top. Therefore, we
|
||||
// need to increase our initial position by the length or width of the
|
||||
// video, depending on the writing direction, and reverse our axis directions.
|
||||
var initialPosition = boxPosition.lineHeight * Math.floor(linePos + 0.5),
|
||||
initialAxis = axis[0];
|
||||
if (linePos < 0) {
|
||||
initialPosition += cue.vertical === "" ? containerBox.height : containerBox.width;
|
||||
axis = reverseAxis(axis);
|
||||
}
|
||||
|
||||
// Move the box to the specified position. This may not be its best
|
||||
// position.
|
||||
boxPosition.move(initialAxis, initialPosition);
|
||||
|
||||
} else {
|
||||
// If we have a percentage line value for the cue.
|
||||
var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
|
||||
|
||||
switch (cue.lineAlign) {
|
||||
case "middle":
|
||||
linePos -= (calculatedPercentage / 2);
|
||||
break;
|
||||
case "end":
|
||||
linePos -= calculatedPercentage;
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply initial line position to the cue box.
|
||||
switch (cue.vertical) {
|
||||
case "":
|
||||
styleBox.applyStyles({
|
||||
top: styleBox.formatStyle(linePos, "%")
|
||||
});
|
||||
break;
|
||||
case "rl":
|
||||
styleBox.applyStyles({
|
||||
left: styleBox.formatStyle(linePos, "%")
|
||||
});
|
||||
break;
|
||||
case "lr":
|
||||
styleBox.applyStyles({
|
||||
right: styleBox.formatStyle(linePos, "%")
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
axis = [ "+y", "-x", "+x", "-y" ];
|
||||
|
||||
// Get the box position again after we've applied the specified positioning
|
||||
// to it.
|
||||
boxPosition = new BoxPosition(styleBox);
|
||||
}
|
||||
|
||||
var bestPosition = findBestPosition(boxPosition, axis);
|
||||
styleBox.move(bestPosition.toCSSCompatValues(containerBox));
|
||||
}
|
||||
|
||||
function WebVTTParser(window, decoder) {
|
||||
this.window = window;
|
||||
@ -891,10 +1051,14 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
return parseContent(window, cuetext);
|
||||
};
|
||||
|
||||
const FONT_SIZE_PERCENT = 0.05;
|
||||
const FONT_STYLE = "sans-serif";
|
||||
const CUE_BACKGROUND_PADDING = "1.5%";
|
||||
|
||||
// Runs the processing model over the cues and regions passed to it.
|
||||
// @param overlay A block level element (usually a div) that the computed cues
|
||||
// and regions will be placed into.
|
||||
WebVTTParser.processCues = function(window, cues, regions, overlay) {
|
||||
WebVTTParser.processCues = function(window, cues, overlay) {
|
||||
if (!window || !cues || !overlay) {
|
||||
return null;
|
||||
}
|
||||
@ -904,32 +1068,56 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
overlay.removeChild(overlay.firstChild);
|
||||
}
|
||||
|
||||
var regionBoxes = regions ? regions.map(function(region) {
|
||||
return new RegionBoundingBox(window, region);
|
||||
}) : null;
|
||||
var paddedOverlay = window.document.createElement("div");
|
||||
paddedOverlay.style.position = "absolute";
|
||||
paddedOverlay.style.left = "0";
|
||||
paddedOverlay.style.right = "0";
|
||||
paddedOverlay.style.top = "0";
|
||||
paddedOverlay.style.bottom = "0";
|
||||
paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
|
||||
overlay.appendChild(paddedOverlay);
|
||||
|
||||
function mapCueToRegion(cue) {
|
||||
for (var i = 0; i < regionBoxes.length; i++) {
|
||||
if (regionBoxes[i].maybeAddCue(cue)) {
|
||||
// Determine if we need to compute the display states of the cues. This could
|
||||
// be the case if a cue's state has been changed since the last computation or
|
||||
// if it has not been computed yet.
|
||||
function shouldCompute(cues) {
|
||||
for (var i = 0; i < cues.length; i++) {
|
||||
if (cues[i].hasBeenReset || !cues[i].displayState) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < cues.length; i++) {
|
||||
// Check to see if this cue is contained within a VTTRegion.
|
||||
if (regionBoxes && mapCueToRegion(cues[i])) {
|
||||
continue;
|
||||
}
|
||||
// Check to see if we can just reuse the last computed styles of the cue.
|
||||
if (cues[i].hasBeenReset !== true && cues[i].displayState) {
|
||||
overlay.appendChild(cues[i].displayState);
|
||||
continue;
|
||||
}
|
||||
// Compute the position of the cue box on the cue overlay.
|
||||
var cueBox = new CueBoundingBox(window, cues[i], overlay);
|
||||
// We don't need to recompute the cues' display states. Just reuse them.
|
||||
if (!shouldCompute(cues)) {
|
||||
cues.forEach(function(cue) {
|
||||
paddedOverlay.appendChild(cue.displayState);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var boxPositions = [],
|
||||
containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
|
||||
fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
|
||||
var styleOptions = {
|
||||
font: fontSize + "px " + FONT_STYLE
|
||||
};
|
||||
|
||||
cues.forEach(function(cue) {
|
||||
// Compute the intial position and styles of the cue div.
|
||||
var styleBox = new CueStyleBox(window, cue, styleOptions);
|
||||
paddedOverlay.appendChild(styleBox.div);
|
||||
|
||||
// Move the cue div to it's correct line position.
|
||||
moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
|
||||
|
||||
// Remember the computed div so that we don't have to recompute it later
|
||||
// if we don't have too.
|
||||
cue.displayState = styleBox.div;
|
||||
|
||||
boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
|
||||
});
|
||||
};
|
||||
|
||||
WebVTTParser.prototype = {
|
||||
@ -972,7 +1160,7 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
settings.set(k, v);
|
||||
break;
|
||||
case "width":
|
||||
settings.percent(k, v, true);
|
||||
settings.percent(k, v);
|
||||
break;
|
||||
case "lines":
|
||||
settings.integer(k, v);
|
||||
@ -986,8 +1174,8 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"];
|
||||
// We have to make sure both x and y parse, so use a temporary
|
||||
// settings object here.
|
||||
var anchor = new Settings();
|
||||
anchor.percent("x", xy[0], true);
|
||||
anchor.percent("y", xy[1], true);
|
||||
anchor.percent("x", xy[0]);
|
||||
anchor.percent("y", xy[1]);
|
||||
if (!anchor.has("x") || !anchor.has("y")) {
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user