mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #491 from dkanada/shaka
Bundle flvjs and shaka and move all libs to one folder
This commit is contained in:
commit
b725d137a0
32 changed files with 181 additions and 266 deletions
|
@ -430,13 +430,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function loadUserSkinWithOptions(ctx) {
|
||||
|
||||
require(['queryString'], function (queryString) {
|
||||
|
||||
//var url = options.url;
|
||||
//var index = url.indexOf('?');
|
||||
var params = queryString.parse(ctx.querystring);
|
||||
|
||||
skinManager.loadUserSkin({
|
||||
start: params.start
|
||||
});
|
||||
|
@ -444,16 +439,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function validateRoles(apiClient, roles) {
|
||||
|
||||
return Promise.all(roles.split(',').map(function (role) {
|
||||
return validateRole(apiClient, role);
|
||||
}));
|
||||
}
|
||||
|
||||
function validateRole(apiClient, role) {
|
||||
|
||||
if (role === 'admin') {
|
||||
|
||||
return apiClient.getCurrentUser().then(function (user) {
|
||||
if (user.Policy.IsAdministrator) {
|
||||
return Promise.resolve();
|
||||
|
@ -480,7 +472,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
route: route,
|
||||
path: ctx.path
|
||||
};
|
||||
//next();
|
||||
|
||||
ctx.handled = true;
|
||||
}
|
||||
|
@ -503,7 +494,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function endsWith(str, srch) {
|
||||
|
||||
return str.lastIndexOf(srch) === srch.length - 1;
|
||||
}
|
||||
|
||||
|
@ -513,6 +503,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
if (endsWith(baseRoute, '/') && !endsWith(baseRoute, '://')) {
|
||||
baseRoute = baseRoute.substring(0, baseRoute.length - 1);
|
||||
}
|
||||
|
||||
function baseUrl() {
|
||||
return baseRoute;
|
||||
}
|
||||
|
@ -551,14 +542,11 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function back() {
|
||||
|
||||
page.back();
|
||||
}
|
||||
|
||||
function canGoBack() {
|
||||
|
||||
var curr = current();
|
||||
|
||||
if (!curr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -576,7 +564,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function show(path, options) {
|
||||
|
||||
if (path.indexOf('/') !== 0 && path.indexOf('://') === -1) {
|
||||
path = '/' + path;
|
||||
}
|
||||
|
@ -585,7 +572,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
path = path.replace(baseRoute, '');
|
||||
|
||||
if (currentRouteInfo && currentRouteInfo.path === path) {
|
||||
|
||||
// can't use this with home right now due to the back menu
|
||||
if (currentRouteInfo.route.type !== 'home') {
|
||||
loading.hide();
|
||||
|
@ -594,7 +580,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
resolveOnNextShow = resolve;
|
||||
page.show(path, options);
|
||||
});
|
||||
|
@ -615,14 +600,12 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function showItem(item, serverId, options) {
|
||||
|
||||
if (typeof (item) === 'string') {
|
||||
var apiClient = serverId ? connectionManager.getApiClient(serverId) : connectionManager.currentApiClient();
|
||||
apiClient.getItem(apiClient.getCurrentUserId(), item).then(function (item) {
|
||||
appRouter.showItem(item, options);
|
||||
});
|
||||
} else {
|
||||
|
||||
if (arguments.length === 2) {
|
||||
options = arguments[1];
|
||||
}
|
||||
|
@ -637,7 +620,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
var allRoutes = [];
|
||||
|
||||
function addRoute(path, newRoute) {
|
||||
|
||||
page(path, getHandler(newRoute));
|
||||
allRoutes.push(newRoute);
|
||||
}
|
||||
|
@ -649,7 +631,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
var backdropContainer;
|
||||
var backgroundContainer;
|
||||
function setTransparency(level) {
|
||||
|
||||
if (!backdropContainer) {
|
||||
backdropContainer = document.querySelector('.backdropContainer');
|
||||
}
|
||||
|
@ -662,8 +643,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
document.documentElement.classList.add('transparentDocument');
|
||||
backgroundContainer.classList.add('backgroundContainer-transparent');
|
||||
backdropContainer.classList.add('hide');
|
||||
}
|
||||
else if (level === 'backdrop' || level === 1) {
|
||||
} else if (level === 'backdrop' || level === 1) {
|
||||
backdrop.externalBackdrop(true);
|
||||
document.documentElement.classList.add('transparentDocument');
|
||||
backgroundContainer.classList.add('backgroundContainer-transparent');
|
||||
|
@ -677,9 +657,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function pushState(state, title, url) {
|
||||
|
||||
state.navigate = false;
|
||||
|
||||
page.pushState(state, title, url);
|
||||
}
|
||||
|
||||
|
@ -690,40 +668,24 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
console.log('Setting page base to ' + baseRoute);
|
||||
|
||||
page.base(baseRoute);
|
||||
}
|
||||
|
||||
setBaseRoute();
|
||||
|
||||
function syncNow() {
|
||||
require(['localsync'], function (localSync) {
|
||||
localSync.sync();
|
||||
});
|
||||
}
|
||||
|
||||
function invokeShortcut(id) {
|
||||
|
||||
if (id.indexOf('library-') === 0) {
|
||||
|
||||
id = id.replace('library-', '');
|
||||
|
||||
id = id.split('_');
|
||||
|
||||
appRouter.showItem(id[0], id[1]);
|
||||
|
||||
} else if (id.indexOf('item-') === 0) {
|
||||
|
||||
id = id.replace('item-', '');
|
||||
|
||||
id = id.split('_');
|
||||
|
||||
appRouter.showItem(id[0], id[1]);
|
||||
|
||||
} else {
|
||||
|
||||
id = id.split('_');
|
||||
|
||||
appRouter.show(appRouter.getRouteUrl(id[0], {
|
||||
serverId: id[1]
|
||||
}));
|
||||
|
@ -740,6 +702,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
appRouter.canGoBack = canGoBack;
|
||||
appRouter.current = current;
|
||||
appRouter.beginConnectionWizard = beginConnectionWizard;
|
||||
appRouter.invokeShortcut = invokeShortcut;
|
||||
appRouter.showItem = showItem;
|
||||
appRouter.setTransparency = setTransparency;
|
||||
appRouter.getRoutes = getRoutes;
|
||||
|
@ -751,7 +714,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
Backdrop: 1,
|
||||
Full: 2
|
||||
};
|
||||
appRouter.invokeShortcut = invokeShortcut;
|
||||
|
||||
return appRouter;
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
'use strict';
|
||||
|
||||
function getKey(name, userId) {
|
||||
|
||||
if (userId) {
|
||||
name = userId + '-' + name;
|
||||
}
|
||||
|
@ -15,20 +14,15 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
}
|
||||
|
||||
AppSettings.prototype.enableAutoLogin = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('enableAutoLogin', val.toString());
|
||||
}
|
||||
|
||||
return this.get('enableAutoLogin') !== 'false';
|
||||
};
|
||||
|
||||
AppSettings.prototype.enableAutomaticBitrateDetection = function (isInNetwork, mediaType, val) {
|
||||
|
||||
var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork;
|
||||
|
||||
if (val != null) {
|
||||
|
||||
if (isInNetwork && mediaType === 'Audio') {
|
||||
val = true;
|
||||
}
|
||||
|
@ -44,11 +38,8 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.maxStreamingBitrate = function (isInNetwork, mediaType, val) {
|
||||
|
||||
var key = 'maxbitrate-' + mediaType + '-' + isInNetwork;
|
||||
|
||||
if (val != null) {
|
||||
|
||||
if (isInNetwork && mediaType === 'Audio') {
|
||||
// nothing to do, this is always a max value
|
||||
} else {
|
||||
|
@ -65,7 +56,6 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.maxStaticMusicBitrate = function (val) {
|
||||
|
||||
if (val !== undefined) {
|
||||
this.set('maxStaticMusicBitrate', val);
|
||||
}
|
||||
|
@ -75,18 +65,15 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.maxChromecastBitrate = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('chromecastBitrate1', val);
|
||||
}
|
||||
|
||||
val = this.get('chromecastBitrate1');
|
||||
|
||||
return val ? parseInt(val) : null;
|
||||
};
|
||||
|
||||
AppSettings.prototype.syncOnlyOnWifi = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('syncOnlyOnWifi', val.toString());
|
||||
}
|
||||
|
@ -95,7 +82,6 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.syncPath = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('syncPath', val);
|
||||
}
|
||||
|
@ -104,13 +90,11 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.cameraUploadServers = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('cameraUploadServers', val.join(','));
|
||||
}
|
||||
|
||||
val = this.get('cameraUploadServers');
|
||||
|
||||
if (val) {
|
||||
return val.split(',');
|
||||
}
|
||||
|
@ -119,7 +103,6 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.runAtStartup = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('runatstartup', val.toString());
|
||||
}
|
||||
|
@ -128,9 +111,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.set = function (name, value, userId) {
|
||||
|
||||
var currentValue = this.get(name, userId);
|
||||
|
||||
appStorage.setItem(getKey(name, userId), value);
|
||||
|
||||
if (currentValue !== value) {
|
||||
|
@ -139,12 +120,10 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
};
|
||||
|
||||
AppSettings.prototype.get = function (name, userId) {
|
||||
|
||||
return appStorage.getItem(getKey(name, userId));
|
||||
};
|
||||
|
||||
AppSettings.prototype.enableSystemExternalPlayers = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
this.set('enableSystemExternalPlayers', val.toString());
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
'use strict';
|
||||
|
||||
function enableAnimation(elem) {
|
||||
|
||||
if (browser.slow) {
|
||||
return false;
|
||||
}
|
||||
|
@ -11,7 +10,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
|
||||
function enableRotation() {
|
||||
|
||||
if (browser.tv) {
|
||||
return false;
|
||||
}
|
||||
|
@ -25,17 +23,13 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
|
||||
function Backdrop() {
|
||||
|
||||
}
|
||||
|
||||
Backdrop.prototype.load = function (url, parent, existingBackdropImage) {
|
||||
|
||||
var img = new Image();
|
||||
|
||||
var self = this;
|
||||
|
||||
img.onload = function () {
|
||||
|
||||
if (self.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
@ -75,6 +69,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
|
||||
internalBackdrop(true);
|
||||
};
|
||||
|
||||
img.src = url;
|
||||
};
|
||||
|
||||
|
@ -87,14 +82,12 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
};
|
||||
|
||||
Backdrop.prototype.destroy = function () {
|
||||
|
||||
this.isDestroyed = true;
|
||||
this.cancelAnimation();
|
||||
};
|
||||
|
||||
var backdropContainer;
|
||||
function getBackdropContainer() {
|
||||
|
||||
if (!backdropContainer) {
|
||||
backdropContainer = document.querySelector('.backdropContainer');
|
||||
}
|
||||
|
@ -109,7 +102,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
|
||||
function clearBackdrop(clearAll) {
|
||||
|
||||
clearRotation();
|
||||
|
||||
if (currentLoadingBackdrop) {
|
||||
|
@ -123,6 +115,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
if (clearAll) {
|
||||
hasExternalBackdrop = false;
|
||||
}
|
||||
|
||||
internalBackdrop(false);
|
||||
}
|
||||
|
||||
|
@ -133,8 +126,8 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
return backgroundContainer;
|
||||
}
|
||||
function setBackgroundContainerBackgroundEnabled() {
|
||||
|
||||
function setBackgroundContainerBackgroundEnabled() {
|
||||
if (hasInternalBackdrop || hasExternalBackdrop) {
|
||||
getBackgroundContainer().classList.add('withBackdrop');
|
||||
} else {
|
||||
|
@ -160,7 +153,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
|
||||
var currentLoadingBackdrop;
|
||||
function setBackdropImage(url) {
|
||||
|
||||
if (currentLoadingBackdrop) {
|
||||
currentLoadingBackdrop.destroy();
|
||||
currentLoadingBackdrop = null;
|
||||
|
@ -183,29 +175,23 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
|
||||
var standardWidths = [480, 720, 1280, 1440, 1920];
|
||||
function getBackdropMaxWidth() {
|
||||
|
||||
var width = dom.getWindowSize().innerWidth;
|
||||
var roundScreenTo = 100;
|
||||
|
||||
if (standardWidths.indexOf(width) !== -1) {
|
||||
return width;
|
||||
}
|
||||
|
||||
var roundScreenTo = 100;
|
||||
width = Math.floor(width / roundScreenTo) * roundScreenTo;
|
||||
|
||||
return Math.min(width, 1920);
|
||||
}
|
||||
|
||||
function getItemImageUrls(item, imageOptions) {
|
||||
|
||||
imageOptions = imageOptions || {};
|
||||
|
||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
|
||||
if (item.BackdropImageTags && item.BackdropImageTags.length > 0) {
|
||||
|
||||
return item.BackdropImageTags.map(function (imgTag, index) {
|
||||
|
||||
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
|
@ -216,9 +202,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
|
||||
if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
||||
|
||||
return item.ParentBackdropImageTags.map(function (imgTag, index) {
|
||||
|
||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
|
@ -232,17 +216,13 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
}
|
||||
|
||||
function getImageUrls(items, imageOptions) {
|
||||
|
||||
var list = [];
|
||||
|
||||
var onImg = function (img) {
|
||||
list.push(img);
|
||||
};
|
||||
|
||||
for (var i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
var itemImages = getItemImageUrls(items[i], imageOptions);
|
||||
|
||||
itemImages.forEach(onImg);
|
||||
}
|
||||
|
||||
|
@ -262,12 +242,12 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
|
||||
// If you don't care about the order of the elements inside
|
||||
// the array, you should sort both arrays here.
|
||||
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -275,20 +255,16 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
var currentRotatingImages = [];
|
||||
var currentRotationIndex = -1;
|
||||
function setBackdrops(items, imageOptions, enableImageRotation) {
|
||||
|
||||
var images = getImageUrls(items, imageOptions);
|
||||
|
||||
if (images.length) {
|
||||
|
||||
startRotation(images, enableImageRotation);
|
||||
|
||||
} else {
|
||||
clearBackdrop();
|
||||
}
|
||||
}
|
||||
|
||||
function startRotation(images, enableImageRotation) {
|
||||
|
||||
if (arraysEqual(images, currentRotatingImages)) {
|
||||
return;
|
||||
}
|
||||
|
@ -301,11 +277,11 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
if (images.length > 1 && enableImageRotation !== false && enableRotation()) {
|
||||
rotationInterval = setInterval(onRotationInterval, 24000);
|
||||
}
|
||||
|
||||
onRotationInterval();
|
||||
}
|
||||
|
||||
function onRotationInterval() {
|
||||
|
||||
if (playbackManager.isPlayingLocally(['Video'])) {
|
||||
return;
|
||||
}
|
||||
|
@ -324,35 +300,29 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
|
|||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
rotationInterval = null;
|
||||
currentRotatingImages = [];
|
||||
currentRotationIndex = -1;
|
||||
}
|
||||
|
||||
function setBackdrop(url, imageOptions) {
|
||||
|
||||
if (url) {
|
||||
if (typeof url !== 'string') {
|
||||
url = getImageUrls([url], imageOptions)[0];
|
||||
}
|
||||
if (url && typeof url !== 'string') {
|
||||
url = getImageUrls([url], imageOptions)[0];
|
||||
}
|
||||
|
||||
if (url) {
|
||||
clearRotation();
|
||||
|
||||
setBackdropImage(url);
|
||||
|
||||
} else {
|
||||
clearBackdrop();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
setBackdrops: setBackdrops,
|
||||
setBackdrop: setBackdrop,
|
||||
clear: clearBackdrop,
|
||||
externalBackdrop: externalBackdrop
|
||||
};
|
||||
|
||||
});
|
|
@ -1,310 +0,0 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function isTv() {
|
||||
|
||||
// This is going to be really difficult to get right
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (userAgent.indexOf('tv') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('samsungbrowser') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('nintendo') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('viera') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('webos') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isMobile(userAgent) {
|
||||
|
||||
var terms = [
|
||||
'mobi',
|
||||
'ipad',
|
||||
'iphone',
|
||||
'ipod',
|
||||
'silk',
|
||||
'gt-p1000',
|
||||
'nexus 7',
|
||||
'kindle fire',
|
||||
'opera mini'
|
||||
];
|
||||
|
||||
var lower = userAgent.toLowerCase();
|
||||
|
||||
for (var i = 0, length = terms.length; i < length; i++) {
|
||||
if (lower.indexOf(terms[i]) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isStyleSupported(prop, value) {
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no value is supplied, use "inherit"
|
||||
value = arguments.length === 2 ? value : 'inherit';
|
||||
// Try the native standard method first
|
||||
if ('CSS' in window && 'supports' in window.CSS) {
|
||||
return window.CSS.supports(prop, value);
|
||||
}
|
||||
// Check Opera's native method
|
||||
if ('supportsCSS' in window) {
|
||||
return window.supportsCSS(prop, value);
|
||||
}
|
||||
|
||||
// need try/catch because it's failing on tizen
|
||||
|
||||
try {
|
||||
// Convert to camel-case for DOM interactions
|
||||
var camel = prop.replace(/-([a-z]|[0-9])/ig, function (all, letter) {
|
||||
return (letter + '').toUpperCase();
|
||||
});
|
||||
// Check if the property is supported
|
||||
var support = (camel in el.style);
|
||||
// Create test element
|
||||
var el = document.createElement('div');
|
||||
// Assign the property and value to invoke
|
||||
// the CSS interpreter
|
||||
el.style.cssText = prop + ':' + value;
|
||||
// Ensure both the property and value are
|
||||
// supported and return
|
||||
return support && (el.style[camel] !== '');
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function hasKeyboard(browser) {
|
||||
|
||||
if (browser.touch) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.xboxOne) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.ps4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.edgeUwp) {
|
||||
// This is OK for now, but this won't always be true
|
||||
// Should we use this?
|
||||
// https://gist.github.com/wagonli/40d8a31bd0d6f0dd7a5d
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.tv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function iOSversion() {
|
||||
if (/iP(hone|od|ad)/.test(navigator.platform)) {
|
||||
// supports iOS 2.0 and later: <http://bit.ly/TJjs1V>
|
||||
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
|
||||
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
|
||||
}
|
||||
}
|
||||
|
||||
var _supportsCssAnimation;
|
||||
var _supportsCssAnimationWithPrefix;
|
||||
function supportsCssAnimation(allowPrefix) {
|
||||
|
||||
if (allowPrefix) {
|
||||
if (_supportsCssAnimationWithPrefix === true || _supportsCssAnimationWithPrefix === false) {
|
||||
return _supportsCssAnimationWithPrefix;
|
||||
}
|
||||
} else {
|
||||
if (_supportsCssAnimation === true || _supportsCssAnimation === false) {
|
||||
return _supportsCssAnimation;
|
||||
}
|
||||
}
|
||||
|
||||
var animation = false,
|
||||
animationstring = 'animation',
|
||||
keyframeprefix = '',
|
||||
domPrefixes = ['Webkit', 'O', 'Moz'],
|
||||
pfx = '',
|
||||
elm = document.createElement('div');
|
||||
|
||||
if (elm.style.animationName !== undefined) { animation = true; }
|
||||
|
||||
if (animation === false && allowPrefix) {
|
||||
for (var i = 0; i < domPrefixes.length; i++) {
|
||||
if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) {
|
||||
pfx = domPrefixes[i];
|
||||
animationstring = pfx + 'Animation';
|
||||
keyframeprefix = '-' + pfx.toLowerCase() + '-';
|
||||
animation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowPrefix) {
|
||||
_supportsCssAnimationWithPrefix = animation;
|
||||
return _supportsCssAnimationWithPrefix;
|
||||
} else {
|
||||
_supportsCssAnimation = animation;
|
||||
return _supportsCssAnimation;
|
||||
}
|
||||
}
|
||||
|
||||
var uaMatch = function (ua) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
var match = /(edge)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(opera)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(opr)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(safari)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(firefox)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(msie) ([\w.]+)/.exec(ua) ||
|
||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
var versionMatch = /(version)[ \/]([\w.]+)/.exec(ua);
|
||||
|
||||
var platform_match = /(ipad)/.exec(ua) ||
|
||||
/(iphone)/.exec(ua) ||
|
||||
/(windows)/.exec(ua) ||
|
||||
/(android)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
var browser = match[1] || "";
|
||||
|
||||
if (browser === "edge") {
|
||||
platform_match = [""];
|
||||
} else {
|
||||
if (ua.indexOf("windows phone") !== -1 || ua.indexOf("iemobile") !== -1) {
|
||||
|
||||
// http://www.neowin.net/news/ie11-fakes-user-agent-to-fool-gmail-in-windows-phone-81-gdr1-update
|
||||
browser = "msie";
|
||||
}
|
||||
else if (ua.indexOf("like gecko") !== -1 && ua.indexOf('webkit') === -1 && ua.indexOf('opera') === -1 && ua.indexOf('chrome') === -1 && ua.indexOf('safari') === -1) {
|
||||
browser = "msie";
|
||||
}
|
||||
}
|
||||
|
||||
if (browser === 'opr') {
|
||||
browser = 'opera';
|
||||
}
|
||||
|
||||
var version;
|
||||
if (versionMatch && versionMatch.length > 2) {
|
||||
version = versionMatch[2];
|
||||
}
|
||||
|
||||
version = version || match[2] || "0";
|
||||
|
||||
var versionMajor = parseInt(version.split('.')[0]);
|
||||
|
||||
if (isNaN(versionMajor)) {
|
||||
versionMajor = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
browser: browser,
|
||||
version: version,
|
||||
platform: platform_match[0] || "",
|
||||
versionMajor: versionMajor
|
||||
};
|
||||
};
|
||||
|
||||
var userAgent = navigator.userAgent;
|
||||
|
||||
var matched = uaMatch(userAgent);
|
||||
var browser = {};
|
||||
|
||||
if (matched.browser) {
|
||||
browser[matched.browser] = true;
|
||||
browser.version = matched.version;
|
||||
browser.versionMajor = matched.versionMajor;
|
||||
}
|
||||
|
||||
if (matched.platform) {
|
||||
browser[matched.platform] = true;
|
||||
}
|
||||
|
||||
if (!browser.chrome && !browser.msie && !browser.edge && !browser.opera && userAgent.toLowerCase().indexOf("webkit") !== -1) {
|
||||
browser.safari = true;
|
||||
}
|
||||
|
||||
if (userAgent.toLowerCase().indexOf("playstation 4") !== -1) {
|
||||
browser.ps4 = true;
|
||||
browser.tv = true;
|
||||
}
|
||||
|
||||
if (isMobile(userAgent)) {
|
||||
browser.mobile = true;
|
||||
}
|
||||
|
||||
browser.xboxOne = userAgent.toLowerCase().indexOf('xbox') !== -1;
|
||||
browser.animate = typeof document !== 'undefined' && document.documentElement.animate != null;
|
||||
browser.tizen = userAgent.toLowerCase().indexOf('tizen') !== -1 || self.tizen != null;
|
||||
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) !== -1;
|
||||
browser.edgeUwp = browser.edge && (userAgent.toLowerCase().indexOf('msapphost') !== -1 || userAgent.toLowerCase().indexOf('webview') !== -1);
|
||||
|
||||
if (!browser.tizen) {
|
||||
browser.orsay = userAgent.toLowerCase().indexOf('smarthub') !== -1;
|
||||
}
|
||||
|
||||
if (browser.edgeUwp) {
|
||||
browser.edge = true;
|
||||
}
|
||||
|
||||
browser.tv = isTv();
|
||||
browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') !== -1;
|
||||
|
||||
if (!isStyleSupported('display', 'flex')) {
|
||||
browser.noFlex = true;
|
||||
}
|
||||
|
||||
if (browser.mobile || browser.tv) {
|
||||
browser.slow = true;
|
||||
}
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
|
||||
browser.touch = true;
|
||||
}
|
||||
}
|
||||
|
||||
browser.keyboard = hasKeyboard(browser);
|
||||
browser.supportsCssAnimation = supportsCssAnimation;
|
||||
|
||||
browser.osx = userAgent.toLowerCase().indexOf('os x') !== -1;
|
||||
browser.iOS = browser.ipad || browser.iphone || browser.ipod;
|
||||
|
||||
if (browser.iOS) {
|
||||
browser.iOSVersion = iOSversion();
|
||||
browser.iOSVersion = browser.iOSVersion[0] + (browser.iOSVersion[1] / 10);
|
||||
}
|
||||
|
||||
browser.chromecast = browser.chrome && userAgent.toLowerCase().indexOf('crkey') !== -1;
|
||||
|
||||
return browser;
|
||||
});
|
|
@ -1,916 +0,0 @@
|
|||
define(['browser'], function (browser) {
|
||||
'use strict';
|
||||
|
||||
function canPlayH264(videoTestElement) {
|
||||
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
|
||||
}
|
||||
|
||||
function canPlayH265(videoTestElement, options) {
|
||||
|
||||
if (browser.tizen || browser.orsay || browser.xboxOne || browser.web0s || options.supportsHevc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (browser.chromecast) {
|
||||
|
||||
var isChromecastUltra = userAgent.indexOf('aarch64') !== -1;
|
||||
if (isChromecastUltra) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Unfortunately haven't yet found a canPlayType for proper detection
|
||||
if (browser.iOS && (browser.iOSVersion || 0) >= 11) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/hevc; codecs="hevc, aac"').replace(/no/, ''));
|
||||
}
|
||||
|
||||
var _supportsTextTracks;
|
||||
function supportsTextTracks() {
|
||||
|
||||
if (browser.tizen || browser.orsay) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_supportsTextTracks == null) {
|
||||
_supportsTextTracks = document.createElement('video').textTracks != null;
|
||||
}
|
||||
|
||||
// For now, until ready
|
||||
return _supportsTextTracks;
|
||||
}
|
||||
|
||||
var _canPlayHls;
|
||||
function canPlayHls(src) {
|
||||
|
||||
if (_canPlayHls == null) {
|
||||
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
|
||||
}
|
||||
return _canPlayHls;
|
||||
}
|
||||
|
||||
function canPlayNativeHls() {
|
||||
|
||||
if (browser.tizen || browser.orsay) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var media = document.createElement('video');
|
||||
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
|
||||
media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function canPlayHlsWithMSE() {
|
||||
if (window.MediaSource != null) {
|
||||
// text tracks don’t work with this in firefox
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function canPlayAudioFormat(format) {
|
||||
|
||||
var typeString;
|
||||
|
||||
if (format === 'flac') {
|
||||
if (browser.tizen || browser.orsay || browser.web0s) {
|
||||
return true;
|
||||
}
|
||||
if (browser.edgeUwp) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (format === 'wma') {
|
||||
if (browser.tizen || browser.orsay) {
|
||||
return true;
|
||||
}
|
||||
if (browser.edgeUwp) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (format === 'opus') {
|
||||
typeString = 'audio/ogg; codecs="opus"';
|
||||
|
||||
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (format === 'mp2') {
|
||||
|
||||
// For now
|
||||
return false;
|
||||
}
|
||||
|
||||
if (format === 'webma') {
|
||||
typeString = 'audio/webm';
|
||||
} else if (format === 'mp2') {
|
||||
typeString = 'audio/mpeg';
|
||||
} else if (format === 'ogg' || format === 'oga') {
|
||||
|
||||
// chrome says probably, but seeing failures
|
||||
if (browser.chrome) {
|
||||
return false;
|
||||
}
|
||||
typeString = 'audio/' + format;
|
||||
|
||||
} else {
|
||||
typeString = 'audio/' + format;
|
||||
}
|
||||
|
||||
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function testCanPlayMkv(videoTestElement) {
|
||||
|
||||
if (browser.tizen || browser.orsay || browser.web0s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (videoTestElement.canPlayType('video/x-matroska').replace(/no/, '') ||
|
||||
videoTestElement.canPlayType('video/mkv').replace(/no/, '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
// Unfortunately there's no real way to detect mkv support
|
||||
if (browser.chrome) {
|
||||
|
||||
// Not supported on opera tv
|
||||
if (browser.operaTv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter out browsers based on chromium that don't support mkv
|
||||
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.edgeUwp) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function testCanPlayTs() {
|
||||
return browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||
}
|
||||
|
||||
function supportsMpeg2Video() {
|
||||
return browser.orsay || browser.tizen || browser.edgeUwp || browser.web0s;
|
||||
}
|
||||
|
||||
function supportsVc1() {
|
||||
return browser.orsay || browser.tizen || browser.edgeUwp || browser.web0s;
|
||||
}
|
||||
|
||||
function getFlvMseDirectPlayProfile() {
|
||||
|
||||
var videoAudioCodecs = ['aac'];
|
||||
|
||||
if (!browser.edge && !browser.msie) {
|
||||
videoAudioCodecs.push('mp3');
|
||||
}
|
||||
|
||||
return {
|
||||
Container: 'flv',
|
||||
Type: 'Video',
|
||||
VideoCodec: 'h264',
|
||||
AudioCodec: videoAudioCodecs.join(',')
|
||||
};
|
||||
}
|
||||
|
||||
function getDirectPlayProfileForVideoContainer(container, videoAudioCodecs, videoTestElement, options) {
|
||||
|
||||
var supported = false;
|
||||
var profileContainer = container;
|
||||
var videoCodecs = [];
|
||||
|
||||
switch (container) {
|
||||
|
||||
case 'asf':
|
||||
supported = browser.tizen || browser.orsay || browser.edgeUwp;
|
||||
videoAudioCodecs = [];
|
||||
break;
|
||||
case 'avi':
|
||||
supported = browser.tizen || browser.orsay || browser.edgeUwp;
|
||||
break;
|
||||
case 'mpg':
|
||||
case 'mpeg':
|
||||
supported = browser.edgeUwp || browser.tizen || browser.orsay;
|
||||
break;
|
||||
case 'flv':
|
||||
supported = browser.tizen || browser.orsay;
|
||||
//if (!supported && window.MediaSource != null && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"')) {
|
||||
// return getFlvMseDirectPlayProfile();
|
||||
//}
|
||||
break;
|
||||
case '3gp':
|
||||
case 'mts':
|
||||
case 'trp':
|
||||
case 'vob':
|
||||
case 'vro':
|
||||
supported = browser.tizen || browser.orsay;
|
||||
break;
|
||||
case 'mov':
|
||||
supported = browser.tizen || browser.orsay || browser.chrome || browser.edgeUwp;
|
||||
videoCodecs.push('h264');
|
||||
break;
|
||||
case 'm2ts':
|
||||
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||
videoCodecs.push('h264');
|
||||
if (supportsVc1()) {
|
||||
videoCodecs.push('vc1');
|
||||
}
|
||||
if (supportsMpeg2Video()) {
|
||||
videoCodecs.push('mpeg2video');
|
||||
}
|
||||
break;
|
||||
case 'wmv':
|
||||
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
|
||||
videoAudioCodecs = [];
|
||||
break;
|
||||
case 'ts':
|
||||
supported = testCanPlayTs();
|
||||
videoCodecs.push('h264');
|
||||
if (canPlayH265(videoTestElement, options)) {
|
||||
videoCodecs.push('h265');
|
||||
videoCodecs.push('hevc');
|
||||
}
|
||||
if (supportsVc1()) {
|
||||
videoCodecs.push('vc1');
|
||||
}
|
||||
if (supportsMpeg2Video()) {
|
||||
videoCodecs.push('mpeg2video');
|
||||
}
|
||||
profileContainer = 'ts,mpegts';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!supported) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
Container: profileContainer,
|
||||
Type: 'Video',
|
||||
VideoCodec: videoCodecs.join(','),
|
||||
AudioCodec: videoAudioCodecs.join(',')
|
||||
};
|
||||
}
|
||||
|
||||
function getMaxBitrate() {
|
||||
|
||||
return 120000000;
|
||||
}
|
||||
|
||||
function getGlobalMaxVideoBitrate() {
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (browser.chromecast) {
|
||||
|
||||
var isChromecastUltra = userAgent.indexOf('aarch64') !== -1;
|
||||
if (isChromecastUltra) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// This is a hack to try and detect chromecast on vizio
|
||||
if (self.screen && self.screen.width >= 3800) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 30000000;
|
||||
}
|
||||
|
||||
var isTizenFhd = false;
|
||||
if (browser.tizen) {
|
||||
try {
|
||||
var isTizenUhd = webapis.productinfo.isUdPanelSupported();
|
||||
isTizenFhd = !isTizenUhd;
|
||||
console.log("isTizenFhd = " + isTizenFhd);
|
||||
} catch (error) {
|
||||
console.log("isUdPanelSupported() error code = " + error.code);
|
||||
}
|
||||
}
|
||||
|
||||
return browser.ps4 ? 8000000 :
|
||||
(browser.xboxOne ? 12000000 :
|
||||
(browser.edgeUwp ? null :
|
||||
(browser.tizen && isTizenFhd ? 20000000 : null)));
|
||||
}
|
||||
|
||||
function supportsAc3(videoTestElement) {
|
||||
|
||||
if (browser.edgeUwp || browser.tizen || browser.orsay || browser.web0s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '') && !browser.osx && !browser.iOS);
|
||||
}
|
||||
|
||||
function supportsEac3(videoTestElement) {
|
||||
|
||||
if (browser.tizen || browser.orsay || browser.web0s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return videoTestElement.canPlayType('audio/mp4; codecs="ec-3"').replace(/no/, '');
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
||||
options = options || {};
|
||||
var physicalAudioChannels = options.audioChannels || (browser.tv || browser.ps4 || browser.xboxOne ? 6 : 2);
|
||||
|
||||
var bitrateSetting = getMaxBitrate();
|
||||
|
||||
var videoTestElement = document.createElement('video');
|
||||
|
||||
var canPlayVp8 = videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/, '');
|
||||
var canPlayVp9 = videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/, '');
|
||||
var webmAudioCodecs = ['vorbis'];
|
||||
|
||||
var canPlayMkv = testCanPlayMkv(videoTestElement);
|
||||
|
||||
var profile = {};
|
||||
|
||||
profile.MaxStreamingBitrate = bitrateSetting;
|
||||
profile.MaxStaticBitrate = 100000000;
|
||||
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
|
||||
|
||||
profile.DirectPlayProfiles = [];
|
||||
|
||||
var videoAudioCodecs = [];
|
||||
var hlsVideoAudioCodecs = [];
|
||||
|
||||
var supportsMp3VideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/, '') ||
|
||||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/, '');
|
||||
|
||||
// Not sure how to test for this
|
||||
var supportsMp2VideoAudio = browser.edgeUwp || browser.tizen || browser.orsay || browser.web0s;
|
||||
|
||||
var maxVideoWidth = browser.xboxOne ?
|
||||
(self.screen ? self.screen.width : null) :
|
||||
null;
|
||||
|
||||
if (options.maxVideoWidth) {
|
||||
maxVideoWidth = options.maxVideoWidth;
|
||||
}
|
||||
|
||||
var canPlayAacVideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/, '');
|
||||
|
||||
if (canPlayAacVideoAudio && browser.chromecast && physicalAudioChannels <= 2) {
|
||||
// prioritize this first
|
||||
videoAudioCodecs.push('aac');
|
||||
}
|
||||
|
||||
// Only put mp3 first if mkv support is there
|
||||
// Otherwise with HLS and mp3 audio we're seeing some browsers
|
||||
// safari is lying
|
||||
if (supportsAc3(videoTestElement)) {
|
||||
|
||||
videoAudioCodecs.push('ac3');
|
||||
|
||||
var eAc3 = supportsEac3(videoTestElement);
|
||||
if (eAc3) {
|
||||
videoAudioCodecs.push('eac3');
|
||||
}
|
||||
|
||||
// This works in edge desktop, but not mobile
|
||||
// TODO: Retest this on mobile
|
||||
var supportsAc3InHls = (!browser.edge || !browser.touch || browser.edgeUwp);
|
||||
if (supportsAc3InHls) {
|
||||
hlsVideoAudioCodecs.push('ac3');
|
||||
if (eAc3) {
|
||||
hlsVideoAudioCodecs.push('eac3');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canPlayAacVideoAudio && browser.chromecast && videoAudioCodecs.indexOf('aac') === -1) {
|
||||
// prioritize this first
|
||||
videoAudioCodecs.push('aac');
|
||||
}
|
||||
|
||||
if (supportsMp3VideoAudio) {
|
||||
videoAudioCodecs.push('mp3');
|
||||
|
||||
// PS4 fails to load HLS with mp3 audio
|
||||
if (!browser.ps4) {
|
||||
|
||||
// mp3 encoder only supports 2 channels, so only make that preferred if we're only requesting 2 channels
|
||||
// Also apply it for chromecast because it no longer supports AAC 5.1
|
||||
if (physicalAudioChannels <= 2) {
|
||||
hlsVideoAudioCodecs.push('mp3');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canPlayAacVideoAudio) {
|
||||
|
||||
if (videoAudioCodecs.indexOf('aac') === -1) {
|
||||
videoAudioCodecs.push('aac');
|
||||
}
|
||||
|
||||
hlsVideoAudioCodecs.push('aac');
|
||||
}
|
||||
if (supportsMp3VideoAudio) {
|
||||
// PS4 fails to load HLS with mp3 audio
|
||||
if (!browser.ps4) {
|
||||
if (hlsVideoAudioCodecs.indexOf('mp3') === -1) {
|
||||
hlsVideoAudioCodecs.push('mp3');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsMp2VideoAudio) {
|
||||
videoAudioCodecs.push('mp2');
|
||||
}
|
||||
|
||||
var supportsDts = browser.tizen || browser.orsay || browser.web0s || options.supportsDts;
|
||||
|
||||
if (self.tizen && self.tizen.systeminfo) {
|
||||
var v = tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version');
|
||||
|
||||
// DTS audio not supported in 2018 models (Tizen 4.0)
|
||||
if (v && parseFloat(v) >= parseFloat('4.0')) {
|
||||
supportsDts = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsDts) {
|
||||
videoAudioCodecs.push('dca');
|
||||
videoAudioCodecs.push('dts');
|
||||
}
|
||||
|
||||
if (browser.tizen || browser.orsay || browser.web0s) {
|
||||
videoAudioCodecs.push('pcm_s16le');
|
||||
videoAudioCodecs.push('pcm_s24le');
|
||||
}
|
||||
|
||||
if (options.supportsTrueHd) {
|
||||
videoAudioCodecs.push('truehd');
|
||||
}
|
||||
|
||||
if (browser.tizen || browser.orsay) {
|
||||
videoAudioCodecs.push('aac_latm');
|
||||
}
|
||||
|
||||
if (canPlayAudioFormat('opus')) {
|
||||
videoAudioCodecs.push('opus');
|
||||
hlsVideoAudioCodecs.push('opus');
|
||||
webmAudioCodecs.push('opus');
|
||||
}
|
||||
|
||||
if (canPlayAudioFormat('flac')) {
|
||||
videoAudioCodecs.push('flac');
|
||||
}
|
||||
|
||||
videoAudioCodecs = videoAudioCodecs.filter(function (c) {
|
||||
return (options.disableVideoAudioCodecs || []).indexOf(c) === -1;
|
||||
});
|
||||
|
||||
hlsVideoAudioCodecs = hlsVideoAudioCodecs.filter(function (c) {
|
||||
return (options.disableHlsVideoAudioCodecs || []).indexOf(c) === -1;
|
||||
});
|
||||
|
||||
var mp4VideoCodecs = [];
|
||||
var hlsVideoCodecs = [];
|
||||
|
||||
if (canPlayH264(videoTestElement)) {
|
||||
mp4VideoCodecs.push('h264');
|
||||
hlsVideoCodecs.push('h264');
|
||||
}
|
||||
if (canPlayH265(videoTestElement, options)) {
|
||||
mp4VideoCodecs.push('h265');
|
||||
mp4VideoCodecs.push('hevc');
|
||||
|
||||
if (browser.tizen || browser.web0s) {
|
||||
hlsVideoCodecs.push('h265');
|
||||
hlsVideoCodecs.push('hevc');
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsMpeg2Video()) {
|
||||
mp4VideoCodecs.push('mpeg2video');
|
||||
}
|
||||
|
||||
if (supportsVc1()) {
|
||||
mp4VideoCodecs.push('vc1');
|
||||
}
|
||||
|
||||
if (browser.tizen || browser.orsay) {
|
||||
mp4VideoCodecs.push('msmpeg4v2');
|
||||
}
|
||||
|
||||
if (canPlayVp8) {
|
||||
mp4VideoCodecs.push('vp8');
|
||||
}
|
||||
if (canPlayVp9) {
|
||||
mp4VideoCodecs.push('vp9');
|
||||
}
|
||||
|
||||
if (canPlayVp8 || browser.tizen || browser.orsay) {
|
||||
videoAudioCodecs.push('vorbis');
|
||||
}
|
||||
|
||||
if (mp4VideoCodecs.length) {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'mp4,m4v',
|
||||
Type: 'Video',
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
AudioCodec: videoAudioCodecs.join(',')
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayMkv && mp4VideoCodecs.length) {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: 'Video',
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
AudioCodec: videoAudioCodecs.join(',')
|
||||
});
|
||||
}
|
||||
|
||||
// These are formats we can't test for but some devices will support
|
||||
['m2ts', 'wmv', 'ts', 'asf', 'avi', 'mpg', 'mpeg', 'flv', '3gp', 'mts', 'trp', 'vob', 'vro', 'mov'].map(function (container) {
|
||||
return getDirectPlayProfileForVideoContainer(container, videoAudioCodecs, videoTestElement, options);
|
||||
}).filter(function (i) {
|
||||
return i != null;
|
||||
}).forEach(function (i) {
|
||||
profile.DirectPlayProfiles.push(i);
|
||||
});
|
||||
|
||||
['opus', 'mp3', 'mp2', 'aac', 'flac', 'alac', 'webma', 'wma', 'wav', 'ogg', 'oga'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
||||
|
||||
if (audioFormat === 'mp2') {
|
||||
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'mp2,mp3',
|
||||
Type: 'Audio',
|
||||
AudioCodec: audioFormat
|
||||
});
|
||||
}
|
||||
|
||||
else if (audioFormat === 'mp3') {
|
||||
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: audioFormat,
|
||||
Type: 'Audio',
|
||||
AudioCodec: audioFormat
|
||||
});
|
||||
|
||||
} else {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: audioFormat === 'webma' ? 'webma,webm' : audioFormat,
|
||||
Type: 'Audio'
|
||||
});
|
||||
}
|
||||
|
||||
// aac also appears in the m4a container
|
||||
if (audioFormat === 'aac' || audioFormat === 'alac') {
|
||||
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'm4a',
|
||||
AudioCodec: audioFormat,
|
||||
Type: 'Audio'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (canPlayVp8) {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: 'Video',
|
||||
AudioCodec: webmAudioCodecs.join(','),
|
||||
VideoCodec: 'VP8'
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayVp9) {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: 'Video',
|
||||
AudioCodec: webmAudioCodecs.join(','),
|
||||
VideoCodec: 'VP9'
|
||||
});
|
||||
}
|
||||
|
||||
profile.TranscodingProfiles = [];
|
||||
|
||||
var hlsBreakOnNonKeyFrames = browser.iOS || browser.osx || browser.edge || !canPlayNativeHls() ? true : false;
|
||||
|
||||
if (canPlayHls() && browser.enableHlsAudio !== false) {
|
||||
profile.TranscodingProfiles.push({
|
||||
|
||||
// hlsjs, edge, and android all seem to require ts container
|
||||
Container: !canPlayNativeHls() || browser.edge || browser.android ? 'ts' : 'aac',
|
||||
Type: 'Audio',
|
||||
AudioCodec: 'aac',
|
||||
Context: 'Streaming',
|
||||
Protocol: 'hls',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
MinSegments: browser.iOS || browser.osx ? '2' : '1',
|
||||
BreakOnNonKeyFrames: hlsBreakOnNonKeyFrames
|
||||
});
|
||||
}
|
||||
|
||||
// For streaming, prioritize opus transcoding after mp3/aac. It is too problematic with random failures
|
||||
// But for static (offline sync), it will be just fine.
|
||||
// Prioritize aac higher because the encoder can accept more channels than mp3
|
||||
['aac', 'mp3', 'opus', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
||||
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: audioFormat,
|
||||
Type: 'Audio',
|
||||
AudioCodec: audioFormat,
|
||||
Context: 'Streaming',
|
||||
Protocol: 'http',
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
});
|
||||
|
||||
['opus', 'mp3', 'aac', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
||||
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: audioFormat,
|
||||
Type: 'Audio',
|
||||
AudioCodec: audioFormat,
|
||||
Context: 'Static',
|
||||
Protocol: 'http',
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
});
|
||||
|
||||
if (canPlayMkv && !browser.tizen && !browser.orsay && options.enableMkvProgressive !== false) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: 'Video',
|
||||
AudioCodec: videoAudioCodecs.join(','),
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
Context: 'Streaming',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
CopyTimestamps: true
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayMkv) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: 'Video',
|
||||
AudioCodec: videoAudioCodecs.join(','),
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
Context: 'Static',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
CopyTimestamps: true
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayHls() && options.enableHls !== false) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'ts',
|
||||
Type: 'Video',
|
||||
AudioCodec: hlsVideoAudioCodecs.join(','),
|
||||
VideoCodec: hlsVideoCodecs.join(','),
|
||||
Context: 'Streaming',
|
||||
Protocol: 'hls',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
MinSegments: browser.iOS || browser.osx ? '2' : '1',
|
||||
BreakOnNonKeyFrames: hlsBreakOnNonKeyFrames
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayVp8) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: 'Video',
|
||||
AudioCodec: 'vorbis',
|
||||
VideoCodec: 'vpx',
|
||||
Context: 'Streaming',
|
||||
Protocol: 'http',
|
||||
// If audio transcoding is needed, limit channels to number of physical audio channels
|
||||
// Trying to transcode to 5 channels when there are only 2 speakers generally does not sound good
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
}
|
||||
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'mp4',
|
||||
Type: 'Video',
|
||||
AudioCodec: videoAudioCodecs.join(','),
|
||||
VideoCodec: 'h264',
|
||||
Context: 'Static',
|
||||
Protocol: 'http'
|
||||
});
|
||||
|
||||
profile.ContainerProfiles = [];
|
||||
|
||||
profile.CodecProfiles = [];
|
||||
|
||||
var supportsSecondaryAudio = browser.tizen || browser.orsay || videoTestElement.audioTracks;
|
||||
|
||||
var aacCodecProfileConditions = [];
|
||||
|
||||
// Handle he-aac not supported
|
||||
if (!videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"').replace(/no/, '')) {
|
||||
// TODO: This needs to become part of the stream url in order to prevent stream copy
|
||||
aacCodecProfileConditions.push({
|
||||
Condition: 'NotEquals',
|
||||
Property: 'AudioProfile',
|
||||
Value: 'HE-AAC'
|
||||
});
|
||||
}
|
||||
|
||||
if (!supportsSecondaryAudio) {
|
||||
aacCodecProfileConditions.push({
|
||||
Condition: 'Equals',
|
||||
Property: 'IsSecondaryAudio',
|
||||
Value: 'false',
|
||||
IsRequired: false
|
||||
});
|
||||
}
|
||||
|
||||
if (browser.chromecast) {
|
||||
aacCodecProfileConditions.push({
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'AudioChannels',
|
||||
Value: '2',
|
||||
IsRequired: true
|
||||
});
|
||||
}
|
||||
|
||||
if (aacCodecProfileConditions.length) {
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'VideoAudio',
|
||||
Codec: 'aac',
|
||||
Conditions: aacCodecProfileConditions
|
||||
});
|
||||
}
|
||||
|
||||
if (!supportsSecondaryAudio) {
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'VideoAudio',
|
||||
Conditions: [
|
||||
{
|
||||
Condition: 'Equals',
|
||||
Property: 'IsSecondaryAudio',
|
||||
Value: 'false',
|
||||
IsRequired: false
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
var maxH264Level = browser.chromecast ? 42 : 51;
|
||||
var h264Profiles = 'high|main|baseline|constrained baseline';
|
||||
|
||||
if (maxH264Level >= 51 && browser.chrome && !browser.osx) {
|
||||
h264Profiles += '|high 10';
|
||||
}
|
||||
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'Video',
|
||||
Codec: 'h264',
|
||||
Conditions: [
|
||||
{
|
||||
Condition: 'NotEquals',
|
||||
Property: 'IsAnamorphic',
|
||||
Value: 'true',
|
||||
IsRequired: false
|
||||
},
|
||||
{
|
||||
Condition: 'EqualsAny',
|
||||
Property: 'VideoProfile',
|
||||
Value: h264Profiles
|
||||
},
|
||||
{
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'VideoLevel',
|
||||
Value: maxH264Level.toString()
|
||||
}]
|
||||
});
|
||||
|
||||
if (!browser.edgeUwp && !browser.tizen && !browser.orsay && !browser.web0s) {
|
||||
//profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
||||
// Condition: 'NotEquals',
|
||||
// Property: 'IsAVC',
|
||||
// Value: 'false',
|
||||
// IsRequired: false
|
||||
//});
|
||||
|
||||
//profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
||||
// Condition: 'NotEquals',
|
||||
// Property: 'IsInterlaced',
|
||||
// Value: 'true',
|
||||
// IsRequired: false
|
||||
//});
|
||||
}
|
||||
|
||||
if (maxVideoWidth) {
|
||||
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'Width',
|
||||
Value: maxVideoWidth.toString(),
|
||||
IsRequired: false
|
||||
});
|
||||
}
|
||||
|
||||
var globalMaxVideoBitrate = (getGlobalMaxVideoBitrate() || '').toString();
|
||||
|
||||
var h264MaxVideoBitrate = globalMaxVideoBitrate;
|
||||
|
||||
if (h264MaxVideoBitrate) {
|
||||
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'VideoBitrate',
|
||||
Value: h264MaxVideoBitrate,
|
||||
IsRequired: true
|
||||
});
|
||||
}
|
||||
|
||||
var globalVideoConditions = [];
|
||||
|
||||
if (globalMaxVideoBitrate) {
|
||||
globalVideoConditions.push({
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'VideoBitrate',
|
||||
Value: globalMaxVideoBitrate
|
||||
});
|
||||
}
|
||||
|
||||
if (maxVideoWidth) {
|
||||
globalVideoConditions.push({
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'Width',
|
||||
Value: maxVideoWidth.toString(),
|
||||
IsRequired: false
|
||||
});
|
||||
}
|
||||
|
||||
if (globalVideoConditions.length) {
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'Video',
|
||||
Conditions: globalVideoConditions
|
||||
});
|
||||
}
|
||||
|
||||
if (browser.chromecast) {
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'Audio',
|
||||
Codec: 'flac',
|
||||
Conditions: [
|
||||
{
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'AudioSampleRate',
|
||||
Value: '96000'
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
// Subtitle profiles
|
||||
// External vtt or burn in
|
||||
profile.SubtitleProfiles = [];
|
||||
if (supportsTextTracks()) {
|
||||
|
||||
profile.SubtitleProfiles.push({
|
||||
Format: 'vtt',
|
||||
Method: 'External'
|
||||
});
|
||||
}
|
||||
|
||||
profile.ResponseProfiles = [];
|
||||
|
||||
profile.ResponseProfiles.push({
|
||||
Type: 'Video',
|
||||
Container: 'm4v',
|
||||
MimeType: 'video/mp4'
|
||||
});
|
||||
|
||||
return profile;
|
||||
};
|
||||
});
|
|
@ -1,282 +0,0 @@
|
|||
define(['globalize'], function (globalize) {
|
||||
'use strict';
|
||||
|
||||
function parseISO8601Date(s, toLocal) {
|
||||
|
||||
// parenthese matches:
|
||||
// year month day hours minutes seconds
|
||||
// dotmilliseconds
|
||||
// tzstring plusminus hours minutes
|
||||
var re = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(Z|([+-])(\d{2}):(\d{2}))?/;
|
||||
|
||||
var d = s.match(re);
|
||||
|
||||
// "2010-12-07T11:00:00.000-09:00" parses to:
|
||||
// ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
|
||||
// "00", "00", ".000", "-09:00", "-", "09", "00"]
|
||||
// "2010-12-07T11:00:00.000Z" parses to:
|
||||
// ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
|
||||
// "00", "00", ".000", "Z", undefined, undefined, undefined]
|
||||
|
||||
if (!d) {
|
||||
|
||||
throw "Couldn't parse ISO 8601 date string '" + s + "'";
|
||||
}
|
||||
|
||||
// parse strings, leading zeros into proper ints
|
||||
var a = [1, 2, 3, 4, 5, 6, 10, 11];
|
||||
for (var i in a) {
|
||||
d[a[i]] = parseInt(d[a[i]], 10);
|
||||
}
|
||||
d[7] = parseFloat(d[7]);
|
||||
|
||||
// Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
|
||||
// note that month is 0-11, not 1-12
|
||||
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC
|
||||
var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
|
||||
|
||||
// if there are milliseconds, add them
|
||||
if (d[7] > 0) {
|
||||
ms += Math.round(d[7] * 1000);
|
||||
}
|
||||
|
||||
// if there's a timezone, calculate it
|
||||
if (d[8] !== "Z" && d[10]) {
|
||||
var offset = d[10] * 60 * 60 * 1000;
|
||||
if (d[11]) {
|
||||
offset += d[11] * 60 * 1000;
|
||||
}
|
||||
if (d[9] === "-") {
|
||||
ms -= offset;
|
||||
} else {
|
||||
ms += offset;
|
||||
}
|
||||
} else if (toLocal === false) {
|
||||
ms += new Date().getTimezoneOffset() * 60000;
|
||||
}
|
||||
|
||||
return new Date(ms);
|
||||
}
|
||||
|
||||
function getDisplayRunningTime(ticks) {
|
||||
var ticksPerHour = 36000000000;
|
||||
var ticksPerMinute = 600000000;
|
||||
var ticksPerSecond = 10000000;
|
||||
|
||||
var parts = [];
|
||||
|
||||
var hours = ticks / ticksPerHour;
|
||||
hours = Math.floor(hours);
|
||||
|
||||
if (hours) {
|
||||
parts.push(hours);
|
||||
}
|
||||
|
||||
ticks -= (hours * ticksPerHour);
|
||||
|
||||
var minutes = ticks / ticksPerMinute;
|
||||
minutes = Math.floor(minutes);
|
||||
|
||||
ticks -= (minutes * ticksPerMinute);
|
||||
|
||||
if (minutes < 10 && hours) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
parts.push(minutes);
|
||||
|
||||
var seconds = ticks / ticksPerSecond;
|
||||
seconds = Math.floor(seconds);
|
||||
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
parts.push(seconds);
|
||||
|
||||
return parts.join(':');
|
||||
}
|
||||
|
||||
var toLocaleTimeStringSupportsLocales = function () {
|
||||
try {
|
||||
new Date().toLocaleTimeString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
function getOptionList(options) {
|
||||
|
||||
var list = [];
|
||||
|
||||
for (var i in options) {
|
||||
list.push({
|
||||
name: i,
|
||||
value: options[i]
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function toLocaleString(date, options) {
|
||||
|
||||
if (!date) {
|
||||
throw new Error('date cannot be null');
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (toLocaleTimeStringSupportsLocales) {
|
||||
|
||||
var currentLocale = globalize.getCurrentDateTimeLocale();
|
||||
|
||||
if (currentLocale) {
|
||||
return date.toLocaleString(currentLocale, options);
|
||||
}
|
||||
}
|
||||
|
||||
return date.toLocaleString();
|
||||
}
|
||||
|
||||
function toLocaleDateString(date, options) {
|
||||
|
||||
if (!date) {
|
||||
throw new Error('date cannot be null');
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (toLocaleTimeStringSupportsLocales) {
|
||||
|
||||
var currentLocale = globalize.getCurrentDateTimeLocale();
|
||||
|
||||
if (currentLocale) {
|
||||
return date.toLocaleDateString(currentLocale, options);
|
||||
}
|
||||
}
|
||||
|
||||
// This is essentially a hard-coded polyfill
|
||||
var optionList = getOptionList(options);
|
||||
if (optionList.length === 1 && optionList[0].name === 'weekday') {
|
||||
var weekday = [];
|
||||
weekday[0] = "Sun";
|
||||
weekday[1] = "Mon";
|
||||
weekday[2] = "Tue";
|
||||
weekday[3] = "Wed";
|
||||
weekday[4] = "Thu";
|
||||
weekday[5] = "Fri";
|
||||
weekday[6] = "Sat";
|
||||
return weekday[date.getDay()];
|
||||
}
|
||||
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
|
||||
function toLocaleTimeString(date, options) {
|
||||
|
||||
if (!date) {
|
||||
throw new Error('date cannot be null');
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (toLocaleTimeStringSupportsLocales) {
|
||||
|
||||
var currentLocale = globalize.getCurrentDateTimeLocale();
|
||||
|
||||
if (currentLocale) {
|
||||
return date.toLocaleTimeString(currentLocale, options);
|
||||
}
|
||||
}
|
||||
|
||||
return date.toLocaleTimeString();
|
||||
}
|
||||
|
||||
function getDisplayTime(date) {
|
||||
|
||||
if (!date) {
|
||||
throw new Error('date cannot be null');
|
||||
}
|
||||
|
||||
if ((typeof date).toString().toLowerCase() === 'string') {
|
||||
try {
|
||||
|
||||
date = parseISO8601Date(date, true);
|
||||
|
||||
} catch (err) {
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
if (toLocaleTimeStringSupportsLocales) {
|
||||
return toLocaleTimeString(date, {
|
||||
|
||||
hour: 'numeric',
|
||||
minute: '2-digit'
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var time = toLocaleTimeString(date);
|
||||
|
||||
var timeLower = time.toLowerCase();
|
||||
|
||||
if (timeLower.indexOf('am') !== -1 || timeLower.indexOf('pm') !== -1) {
|
||||
|
||||
time = timeLower;
|
||||
var hour = date.getHours() % 12;
|
||||
var suffix = date.getHours() > 11 ? 'pm' : 'am';
|
||||
if (!hour) {
|
||||
hour = 12;
|
||||
}
|
||||
var minutes = date.getMinutes();
|
||||
|
||||
if (minutes < 10) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
|
||||
minutes = ':' + minutes;
|
||||
time = hour + minutes + suffix;
|
||||
} else {
|
||||
|
||||
var timeParts = time.split(':');
|
||||
|
||||
// Trim off seconds
|
||||
if (timeParts.length > 2) {
|
||||
|
||||
// setting to 2 also handles '21:00:28 GMT+9:30'
|
||||
timeParts.length = 2;
|
||||
time = timeParts.join(':');
|
||||
}
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
function isRelativeDay(date, offsetInDays) {
|
||||
|
||||
if (!date) {
|
||||
throw new Error('date cannot be null');
|
||||
}
|
||||
|
||||
var yesterday = new Date();
|
||||
var day = yesterday.getDate() + offsetInDays;
|
||||
|
||||
yesterday.setDate(day); // automatically adjusts month/year appropriately
|
||||
|
||||
return date.getFullYear() === yesterday.getFullYear() && date.getMonth() === yesterday.getMonth() && date.getDate() === day;
|
||||
}
|
||||
|
||||
return {
|
||||
parseISO8601Date: parseISO8601Date,
|
||||
getDisplayRunningTime: getDisplayRunningTime,
|
||||
toLocaleDateString: toLocaleDateString,
|
||||
toLocaleString: toLocaleString,
|
||||
getDisplayTime: getDisplayTime,
|
||||
isRelativeDay: isRelativeDay,
|
||||
toLocaleTimeString: toLocaleTimeString,
|
||||
supportsLocalization: function () {
|
||||
return toLocaleTimeStringSupportsLocales;
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,274 +0,0 @@
|
|||
define(['connectionManager', 'userSettings', 'events'], function (connectionManager, userSettings, events) {
|
||||
'use strict';
|
||||
var fallbackCulture = 'en-us';
|
||||
|
||||
var allTranslations = {};
|
||||
var currentCulture;
|
||||
var currentDateTimeCulture;
|
||||
|
||||
function getCurrentLocale() {
|
||||
return currentCulture;
|
||||
}
|
||||
|
||||
function getCurrentDateTimeLocale() {
|
||||
return currentDateTimeCulture;
|
||||
}
|
||||
|
||||
function getDefaultLanguage() {
|
||||
var culture = document.documentElement.getAttribute('data-culture');
|
||||
if (culture) {
|
||||
return culture;
|
||||
}
|
||||
|
||||
if (navigator.language) {
|
||||
return navigator.language;
|
||||
}
|
||||
if (navigator.userLanguage) {
|
||||
return navigator.userLanguage;
|
||||
}
|
||||
if (navigator.languages && navigator.languages.length) {
|
||||
return navigator.languages[0];
|
||||
}
|
||||
|
||||
return fallbackCulture;
|
||||
}
|
||||
|
||||
function updateCurrentCulture() {
|
||||
var culture;
|
||||
try {
|
||||
culture = userSettings.language();
|
||||
} catch (err) {
|
||||
console.log('no language set in user settings');
|
||||
}
|
||||
culture = culture || getDefaultLanguage();
|
||||
|
||||
currentCulture = normalizeLocaleName(culture);
|
||||
|
||||
var dateTimeCulture;
|
||||
try {
|
||||
dateTimeCulture = userSettings.dateTimeLocale();
|
||||
} catch (err) {
|
||||
console.log('no date format set in user settings');
|
||||
}
|
||||
|
||||
if (dateTimeCulture) {
|
||||
currentDateTimeCulture = normalizeLocaleName(dateTimeCulture);
|
||||
} else {
|
||||
currentDateTimeCulture = currentCulture;
|
||||
}
|
||||
ensureTranslations(currentCulture);
|
||||
}
|
||||
|
||||
function ensureTranslations(culture) {
|
||||
for (var i in allTranslations) {
|
||||
ensureTranslation(allTranslations[i], culture);
|
||||
}
|
||||
if (culture !== fallbackCulture) {
|
||||
for (var i in allTranslations) {
|
||||
ensureTranslation(allTranslations[i], fallbackCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ensureTranslation(translationInfo, culture) {
|
||||
if (translationInfo.dictionaries[culture]) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return loadTranslation(translationInfo.translations, culture).then(function (dictionary) {
|
||||
translationInfo.dictionaries[culture] = dictionary;
|
||||
});
|
||||
}
|
||||
|
||||
function normalizeLocaleName(culture) {
|
||||
// TODO remove normalizations
|
||||
culture = culture.replace('_', '-');
|
||||
|
||||
// convert de-DE to de
|
||||
var parts = culture.split('-');
|
||||
if (parts.length === 2) {
|
||||
if (parts[0].toLowerCase() === parts[1].toLowerCase()) {
|
||||
culture = parts[0].toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
var lower = culture.toLowerCase();
|
||||
if (lower === 'ca-es') {
|
||||
return 'ca';
|
||||
}
|
||||
|
||||
// normalize Swedish
|
||||
if (lower === 'sv-se') {
|
||||
return 'sv';
|
||||
}
|
||||
|
||||
return lower;
|
||||
}
|
||||
|
||||
function getDictionary(module, locale) {
|
||||
if (!module) {
|
||||
module = defaultModule();
|
||||
}
|
||||
|
||||
var translations = allTranslations[module];
|
||||
if (!translations) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return translations.dictionaries[locale];
|
||||
}
|
||||
|
||||
function register(options) {
|
||||
allTranslations[options.name] = {
|
||||
translations: options.strings || options.translations,
|
||||
dictionaries: {}
|
||||
};
|
||||
}
|
||||
|
||||
function loadStrings(options) {
|
||||
var locale = getCurrentLocale();
|
||||
var promises = [];
|
||||
var optionsName;
|
||||
if (typeof options === 'string') {
|
||||
optionsName = options;
|
||||
} else {
|
||||
optionsName = options.name;
|
||||
register(options);
|
||||
}
|
||||
promises.push(ensureTranslation(allTranslations[optionsName], locale));
|
||||
promises.push(ensureTranslation(allTranslations[optionsName], fallbackCulture));
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
var cacheParam = new Date().getTime();
|
||||
function loadTranslation(translations, lang) {
|
||||
lang = normalizeLocaleName(lang);
|
||||
var filtered = translations.filter(function (t) {
|
||||
return normalizeLocaleName(t.lang) === lang;
|
||||
});
|
||||
|
||||
if (!filtered.length) {
|
||||
filtered = translations.filter(function (t) {
|
||||
return normalizeLocaleName(t.lang) === fallbackCulture;
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!filtered.length) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
var url = filtered[0].path;
|
||||
|
||||
url += url.indexOf('?') === -1 ? '?' : '&';
|
||||
url += 'v=' + cacheParam;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
xhr.onload = function (e) {
|
||||
if (this.status < 400) {
|
||||
resolve(JSON.parse(this.response));
|
||||
} else {
|
||||
resolve({});
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function () {
|
||||
resolve({});
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function translateKey(key) {
|
||||
var parts = key.split('#');
|
||||
var module;
|
||||
|
||||
if (parts.length > 1) {
|
||||
module = parts[0];
|
||||
key = parts[1];
|
||||
}
|
||||
|
||||
return translateKeyFromModule(key, module);
|
||||
}
|
||||
|
||||
function translateKeyFromModule(key, module) {
|
||||
var dictionary = getDictionary(module, getCurrentLocale());
|
||||
if (!dictionary || !dictionary[key]) {
|
||||
dictionary = getDictionary(module, fallbackCulture);
|
||||
}
|
||||
if (!dictionary) {
|
||||
return key;
|
||||
}
|
||||
return dictionary[key] || key;
|
||||
}
|
||||
|
||||
function replaceAll(str, find, replace) {
|
||||
return str.split(find).join(replace);
|
||||
}
|
||||
|
||||
function translate(key) {
|
||||
var val = translateKey(key);
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
val = replaceAll(val, '{' + (i - 1) + '}', arguments[i]);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function translateHtml(html, module) {
|
||||
if (!module) {
|
||||
module = defaultModule();
|
||||
}
|
||||
if (!module) {
|
||||
throw new Error('module cannot be null or empty');
|
||||
}
|
||||
|
||||
var startIndex = html.indexOf('${');
|
||||
if (startIndex === -1) {
|
||||
return html;
|
||||
}
|
||||
|
||||
startIndex += 2;
|
||||
var endIndex = html.indexOf('}', startIndex);
|
||||
if (endIndex === -1) {
|
||||
return html;
|
||||
}
|
||||
|
||||
var key = html.substring(startIndex, endIndex);
|
||||
var val = translateKeyFromModule(key, module);
|
||||
|
||||
html = html.replace('${' + key + '}', val);
|
||||
return translateHtml(html, module);
|
||||
}
|
||||
|
||||
var _defaultModule;
|
||||
function defaultModule(val) {
|
||||
if (val) {
|
||||
_defaultModule = val;
|
||||
}
|
||||
return _defaultModule;
|
||||
}
|
||||
|
||||
updateCurrentCulture();
|
||||
|
||||
events.on(connectionManager, 'localusersignedin', updateCurrentCulture);
|
||||
events.on(userSettings, 'change', function (e, name) {
|
||||
if (name === 'language' || name === 'datetimelocale') {
|
||||
updateCurrentCulture();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
getString: translate,
|
||||
translate: translate,
|
||||
translateDocument: translateHtml,
|
||||
translateHtml: translateHtml,
|
||||
loadStrings: loadStrings,
|
||||
defaultModule: defaultModule,
|
||||
getCurrentLocale: getCurrentLocale,
|
||||
getCurrentDateTimeLocale: getCurrentDateTimeLocale,
|
||||
register: register
|
||||
};
|
||||
});
|
|
@ -1,241 +0,0 @@
|
|||
define(['playbackManager', 'focusManager', 'appRouter', 'dom'], function (playbackManager, focusManager, appRouter, dom) {
|
||||
'use strict';
|
||||
|
||||
var lastInputTime = new Date().getTime();
|
||||
|
||||
function notify() {
|
||||
lastInputTime = new Date().getTime();
|
||||
handleCommand('unknown');
|
||||
}
|
||||
|
||||
function notifyMouseMove() {
|
||||
lastInputTime = new Date().getTime();
|
||||
}
|
||||
|
||||
function idleTime() {
|
||||
return new Date().getTime() - lastInputTime;
|
||||
}
|
||||
|
||||
function select(sourceElement) {
|
||||
sourceElement.click();
|
||||
}
|
||||
|
||||
var eventListenerCount = 0;
|
||||
function on(scope, fn) {
|
||||
if (eventListenerCount) {
|
||||
eventListenerCount++;
|
||||
}
|
||||
dom.addEventListener(scope, 'command', fn, {});
|
||||
}
|
||||
|
||||
function off(scope, fn) {
|
||||
if (eventListenerCount) {
|
||||
eventListenerCount--;
|
||||
}
|
||||
dom.removeEventListener(scope, 'command', fn, {});
|
||||
}
|
||||
|
||||
var commandTimes = {};
|
||||
|
||||
function checkCommandTime(command) {
|
||||
|
||||
var last = commandTimes[command] || 0;
|
||||
var now = new Date().getTime();
|
||||
|
||||
if ((now - last) < 1000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
commandTimes[command] = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleCommand(name, options) {
|
||||
|
||||
lastInputTime = new Date().getTime();
|
||||
|
||||
var sourceElement = (options ? options.sourceElement : null);
|
||||
|
||||
if (sourceElement) {
|
||||
sourceElement = focusManager.focusableParent(sourceElement);
|
||||
}
|
||||
|
||||
sourceElement = sourceElement || document.activeElement || window;
|
||||
|
||||
if (eventListenerCount) {
|
||||
var customEvent = new CustomEvent("command", {
|
||||
detail: {
|
||||
command: name
|
||||
},
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
|
||||
var eventResult = sourceElement.dispatchEvent(customEvent);
|
||||
if (!eventResult) {
|
||||
// event cancelled
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case 'up':
|
||||
focusManager.moveUp(sourceElement);
|
||||
break;
|
||||
case 'down':
|
||||
focusManager.moveDown(sourceElement);
|
||||
break;
|
||||
case 'left':
|
||||
focusManager.moveLeft(sourceElement);
|
||||
break;
|
||||
case 'right':
|
||||
focusManager.moveRight(sourceElement);
|
||||
break;
|
||||
case 'home':
|
||||
appRouter.goHome();
|
||||
break;
|
||||
case 'settings':
|
||||
appRouter.showSettings();
|
||||
break;
|
||||
case 'back':
|
||||
appRouter.back();
|
||||
break;
|
||||
case 'forward':
|
||||
break;
|
||||
case 'select':
|
||||
select(sourceElement);
|
||||
break;
|
||||
case 'pageup':
|
||||
break;
|
||||
case 'pagedown':
|
||||
break;
|
||||
case 'end':
|
||||
break;
|
||||
case 'menu':
|
||||
break;
|
||||
case 'info':
|
||||
break;
|
||||
case 'nextchapter':
|
||||
playbackManager.nextChapter();
|
||||
break;
|
||||
case 'next':
|
||||
case 'nexttrack':
|
||||
playbackManager.nextTrack();
|
||||
break;
|
||||
case 'previous':
|
||||
case 'previoustrack':
|
||||
playbackManager.previousTrack();
|
||||
break;
|
||||
case 'previouschapter':
|
||||
playbackManager.previousChapter();
|
||||
break;
|
||||
case 'guide':
|
||||
appRouter.showGuide();
|
||||
break;
|
||||
case 'recordedtv':
|
||||
appRouter.showRecordedTV();
|
||||
break;
|
||||
case 'record':
|
||||
break;
|
||||
case 'livetv':
|
||||
appRouter.showLiveTV();
|
||||
break;
|
||||
case 'mute':
|
||||
playbackManager.setMute(true);
|
||||
break;
|
||||
case 'unmute':
|
||||
playbackManager.setMute(false);
|
||||
break;
|
||||
case 'togglemute':
|
||||
playbackManager.toggleMute();
|
||||
break;
|
||||
case 'channelup':
|
||||
playbackManager.channelUp();
|
||||
break;
|
||||
case 'channeldown':
|
||||
playbackManager.channelDown();
|
||||
break;
|
||||
case 'volumedown':
|
||||
playbackManager.volumeDown();
|
||||
break;
|
||||
case 'volumeup':
|
||||
playbackManager.volumeUp();
|
||||
break;
|
||||
case 'play':
|
||||
playbackManager.unpause();
|
||||
break;
|
||||
case 'pause':
|
||||
playbackManager.pause();
|
||||
break;
|
||||
case 'playpause':
|
||||
playbackManager.playPause();
|
||||
break;
|
||||
case 'stop':
|
||||
if (checkCommandTime('stop')) {
|
||||
playbackManager.stop();
|
||||
}
|
||||
break;
|
||||
case 'changezoom':
|
||||
playbackManager.toggleAspectRatio();
|
||||
break;
|
||||
case 'changeaudiotrack':
|
||||
playbackManager.changeAudioStream();
|
||||
break;
|
||||
case 'changesubtitletrack':
|
||||
playbackManager.changeSubtitleStream();
|
||||
break;
|
||||
case 'search':
|
||||
appRouter.showSearch();
|
||||
break;
|
||||
case 'favorites':
|
||||
appRouter.showFavorites();
|
||||
break;
|
||||
case 'fastforward':
|
||||
playbackManager.fastForward();
|
||||
break;
|
||||
case 'rewind':
|
||||
playbackManager.rewind();
|
||||
break;
|
||||
case 'togglefullscreen':
|
||||
playbackManager.toggleFullscreen();
|
||||
break;
|
||||
case 'disabledisplaymirror':
|
||||
playbackManager.enableDisplayMirroring(false);
|
||||
break;
|
||||
case 'enabledisplaymirror':
|
||||
playbackManager.enableDisplayMirroring(true);
|
||||
break;
|
||||
case 'toggledisplaymirror':
|
||||
playbackManager.toggleDisplayMirroring();
|
||||
break;
|
||||
case 'nowplaying':
|
||||
appRouter.showNowPlaying();
|
||||
break;
|
||||
case 'repeatnone':
|
||||
playbackManager.setRepeatMode('RepeatNone');
|
||||
break;
|
||||
case 'repeatall':
|
||||
playbackManager.setRepeatMode('RepeatAll');
|
||||
break;
|
||||
case 'repeatone':
|
||||
playbackManager.setRepeatMode('RepeatOne');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dom.addEventListener(document, 'click', notify, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
return {
|
||||
trigger: handleCommand,
|
||||
handle: handleCommand,
|
||||
notify: notify,
|
||||
notifyMouseMove: notifyMouseMove,
|
||||
idleTime: idleTime,
|
||||
on: on,
|
||||
off: off
|
||||
};
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
define(['inputmanager', 'focusManager'], function(inputmanager, focusManager) {
|
||||
define(['inputManager', 'focusManager'], function(inputManager, focusManager) {
|
||||
'use strict';
|
||||
|
||||
console.log("keyboardnavigation");
|
||||
|
@ -9,16 +9,16 @@ define(['inputmanager', 'focusManager'], function(inputmanager, focusManager) {
|
|||
|
||||
switch (e.keyCode) {
|
||||
case 37: // ArrowLeft
|
||||
inputmanager.handle('left');
|
||||
inputManager.handle('left');
|
||||
break;
|
||||
case 38: // ArrowUp
|
||||
inputmanager.handle('up');
|
||||
inputManager.handle('up');
|
||||
break;
|
||||
case 39: // ArrowRight
|
||||
inputmanager.handle('right');
|
||||
inputManager.handle('right');
|
||||
break;
|
||||
case 40: // ArrowDown
|
||||
inputmanager.handle('down');
|
||||
inputManager.handle('down');
|
||||
break;
|
||||
default:
|
||||
capture = false;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
.scrollX {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.smoothScrollX {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.hiddenScrollX, .layout-tv .scrollX {
|
||||
-ms-overflow-style: none;
|
||||
/* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
|
||||
/*overflow: -moz-scrollbars-none;*/
|
||||
}
|
||||
|
||||
.hiddenScrollX-forced {
|
||||
overflow: -moz-scrollbars-none;
|
||||
}
|
||||
|
||||
.hiddenScrollX::-webkit-scrollbar, .layout-tv .scrollX::-webkit-scrollbar {
|
||||
height: 0 !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scrollY {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.smoothScrollY {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-x: hidden;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.hiddenScrollY, .layout-tv .smoothScrollY {
|
||||
-ms-overflow-style: none;
|
||||
/* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
|
||||
/*overflow: -moz-scrollbars-none;*/
|
||||
}
|
||||
|
||||
.hiddenScrollY-forced {
|
||||
overflow: -moz-scrollbars-none;
|
||||
}
|
||||
|
||||
.hiddenScrollY::-webkit-scrollbar, .layout-tv .smoothScrollY::-webkit-scrollbar, .layout-tv .scrollY::-webkit-scrollbar {
|
||||
width: 0 !important;
|
||||
display: none;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'dom'], function (inputmanager, focusManager, browser, layoutManager, events, dom) {
|
||||
define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'dom'], function (inputManager, focusManager, browser, layoutManager, events, dom) {
|
||||
'use strict';
|
||||
|
||||
var self = {};
|
||||
|
@ -12,7 +12,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd
|
|||
|
||||
function notifyApp() {
|
||||
|
||||
inputmanager.notifyMouseMove();
|
||||
inputManager.notifyMouseMove();
|
||||
}
|
||||
|
||||
function removeIdleClasses() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'loading', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputmanager, connectionManager, layoutManager, focusManager, browser, appHost, loading) {
|
||||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'loading', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, loading) {
|
||||
'use strict';
|
||||
|
||||
function getImageUrl(item, options, apiClient) {
|
||||
|
@ -189,7 +189,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
stopInterval();
|
||||
});
|
||||
|
||||
inputmanager.on(window, onInputCommand);
|
||||
inputManager.on(window, onInputCommand);
|
||||
document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||
|
||||
dlg.addEventListener('close', onDialogClosed);
|
||||
|
@ -372,7 +372,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
swiperInstance = null;
|
||||
}
|
||||
|
||||
inputmanager.off(window, onInputCommand);
|
||||
inputManager.off(window, onInputCommand);
|
||||
document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ define(["browser", "dom", "layoutManager", "css!components/viewManager/viewConta
|
|||
|
||||
|
||||
if (isPluginpage) {
|
||||
require(["legacy/dashboard"]);
|
||||
require(["legacyDashboard"]);
|
||||
}
|
||||
|
||||
if (newViewInfo.hasjQuerySelect) {
|
||||
require(["legacy/selectmenu"]);
|
||||
require(["legacySelectMenu"]);
|
||||
}
|
||||
|
||||
if (newViewInfo.hasjQueryChecked) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue