mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
render ssa/ass subs in browser
This commit is contained in:
parent
3c2d0cd3a1
commit
cc2c794ad0
26 changed files with 10493 additions and 138 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "iron-overlay-behavior",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.2",
|
||||
"license": "http://polymer.github.io/LICENSE.txt",
|
||||
"description": "Provides a behavior for making an element an overlay",
|
||||
"private": true,
|
||||
|
@ -35,11 +35,11 @@
|
|||
},
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/polymerelements/iron-overlay-behavior",
|
||||
"_release": "1.6.1",
|
||||
"_release": "1.6.2",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.6.1",
|
||||
"commit": "34f2ed86b2e46f2827dd09594ae99acff0f28029"
|
||||
"tag": "v1.6.2",
|
||||
"commit": "be4e703b6894af6d4013a8a9f514a384ee91e2db"
|
||||
},
|
||||
"_source": "git://github.com/polymerelements/iron-overlay-behavior.git",
|
||||
"_target": "^1.0.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "iron-overlay-behavior",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.2",
|
||||
"license": "http://polymer.github.io/LICENSE.txt",
|
||||
"description": "Provides a behavior for making an element an overlay",
|
||||
"private": true,
|
||||
|
|
|
@ -15,6 +15,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
<link rel="import" href="iron-overlay-manager.html">
|
||||
|
||||
<script>
|
||||
// IIFE to help scripts concatenation.
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
|
||||
|
@ -233,6 +236,10 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
this.__shouldRemoveTabIndex = false;
|
||||
// Used for wrapping the focus on TAB / Shift+TAB.
|
||||
this.__firstFocusableNode = this.__lastFocusableNode = null;
|
||||
// Used for requestAnimationFrame when opened changes.
|
||||
this.__openChangedAsync = null;
|
||||
// Used for requestAnimationFrame when iron-resize is fired.
|
||||
this.__onIronResizeAsync = null;
|
||||
this._ensureSetup();
|
||||
},
|
||||
|
||||
|
@ -317,26 +324,22 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
|
||||
this.__isAnimating = true;
|
||||
|
||||
// requestAnimationFrame for non-blocking rendering
|
||||
if (this.__openChangedAsync) {
|
||||
cancelAnimationFrame(this.__openChangedAsync);
|
||||
}
|
||||
if (this.opened) {
|
||||
this._prepareRenderOpened();
|
||||
}
|
||||
if (this._openChangedAsync) {
|
||||
this.cancelAsync(this._openChangedAsync);
|
||||
}
|
||||
// Async here to allow overlay layer to become visible.
|
||||
this._openChangedAsync = this.async(function() {
|
||||
// overlay becomes visible here
|
||||
this.style.display = '';
|
||||
// Force layout to ensure transition will go. Set offsetWidth to itself
|
||||
// so that compilers won't remove it.
|
||||
this.offsetWidth = this.offsetWidth;
|
||||
if (this.opened) {
|
||||
this._renderOpened();
|
||||
} else {
|
||||
this._renderClosed();
|
||||
if (this.withBackdrop) {
|
||||
this.backdropElement.prepare();
|
||||
}
|
||||
this._openChangedAsync = null;
|
||||
});
|
||||
this.__openChangedAsync = requestAnimationFrame(function() {
|
||||
this.__openChangedAsync = null;
|
||||
this._prepareRenderOpened();
|
||||
this._renderOpened();
|
||||
}.bind(this));
|
||||
} else {
|
||||
this._renderClosed();
|
||||
}
|
||||
},
|
||||
|
||||
_canceledChanged: function() {
|
||||
|
@ -379,10 +382,6 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
this.refit();
|
||||
this._finishPositioning();
|
||||
|
||||
if (this.withBackdrop) {
|
||||
this.backdropElement.prepare();
|
||||
}
|
||||
|
||||
// Safari will apply the focus to the autofocus element when displayed for the first time,
|
||||
// so we blur it. Later, _applyFocus will set the focus if necessary.
|
||||
if (this.noAutoFocus && document.activeElement === this._focusNode) {
|
||||
|
@ -432,6 +431,8 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
_finishRenderClosed: function() {
|
||||
// Hide the overlay and remove the backdrop.
|
||||
this.style.display = 'none';
|
||||
// Reset z-index only at the end of the animation.
|
||||
this.style.zIndex = '';
|
||||
|
||||
this._applyFocus();
|
||||
|
||||
|
@ -447,12 +448,18 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
},
|
||||
|
||||
_finishPositioning: function() {
|
||||
// First, make it invisible & reactivate animations.
|
||||
this.style.display = 'none';
|
||||
this.style.transform = this.style.webkitTransform = '';
|
||||
// Force layout layout to avoid application of transform.
|
||||
// Set offsetWidth to itself so that compilers won't remove it.
|
||||
this.offsetWidth = this.offsetWidth;
|
||||
// Force reflow before re-enabling animations so that they don't start.
|
||||
// Set scrollTop to itself so that Closure Compiler doesn't remove this.
|
||||
this.scrollTop = this.scrollTop;
|
||||
this.style.transition = this.style.webkitTransition = '';
|
||||
this.style.transform = this.style.webkitTransform = '';
|
||||
// Now that animations are enabled, make it visible again
|
||||
this.style.display = '';
|
||||
// Force reflow, so that following animations are properly started.
|
||||
// Set scrollTop to itself so that Closure Compiler doesn't remove this.
|
||||
this.scrollTop = this.scrollTop;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -535,12 +542,15 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
* @protected
|
||||
*/
|
||||
_onIronResize: function() {
|
||||
if (this.__isAnimating) {
|
||||
return;
|
||||
if (this.__onIronResizeAsync) {
|
||||
cancelAnimationFrame(this.__onIronResizeAsync);
|
||||
this.__onIronResizeAsync = null;
|
||||
}
|
||||
|
||||
if (this.opened) {
|
||||
this.refit();
|
||||
if (this.opened && !this.__isAnimating) {
|
||||
this.__onIronResizeAsync = requestAnimationFrame(function() {
|
||||
this.__onIronResizeAsync = null;
|
||||
this.refit();
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -583,4 +593,5 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|||
* @param {{canceled: (boolean|undefined)}} closingReason Contains `canceled` (whether the overlay was canceled).
|
||||
*/
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
|
|
@ -38,11 +38,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
*/
|
||||
this._backdropElement = null;
|
||||
|
||||
// Enable document-wide tap recognizer.
|
||||
Polymer.Gestures.add(document, 'tap', null);
|
||||
// We should be using only 'tap', but this would be a breaking change.
|
||||
var tapEvent = ('ontouchstart' in window) ? 'tap' : 'click';
|
||||
document.addEventListener(tapEvent, this._onCaptureClick.bind(this), true);
|
||||
// Listen to mousedown or touchstart to be sure to be the first to capture
|
||||
// clicks outside the overlay.
|
||||
var clickEvent = ('ontouchstart' in window) ? 'touchstart' : 'mousedown';
|
||||
document.addEventListener(clickEvent, this._onCaptureClick.bind(this), true);
|
||||
document.addEventListener('focus', this._onCaptureFocus.bind(this), true);
|
||||
document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true);
|
||||
};
|
||||
|
@ -167,7 +166,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
return;
|
||||
}
|
||||
this._overlays.splice(i, 1);
|
||||
this._setZ(overlay, '');
|
||||
|
||||
var node = overlay.restoreFocusOnClose ? overlay.restoreFocusNode : null;
|
||||
overlay.restoreFocusNode = null;
|
||||
|
@ -267,7 +265,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
_getZ: function(overlay) {
|
||||
var z = this._minimumZ;
|
||||
if (overlay) {
|
||||
var z1 = Number(window.getComputedStyle(overlay).zIndex);
|
||||
var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).zIndex);
|
||||
// Check if is a number
|
||||
// Number.isNaN not supported in IE 10+
|
||||
if (z1 === z1) {
|
||||
|
|
|
@ -127,10 +127,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
<input id="focusInput" placeholder="focus input">
|
||||
|
||||
<script>
|
||||
|
||||
HTMLImports.whenReady(function() {
|
||||
// Enable document-wide tap recognizer.
|
||||
Polymer.Gestures.add(document, 'tap', null);
|
||||
});
|
||||
|
||||
function runAfterOpen(overlay, callback) {
|
||||
overlay.addEventListener('iron-overlay-opened', function() {
|
||||
Polymer.Base.async(callback, 1);
|
||||
});
|
||||
overlay.addEventListener('iron-overlay-opened', callback);
|
||||
overlay.open();
|
||||
}
|
||||
|
||||
|
@ -168,10 +172,34 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
overlay.opened = true;
|
||||
});
|
||||
|
||||
test('closed overlay does not refit on iron-resize', function() {
|
||||
test('open() refits overlay only once', function(done) {
|
||||
var spy = sinon.spy(overlay, 'refit');
|
||||
runAfterOpen(overlay, function() {
|
||||
assert.equal(spy.callCount, 1, 'overlay did refit only once');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('open overlay refits on iron-resize', function(done) {
|
||||
runAfterOpen(overlay, function() {
|
||||
var spy = sinon.spy(overlay, 'refit');
|
||||
overlay.fire('iron-resize');
|
||||
Polymer.dom.flush();
|
||||
requestAnimationFrame(function() {
|
||||
assert.isTrue(spy.called, 'overlay did refit');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('closed overlay does not refit on iron-resize', function(done) {
|
||||
var spy = sinon.spy(overlay, 'refit');
|
||||
overlay.fire('iron-resize');
|
||||
assert.isFalse(spy.called, 'overlay should not refit');
|
||||
Polymer.dom.flush();
|
||||
requestAnimationFrame(function() {
|
||||
assert.isFalse(spy.called, 'overlay should not refit');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('open() triggers iron-resize', function(done) {
|
||||
|
@ -242,6 +270,21 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
});
|
||||
});
|
||||
|
||||
test('open overlay on mousedown does not close it', function(done) {
|
||||
var btn = document.createElement('button');
|
||||
btn.addEventListener('mousedown', overlay.open.bind(overlay));
|
||||
document.body.appendChild(btn);
|
||||
// It triggers mousedown, mouseup, and click.
|
||||
MockInteractions.tap(btn);
|
||||
document.body.removeChild(btn);
|
||||
|
||||
assert.isTrue(overlay.opened, 'overlay opened');
|
||||
overlay.async(function() {
|
||||
assert.isTrue(overlay.opened, 'overlay is still open');
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
test('clicking outside fires iron-overlay-canceled', function(done) {
|
||||
runAfterOpen(overlay, function() {
|
||||
overlay.addEventListener('iron-overlay-canceled', function(event) {
|
||||
|
@ -396,18 +439,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('open overlay refits on iron-resize', function(done) {
|
||||
var spy = sinon.spy(overlay, 'refit');
|
||||
// At this point, overlay is still opening.
|
||||
overlay.fire('iron-resize');
|
||||
assert.isFalse(spy.called, 'overlay did not refit while animating');
|
||||
overlay.addEventListener('iron-overlay-opened', function() {
|
||||
overlay.fire('iron-resize');
|
||||
assert.isTrue(spy.called, 'overlay did refit');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('focus handling', function() {
|
||||
|
@ -504,17 +535,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
overlay.withBackdrop = true;
|
||||
var focusableNodes = overlay._focusableNodes;
|
||||
runAfterOpen(overlay, function() {
|
||||
// Go to last element.
|
||||
MockInteractions.focus(focusableNodes[focusableNodes.length-1]);
|
||||
// Simulate TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[0], document.activeElement, 'focus wrapped to first focusable');
|
||||
// Simulate Shift+TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[focusableNodes.length-1], document.activeElement, 'focus wrapped to last focusable');
|
||||
done();
|
||||
Polymer.Base.async(function() {
|
||||
// Go to last element.
|
||||
MockInteractions.focus(focusableNodes[focusableNodes.length-1]);
|
||||
// Simulate TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9);
|
||||
MockInteractions.focus(document.body);
|
||||
|
||||
assert.equal(focusableNodes[0], document.activeElement, 'focus wrapped to first focusable');
|
||||
// Simulate Shift+TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[focusableNodes.length-1], document.activeElement, 'focus wrapped to last focusable');
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -522,17 +556,19 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
overlayWithTabIndex.withBackdrop = true;
|
||||
var focusableNodes = overlayWithTabIndex._focusableNodes;
|
||||
runAfterOpen(overlayWithTabIndex, function() {
|
||||
// Go to last element.
|
||||
MockInteractions.focus(focusableNodes[focusableNodes.length-1]);
|
||||
// Simulate TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[0], document.activeElement, 'focus wrapped to first focusable');
|
||||
// Simulate Shift+TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[focusableNodes.length-1], document.activeElement, 'focus wrapped to last focusable');
|
||||
done();
|
||||
Polymer.Base.async(function() {
|
||||
// Go to last element.
|
||||
MockInteractions.focus(focusableNodes[focusableNodes.length-1]);
|
||||
// Simulate TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[0], document.activeElement, 'focus wrapped to first focusable');
|
||||
// Simulate Shift+TAB & focus out of overlay.
|
||||
MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']);
|
||||
MockInteractions.focus(document.body);
|
||||
assert.equal(focusableNodes[focusableNodes.length-1], document.activeElement, 'focus wrapped to last focusable');
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -890,7 +926,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
Polymer.Base.async(function() {
|
||||
assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'), 0, 'backdrop element removed from the DOM');
|
||||
done();
|
||||
}, 1);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('newest overlay appear on top', function(done) {
|
||||
|
@ -950,7 +986,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
}, 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
suite('always-on-top', function() {
|
||||
|
@ -1003,6 +1039,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
|
||||
});
|
||||
|
||||
suite('animations', function() {
|
||||
|
||||
test('overlay animations correctly triggered', function(done) {
|
||||
var overlay = fixture('basic');
|
||||
overlay.animated = true;
|
||||
overlay.open();
|
||||
overlay.addEventListener('simple-overlay-open-animation-start', function() {
|
||||
// Since animated overlay will transition center + 300px to center,
|
||||
// we should not find the element at the center when the open animation starts.
|
||||
var centerElement = document.elementFromPoint(window.innerWidth/2, window.innerHeight/2);
|
||||
assert.notEqual(centerElement, overlay, 'overlay should not be centered already');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('a11y', function() {
|
||||
|
||||
test('overlay has aria-hidden=true when opened', function() {
|
||||
|
|
|
@ -15,13 +15,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
<dom-module id="test-overlay">
|
||||
|
||||
<style>
|
||||
|
||||
:host {
|
||||
background: white;
|
||||
color: black;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
:host([animated]) {
|
||||
-webkit-transition: -webkit-transform 0.3s;
|
||||
transition: transform 0.3s;
|
||||
-webkit-transform: translateY(300px);
|
||||
transform: translateY(300px);
|
||||
}
|
||||
|
||||
:host(.opened[animated]) {
|
||||
-webkit-transform: translateY(0px);
|
||||
transform: translateY(0px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
|
@ -31,19 +41,62 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||
</dom-module>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
(function() {
|
||||
Polymer({
|
||||
|
||||
Polymer({
|
||||
is: 'test-overlay',
|
||||
|
||||
is: 'test-overlay',
|
||||
properties: {
|
||||
animated: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true
|
||||
}
|
||||
},
|
||||
|
||||
behaviors: [
|
||||
Polymer.IronOverlayBehavior
|
||||
]
|
||||
behaviors: [
|
||||
Polymer.IronOverlayBehavior
|
||||
],
|
||||
|
||||
});
|
||||
listeners: {
|
||||
'transitionend': '__onTransitionEnd'
|
||||
},
|
||||
|
||||
})();
|
||||
_renderOpened: function() {
|
||||
if (this.animated) {
|
||||
if (this.withBackdrop) {
|
||||
this.backdropElement.open();
|
||||
}
|
||||
this.classList.add('opened');
|
||||
this.fire('simple-overlay-open-animation-start');
|
||||
} else {
|
||||
Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
_renderClosed: function() {
|
||||
if (this.animated) {
|
||||
if (this.withBackdrop) {
|
||||
this.backdropElement.close();
|
||||
}
|
||||
this.classList.remove('opened');
|
||||
this.fire('simple-overlay-close-animation-start');
|
||||
} else {
|
||||
Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
__onTransitionEnd: function(e) {
|
||||
if (e && e.target === this) {
|
||||
if (this.opened) {
|
||||
this._finishRenderOpened();
|
||||
} else {
|
||||
this._finishRenderClosed();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue