mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
use shared play menu
This commit is contained in:
parent
f3cde16786
commit
83adc06fa2
15 changed files with 222 additions and 164 deletions
|
@ -15,12 +15,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.4.93",
|
||||
"_release": "1.4.93",
|
||||
"version": "1.4.94",
|
||||
"_release": "1.4.94",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.4.93",
|
||||
"commit": "8b6b445547b02a088fbafed08120ed87c4004df5"
|
||||
"tag": "1.4.94",
|
||||
"commit": "1914cf851948d6f4f5e730c5e831e5e604fe3c9e"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.0",
|
||||
|
|
|
@ -2,19 +2,6 @@
|
|||
|
||||
var ItemsContainerProtoType = Object.create(HTMLDivElement.prototype);
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function parentWithAttribute(elem, name) {
|
||||
|
||||
while (!elem.getAttribute(name)) {
|
||||
|
@ -28,75 +15,11 @@
|
|||
return elem;
|
||||
}
|
||||
|
||||
function getItem(button) {
|
||||
|
||||
button = parentWithAttribute(button, 'data-id');
|
||||
var serverId = button.getAttribute('data-serverid');
|
||||
var id = button.getAttribute('data-id');
|
||||
var type = button.getAttribute('data-type');
|
||||
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
|
||||
return apiClient.getItem(apiClient.getCurrentUserId(), id);
|
||||
}
|
||||
|
||||
function showContextMenu(button, itemsContainer) {
|
||||
|
||||
getItem(button).then(function (item) {
|
||||
|
||||
var playlistId = itemsContainer.getAttribute('data-playlistid');
|
||||
var collectionId = itemsContainer.getAttribute('data-collectionid');
|
||||
|
||||
if (playlistId) {
|
||||
var elem = parentWithAttribute(button, 'data-playlistitemid');
|
||||
item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null;
|
||||
}
|
||||
|
||||
require(['itemContextMenu'], function (itemContextMenu) {
|
||||
itemContextMenu.show({
|
||||
positionTo: button,
|
||||
item: item,
|
||||
play: true,
|
||||
queue: true,
|
||||
playAllFromHere: !item.IsFolder,
|
||||
queueAllFromHere: !item.IsFolder,
|
||||
identify: false,
|
||||
playlistId: playlistId,
|
||||
collectionId: collectionId
|
||||
|
||||
}).then(function (result) {
|
||||
|
||||
if (result.command == 'playallfromhere' || result.command == 'queueallfromhere') {
|
||||
itemShortcuts.execute(button, result.command);
|
||||
}
|
||||
else if (result.command == 'removefromplaylist' || result.command == 'removefromcollection') {
|
||||
|
||||
itemsContainer.dispatchEvent(new CustomEvent('needsrefresh', {
|
||||
detail: {},
|
||||
cancelable: false,
|
||||
bubbles: true
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
|
||||
var itemsContainer = this;
|
||||
var target = e.target;
|
||||
|
||||
var menuButton = parentWithClass(target, 'menuButton');
|
||||
if (menuButton) {
|
||||
var card = parentWithAttribute(target, 'data-id');
|
||||
if (card) {
|
||||
showContextMenu(card, target);
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
itemShortcuts.onClick.call(this, e);
|
||||
}
|
||||
|
||||
|
@ -107,28 +30,6 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function showContextMenu(card, target, options) {
|
||||
|
||||
var itemId = card.getAttribute('data-id');
|
||||
var serverId = card.getAttribute('data-serverid');
|
||||
var type = card.getAttribute('data-type');
|
||||
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
|
||||
var promise = type == 'Timer' ? apiClient.getLiveTvTimer(itemId) : apiClient.getItem(apiClient.getCurrentUserId(), itemId);
|
||||
|
||||
promise.then(function (item) {
|
||||
|
||||
require(['itemContextMenu'], function (itemContextMenu) {
|
||||
|
||||
itemContextMenu.show(Object.assign(options || {}, {
|
||||
item: item,
|
||||
positionTo: target
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onContextMenu(e) {
|
||||
|
||||
var itemsContainer = this;
|
||||
|
@ -143,8 +44,10 @@
|
|||
// showContextMenu(card, {});
|
||||
//}
|
||||
|
||||
showContextMenu(card, target, {
|
||||
identify: false
|
||||
itemShortcuts.showContextMenu(card, {
|
||||
identify: false,
|
||||
positionTo: target,
|
||||
itemsContainer: itemsContainer
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
}
|
||||
|
||||
if (!clickEntireItem) {
|
||||
html += '<button is="paper-icon-button-light" class="menuButton autoSize"><i class="md-icon"></i></button>';
|
||||
html += '<button is="paper-icon-button-light" class="itemAction autoSize" data-action="menu"><i class="md-icon"></i></button>';
|
||||
html += '<span class="listViewUserDataButtons">';
|
||||
html += userdataButtons.getIconsHtml(item, false);
|
||||
html += '</span>';
|
||||
|
|
|
@ -26,7 +26,7 @@ i.mediaInfoItem {
|
|||
color: #CB272A;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
font-size: 120%;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.mediaInfoItem.criticRating {
|
||||
|
|
100
dashboard-ui/bower_components/emby-webcomponents/playmenu.js
vendored
Normal file
100
dashboard-ui/bower_components/emby-webcomponents/playmenu.js
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
define(['actionsheet', 'datetime', 'playbackManager', 'globalize'], function (actionsheet, datetime, playbackManager, globalize) {
|
||||
|
||||
function show(options) {
|
||||
|
||||
var item = options.item;
|
||||
|
||||
var itemType = item.Type;
|
||||
var mediaType = item.MediaType;
|
||||
var isFolder = item.IsFolder;
|
||||
var itemId = item.Id;
|
||||
var serverId = item.ServerId;
|
||||
var resumePositionTicks = item.UserData ? item.UserData.PlaybackPositionTicks : null;
|
||||
|
||||
if (!resumePositionTicks && mediaType != "Audio" && !isFolder) {
|
||||
playbackManager.play({
|
||||
items: [item]
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var menuItems = [];
|
||||
|
||||
if (resumePositionTicks) {
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#ResumeAt', datetime.getDisplayRunningTime(resumePositionTicks)),
|
||||
id: 'resume'
|
||||
});
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#PlayFromBeginning'),
|
||||
id: 'play'
|
||||
});
|
||||
} else {
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#Play'),
|
||||
id: 'play'
|
||||
});
|
||||
}
|
||||
|
||||
if (playbackManager.canQueueMediaType(mediaType)) {
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#Queue'),
|
||||
id: 'queue'
|
||||
});
|
||||
}
|
||||
|
||||
if (itemType == "Audio" || itemType == "MusicAlbum" || itemType == "MusicArtist" || itemType == "MusicGenre") {
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#InstantMix'),
|
||||
id: 'instantmix'
|
||||
});
|
||||
}
|
||||
|
||||
if (isFolder || itemType == "MusicArtist" || itemType == "MusicGenre") {
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#Shuffle'),
|
||||
id: 'shuffle'
|
||||
});
|
||||
}
|
||||
|
||||
actionsheet.show({
|
||||
|
||||
items: menuItems,
|
||||
positionTo: options.positionTo
|
||||
|
||||
}).then(function (id) {
|
||||
switch (id) {
|
||||
|
||||
case 'play':
|
||||
playbackManager.play({
|
||||
ids: [itemId],
|
||||
serverId: item.ServerId
|
||||
});
|
||||
break;
|
||||
case 'resume':
|
||||
playbackManager.play({
|
||||
ids: [itemId],
|
||||
startPositionTicks: resumePositionTicks,
|
||||
serverId: item.ServerId
|
||||
});
|
||||
break;
|
||||
case 'queue':
|
||||
playbackManager.queue(item);
|
||||
break;
|
||||
case 'instantmix':
|
||||
playbackManager.instantMix(item);
|
||||
break;
|
||||
case 'shuffle':
|
||||
playbackManager.shuffle(item);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
show: show
|
||||
};
|
||||
});
|
|
@ -90,7 +90,80 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
embyRouter.showItem(options);
|
||||
}
|
||||
|
||||
function executeAction(card, action) {
|
||||
function getItem(button) {
|
||||
|
||||
button = parentWithAttribute(button, 'data-id');
|
||||
var serverId = button.getAttribute('data-serverid');
|
||||
var id = button.getAttribute('data-id');
|
||||
var type = button.getAttribute('data-type');
|
||||
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
|
||||
return apiClient.getItem(apiClient.getCurrentUserId(), id);
|
||||
}
|
||||
|
||||
function showContextMenu(card, options) {
|
||||
|
||||
getItem(card).then(function (item) {
|
||||
|
||||
var itemsContainer = options.itemsContainer || parentWithAttribute(card, 'is', 'emby-itemscontainer');
|
||||
|
||||
var playlistId = itemsContainer ? itemsContainer.getAttribute('data-playlistid') : null;
|
||||
var collectionId = itemsContainer ? itemsContainer.getAttribute('data-collectionid') : null;
|
||||
|
||||
if (playlistId) {
|
||||
var elem = parentWithAttribute(card, 'data-playlistitemid');
|
||||
item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null;
|
||||
}
|
||||
|
||||
require(['itemContextMenu'], function (itemContextMenu) {
|
||||
|
||||
itemContextMenu.show(Object.assign({
|
||||
item: item,
|
||||
play: true,
|
||||
queue: true,
|
||||
playAllFromHere: !item.IsFolder,
|
||||
queueAllFromHere: !item.IsFolder,
|
||||
identify: false,
|
||||
playlistId: playlistId,
|
||||
collectionId: collectionId
|
||||
|
||||
}, options || {})).then(function (result) {
|
||||
|
||||
if (result.command == 'playallfromhere' || result.command == 'queueallfromhere') {
|
||||
executeAction(card, options.positionTo, result.command);
|
||||
}
|
||||
else if (result.command == 'removefromplaylist' || result.command == 'removefromcollection') {
|
||||
|
||||
if (itemsContainer) {
|
||||
itemsContainer.dispatchEvent(new CustomEvent('needsrefresh', {
|
||||
detail: {},
|
||||
cancelable: false,
|
||||
bubbles: true
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showPlayMenu(card, target) {
|
||||
|
||||
getItem(card).then(function (item) {
|
||||
|
||||
require(['playMenu'], function (playMenu) {
|
||||
|
||||
playMenu.show({
|
||||
|
||||
item: item,
|
||||
positionTo: target
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function executeAction(card, target, action) {
|
||||
|
||||
var id = card.getAttribute('data-id');
|
||||
|
||||
|
@ -142,6 +215,17 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
else if (action == 'record') {
|
||||
onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid'));
|
||||
}
|
||||
|
||||
else if (action == 'menu') {
|
||||
showContextMenu(card, {
|
||||
identify: false,
|
||||
positionTo: target || card
|
||||
});
|
||||
}
|
||||
|
||||
else if (action == 'playmenu') {
|
||||
showPlayMenu(card, target || card);
|
||||
}
|
||||
}
|
||||
|
||||
function onRecordCommand(serverId, id, type, timerId, seriesTimerId) {
|
||||
|
@ -234,7 +318,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
}
|
||||
|
||||
if (action) {
|
||||
executeAction(card, action);
|
||||
executeAction(card, e.target, action);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -243,9 +327,9 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
}
|
||||
}
|
||||
|
||||
function parentWithAttribute(elem, name) {
|
||||
function parentWithAttribute(elem, name, value) {
|
||||
|
||||
while (!elem.getAttribute(name)) {
|
||||
while ((value ? elem.getAttribute(name) != value : !elem.getAttribute(name))) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
|
@ -276,7 +360,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
var card = parentWithClass(e.target, 'itemAction');
|
||||
|
||||
if (card) {
|
||||
executeAction(card, cmd);
|
||||
executeAction(card, card, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,8 +391,8 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
|
|||
return {
|
||||
on: on,
|
||||
off: off,
|
||||
execute: executeAction,
|
||||
onClick: onClick
|
||||
onClick: onClick,
|
||||
showContextMenu: showContextMenu
|
||||
};
|
||||
|
||||
});
|
|
@ -112,5 +112,7 @@
|
|||
"ViewArtist": "View Artist",
|
||||
"QueueAllFromHere": "Queue All from Here",
|
||||
"PlayAllFromHere": "Play All from Here",
|
||||
"PlayFromBeginning": "Play from beginning",
|
||||
"ResumeAt": "Resume at {0}",
|
||||
"RemoveFromPlaylist": "Remove from Playlist"
|
||||
}
|
|
@ -23,15 +23,14 @@
|
|||
"spec"
|
||||
],
|
||||
"homepage": "https://github.com/Valve/fingerprintjs2",
|
||||
"version": "1.4.0",
|
||||
"_release": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"_release": "1.4.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.4.0",
|
||||
"commit": "75cbd474158f8ecce43e00f198c76e486b896937"
|
||||
"tag": "1.4.1",
|
||||
"commit": "6320cfa19c89aca0eb39e811d101336a2812ad61"
|
||||
},
|
||||
"_source": "https://github.com/Valve/fingerprintjs2.git",
|
||||
"_target": "^1.4.0",
|
||||
"_originalSource": "fingerprintjs2",
|
||||
"_direct": true
|
||||
"_originalSource": "fingerprintjs2"
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Fingerprintjs2 1.4.0 - Modern & flexible browser fingerprint library v2
|
||||
* Fingerprintjs2 1.4.1 - Modern & flexible browser fingerprint library v2
|
||||
* https://github.com/Valve/fingerprintjs2
|
||||
* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com)
|
||||
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
||||
|
@ -58,7 +58,8 @@
|
|||
swfContainerId: "fingerprintjs2",
|
||||
swfPath: "flash/compiled/FontList.swf",
|
||||
detectScreenOrientation: true,
|
||||
sortPluginsFor: [/palemoon/i]
|
||||
sortPluginsFor: [/palemoon/i],
|
||||
userDefinedFonts: []
|
||||
};
|
||||
this.options = this.extend(options, defaultOptions);
|
||||
this.nativeForEach = Array.prototype.forEach;
|
||||
|
@ -395,6 +396,8 @@
|
|||
fontList = fontList.concat(extendedFontList);
|
||||
}
|
||||
|
||||
fontList = fontList.concat(that.options.userDefinedFonts);
|
||||
|
||||
//we use m or w because these two characters take up the maximum width.
|
||||
// And we use a LLi so that the same matching fonts can get separated
|
||||
var testString = "mmmmmmmmmmlli";
|
||||
|
@ -1283,6 +1286,6 @@
|
|||
return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8);
|
||||
}
|
||||
};
|
||||
Fingerprint2.VERSION = "1.4.0";
|
||||
Fingerprint2.VERSION = "1.4.1";
|
||||
return Fingerprint2;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "fingerprintjs2",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"description": "Modern & flexible browser fingerprinting library",
|
||||
"main": "dist/fingerprint2.min.js",
|
||||
"devDependencies": {
|
||||
|
|
|
@ -39,6 +39,6 @@
|
|||
"commit": "8715c83bf04a228de00ec662ed43eb6141e61b91"
|
||||
},
|
||||
"_source": "git://github.com/Polymer/polymer.git",
|
||||
"_target": "^1.1.0",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "Polymer/polymer"
|
||||
}
|
|
@ -1604,10 +1604,10 @@
|
|||
html += '</a>';
|
||||
|
||||
if (options.overlayPlayButton && !item.IsPlaceHolder && (item.LocationType != 'Virtual' || !item.MediaType || item.Type == 'Program') && item.Type != 'Person' && item.PlayAccess == 'Full') {
|
||||
html += '<div class="cardOverlayButtonContainer"><button is="paper-icon-button-light" class="cardOverlayPlayButton autoSize" onclick="return false;"><i class="md-icon">play_arrow</i></button></div>';
|
||||
html += '<div class="cardOverlayButtonContainer"><button is="paper-icon-button-light" class="cardOverlayPlayButton itemAction autoSize" data-action="playmenu" onclick="return false;"><i class="md-icon">play_arrow</i></button></div>';
|
||||
}
|
||||
if (options.overlayMoreButton) {
|
||||
html += '<div class="cardOverlayButtonContainer"><button is="paper-icon-button-light" class="cardOverlayMoreButton menuButton autoSize" onclick="return false;"><i class="md-icon">' + AppInfo.moreIcon.replace('-', '_') + '</i></button></div>';
|
||||
html += '<div class="cardOverlayButtonContainer"><button is="paper-icon-button-light" class="cardOverlayMoreButton itemAction autoSize" data-action="menu" onclick="return false;"><i class="md-icon">' + AppInfo.moreIcon.replace('-', '_') + '</i></button></div>';
|
||||
}
|
||||
|
||||
// cardScalable
|
||||
|
@ -1632,7 +1632,7 @@
|
|||
|
||||
if (options.cardLayout) {
|
||||
html += '<div class="cardButtonContainer">';
|
||||
html += '<button is="paper-icon-button-light" class="menuButton btnCardOptions autoSize"><i class="md-icon">' + AppInfo.moreIcon.replace('-', '_') + '</i></button>';
|
||||
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><i class="md-icon">' + AppInfo.moreIcon.replace('-', '_') + '</i></button>';
|
||||
html += "</div>";
|
||||
}
|
||||
|
||||
|
|
|
@ -246,34 +246,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onListViewPlayButtonClick(e, playButton) {
|
||||
|
||||
var card = e.target;
|
||||
|
||||
if (!card.classList.contains('card') && !card.classList.contains('listItem')) {
|
||||
card = parentWithAnyClass(card, ['listItem', 'card']);
|
||||
}
|
||||
|
||||
var id = card.getAttribute('data-itemid');
|
||||
var type = card.getAttribute('data-itemtype');
|
||||
var isFolder = card.getAttribute('data-isfolder') == 'true';
|
||||
var mediaType = card.getAttribute('data-mediatype');
|
||||
var resumePosition = parseInt(card.getAttribute('data-positionticks'));
|
||||
|
||||
if (type == 'MusicAlbum' || type == 'MusicArtist' || type == 'MusicGenre' || type == 'Playlist') {
|
||||
isFolder = true;
|
||||
}
|
||||
|
||||
if (type == 'Program') {
|
||||
id = card.getAttribute('data-channelid');
|
||||
}
|
||||
|
||||
LibraryBrowser.showPlayMenu(playButton, id, type, isFolder, mediaType, resumePosition);
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function isClickable(target) {
|
||||
|
||||
while (target != null) {
|
||||
|
@ -291,12 +263,6 @@
|
|||
|
||||
function onCardClick(e) {
|
||||
|
||||
var playButton = parentWithClass(e.target, 'cardOverlayPlayButton');
|
||||
|
||||
if (playButton) {
|
||||
return onListViewPlayButtonClick(e, playButton);
|
||||
}
|
||||
|
||||
var card = parentWithClass(e.target, 'card');
|
||||
|
||||
if (card) {
|
||||
|
|
|
@ -1820,6 +1820,7 @@ var AppInfo = {};
|
|||
define("subtitleEditor", [embyWebComponentsBowerPath + "/subtitleeditor/subtitleeditor"], returnFirstDependency);
|
||||
define("mediaInfo", [embyWebComponentsBowerPath + "/mediainfo/mediainfo"], returnFirstDependency);
|
||||
define("itemContextMenu", [embyWebComponentsBowerPath + "/itemcontextmenu"], returnFirstDependency);
|
||||
define("playMenu", [embyWebComponentsBowerPath + "/playmenu"], returnFirstDependency);
|
||||
define("refreshDialog", [embyWebComponentsBowerPath + "/refreshdialog/refreshdialog"], returnFirstDependency);
|
||||
define("backdrop", [embyWebComponentsBowerPath + "/backdrop/backdrop"], returnFirstDependency);
|
||||
define("fetchHelper", [embyWebComponentsBowerPath + "/fetchhelper"], returnFirstDependency);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue