update components
This commit is contained in:
@@ -16,12 +16,12 @@
|
||||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.2.25",
|
||||
"_release": "1.2.25",
|
||||
"version": "1.2.26",
|
||||
"_release": "1.2.26",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.2.25",
|
||||
"commit": "7d3165462b584cfe4e1a76dd0afd4bade40274f5"
|
||||
"tag": "1.2.26",
|
||||
"commit": "7e13c8d9c17a4946681b3485c5fbf3e62f39cd2f"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.0",
|
||||
|
||||
+6
-2
@@ -5,7 +5,6 @@
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
|
||||
|
||||
/*opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
@@ -43,7 +42,7 @@
|
||||
}
|
||||
|
||||
.actionSheetMenuItem {
|
||||
padding: .7em 1.5em;
|
||||
padding: .8em 1.6em;
|
||||
margin: 0;
|
||||
text-transform: none;
|
||||
text-align: inherit;
|
||||
@@ -52,6 +51,11 @@
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.layout-tv .actionSheetMenuItem {
|
||||
padding-top: .6em;
|
||||
padding-bottom: .6em;
|
||||
}
|
||||
|
||||
.actionSheetItemIcon {
|
||||
margin-right: 1.5em !important;
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
||||
translateDocument: translateHtml,
|
||||
translateHtml: translateHtml,
|
||||
loadStrings: loadTranslations,
|
||||
defaultModule: defaultModule
|
||||
defaultModule: defaultModule,
|
||||
getCurrentLocale: getCurrentLocale
|
||||
};
|
||||
});
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.21",
|
||||
"version": "0.5.22",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
@@ -16,11 +16,11 @@
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.5.21",
|
||||
"_release": "0.5.22",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.5.21",
|
||||
"commit": "25b13e24bbd97785da7e255db117902e692c09dd"
|
||||
"tag": "v0.5.22",
|
||||
"commit": "ed41f6bffac7c6e35963c8aa741e00be8edea2c8"
|
||||
},
|
||||
"_source": "git://github.com/dailymotion/hls.js.git",
|
||||
"_target": "~0.5.7",
|
||||
|
||||
+10
-1
@@ -97,6 +97,7 @@ each error is categorized by :
|
||||
- ```Hls.ErrorDetails.FRAG_LOAD_TIMEOUT```raised when fragment loading fails because of a timeout
|
||||
- ```Hls.ErrorDetails.FRAG_DECRYPT_ERROR```raised when fragment decryption fails
|
||||
- ```Hls.ErrorDetails.FRAG_PARSING_ERROR```raised when fragment parsing fails
|
||||
- ```Hls.ErrorDetails.BUFFER_ADD_CODEC_ERROR```raised when exception is raised while adding a new sourceBuffer to MediaSource
|
||||
- ```Hls.ErrorDetails.BUFFER_APPEND_ERROR```raised when exception is raised while preparing buffer append
|
||||
- ```Hls.ErrorDetails.BUFFER_APPENDING_ERROR```raised when exception is raised during buffer appending
|
||||
- ```Hls.ErrorDetails.BUFFER_STALLED_ERROR```raised when playback stalls because the buffer runs out
|
||||
@@ -559,6 +560,10 @@ get/set : capping/max level value that could be used by ABR Controller
|
||||
default value is -1 (no level capping)
|
||||
|
||||
|
||||
## Version Control
|
||||
|
||||
#### ```Hls.version```
|
||||
static getter: return hls.js dist version number
|
||||
|
||||
## Network Loading Control API
|
||||
|
||||
@@ -615,7 +620,7 @@ full list of Events available below :
|
||||
- `Hls.Events.FRAG_LOADING` - fired when a fragment loading starts
|
||||
- data: { frag : fragment object}
|
||||
- `Hls.Events.FRAG_LOAD_PROGRESS` - fired when a fragment load is in progress
|
||||
- data: { frag : fragment object with frag.loaded=stats.loaded, stats : { trequest, tfirst, loaded} }
|
||||
- data: { frag : fragment object with frag.loaded=stats.loaded, stats : { trequest, tfirst, loaded, total} }
|
||||
- `Hls.Events.FRAG_LOADED` - fired when a fragment loading is completed
|
||||
- data: { frag : fragment object, payload : fragment payload, stats : { trequest, tfirst, tload, length}}
|
||||
- `Hls.Events.FRAG_PARSING_INIT_SEGMENT` - fired when Init Segment has been extracted from fragment
|
||||
@@ -632,6 +637,8 @@ full list of Events available below :
|
||||
- data: { frag : fragment object }
|
||||
- `Hls.Events.FPS_DROP` - triggered when FPS drop in last monitoring period is higher than given threshold
|
||||
- data: {curentDropped : nb of dropped frames in last monitoring period, currentDecoded: nb of decoded frames in last monitoring period, totalDropped : total dropped frames on this video element}
|
||||
- `Hls.Events.FPS_DROP_LEVEL_CAPPING` - triggered when FPS drop triggers auto level capping
|
||||
- data: { level: suggested new auto level capping by fps controller, droppedLevel : level has to much dropped frame will be restricted }
|
||||
- `Hls.Events.ERROR` - Identifier for an error event
|
||||
- data: { type : error Type, details : error details, fatal : is error fatal or not, other error specific data}
|
||||
- `Hls.Events.DESTROYING` - fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a video to the instance of hls.js to handle mid-rolls for example.
|
||||
@@ -669,6 +676,8 @@ full list of Errors is described below:
|
||||
### Media Errors
|
||||
- ```Hls.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR```raised when manifest only contains quality level with codecs incompatible with MediaSource Engine.
|
||||
- data: { type : ```MEDIA_ERROR```, details : ```Hls.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR```, fatal : ```true```, url : manifest URL}
|
||||
- ```Hls.ErrorDetails.BUFFER_ADD_CODEC_ERROR```raised when MediaSource fails to add new sourceBuffer
|
||||
- data: { type : ```MEDIA_ERROR```, details : ```Hls.ErrorDetails.BUFFER_ADD_CODEC_ERROR```, fatal : ```false```, err : error raised by MediaSource, mimeType: mimeType on which the failure happened}
|
||||
- ```Hls.ErrorDetails.BUFFER_APPEND_ERROR```raised when exception is raised while calling buffer append
|
||||
- data: { type : ```MEDIA_ERROR```, details : ```Hls.ErrorDetails.BUFFER_APPEND_ERROR```, fatal : ```true```, frag : fragment object}
|
||||
- ```Hls.ErrorDetails.BUFFER_APPENDING_ERROR```raised when exception is raised during buffer appending
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.21",
|
||||
"version": "0.6.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
|
||||
+4
-1
@@ -93,7 +93,7 @@ header {
|
||||
|
||||
<video id="video" controls autoplay class="videoCentered"></video><br>
|
||||
<canvas id="buffered_c" height="15" class="videoCentered" onclick="buffered_seek(event);"></canvas><br><br>
|
||||
<pre id="HlsStatus" class="center"></pre>
|
||||
<pre id="HlsStatus" class="center" style="white-space: pre-wrap;"></pre>
|
||||
|
||||
<div class="center" id="toggleButtons">
|
||||
<button type="button" class="btn btn-sm" onclick="$('#PlaybackControl').toggle();">toggle playback controls</button>
|
||||
@@ -477,6 +477,9 @@ $(document).ready(function() {
|
||||
case Hls.ErrorDetails.BUFFER_APPEND_ERROR:
|
||||
$("#HlsStatus").text("Buffer Append Error");
|
||||
break;
|
||||
case Hls.ErrorDetails.BUFFER_ADD_CODEC_ERROR:
|
||||
$("#HlsStatus").text("Buffer Add Codec Error for " + data.mimeType + ":" + data.err.message);
|
||||
break;
|
||||
case Hls.ErrorDetails.BUFFER_APPENDING_ERROR:
|
||||
$("#HlsStatus").text("Buffer Appending Error");
|
||||
break;
|
||||
|
||||
+365
-190
File diff suppressed because it is too large
Load Diff
+15
-13
File diff suppressed because one or more lines are too long
+5
-4
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,5 +1,5 @@
|
||||
#/bin/sh
|
||||
git checkout gh-pages
|
||||
git rebase v0.5.x
|
||||
git rebase master
|
||||
git push origin gh-pages --force
|
||||
git checkout v0.5.x
|
||||
git checkout master
|
||||
|
||||
+6
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.21",
|
||||
"version": "0.6.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
@@ -17,7 +17,7 @@
|
||||
"scripts": {
|
||||
"clean": "find dist -mindepth 1 -delete",
|
||||
"prebuild": "npm run clean & npm run test",
|
||||
"build": "npm run babel && browserify -t [babelify] -s Hls src/index.js --debug | exorcist dist/hls.js.map -b . > dist/hls.js",
|
||||
"build": "npm run babel && browserify -t browserify-versionify -t [babelify] -s Hls src/index.js --debug | exorcist dist/hls.js.map -b . > dist/hls.js",
|
||||
"postbuild": "npm run minify",
|
||||
"prerelease": "npm run prebuild && npm run build && npm run postbuild && git add dist/* && git commit -m 'update dist'",
|
||||
"patch": "npm run prerelease && mversion p",
|
||||
@@ -38,13 +38,14 @@
|
||||
"webworkify": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-register": "^6.3.13",
|
||||
"babelify": "^7.2.0",
|
||||
"arraybuffer-equal": "^1.0.4",
|
||||
"babel": "^6.3.26",
|
||||
"babel-cli": "^6.3.17",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-register": "^6.3.13",
|
||||
"babelify": "^7.2.0",
|
||||
"browserify": "^13.0.0",
|
||||
"browserify-versionify": "^1.0.6",
|
||||
"deep-strict-equal": "^0.1.0",
|
||||
"exorcist": "^0.4.0",
|
||||
"http-server": "^0.9.0",
|
||||
|
||||
@@ -67,7 +67,7 @@ class BufferController extends EventHandler {
|
||||
this.mediaSource = null;
|
||||
this.media = null;
|
||||
this.pendingTracks = null;
|
||||
this.sourceBuffer = null;
|
||||
this.sourceBuffer = {};
|
||||
}
|
||||
this.onmso = this.onmse = this.onmsc = null;
|
||||
this.hls.trigger(Event.MEDIA_DETACHED);
|
||||
@@ -122,18 +122,16 @@ class BufferController extends EventHandler {
|
||||
|
||||
onBufferReset() {
|
||||
var sourceBuffer = this.sourceBuffer;
|
||||
if (sourceBuffer) {
|
||||
for(var type in sourceBuffer) {
|
||||
var sb = sourceBuffer[type];
|
||||
try {
|
||||
this.mediaSource.removeSourceBuffer(sb);
|
||||
sb.removeEventListener('updateend', this.onsbue);
|
||||
sb.removeEventListener('error', this.onsbe);
|
||||
} catch(err) {
|
||||
}
|
||||
for(var type in sourceBuffer) {
|
||||
var sb = sourceBuffer[type];
|
||||
try {
|
||||
this.mediaSource.removeSourceBuffer(sb);
|
||||
sb.removeEventListener('updateend', this.onsbue);
|
||||
sb.removeEventListener('error', this.onsbe);
|
||||
} catch(err) {
|
||||
}
|
||||
this.sourceBuffer = null;
|
||||
}
|
||||
this.sourceBuffer = {};
|
||||
this.flushRange = [];
|
||||
this.appended = 0;
|
||||
}
|
||||
@@ -146,19 +144,24 @@ class BufferController extends EventHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.sourceBuffer) {
|
||||
var sourceBuffer = {}, mediaSource = this.mediaSource;
|
||||
for (trackName in tracks) {
|
||||
var sourceBuffer = this.sourceBuffer,mediaSource = this.mediaSource;
|
||||
|
||||
for (trackName in tracks) {
|
||||
if(!sourceBuffer[trackName]) {
|
||||
track = tracks[trackName];
|
||||
// use levelCodec as first priority
|
||||
codec = track.levelCodec || track.codec;
|
||||
mimeType = `${track.container};codecs=${codec}`;
|
||||
logger.log(`creating sourceBuffer with mimeType:${mimeType}`);
|
||||
sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType);
|
||||
sb.addEventListener('updateend', this.onsbue);
|
||||
sb.addEventListener('error', this.onsbe);
|
||||
try {
|
||||
sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType);
|
||||
sb.addEventListener('updateend', this.onsbue);
|
||||
sb.addEventListener('error', this.onsbe);
|
||||
} catch(err) {
|
||||
logger.error(`error while trying to add sourceBuffer:${err.message}`);
|
||||
this.hls.trigger(Event.ERROR, {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_ADD_CODEC_ERROR, fatal: false, err: err, mimeType : mimeType});
|
||||
}
|
||||
}
|
||||
this.sourceBuffer = sourceBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,10 +226,8 @@ class BufferController extends EventHandler {
|
||||
// let's recompute this.appended, which is used to avoid flush looping
|
||||
var appended = 0;
|
||||
var sourceBuffer = this.sourceBuffer;
|
||||
if (sourceBuffer) {
|
||||
for (var type in sourceBuffer) {
|
||||
appended += sourceBuffer[type].buffered.length;
|
||||
}
|
||||
for (var type in sourceBuffer) {
|
||||
appended += sourceBuffer[type].buffered.length;
|
||||
}
|
||||
this.appended = appended;
|
||||
this.hls.trigger(Event.BUFFER_FLUSHED);
|
||||
@@ -251,9 +252,16 @@ class BufferController extends EventHandler {
|
||||
var segment = segments.shift();
|
||||
try {
|
||||
//logger.log(`appending ${segment.type} SB, size:${segment.data.length});
|
||||
sourceBuffer[segment.type].appendBuffer(segment.data);
|
||||
this.appendError = 0;
|
||||
this.appended++;
|
||||
if(sourceBuffer[segment.type]) {
|
||||
sourceBuffer[segment.type].appendBuffer(segment.data);
|
||||
this.appendError = 0;
|
||||
this.appended++;
|
||||
} else {
|
||||
// in case we don't have any source buffer matching with this segment type,
|
||||
// it means that Mediasource fails to create sourcebuffer
|
||||
// discard this segment, and trigger update end
|
||||
this.onSBUpdateEnd();
|
||||
}
|
||||
} catch(err) {
|
||||
// in case any error occured while appending, put back segment in segments table
|
||||
logger.error(`error while trying to append buffer:${err.message}`);
|
||||
|
||||
+20
-3
@@ -8,20 +8,30 @@ import EventHandler from '../event-handler';
|
||||
class CapLevelController extends EventHandler {
|
||||
constructor(hls) {
|
||||
super(hls,
|
||||
Event.FPS_DROP_LEVEL_CAPPING,
|
||||
Event.MEDIA_ATTACHING,
|
||||
Event.MANIFEST_PARSED);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.hls.config.capLevelToPlayerSize) {
|
||||
this.media = null;
|
||||
this.media = this.restrictedLevels = null;
|
||||
this.autoLevelCapping = Number.POSITIVE_INFINITY;
|
||||
if (this.timer) {
|
||||
this.timer = clearInterval(this.timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onFpsDropLevelCapping(data) {
|
||||
if (!this.restrictedLevels) {
|
||||
this.restrictedLevels = [];
|
||||
}
|
||||
if (!this.isLevelRestricted(data.droppedLevel)) {
|
||||
this.restrictedLevels.push(data.droppedLevel);
|
||||
}
|
||||
}
|
||||
|
||||
onMediaAttaching(data) {
|
||||
this.media = data.media instanceof HTMLVideoElement ? data.media : null;
|
||||
}
|
||||
@@ -56,7 +66,7 @@ class CapLevelController extends EventHandler {
|
||||
* returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled)
|
||||
*/
|
||||
getMaxLevel(capLevelIndex) {
|
||||
let result,
|
||||
let result = 0,
|
||||
i,
|
||||
level,
|
||||
mWidth = this.mediaWidth,
|
||||
@@ -66,6 +76,9 @@ class CapLevelController extends EventHandler {
|
||||
|
||||
for (i = 0; i <= capLevelIndex; i++) {
|
||||
level = this.levels[i];
|
||||
if (this.isLevelRestricted(i)) {
|
||||
break;
|
||||
}
|
||||
result = i;
|
||||
lWidth = level.width;
|
||||
lHeight = level.height;
|
||||
@@ -76,6 +89,10 @@ class CapLevelController extends EventHandler {
|
||||
return result;
|
||||
}
|
||||
|
||||
isLevelRestricted(level) {
|
||||
return (this.restrictedLevels && this.restrictedLevels.indexOf(level) !== -1) ? true : false;
|
||||
}
|
||||
|
||||
get contentScaleFactor() {
|
||||
let pixelRatio = 1;
|
||||
try {
|
||||
|
||||
@@ -3,46 +3,72 @@
|
||||
*/
|
||||
|
||||
import Event from '../events';
|
||||
import EventHandler from '../event-handler';
|
||||
import {logger} from '../utils/logger';
|
||||
|
||||
class FPSController {
|
||||
class FPSController extends EventHandler{
|
||||
|
||||
constructor(hls) {
|
||||
this.hls = hls;
|
||||
this.timer = setInterval(this.checkFPS, hls.config.fpsDroppedMonitoringPeriod);
|
||||
super(hls, Event.MEDIA_ATTACHING);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
this.isVideoPlaybackQualityAvailable = false;
|
||||
}
|
||||
|
||||
checkFPS() {
|
||||
var v = this.hls.video;
|
||||
if (v) {
|
||||
var decodedFrames = v.webkitDecodedFrameCount, droppedFrames = v.webkitDroppedFrameCount, currentTime = new Date();
|
||||
if (decodedFrames) {
|
||||
if (this.lastTime) {
|
||||
var currentPeriod = currentTime - this.lastTime;
|
||||
var currentDropped = droppedFrames - this.lastDroppedFrames;
|
||||
var currentDecoded = decodedFrames - this.lastDecodedFrames;
|
||||
var decodedFPS = 1000 * currentDecoded / currentPeriod;
|
||||
var droppedFPS = 1000 * currentDropped / currentPeriod;
|
||||
if (droppedFPS > 0) {
|
||||
logger.log(`checkFPS : droppedFPS/decodedFPS:${droppedFPS.toFixed(1)}/${decodedFPS.toFixed(1)}`);
|
||||
if (currentDropped > this.hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
||||
logger.warn('drop FPS ratio greater than max allowed value');
|
||||
this.hls.trigger(Event.FPS_DROP, {currentDropped: currentDropped, currentDecoded: currentDecoded, totalDroppedFrames: droppedFrames});
|
||||
|
||||
onMediaAttaching(data) {
|
||||
if (this.hls.config.capLevelOnFPSDrop) {
|
||||
this.video = data.media instanceof HTMLVideoElement ? data.media : null;
|
||||
if (typeof this.video.getVideoPlaybackQuality === 'function') {
|
||||
this.isVideoPlaybackQualityAvailable = true;
|
||||
}
|
||||
clearInterval(this.timer);
|
||||
this.timer = setInterval(this.checkFPSInterval.bind(this), this.hls.config.fpsDroppedMonitoringPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
checkFPS(video, decodedFrames, droppedFrames) {
|
||||
let currentTime = performance.now();
|
||||
if (decodedFrames) {
|
||||
if (this.lastTime) {
|
||||
let currentPeriod = currentTime - this.lastTime,
|
||||
currentDropped = droppedFrames - this.lastDroppedFrames,
|
||||
currentDecoded = decodedFrames - this.lastDecodedFrames,
|
||||
droppedFPS = 1000 * currentDropped / currentPeriod;
|
||||
this.hls.trigger(Event.FPS_DROP, {currentDropped: currentDropped, currentDecoded: currentDecoded, totalDroppedFrames: droppedFrames});
|
||||
if (droppedFPS > 0) {
|
||||
//logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
||||
if (currentDropped > this.hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
||||
let currentLevel = this.hls.currentLevel;
|
||||
logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
|
||||
if (currentLevel > 0 && (this.hls.autoLevelCapping === -1 || this.hls.autoLevelCapping >= currentLevel)) {
|
||||
currentLevel = currentLevel - 1;
|
||||
this.hls.trigger(Event.FPS_DROP_LEVEL_CAPPING, {level: currentLevel, droppedLevel: this.hls.currentLevel});
|
||||
this.hls.autoLevelCapping = currentLevel;
|
||||
this.hls.streamController.nextLevelSwitch();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.lastTime = currentTime;
|
||||
this.lastDroppedFrames = droppedFrames;
|
||||
this.lastDecodedFrames = decodedFrames;
|
||||
}
|
||||
this.lastTime = currentTime;
|
||||
this.lastDroppedFrames = droppedFrames;
|
||||
this.lastDecodedFrames = decodedFrames;
|
||||
}
|
||||
}
|
||||
|
||||
checkFPSInterval() {
|
||||
if (this.video) {
|
||||
if (this.isVideoPlaybackQualityAvailable) {
|
||||
let videoPlaybackQuality = this.video.getVideoPlaybackQuality();
|
||||
this.checkFPS(this.video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames);
|
||||
} else {
|
||||
this.checkFPS(this.video, this.video.webkitDecodedFrameCount, this.video.webkitDroppedFrameCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FPSController;
|
||||
|
||||
@@ -234,10 +234,15 @@ class LevelController extends EventHandler {
|
||||
|
||||
onLevelLoaded(data) {
|
||||
// check if current playlist is a live playlist
|
||||
if (data.details.live && !this.timer) {
|
||||
if (data.details.live) {
|
||||
// if live playlist we will have to reload it periodically
|
||||
// set reload period to playlist target duration
|
||||
this.timer = setInterval(this.ontick, 1000 * data.details.targetduration);
|
||||
// set reload period to average of the frag duration, if average not set then use playlist target duration
|
||||
let timerInterval = data.details.averagetargetduration ? data.details.averagetargetduration : data.details.targetduration;
|
||||
if (!this.timer || timerInterval !== this.timerInterval) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = setInterval(this.ontick, 1000 * timerInterval);
|
||||
this.timerInterval = timerInterval;
|
||||
}
|
||||
}
|
||||
if (!data.details.live && this.timer) {
|
||||
// playlist is not live and timer is armed : stopping it
|
||||
|
||||
@@ -36,6 +36,8 @@ export const ErrorDetails = {
|
||||
KEY_LOAD_ERROR: 'keyLoadError',
|
||||
// Identifier for decrypt key load timeout error - data: { frag : fragment object}
|
||||
KEY_LOAD_TIMEOUT: 'keyLoadTimeOut',
|
||||
// Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { err : exception , mimeType : mimeType }
|
||||
BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError',
|
||||
// Identifier for a buffer append error - data: append error description
|
||||
BUFFER_APPEND_ERROR: 'bufferAppendError',
|
||||
// Identifier for a buffer appending error event - data: appending error description
|
||||
|
||||
+3
-1
@@ -59,8 +59,10 @@ module.exports = {
|
||||
FRAG_BUFFERED: 'hlsFragBuffered',
|
||||
// fired when fragment matching with current media position is changing - data : { frag : fragment object }
|
||||
FRAG_CHANGED: 'hlsFragChanged',
|
||||
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
||||
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
||||
FPS_DROP: 'hlsFpsDrop',
|
||||
//triggered when FPS drop triggers auto level capping - data: {level, droppedlevel}
|
||||
FPS_DROP_LEVEL_CAPPING: 'hlsFpsDropLevelCapping',
|
||||
// Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
|
||||
ERROR: 'hlsError',
|
||||
// fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
|
||||
|
||||
@@ -45,8 +45,9 @@ class LevelHelper {
|
||||
LevelHelper.updateFragPTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS);
|
||||
} else {
|
||||
// ensure that delta is within oldfragments range
|
||||
// no need to offset start if delta === 0
|
||||
if (delta > 0 && delta < oldfragments.length) {
|
||||
// also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
|
||||
// in that case we also need to adjust start offset of all fragments
|
||||
if (delta >= 0 && delta < oldfragments.length) {
|
||||
// adjust start by sliding offset
|
||||
var sliding = oldfragments[delta].start;
|
||||
for(i = 0 ; i < newfragments.length ; i++) {
|
||||
|
||||
+13
-6
@@ -13,7 +13,7 @@ import CapLevelController from './controller/cap-level-controller';
|
||||
import StreamController from './controller/stream-controller';
|
||||
import LevelController from './controller/level-controller';
|
||||
import TimelineController from './controller/timeline-controller';
|
||||
//import FPSController from './controller/fps-controller';
|
||||
import FPSController from './controller/fps-controller';
|
||||
import {logger, enableLogs} from './utils/logger';
|
||||
import XhrLoader from './utils/xhr-loader';
|
||||
import EventEmitter from 'events';
|
||||
@@ -21,6 +21,11 @@ import KeyLoader from './loader/key-loader';
|
||||
|
||||
class Hls {
|
||||
|
||||
static get version() {
|
||||
// replaced with browserify-versionify transform
|
||||
return '__VERSION__';
|
||||
}
|
||||
|
||||
static isSupported() {
|
||||
return (window.MediaSource && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'));
|
||||
}
|
||||
@@ -42,6 +47,7 @@ class Hls {
|
||||
Hls.defaultConfig = {
|
||||
autoStartLoad: true,
|
||||
debug: false,
|
||||
capLevelOnFPSDrop: false,
|
||||
capLevelToPlayerSize: false,
|
||||
maxBufferLength: 30,
|
||||
maxBufferSize: 60 * 1000 * 1000,
|
||||
@@ -67,8 +73,8 @@ class Hls {
|
||||
fragLoadingRetryDelay: 1000,
|
||||
fragLoadingLoopThreshold: 3,
|
||||
startFragPrefetch : false,
|
||||
// fpsDroppedMonitoringPeriod: 5000,
|
||||
// fpsDroppedMonitoringThreshold: 0.2,
|
||||
fpsDroppedMonitoringPeriod: 5000,
|
||||
fpsDroppedMonitoringThreshold: 0.2,
|
||||
appendErrorMaxRetry: 3,
|
||||
loader: XhrLoader,
|
||||
fLoader: undefined,
|
||||
@@ -76,6 +82,7 @@ class Hls {
|
||||
abrController : AbrController,
|
||||
bufferController : BufferController,
|
||||
capLevelController : CapLevelController,
|
||||
fpsController: FPSController,
|
||||
streamController: StreamController,
|
||||
timelineController: TimelineController,
|
||||
enableCEA708Captions: true,
|
||||
@@ -129,10 +136,10 @@ class Hls {
|
||||
this.abrController = new config.abrController(this);
|
||||
this.bufferController = new config.bufferController(this);
|
||||
this.capLevelController = new config.capLevelController(this);
|
||||
this.fpsController = new config.fpsController(this);
|
||||
this.streamController = new config.streamController(this);
|
||||
this.timelineController = new config.timelineController(this);
|
||||
this.keyLoader = new KeyLoader(this);
|
||||
//this.fpsController = new FPSController(this);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@@ -145,10 +152,10 @@ class Hls {
|
||||
this.abrController.destroy();
|
||||
this.bufferController.destroy();
|
||||
this.capLevelController.destroy();
|
||||
this.fpsController.destroy();
|
||||
this.streamController.destroy();
|
||||
this.timelineController.destroy();
|
||||
this.keyLoader.destroy();
|
||||
//this.fpsController.destroy();
|
||||
this.keyLoader.destroy();
|
||||
this.url = null;
|
||||
this.observer.removeAllListeners();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class FragmentLoader extends EventHandler {
|
||||
this.hls.trigger(Event.ERROR, {type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.FRAG_LOAD_TIMEOUT, fatal: false, frag: this.frag});
|
||||
}
|
||||
|
||||
loadprogress(event, stats) {
|
||||
loadprogress(stats) {
|
||||
this.frag.loaded = stats.loaded;
|
||||
this.hls.trigger(Event.FRAG_LOAD_PROGRESS, {frag: this.frag, stats: stats});
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ class PlaylistLoader extends EventHandler {
|
||||
totalduration-=frag.duration;
|
||||
}
|
||||
level.totalduration = totalduration;
|
||||
level.averagetargetduration = totalduration / level.fragments.length;
|
||||
level.endSN = currentSN - 1;
|
||||
return level;
|
||||
}
|
||||
@@ -224,7 +225,8 @@ class PlaylistLoader extends EventHandler {
|
||||
hls = this.hls,
|
||||
levels;
|
||||
// responseURL not supported on some browsers (it is used to detect URL redirection)
|
||||
if (url === undefined) {
|
||||
// data-uri mode also not supported (but no need to detect redirection)
|
||||
if (url === undefined || url.indexOf('data:') === 0) {
|
||||
// fallback to initial URL
|
||||
url = this.url;
|
||||
}
|
||||
|
||||
+117
-88
@@ -132,135 +132,164 @@ class MP4Remuxer {
|
||||
}
|
||||
|
||||
remuxVideo(track, timeOffset, contiguous) {
|
||||
var view,
|
||||
offset = 8,
|
||||
var offset = 8,
|
||||
pesTimeScale = this.PES_TIMESCALE,
|
||||
pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,
|
||||
avcSample,
|
||||
mp4Sample,
|
||||
mp4SampleLength,
|
||||
unit,
|
||||
mp4SampleDuration,
|
||||
mdat, moof,
|
||||
firstPTS, firstDTS, lastDTS,
|
||||
pts, dts, ptsnorm, dtsnorm,
|
||||
flags,
|
||||
samples = [];
|
||||
firstPTS, firstDTS,
|
||||
nextDTS,
|
||||
lastPTS, lastDTS,
|
||||
inputSamples = track.samples,
|
||||
outputSamples = [];
|
||||
|
||||
// PTS is coded on 33bits, and can loop from -2^32 to 2^32
|
||||
// PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
|
||||
let nextAvcDts;
|
||||
if (contiguous) {
|
||||
// if parsed fragment is contiguous with last one, let's use last DTS value as reference
|
||||
nextAvcDts = this.nextAvcDts;
|
||||
} else {
|
||||
// if not contiguous, let's use target timeOffset
|
||||
nextAvcDts = timeOffset*pesTimeScale;
|
||||
}
|
||||
|
||||
// compute first DTS and last DTS, normalize them against reference value
|
||||
let sample = inputSamples[0];
|
||||
firstDTS = Math.max(this._PTSNormalize(sample.dts,nextAvcDts) - this._initDTS,0);
|
||||
firstPTS = Math.max(this._PTSNormalize(sample.pts,nextAvcDts) - this._initDTS,0);
|
||||
|
||||
// check timestamp continuity accross consecutive fragments (this is to remove inter-fragment gap/hole)
|
||||
let delta = Math.round((firstDTS - nextAvcDts) / 90);
|
||||
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
|
||||
if (contiguous || Math.abs(delta) > 10000) {
|
||||
if (delta) {
|
||||
if (delta > 1) {
|
||||
logger.log(`AVC:${delta} ms hole between fragments detected,filling it`);
|
||||
} else if (delta < -1) {
|
||||
logger.log(`AVC:${(-delta)} ms overlapping between fragments detected`);
|
||||
}
|
||||
// remove hole/gap : set DTS to next expected DTS
|
||||
firstDTS = nextAvcDts;
|
||||
inputSamples[0].dts = firstDTS + this._initDTS;
|
||||
// offset PTS as well, ensure that PTS is smaller or equal than new DTS
|
||||
firstPTS = Math.max(firstPTS - delta, nextAvcDts);
|
||||
inputSamples[0].pts = firstPTS + this._initDTS;
|
||||
logger.log(`Video/PTS/DTS adjusted: ${firstPTS}/${firstDTS},delta:${delta}`);
|
||||
}
|
||||
}
|
||||
nextDTS = firstDTS;
|
||||
|
||||
// compute lastPTS/lastDTS
|
||||
sample = inputSamples[inputSamples.length-1];
|
||||
lastDTS = Math.max(this._PTSNormalize(sample.dts,nextAvcDts) - this._initDTS,0);
|
||||
lastPTS = Math.max(this._PTSNormalize(sample.pts,nextAvcDts) - this._initDTS,0);
|
||||
lastPTS = Math.max(lastPTS, lastDTS);
|
||||
|
||||
let vendor = navigator.vendor, userAgent = navigator.userAgent,
|
||||
isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS');
|
||||
|
||||
// on Safari let's signal the same sample duration for all samples
|
||||
// sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
|
||||
// set this constant duration as being the avg delta between consecutive DTS.
|
||||
if (isSafari) {
|
||||
mp4SampleDuration = Math.round((lastDTS-firstDTS)/(pes2mp4ScaleFactor*(inputSamples.length-1)));
|
||||
}
|
||||
|
||||
// normalize all PTS/DTS now ...
|
||||
for (let i = 0; i < inputSamples.length; i++) {
|
||||
let sample = inputSamples[i];
|
||||
if (isSafari) {
|
||||
// sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples
|
||||
sample.dts = firstDTS + i*pes2mp4ScaleFactor*mp4SampleDuration;
|
||||
} else {
|
||||
// ensure sample monotonic DTS
|
||||
sample.dts = Math.max(this._PTSNormalize(sample.dts, nextAvcDts) - this._initDTS,firstDTS);
|
||||
// ensure dts is a multiple of scale factor to avoid rounding issues
|
||||
sample.dts = Math.round(sample.dts/pes2mp4ScaleFactor)*pes2mp4ScaleFactor;
|
||||
}
|
||||
// we normalize PTS against nextAvcDts, we also substract initDTS (some streams don't start @ PTS O)
|
||||
// and we ensure that computed value is greater or equal than sample DTS
|
||||
sample.pts = Math.max(this._PTSNormalize(sample.pts,nextAvcDts) - this._initDTS, sample.dts);
|
||||
// ensure pts is a multiple of scale factor to avoid rounding issues
|
||||
sample.pts = Math.round(sample.pts/pes2mp4ScaleFactor)*pes2mp4ScaleFactor;
|
||||
}
|
||||
|
||||
/* concatenate the video data and construct the mdat in place
|
||||
(need 8 more bytes to fill length and mpdat type) */
|
||||
mdat = new Uint8Array(track.len + (4 * track.nbNalu) + 8);
|
||||
view = new DataView(mdat.buffer);
|
||||
let view = new DataView(mdat.buffer);
|
||||
view.setUint32(0, mdat.byteLength);
|
||||
mdat.set(MP4.types.mdat, 4);
|
||||
while (track.samples.length) {
|
||||
avcSample = track.samples.shift();
|
||||
mp4SampleLength = 0;
|
||||
|
||||
for (let i = 0; i < inputSamples.length; i++) {
|
||||
let avcSample = inputSamples[i],
|
||||
mp4SampleLength = 0,
|
||||
compositionTimeOffset;
|
||||
// convert NALU bitstream to MP4 format (prepend NALU with size field)
|
||||
while (avcSample.units.units.length) {
|
||||
unit = avcSample.units.units.shift();
|
||||
let unit = avcSample.units.units.shift();
|
||||
view.setUint32(offset, unit.data.byteLength);
|
||||
offset += 4;
|
||||
mdat.set(unit.data, offset);
|
||||
offset += unit.data.byteLength;
|
||||
mp4SampleLength += 4 + unit.data.byteLength;
|
||||
}
|
||||
pts = avcSample.pts - this._initDTS;
|
||||
dts = avcSample.dts - this._initDTS;
|
||||
// ensure DTS is not bigger than PTS
|
||||
dts = Math.min(pts,dts);
|
||||
//logger.log(`Video/PTS/DTS:${Math.round(pts/90)}/${Math.round(dts/90)}`);
|
||||
// if not first AVC sample of video track, normalize PTS/DTS with previous sample value
|
||||
// and ensure that sample duration is positive
|
||||
if (lastDTS !== undefined) {
|
||||
ptsnorm = this._PTSNormalize(pts, lastDTS);
|
||||
dtsnorm = this._PTSNormalize(dts, lastDTS);
|
||||
var sampleDuration = (dtsnorm - lastDTS) / pes2mp4ScaleFactor;
|
||||
if (sampleDuration <= 0) {
|
||||
logger.log(`invalid sample duration at PTS/DTS: ${avcSample.pts}/${avcSample.dts}:${sampleDuration}`);
|
||||
sampleDuration = 1;
|
||||
}
|
||||
mp4Sample.duration = sampleDuration;
|
||||
} else {
|
||||
let nextAvcDts, delta;
|
||||
if (contiguous) {
|
||||
nextAvcDts = this.nextAvcDts;
|
||||
|
||||
if(!isSafari) {
|
||||
// expected sample duration is the Decoding Timestamp diff of consecutive samples
|
||||
if (i < inputSamples.length - 1) {
|
||||
mp4SampleDuration = inputSamples[i+1].dts - avcSample.dts;
|
||||
} else {
|
||||
nextAvcDts = timeOffset*pesTimeScale;
|
||||
// last sample duration is same than previous one
|
||||
mp4SampleDuration = avcSample.dts - inputSamples[i-1].dts;
|
||||
}
|
||||
// first AVC sample of video track, normalize PTS/DTS
|
||||
ptsnorm = this._PTSNormalize(pts, nextAvcDts);
|
||||
dtsnorm = this._PTSNormalize(dts, nextAvcDts);
|
||||
delta = Math.round((dtsnorm - nextAvcDts) / 90);
|
||||
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
|
||||
if (contiguous || Math.abs(delta) > 10000) {
|
||||
if (delta) {
|
||||
if (delta > 1) {
|
||||
logger.log(`AVC:${delta} ms hole between fragments detected,filling it`);
|
||||
} else if (delta < -1) {
|
||||
logger.log(`AVC:${(-delta)} ms overlapping between fragments detected`);
|
||||
}
|
||||
// set DTS to next DTS
|
||||
dtsnorm = nextAvcDts;
|
||||
// offset PTS as well, ensure that PTS is smaller or equal than new DTS
|
||||
ptsnorm = Math.max(ptsnorm - delta, dtsnorm);
|
||||
logger.log(`Video/PTS/DTS adjusted: ${ptsnorm}/${dtsnorm},delta:${delta}`);
|
||||
}
|
||||
}
|
||||
// remember first PTS of our avcSamples, ensure value is positive
|
||||
firstPTS = Math.max(0, ptsnorm);
|
||||
firstDTS = Math.max(0, dtsnorm);
|
||||
mp4SampleDuration /= pes2mp4ScaleFactor;
|
||||
compositionTimeOffset = Math.round((avcSample.pts - avcSample.dts) / pes2mp4ScaleFactor);
|
||||
} else {
|
||||
compositionTimeOffset = Math.max(0,mp4SampleDuration*Math.round((avcSample.pts - avcSample.dts)/(pes2mp4ScaleFactor*mp4SampleDuration)));
|
||||
}
|
||||
|
||||
|
||||
//console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${avcSample.pts}/${avcSample.dts}/${this._initDTS}/${ptsnorm}/${dtsnorm}/${(avcSample.pts/4294967296).toFixed(3)}');
|
||||
mp4Sample = {
|
||||
outputSamples.push({
|
||||
size: mp4SampleLength,
|
||||
duration: 0,
|
||||
cts: (ptsnorm - dtsnorm) / pes2mp4ScaleFactor,
|
||||
// constant duration
|
||||
duration: mp4SampleDuration,
|
||||
cts: compositionTimeOffset,
|
||||
flags: {
|
||||
isLeading: 0,
|
||||
isDependedOn: 0,
|
||||
hasRedundancy: 0,
|
||||
degradPrio: 0
|
||||
degradPrio: 0,
|
||||
dependsOn : avcSample.key ? 2 : 1,
|
||||
isNonSync : avcSample.key ? 0 : 1
|
||||
}
|
||||
};
|
||||
flags = mp4Sample.flags;
|
||||
if (avcSample.key === true) {
|
||||
// the current sample is a key frame
|
||||
flags.dependsOn = 2;
|
||||
flags.isNonSync = 0;
|
||||
} else {
|
||||
flags.dependsOn = 1;
|
||||
flags.isNonSync = 1;
|
||||
}
|
||||
samples.push(mp4Sample);
|
||||
lastDTS = dtsnorm;
|
||||
});
|
||||
}
|
||||
var lastSampleDuration = 0;
|
||||
if (samples.length >= 2) {
|
||||
lastSampleDuration = samples[samples.length - 2].duration;
|
||||
mp4Sample.duration = lastSampleDuration;
|
||||
}
|
||||
// next AVC sample DTS should be equal to last sample DTS + last sample duration
|
||||
this.nextAvcDts = dtsnorm + lastSampleDuration * pes2mp4ScaleFactor;
|
||||
// next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
|
||||
this.nextAvcDts = lastDTS + mp4SampleDuration*pes2mp4ScaleFactor;
|
||||
track.len = 0;
|
||||
track.nbNalu = 0;
|
||||
if(samples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
||||
flags = samples[0].flags;
|
||||
if(outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
||||
let flags = outputSamples[0].flags;
|
||||
// chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
|
||||
// https://code.google.com/p/chromium/issues/detail?id=229412
|
||||
flags.dependsOn = 2;
|
||||
flags.isNonSync = 0;
|
||||
}
|
||||
track.samples = samples;
|
||||
track.samples = outputSamples;
|
||||
moof = MP4.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);
|
||||
track.samples = [];
|
||||
this.observer.trigger(Event.FRAG_PARSING_DATA, {
|
||||
data1: moof,
|
||||
data2: mdat,
|
||||
startPTS: firstPTS / pesTimeScale,
|
||||
endPTS: (ptsnorm + pes2mp4ScaleFactor * lastSampleDuration) / pesTimeScale,
|
||||
endPTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,
|
||||
startDTS: firstDTS / pesTimeScale,
|
||||
endDTS: this.nextAvcDts / pesTimeScale,
|
||||
type: 'video',
|
||||
nb: samples.length
|
||||
nb: outputSamples.length
|
||||
});
|
||||
}
|
||||
|
||||
@@ -299,7 +328,7 @@ class MP4Remuxer {
|
||||
mp4Sample.duration = (dtsnorm - lastDTS) / pes2mp4ScaleFactor;
|
||||
if(Math.abs(mp4Sample.duration - expectedSampleDuration) > expectedSampleDuration/10) {
|
||||
// more than 10% diff between sample duration and expectedSampleDuration .... lets log that
|
||||
logger.log(`invalid AAC sample duration at PTS ${Math.round(pts/90)},should be 1024,found :${Math.round(mp4Sample.duration*track.audiosamplerate/track.timescale)}`);
|
||||
logger.trace(`invalid AAC sample duration at PTS ${Math.round(pts/90)},should be 1024,found :${Math.round(mp4Sample.duration*track.audiosamplerate/track.timescale)}`);
|
||||
}
|
||||
// always adjust sample duration to avoid av sync issue
|
||||
mp4Sample.duration = expectedSampleDuration;
|
||||
@@ -327,7 +356,7 @@ class MP4Remuxer {
|
||||
track.len -= unit.byteLength;
|
||||
continue;
|
||||
}
|
||||
// set PTS/DTS to next PTS/DTS
|
||||
// set PTS/DTS to expected PTS/DTS
|
||||
ptsnorm = dtsnorm = nextAacPts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +112,11 @@ class XhrLoader {
|
||||
stats.tfirst = performance.now();
|
||||
}
|
||||
stats.loaded = event.loaded;
|
||||
if (event.lengthComputable) {
|
||||
stats.total = event.total;
|
||||
}
|
||||
if (this.onProgress) {
|
||||
this.onProgress(event, stats);
|
||||
this.onProgress(stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@
|
||||
"web-component-tester": "polymer/web-component-tester#^3.4.0"
|
||||
},
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/polymerelements/iron-a11y-announcer",
|
||||
"homepage": "https://github.com/PolymerElements/iron-a11y-announcer",
|
||||
"_release": "1.0.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.4",
|
||||
"commit": "5ce3eb8c4282bb53cd72e348858dc6be6b4c50b9"
|
||||
},
|
||||
"_source": "git://github.com/polymerelements/iron-a11y-announcer.git",
|
||||
"_source": "git://github.com/PolymerElements/iron-a11y-announcer.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "polymerelements/iron-a11y-announcer"
|
||||
"_originalSource": "PolymerElements/iron-a11y-announcer"
|
||||
}
|
||||
+3
-3
@@ -32,14 +32,14 @@
|
||||
"web-component-tester": "^4.0.0",
|
||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||
},
|
||||
"homepage": "https://github.com/polymerelements/iron-icon",
|
||||
"homepage": "https://github.com/PolymerElements/iron-icon",
|
||||
"_release": "1.0.8",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.8",
|
||||
"commit": "f36b38928849ef3853db727faa8c9ef104d611eb"
|
||||
},
|
||||
"_source": "git://github.com/polymerelements/iron-icon.git",
|
||||
"_source": "git://github.com/PolymerElements/iron-icon.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "polymerelements/iron-icon"
|
||||
"_originalSource": "PolymerElements/iron-icon"
|
||||
}
|
||||
+2
-2
@@ -36,7 +36,7 @@
|
||||
"tag": "v1.4.0",
|
||||
"commit": "554f7418fdbd97688eb21518b5f8172167d53a95"
|
||||
},
|
||||
"_source": "git://github.com/PolymerElements/iron-selector.git",
|
||||
"_source": "git://github.com/polymerelements/iron-selector.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "PolymerElements/iron-selector"
|
||||
"_originalSource": "polymerelements/iron-selector"
|
||||
}
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "paper-input",
|
||||
"version": "1.1.10",
|
||||
"version": "1.1.11",
|
||||
"description": "Material design text fields",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
@@ -33,7 +33,7 @@
|
||||
"iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
|
||||
"iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
|
||||
"iron-input": "PolymerElements/iron-input#^1.0.0",
|
||||
"paper-styles": "PolymerElements/paper-styles#^1.1.0",
|
||||
"paper-styles": "PolymerElements/paper-styles#^1.1.4",
|
||||
"iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -48,11 +48,11 @@
|
||||
"web-component-tester": "^4.0.0",
|
||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||
},
|
||||
"_release": "1.1.10",
|
||||
"_release": "1.1.11",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.1.10",
|
||||
"commit": "d8e201099b4b2987bea1dbcf5804c0383544bbfd"
|
||||
"tag": "v1.1.11",
|
||||
"commit": "8cfe5c5bf8c2e40d243443d046a94b6fe371983c"
|
||||
},
|
||||
"_source": "git://github.com/polymerelements/paper-input.git",
|
||||
"_target": "^1.0.9",
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<!-- Instructions: https://github.com/PolymerElements/paper-input/CONTRIBUTING.md#filing-issues -->
|
||||
### Description
|
||||
<!-- Example: The `paper-foo` element causes the page to turn pink when clicked. -->
|
||||
|
||||
### Expected outcome
|
||||
|
||||
<!-- Example: The page stays the same color. -->
|
||||
|
||||
### Actual outcome
|
||||
|
||||
<!-- Example: The page turns pink. -->
|
||||
|
||||
### Live Demo
|
||||
<!-- Example: https://jsbin.com/cagaye/edit?html,output -->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
<!-- Example
|
||||
1. Put a `paper-foo` element in the page.
|
||||
2. Open the page in a web browser.
|
||||
3. Click the `paper-foo` element.
|
||||
-->
|
||||
|
||||
### Browsers Affected
|
||||
<!-- Check all that apply -->
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Safari 9
|
||||
- [ ] Safari 8
|
||||
- [ ] Safari 7
|
||||
- [ ] Edge
|
||||
- [ ] IE 11
|
||||
- [ ] IE 10
|
||||
+6
-5
@@ -1,15 +1,14 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
sudo: required
|
||||
before_script:
|
||||
- npm install web-component-tester
|
||||
- npm install bower
|
||||
- 'export PATH=$PWD/node_modules/.bin:$PATH'
|
||||
- npm install -g bower polylint web-component-tester
|
||||
- bower install
|
||||
- polylint
|
||||
env:
|
||||
global:
|
||||
- secure: TcDqx+YdNCa/DRQjdKt9dgYCPgXtPl2EZ7Nnv6bRvbcmUjW2eSr7Zwb+e0fO8wgwms/RqFaVx+u5jo7D1lnC4Ybcg1HKiMOvCyzY36MjF9oB/VKSEUC+p4tMVQfw1IZ/RmK3dD+WEWaoT/EKmNfctz7v5kR+yk2lZo44D9I7rrc=
|
||||
- secure: nh65tvhnhOrK05qKvDJKMV7Jm9yiCoG1wFkP3ZnqOHix9Ny+KmcTa41Bl6NXQdvYaMTFtzS7lMZX5cqIziyKyGWHVN30LzGMHJNz12fhcMi3nJ84trhQGcu/9qR9yDv16q9ouGlcz1VxnDOHaRAHnIKjLIbhN3aJtMtZBbnWihA=
|
||||
node_js: 4
|
||||
node_js: stable
|
||||
addons:
|
||||
firefox: latest
|
||||
apt:
|
||||
@@ -17,6 +16,8 @@ addons:
|
||||
- google-chrome
|
||||
packages:
|
||||
- google-chrome-stable
|
||||
sauce_connect: true
|
||||
script:
|
||||
- xvfb-run wct
|
||||
- "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then wct -s 'default'; fi"
|
||||
dist: trusty
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "paper-input",
|
||||
"version": "1.1.10",
|
||||
"version": "1.1.11",
|
||||
"description": "Material design text fields",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
@@ -33,7 +33,7 @@
|
||||
"iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
|
||||
"iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
|
||||
"iron-input": "PolymerElements/iron-input#^1.0.0",
|
||||
"paper-styles": "PolymerElements/paper-styles#^1.1.0",
|
||||
"paper-styles": "PolymerElements/paper-styles#^1.1.4",
|
||||
"iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -13,6 +13,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<link rel="import" href="../iron-behaviors/iron-control-state.html">
|
||||
|
||||
<script>
|
||||
|
||||
// Generate unique, monotonically increasing IDs for labels (needed by
|
||||
// aria-labelledby) and add-ons.
|
||||
Polymer.PaperInputHelper = {};
|
||||
Polymer.PaperInputHelper.NextLabelID = 1;
|
||||
Polymer.PaperInputHelper.NextAddonID = 1;
|
||||
|
||||
/**
|
||||
* Use `Polymer.PaperInputBehavior` to implement inputs with `<paper-input-container>`. This
|
||||
* behavior is implemented by `<paper-input>`. It exposes a number of properties from
|
||||
@@ -24,6 +31,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* @polymerBehavior Polymer.PaperInputBehavior
|
||||
*/
|
||||
Polymer.PaperInputBehaviorImpl = {
|
||||
|
||||
properties: {
|
||||
/**
|
||||
* Fired when the input changes due to user interaction.
|
||||
@@ -419,7 +427,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
if (target.id) {
|
||||
this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, target.id);
|
||||
} else {
|
||||
var id = 'paper-input-add-on-' + Math.floor((Math.random() * 100000));
|
||||
var id = 'paper-input-add-on-' + Polymer.PaperInputHelper.NextAddonID++;
|
||||
target.id = id;
|
||||
this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, id);
|
||||
}
|
||||
@@ -507,7 +515,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
if (label.id) {
|
||||
labelledBy = label.id;
|
||||
} else {
|
||||
labelledBy = 'paper-input-label-' + new Date().getUTCMilliseconds();
|
||||
labelledBy = 'paper-input-label-' + Polymer.PaperInputHelper.NextLabelID++;
|
||||
label.id = labelledBy;
|
||||
}
|
||||
this._ariaLabelledBy = labelledBy;
|
||||
@@ -525,7 +533,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @polymerBehavior */
|
||||
Polymer.PaperInputBehavior = [
|
||||
|
||||
@@ -25,7 +25,7 @@ For example:
|
||||
<input is="iron-input">
|
||||
</paper-input-container>
|
||||
|
||||
Do not wrap <paper-input-contanter> around elements that already include it, such as <paper-input>.
|
||||
Do not wrap `<paper-input-container>` around elements that already include it, such as `<paper-input>`.
|
||||
Doing so may cause events to bounce infintely between the container and its contained element.
|
||||
|
||||
### Listening for input changes
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<!DOCTYPE html><!--
|
||||
@license
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
@@ -108,6 +109,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<test-fixture id="multiple-inputs">
|
||||
<template>
|
||||
<paper-input label="one"></paper-input>
|
||||
<paper-input label="two"></paper-input>
|
||||
<paper-input label="three"></paper-input>
|
||||
<paper-input label="four"></paper-input>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
|
||||
suite('basic', function() {
|
||||
@@ -274,11 +284,24 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
});
|
||||
|
||||
suite('a11y', function() {
|
||||
test('has aria-labelledby, which is monotonically increasing', function() {
|
||||
var inputs = fixture('multiple-inputs');
|
||||
|
||||
test('has aria-labelledby', function() {
|
||||
var input = fixture('label');
|
||||
assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
|
||||
assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
|
||||
// Find the first index of the input in this fixture. Since the label
|
||||
// ids monotonically increase every time a new input is created, and
|
||||
// this fixture isn't the first one in the document, we're going to start
|
||||
// at an ID > 1.
|
||||
var firstLabel = Polymer.dom(inputs[0].root).querySelector('label').id;
|
||||
var index = parseInt(firstLabel.substr(firstLabel.lastIndexOf('-') + 1));
|
||||
|
||||
for (var i = 0; i < inputs.length; i++ ) {
|
||||
var input = inputs[i].inputElement;
|
||||
var label = Polymer.dom(inputs[i].root).querySelector('label').id;
|
||||
|
||||
assert.isTrue(input.hasAttribute('aria-labelledby'));
|
||||
assert.equal(label, 'paper-input-label-' + (index++));
|
||||
assert.equal(input.getAttribute('aria-labelledby'), label);
|
||||
}
|
||||
});
|
||||
|
||||
test('has aria-describedby for error message', function() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "paper-item",
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"description": "A material-design styled list item",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
@@ -40,11 +40,11 @@
|
||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
|
||||
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
|
||||
},
|
||||
"_release": "1.2.0",
|
||||
"_release": "1.2.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.2.0",
|
||||
"commit": "04568bc89c181222d53d8d166aef07708640484f"
|
||||
"tag": "v1.2.1",
|
||||
"commit": "1eab91333b318ae19e315866575b2dddd38e6abc"
|
||||
},
|
||||
"_source": "git://github.com/PolymerElements/paper-item.git",
|
||||
"_target": "^1.0.0",
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
sudo: required
|
||||
before_script:
|
||||
- npm install -g bower polylint web-component-tester
|
||||
- bower install
|
||||
@@ -8,18 +8,16 @@ env:
|
||||
global:
|
||||
- secure: NCk3KK+wbaXMzp8XAY6FeL+TSdI0AlPI3/tl0OpsUIaU2EiCjQuzf/UpyzCW5XZMEVFF4q/eDjrPkqJodHfpngj36mpkfmfqj9DrgDmYsV9BDvsTd8KmLsA6H8D6p7Qer+r1JMMB8PvX44vdhQ6GhZD1HFNYK1Ekpt0TkYwWKNw=
|
||||
- secure: TGgUEQe6FJS+GuYk94d//8YQmDLUu0ekMvPSIs8TQ2QkdBK4SL+2bSXZt44BbDEOwc9P4NCPSUx/RMiCAqsc5OGRJImzb/zqPNIDTeKG6q72HPBBBD3Sk0CrEpTQbOK/Flaa/B7RYR0U1kuljSmRS7lPG19nnY8gOHnIAgwIyk0=
|
||||
- CXX=g++-4.8
|
||||
node_js: stable
|
||||
addons:
|
||||
firefox: latest
|
||||
apt:
|
||||
sources:
|
||||
- google-chrome
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- google-chrome-stable
|
||||
- g++-4.8
|
||||
sauce_connect: true
|
||||
script:
|
||||
- xvfb-run wct
|
||||
- "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then wct -s 'default'; fi"
|
||||
dist: trusty
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "paper-item",
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"description": "A material-design styled list item",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
|
||||
@@ -11,7 +11,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
|
||||
<link rel="import" href="../paper-styles/color.html">
|
||||
<link rel="import" href="../paper-styles/default-theme.html">
|
||||
<llink rel="import" href="../paper-styles/typography.html">
|
||||
<link rel="import" href="../paper-styles/typography.html">
|
||||
|
||||
<dom-module id="paper-item-shared-styles">
|
||||
<template>
|
||||
|
||||
+3
-3
@@ -26,14 +26,14 @@
|
||||
"web-component-tester": "*"
|
||||
},
|
||||
"private": true,
|
||||
"homepage": "https://github.com/polymer/polymer",
|
||||
"homepage": "https://github.com/Polymer/polymer",
|
||||
"_release": "1.4.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.4.0",
|
||||
"commit": "11c987b2eb3c73b388a79fc8aaea8ca01624f514"
|
||||
},
|
||||
"_source": "git://github.com/polymer/polymer.git",
|
||||
"_source": "git://github.com/Polymer/polymer.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "polymer/polymer"
|
||||
"_originalSource": "Polymer/polymer"
|
||||
}
|
||||
+1
-1
@@ -769,7 +769,7 @@ prevent = dy > dx;
|
||||
prevent = dx > dy;
|
||||
}
|
||||
if (prevent) {
|
||||
//ev.preventDefault();
|
||||
ev.preventDefault();
|
||||
} else {
|
||||
Gestures.prevent('track');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "webcomponentsjs",
|
||||
"main": "webcomponents.js",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22",
|
||||
"homepage": "http://webcomponents.org",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
@@ -18,13 +18,13 @@
|
||||
"devDependencies": {
|
||||
"web-component-tester": "^4.0.1"
|
||||
},
|
||||
"_release": "0.7.21",
|
||||
"_release": "0.7.22",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.21",
|
||||
"commit": "19ffcd921e1aef84b55f515b00eb56e8e9116126"
|
||||
"tag": "v0.7.22",
|
||||
"commit": "50f9751f8e638301603aebb33ba9f1e90d2b0d32"
|
||||
},
|
||||
"_source": "git://github.com/Polymer/webcomponentsjs.git",
|
||||
"_source": "https://github.com/Polymer/webcomponentsjs.git",
|
||||
"_target": "^0.7.20",
|
||||
"_originalSource": "webcomponentsjs"
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
if (typeof WeakMap === "undefined") {
|
||||
(function() {
|
||||
var defineProperty = Object.defineProperty;
|
||||
@@ -778,6 +778,9 @@ window.CustomElements.addModule(function(scope) {
|
||||
definition.prototype = Object.create(HTMLElement.prototype);
|
||||
}
|
||||
definition.__name = name.toLowerCase();
|
||||
if (definition.extends) {
|
||||
definition.extends = definition.extends.toLowerCase();
|
||||
}
|
||||
definition.lifecycle = definition.lifecycle || {};
|
||||
definition.ancestry = ancestry(definition.extends);
|
||||
resolveTagName(definition);
|
||||
@@ -950,21 +953,6 @@ window.CustomElements.addModule(function(scope) {
|
||||
}
|
||||
wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
|
||||
wrapDomMethodToForceUpgrade(document, "importNode");
|
||||
if (isIE) {
|
||||
(function() {
|
||||
var importNode = document.importNode;
|
||||
document.importNode = function() {
|
||||
var n = importNode.apply(document, arguments);
|
||||
if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
|
||||
var f = document.createDocumentFragment();
|
||||
f.appendChild(n);
|
||||
return f;
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
document.registerElement = register;
|
||||
document.createElement = createElement;
|
||||
document.createElementNS = createElementNS;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
if (typeof WeakMap === "undefined") {
|
||||
(function() {
|
||||
var defineProperty = Object.defineProperty;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
if (typeof WeakMap === "undefined") {
|
||||
(function() {
|
||||
var defineProperty = Object.defineProperty;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
if (typeof WeakMap === "undefined") {
|
||||
(function() {
|
||||
var defineProperty = Object.defineProperty;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "webcomponentsjs",
|
||||
"main": "webcomponents.js",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22",
|
||||
"homepage": "http://webcomponents.org",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "webcomponents.js",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22",
|
||||
"description": "webcomponents.js",
|
||||
"main": "webcomponents.js",
|
||||
"directories": {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
(function() {
|
||||
window.WebComponents = window.WebComponents || {
|
||||
flags: {}
|
||||
@@ -914,14 +914,29 @@ if (typeof WeakMap === "undefined") {
|
||||
|
||||
(function() {
|
||||
var needsTemplate = typeof HTMLTemplateElement === "undefined";
|
||||
if (/Trident/.test(navigator.userAgent)) {
|
||||
(function() {
|
||||
var importNode = document.importNode;
|
||||
document.importNode = function() {
|
||||
var n = importNode.apply(document, arguments);
|
||||
if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
||||
var f = document.createDocumentFragment();
|
||||
f.appendChild(n);
|
||||
return f;
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
var needsCloning = function() {
|
||||
if (!needsTemplate) {
|
||||
var frag = document.createDocumentFragment();
|
||||
var t = document.createElement("template");
|
||||
frag.appendChild(t);
|
||||
t.content.appendChild(document.createElement("div"));
|
||||
var clone = frag.cloneNode(true);
|
||||
return clone.firstChild.content.childNodes.length === 0;
|
||||
var t2 = document.createElement("template");
|
||||
t2.content.appendChild(document.createElement("div"));
|
||||
t.content.appendChild(t2);
|
||||
var clone = t.cloneNode(true);
|
||||
return clone.content.childNodes.length === 0 || clone.content.firstChild.content.childNodes.length === 0;
|
||||
}
|
||||
}();
|
||||
var TEMPLATE_TAG = "template";
|
||||
@@ -943,6 +958,9 @@ if (typeof WeakMap === "undefined") {
|
||||
while (child = template.firstChild) {
|
||||
template.content.appendChild(child);
|
||||
}
|
||||
template.cloneNode = function(deep) {
|
||||
return TemplateImpl.cloneNode(this, deep);
|
||||
};
|
||||
if (canDecorate) {
|
||||
try {
|
||||
Object.defineProperty(template, "innerHTML", {
|
||||
@@ -965,9 +983,6 @@ if (typeof WeakMap === "undefined") {
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
template.cloneNode = function(deep) {
|
||||
return TemplateImpl.cloneNode(this, deep);
|
||||
};
|
||||
} catch (err) {
|
||||
canDecorate = false;
|
||||
}
|
||||
@@ -987,7 +1002,7 @@ if (typeof WeakMap === "undefined") {
|
||||
document.createElement = function() {
|
||||
"use strict";
|
||||
var el = createElement.apply(document, arguments);
|
||||
if (el.localName == "template") {
|
||||
if (el.localName === "template") {
|
||||
TemplateImpl.decorate(el);
|
||||
}
|
||||
return el;
|
||||
@@ -1015,7 +1030,7 @@ if (typeof WeakMap === "undefined") {
|
||||
if (needsTemplate || needsCloning) {
|
||||
var nativeCloneNode = Node.prototype.cloneNode;
|
||||
TemplateImpl.cloneNode = function(template, deep) {
|
||||
var clone = nativeCloneNode.call(template);
|
||||
var clone = nativeCloneNode.call(template, false);
|
||||
if (this.decorate) {
|
||||
this.decorate(clone);
|
||||
}
|
||||
@@ -1026,6 +1041,7 @@ if (typeof WeakMap === "undefined") {
|
||||
return clone;
|
||||
};
|
||||
TemplateImpl.fixClonedDom = function(clone, source) {
|
||||
if (!source.querySelectorAll) return;
|
||||
var s$ = source.querySelectorAll(TEMPLATE_TAG);
|
||||
var t$ = clone.querySelectorAll(TEMPLATE_TAG);
|
||||
for (var i = 0, l = t$.length, t, s; i < l; i++) {
|
||||
@@ -1063,7 +1079,7 @@ if (typeof WeakMap === "undefined") {
|
||||
}
|
||||
}
|
||||
if (needsTemplate) {
|
||||
HTMLTemplateElement = TemplateImpl;
|
||||
window.HTMLTemplateElement = TemplateImpl;
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -2231,6 +2247,9 @@ window.CustomElements.addModule(function(scope) {
|
||||
definition.prototype = Object.create(HTMLElement.prototype);
|
||||
}
|
||||
definition.__name = name.toLowerCase();
|
||||
if (definition.extends) {
|
||||
definition.extends = definition.extends.toLowerCase();
|
||||
}
|
||||
definition.lifecycle = definition.lifecycle || {};
|
||||
definition.ancestry = ancestry(definition.extends);
|
||||
resolveTagName(definition);
|
||||
@@ -2403,21 +2422,6 @@ window.CustomElements.addModule(function(scope) {
|
||||
}
|
||||
wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
|
||||
wrapDomMethodToForceUpgrade(document, "importNode");
|
||||
if (isIE) {
|
||||
(function() {
|
||||
var importNode = document.importNode;
|
||||
document.importNode = function() {
|
||||
var n = importNode.apply(document, arguments);
|
||||
if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
|
||||
var f = document.createDocumentFragment();
|
||||
f.appendChild(n);
|
||||
return f;
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
document.registerElement = register;
|
||||
document.createElement = createElement;
|
||||
document.createElementNS = createElementNS;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
// @version 0.7.21
|
||||
// @version 0.7.22
|
||||
(function() {
|
||||
window.WebComponents = window.WebComponents || {
|
||||
flags: {}
|
||||
@@ -6930,6 +6930,9 @@ window.CustomElements.addModule(function(scope) {
|
||||
definition.prototype = Object.create(HTMLElement.prototype);
|
||||
}
|
||||
definition.__name = name.toLowerCase();
|
||||
if (definition.extends) {
|
||||
definition.extends = definition.extends.toLowerCase();
|
||||
}
|
||||
definition.lifecycle = definition.lifecycle || {};
|
||||
definition.ancestry = ancestry(definition.extends);
|
||||
resolveTagName(definition);
|
||||
@@ -7102,21 +7105,6 @@ window.CustomElements.addModule(function(scope) {
|
||||
}
|
||||
wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
|
||||
wrapDomMethodToForceUpgrade(document, "importNode");
|
||||
if (isIE) {
|
||||
(function() {
|
||||
var importNode = document.importNode;
|
||||
document.importNode = function() {
|
||||
var n = importNode.apply(document, arguments);
|
||||
if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
|
||||
var f = document.createDocumentFragment();
|
||||
f.appendChild(n);
|
||||
return f;
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
document.registerElement = register;
|
||||
document.createElement = createElement;
|
||||
document.createElementNS = createElementNS;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -779,11 +779,28 @@ paper-input + .fieldDescription {
|
||||
}
|
||||
|
||||
.mainDrawerPanel:not([narrow]) .content-primary {
|
||||
padding: 110px 1.5em 3em 3em;
|
||||
padding-top: 110px;
|
||||
padding-bottom: 3em;
|
||||
}
|
||||
|
||||
@media all and (min-width: 800px) {
|
||||
|
||||
.mainDrawerPanel:not([narrow]) .content-primary {
|
||||
padding-right: 1.5em;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1200px) {
|
||||
|
||||
.mainDrawerPanel:not([narrow]) .content-primary {
|
||||
padding-right: 1.5em;
|
||||
padding-left: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
.mainDrawerPanel:not([narrow]) .withTabs .content-primary {
|
||||
padding-top: 135px!important;
|
||||
padding-top: 135px !important;
|
||||
}
|
||||
|
||||
.mainDrawerPanel:not([narrow]) .content-primary ul:first-child {
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
}
|
||||
|
||||
var cacheKey = 'lastappinfopresent5';
|
||||
if ((new Date().getTime() - parseInt(appSettings.get(cacheKey) || '0')) < 172800000) {
|
||||
if ((new Date().getTime() - parseInt(appSettings.get(cacheKey) || '0')) < 86400000) {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user