MOBILE-2235 h5p: Save content and create player
parent
ef5f96a643
commit
fb898f6f05
|
@ -1550,7 +1550,73 @@
|
||||||
"core.group": "Group",
|
"core.group": "Group",
|
||||||
"core.groupsseparate": "Separate groups",
|
"core.groupsseparate": "Separate groups",
|
||||||
"core.groupsvisible": "Visible groups",
|
"core.groupsvisible": "Visible groups",
|
||||||
|
"core.h5p.author": "Author",
|
||||||
|
"core.h5p.by": "by",
|
||||||
|
"core.h5p.cancellabel": "Cancel",
|
||||||
|
"core.h5p.ccattribution": "Attribution (CC BY)",
|
||||||
|
"core.h5p.ccattributionnc": "Attribution-NonCommercial (CC BY-NC)",
|
||||||
|
"core.h5p.ccattributionncnd": "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)",
|
||||||
|
"core.h5p.ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
||||||
|
"core.h5p.ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
||||||
|
"core.h5p.ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
||||||
|
"core.h5p.changelog": "Changelog",
|
||||||
|
"core.h5p.close": "Close",
|
||||||
|
"core.h5p.confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
||||||
|
"core.h5p.confirmdialogheader": "Confirm action",
|
||||||
|
"core.h5p.confirmlabel": "Confirm",
|
||||||
|
"core.h5p.connectionLost": "Connection lost. Results will be stored and sent when you regain connection.",
|
||||||
|
"core.h5p.connectionReestablished": "Connection reestablished.",
|
||||||
|
"core.h5p.contentCopied": "Content is copied to the clipboard",
|
||||||
|
"core.h5p.contentchanged": "This content has changed since you last used it.",
|
||||||
|
"core.h5p.contenttype": "Content Type",
|
||||||
|
"core.h5p.copyright": "Rights of use",
|
||||||
|
"core.h5p.copyrightstring": "Copyright",
|
||||||
|
"core.h5p.copyrighttitle": "View copyright information for this content.",
|
||||||
|
"core.h5p.disablefullscreen": "Disable fullscreen",
|
||||||
|
"core.h5p.download": "Download",
|
||||||
|
"core.h5p.downloadtitle": "Download this content as a H5P file.",
|
||||||
|
"core.h5p.embed": "Embed",
|
||||||
|
"core.h5p.embedtitle": "View the embed code for this content.",
|
||||||
|
"core.h5p.fullscreen": "Fullscreen",
|
||||||
|
"core.h5p.h5ptitle": "Visit H5P.org to check out more cool content.",
|
||||||
|
"core.h5p.hideadvanced": "Hide advanced",
|
||||||
|
"core.h5p.license": "License",
|
||||||
|
"core.h5p.licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
||||||
|
"core.h5p.licenseCC10": "1.0 Generic",
|
||||||
|
"core.h5p.licenseCC20": "2.0 Generic",
|
||||||
|
"core.h5p.licenseCC25": "2.5 Generic",
|
||||||
|
"core.h5p.licenseCC30": "3.0 Unported",
|
||||||
|
"core.h5p.licenseCC40": "4.0 International",
|
||||||
|
"core.h5p.licenseGPL": "General Public License",
|
||||||
|
"core.h5p.licenseV1": "Version 1",
|
||||||
|
"core.h5p.licenseV2": "Version 2",
|
||||||
|
"core.h5p.licenseV3": "Version 3",
|
||||||
|
"core.h5p.licenseextras": "License Extras",
|
||||||
|
"core.h5p.nocopyright": "No copyright information available for this content.",
|
||||||
|
"core.h5p.offlineDialogBody": "We were unable to send information about your completion of this task. Please check your internet connection.",
|
||||||
|
"core.h5p.offlineDialogHeader": "Your connection to the server was lost",
|
||||||
|
"core.h5p.offlineDialogRetryButtonLabel": "Retry now",
|
||||||
|
"core.h5p.offlineDialogRetryMessage": "Retrying in :num....",
|
||||||
|
"core.h5p.offlineSuccessfulSubmit": "Successfully submitted results.",
|
||||||
|
"core.h5p.pd": "Public Domain",
|
||||||
|
"core.h5p.pdm": "Public Domain Mark (PDM)",
|
||||||
"core.h5p.play": "Play H5P",
|
"core.h5p.play": "Play H5P",
|
||||||
|
"core.h5p.resizescript": "Include this script on your website if you want dynamic sizing of the embedded content:",
|
||||||
|
"core.h5p.resubmitScores": "Attempting to submit stored results.",
|
||||||
|
"core.h5p.reuse": "Reuse",
|
||||||
|
"core.h5p.reuseContent": "Reuse Content",
|
||||||
|
"core.h5p.reuseDescription": "Reuse this content.",
|
||||||
|
"core.h5p.showadvanced": "Show advanced",
|
||||||
|
"core.h5p.showless": "Show less",
|
||||||
|
"core.h5p.showmore": "Show more",
|
||||||
|
"core.h5p.size": "Size",
|
||||||
|
"core.h5p.source": "Source",
|
||||||
|
"core.h5p.startingover": "You'll be starting over.",
|
||||||
|
"core.h5p.sublevel": "Sublevel",
|
||||||
|
"core.h5p.thumbnail": "Thumbnail",
|
||||||
|
"core.h5p.title": "Title",
|
||||||
|
"core.h5p.undisclosed": "Undisclosed",
|
||||||
|
"core.h5p.year": "Year",
|
||||||
"core.hasdatatosync": "This {{$a}} has offline data to be synchronised.",
|
"core.hasdatatosync": "This {{$a}} has offline data to be synchronised.",
|
||||||
"core.help": "Help",
|
"core.help": "Help",
|
||||||
"core.hide": "Hide",
|
"core.hide": "Hide",
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { Component, Input, ElementRef, OnInit, OnDestroy, OnChanges, SimpleChang
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreFilepoolProvider } from '@providers/filepool';
|
import { CoreFilepoolProvider } from '@providers/filepool';
|
||||||
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
|
@ -23,6 +24,7 @@ import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { CoreH5PProvider } from '@core/h5p/providers/h5p';
|
import { CoreH5PProvider } from '@core/h5p/providers/h5p';
|
||||||
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
|
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
|
||||||
|
import { CoreConstants } from '@core/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render an H5P package.
|
* Component to render an H5P package.
|
||||||
|
@ -47,8 +49,10 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
protected siteCanDownload: boolean;
|
protected siteCanDownload: boolean;
|
||||||
protected observer;
|
protected observer;
|
||||||
protected urlParams;
|
protected urlParams;
|
||||||
|
protected logger;
|
||||||
|
|
||||||
constructor(public elementRef: ElementRef,
|
constructor(loggerProvider: CoreLoggerProvider,
|
||||||
|
public elementRef: ElementRef,
|
||||||
protected sitesProvider: CoreSitesProvider,
|
protected sitesProvider: CoreSitesProvider,
|
||||||
protected urlUtils: CoreUrlUtilsProvider,
|
protected urlUtils: CoreUrlUtilsProvider,
|
||||||
protected utils: CoreUtilsProvider,
|
protected utils: CoreUtilsProvider,
|
||||||
|
@ -60,6 +64,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
protected domUtils: CoreDomUtilsProvider,
|
protected domUtils: CoreDomUtilsProvider,
|
||||||
protected pluginFileDelegate: CorePluginFileDelegate) {
|
protected pluginFileDelegate: CorePluginFileDelegate) {
|
||||||
|
|
||||||
|
this.logger = loggerProvider.getInstance('CoreH5PPlayerComponent');
|
||||||
this.siteId = sitesProvider.getCurrentSiteId();
|
this.siteId = sitesProvider.getCurrentSiteId();
|
||||||
this.siteCanDownload = this.sitesProvider.getCurrentSite().canDownloadFiles();
|
this.siteCanDownload = this.sitesProvider.getCurrentSite().canDownloadFiles();
|
||||||
}
|
}
|
||||||
|
@ -92,11 +97,30 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
// @TODO: Check if package is downloaded and use the local player if so.
|
let promise;
|
||||||
|
|
||||||
// Get auto-login URL so the user is automatically authenticated.
|
if (this.canDownload && (this.state == CoreConstants.DOWNLOADED || this.state == CoreConstants.OUTDATED)) {
|
||||||
this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
// Package is downloaded, use the local URL.
|
||||||
|
promise = this.h5pProvider.getContentIndexFileUrl(this.urlParams.url).catch((error) => {
|
||||||
|
// It seems there was something wrong when creating the index file. Delete the package?
|
||||||
|
this.logger.error('Error loading downloaded index:', error, this.src);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
promise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then((url) => {
|
||||||
|
if (url) {
|
||||||
|
// Local package.
|
||||||
this.playerSrc = url;
|
this.playerSrc = url;
|
||||||
|
} else {
|
||||||
|
// Get auto-login URL so the user is automatically authenticated.
|
||||||
|
return this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
||||||
|
// Add the preventredirect param so the user can authenticate.
|
||||||
|
this.playerSrc = this.urlUtils.addParamsToUrl(url, {preventredirect: false});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.showPackage = true;
|
this.showPackage = true;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,69 @@
|
||||||
{
|
{
|
||||||
"play": "Play H5P"
|
"author": "Author",
|
||||||
|
"by": "by",
|
||||||
|
"cancellabel": "Cancel",
|
||||||
|
"ccattribution": "Attribution (CC BY)",
|
||||||
|
"ccattributionnc": "Attribution-NonCommercial (CC BY-NC)",
|
||||||
|
"ccattributionncnd": "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)",
|
||||||
|
"ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
||||||
|
"ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
||||||
|
"ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
||||||
|
"changelog": "Changelog",
|
||||||
|
"close": "Close",
|
||||||
|
"confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
||||||
|
"confirmdialogheader": "Confirm action",
|
||||||
|
"confirmlabel": "Confirm",
|
||||||
|
"connectionLost": "Connection lost. Results will be stored and sent when you regain connection.",
|
||||||
|
"connectionReestablished": "Connection reestablished.",
|
||||||
|
"contentCopied": "Content is copied to the clipboard",
|
||||||
|
"contentchanged": "This content has changed since you last used it.",
|
||||||
|
"contenttype": "Content Type",
|
||||||
|
"copyright": "Rights of use",
|
||||||
|
"copyrightstring": "Copyright",
|
||||||
|
"copyrighttitle": "View copyright information for this content.",
|
||||||
|
"disablefullscreen": "Disable fullscreen",
|
||||||
|
"download": "Download",
|
||||||
|
"downloadtitle": "Download this content as a H5P file.",
|
||||||
|
"embed": "Embed",
|
||||||
|
"embedtitle": "View the embed code for this content.",
|
||||||
|
"fullscreen": "Fullscreen",
|
||||||
|
"h5ptitle": "Visit H5P.org to check out more cool content.",
|
||||||
|
"hideadvanced": "Hide advanced",
|
||||||
|
"license": "License",
|
||||||
|
"licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
||||||
|
"licenseCC10": "1.0 Generic",
|
||||||
|
"licenseCC20": "2.0 Generic",
|
||||||
|
"licenseCC25": "2.5 Generic",
|
||||||
|
"licenseCC30": "3.0 Unported",
|
||||||
|
"licenseCC40": "4.0 International",
|
||||||
|
"licenseGPL": "General Public License",
|
||||||
|
"licenseV1": "Version 1",
|
||||||
|
"licenseV2": "Version 2",
|
||||||
|
"licenseV3": "Version 3",
|
||||||
|
"licenseextras": "License Extras",
|
||||||
|
"nocopyright": "No copyright information available for this content.",
|
||||||
|
"offlineDialogBody": "We were unable to send information about your completion of this task. Please check your internet connection.",
|
||||||
|
"offlineDialogHeader": "Your connection to the server was lost",
|
||||||
|
"offlineDialogRetryButtonLabel": "Retry now",
|
||||||
|
"offlineDialogRetryMessage": "Retrying in :num....",
|
||||||
|
"offlineSuccessfulSubmit": "Successfully submitted results.",
|
||||||
|
"pd": "Public Domain",
|
||||||
|
"pdm": "Public Domain Mark (PDM)",
|
||||||
|
"play": "Play H5P",
|
||||||
|
"resizescript": "Include this script on your website if you want dynamic sizing of the embedded content:",
|
||||||
|
"resubmitScores": "Attempting to submit stored results.",
|
||||||
|
"reuse": "Reuse",
|
||||||
|
"reuseContent": "Reuse Content",
|
||||||
|
"reuseDescription": "Reuse this content.",
|
||||||
|
"showadvanced": "Show advanced",
|
||||||
|
"showless": "Show less",
|
||||||
|
"showmore": "Show more",
|
||||||
|
"size": "Size",
|
||||||
|
"source": "Source",
|
||||||
|
"startingover": "You'll be starting over.",
|
||||||
|
"sublevel": "Sublevel",
|
||||||
|
"thumbnail": "Thumbnail",
|
||||||
|
"title": "Title",
|
||||||
|
"undisclosed": "Undisclosed",
|
||||||
|
"year": "Year"
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -13,6 +13,10 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
|
import { CoreH5PContentDependencyData, CoreH5PDependencyAsset } from './h5p';
|
||||||
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utils service with helper functions for H5P.
|
* Utils service with helper functions for H5P.
|
||||||
|
@ -20,9 +24,120 @@ import { Injectable } from '@angular/core';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CoreH5PUtilsProvider {
|
export class CoreH5PUtilsProvider {
|
||||||
|
|
||||||
constructor() {
|
// Map to slugify characters.
|
||||||
// Nothing to do.
|
protected SLUGIFY_MAP = {
|
||||||
}
|
æ: 'ae',
|
||||||
|
ø: 'oe',
|
||||||
|
ö: 'o',
|
||||||
|
ó: 'o',
|
||||||
|
ô: 'o',
|
||||||
|
Ò: 'oe',
|
||||||
|
Õ: 'o',
|
||||||
|
Ý: 'o',
|
||||||
|
ý: 'y',
|
||||||
|
ÿ: 'y',
|
||||||
|
ā: 'y',
|
||||||
|
ă: 'a',
|
||||||
|
ą: 'a',
|
||||||
|
œ: 'a',
|
||||||
|
å: 'a',
|
||||||
|
ä: 'a',
|
||||||
|
á: 'a',
|
||||||
|
à: 'a',
|
||||||
|
â: 'a',
|
||||||
|
ã: 'a',
|
||||||
|
ç: 'c',
|
||||||
|
ć: 'c',
|
||||||
|
ĉ: 'c',
|
||||||
|
ċ: 'c',
|
||||||
|
č: 'c',
|
||||||
|
é: 'e',
|
||||||
|
è: 'e',
|
||||||
|
ê: 'e',
|
||||||
|
ë: 'e',
|
||||||
|
í: 'i',
|
||||||
|
ì: 'i',
|
||||||
|
î: 'i',
|
||||||
|
ï: 'i',
|
||||||
|
ú: 'u',
|
||||||
|
ñ: 'n',
|
||||||
|
ü: 'u',
|
||||||
|
ù: 'u',
|
||||||
|
û: 'u',
|
||||||
|
ß: 'es',
|
||||||
|
ď: 'd',
|
||||||
|
đ: 'd',
|
||||||
|
ē: 'e',
|
||||||
|
ĕ: 'e',
|
||||||
|
ė: 'e',
|
||||||
|
ę: 'e',
|
||||||
|
ě: 'e',
|
||||||
|
ĝ: 'g',
|
||||||
|
ğ: 'g',
|
||||||
|
ġ: 'g',
|
||||||
|
ģ: 'g',
|
||||||
|
ĥ: 'h',
|
||||||
|
ħ: 'h',
|
||||||
|
ĩ: 'i',
|
||||||
|
ī: 'i',
|
||||||
|
ĭ: 'i',
|
||||||
|
į: 'i',
|
||||||
|
ı: 'i',
|
||||||
|
ij: 'ij',
|
||||||
|
ĵ: 'j',
|
||||||
|
ķ: 'k',
|
||||||
|
ĺ: 'l',
|
||||||
|
ļ: 'l',
|
||||||
|
ľ: 'l',
|
||||||
|
ŀ: 'l',
|
||||||
|
ł: 'l',
|
||||||
|
ń: 'n',
|
||||||
|
ņ: 'n',
|
||||||
|
ň: 'n',
|
||||||
|
ʼn: 'n',
|
||||||
|
ō: 'o',
|
||||||
|
ŏ: 'o',
|
||||||
|
ő: 'o',
|
||||||
|
ŕ: 'r',
|
||||||
|
ŗ: 'r',
|
||||||
|
ř: 'r',
|
||||||
|
ś: 's',
|
||||||
|
ŝ: 's',
|
||||||
|
ş: 's',
|
||||||
|
š: 's',
|
||||||
|
ţ: 't',
|
||||||
|
ť: 't',
|
||||||
|
ŧ: 't',
|
||||||
|
ũ: 'u',
|
||||||
|
ū: 'u',
|
||||||
|
ŭ: 'u',
|
||||||
|
ů: 'u',
|
||||||
|
ű: 'u',
|
||||||
|
ų: 'u',
|
||||||
|
ŵ: 'w',
|
||||||
|
ŷ: 'y',
|
||||||
|
ź: 'z',
|
||||||
|
ż: 'z',
|
||||||
|
ž: 'z',
|
||||||
|
ſ: 's',
|
||||||
|
ƒ: 'f',
|
||||||
|
ơ: 'o',
|
||||||
|
ư: 'u',
|
||||||
|
ǎ: 'a',
|
||||||
|
ǐ: 'i',
|
||||||
|
ǒ: 'o',
|
||||||
|
ǔ: 'u',
|
||||||
|
ǖ: 'u',
|
||||||
|
ǘ: 'u',
|
||||||
|
ǚ: 'u',
|
||||||
|
ǜ: 'u',
|
||||||
|
ǻ: 'a',
|
||||||
|
ǽ: 'ae',
|
||||||
|
ǿ: 'oe'
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private translate: TranslateService,
|
||||||
|
private textUtils: CoreTextUtilsProvider) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The metadataSettings field in libraryJson uses 1 for true and 0 for false.
|
* The metadataSettings field in libraryJson uses 1 for true and 0 for false.
|
||||||
|
@ -43,6 +158,161 @@ export class CoreH5PUtilsProvider {
|
||||||
return JSON.stringify(metadataSettings);
|
return JSON.stringify(metadataSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the correct embed type to use.
|
||||||
|
*
|
||||||
|
* @param Embed type of the content.
|
||||||
|
* @param Embed type of the main library.
|
||||||
|
* @return Either 'div' or 'iframe'.
|
||||||
|
*/
|
||||||
|
determineEmbedType(contentEmbedType: string, libraryEmbedTypes: string): string {
|
||||||
|
// Detect content embed type.
|
||||||
|
let embedType = contentEmbedType.toLowerCase().indexOf('div') != -1 ? 'div' : 'iframe';
|
||||||
|
|
||||||
|
if (libraryEmbedTypes) {
|
||||||
|
// Check that embed type is available for library
|
||||||
|
const embedTypes = libraryEmbedTypes.toLowerCase();
|
||||||
|
|
||||||
|
if (embedTypes.indexOf(embedType) == -1) {
|
||||||
|
// Not available, pick default.
|
||||||
|
embedType = embedTypes.indexOf('div') != -1 ? 'div' : 'iframe';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return embedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines path with version.
|
||||||
|
*
|
||||||
|
* @param assets List of assets to get their URLs.
|
||||||
|
* @param assetsFolderPath The path of the folder where the assets are.
|
||||||
|
* @return List of urls.
|
||||||
|
*/
|
||||||
|
getAssetsUrls(assets: CoreH5PDependencyAsset[], assetsFolderPath: string = ''): string[] {
|
||||||
|
const urls = [];
|
||||||
|
|
||||||
|
assets.forEach((asset) => {
|
||||||
|
let url = asset.path;
|
||||||
|
|
||||||
|
// Add URL prefix if not external.
|
||||||
|
if (asset.path.indexOf('://') == -1 && assetsFolderPath) {
|
||||||
|
url = this.textUtils.concatenatePaths(assetsFolderPath, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add version if set.
|
||||||
|
if (asset.version) {
|
||||||
|
url += asset.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
urls.push(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash of a list of dependencies.
|
||||||
|
*
|
||||||
|
* @param dependencies Dependencies.
|
||||||
|
* @return Hash.
|
||||||
|
*/
|
||||||
|
getDependenciesHash(dependencies: {[machineName: string]: CoreH5PContentDependencyData}): string {
|
||||||
|
// Build hash of dependencies.
|
||||||
|
const toHash = [];
|
||||||
|
|
||||||
|
// Use unique identifier for each library version.
|
||||||
|
for (const name in dependencies) {
|
||||||
|
const dep = dependencies[name];
|
||||||
|
toHash.push(dep.machineName + '-' + dep.majorVersion + '.' + dep.minorVersion + '.' + dep.patchVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort in case the same dependencies comes in a different order.
|
||||||
|
toHash.sort((a, b) => {
|
||||||
|
return a.localeCompare(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate hash.
|
||||||
|
return <string> Md5.hashAsciiStr(toHash.join(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide localization for the Core JS.
|
||||||
|
*
|
||||||
|
* @return Object with the translations.
|
||||||
|
*/
|
||||||
|
getLocalization(): any {
|
||||||
|
return {
|
||||||
|
fullscreen: this.translate.instant('core.h5p.fullscreen'),
|
||||||
|
disableFullscreen: this.translate.instant('core.h5p.disablefullscreen'),
|
||||||
|
download: this.translate.instant('core.h5p.download'),
|
||||||
|
copyrights: this.translate.instant('core.h5p.copyright'),
|
||||||
|
embed: this.translate.instant('core.h5p.embed'),
|
||||||
|
size: this.translate.instant('core.h5p.size'),
|
||||||
|
showAdvanced: this.translate.instant('core.h5p.showadvanced'),
|
||||||
|
hideAdvanced: this.translate.instant('core.h5p.hideadvanced'),
|
||||||
|
advancedHelp: this.translate.instant('core.h5p.resizescript'),
|
||||||
|
copyrightInformation: this.translate.instant('core.h5p.copyright'),
|
||||||
|
close: this.translate.instant('core.h5p.close'),
|
||||||
|
title: this.translate.instant('core.h5p.title'),
|
||||||
|
author: this.translate.instant('core.h5p.author'),
|
||||||
|
year: this.translate.instant('core.h5p.year'),
|
||||||
|
source: this.translate.instant('core.h5p.source'),
|
||||||
|
license: this.translate.instant('core.h5p.license'),
|
||||||
|
thumbnail: this.translate.instant('core.h5p.thumbnail'),
|
||||||
|
noCopyrights: this.translate.instant('core.h5p.nocopyright'),
|
||||||
|
reuse: this.translate.instant('core.h5p.reuse'),
|
||||||
|
reuseContent: this.translate.instant('core.h5p.reuseContent'),
|
||||||
|
reuseDescription: this.translate.instant('core.h5p.reuseDescription'),
|
||||||
|
downloadDescription: this.translate.instant('core.h5p.downloadtitle'),
|
||||||
|
copyrightsDescription: this.translate.instant('core.h5p.copyrighttitle'),
|
||||||
|
embedDescription: this.translate.instant('core.h5p.embedtitle'),
|
||||||
|
h5pDescription: this.translate.instant('core.h5p.h5ptitle'),
|
||||||
|
contentChanged: this.translate.instant('core.h5p.contentchanged'),
|
||||||
|
startingOver: this.translate.instant('core.h5p.startingover'),
|
||||||
|
by: this.translate.instant('core.h5p.by'),
|
||||||
|
showMore: this.translate.instant('core.h5p.showmore'),
|
||||||
|
showLess: this.translate.instant('core.h5p.showless'),
|
||||||
|
subLevel: this.translate.instant('core.h5p.sublevel'),
|
||||||
|
confirmDialogHeader: this.translate.instant('core.h5p.confirmdialogheader'),
|
||||||
|
confirmDialogBody: this.translate.instant('core.h5p.confirmdialogbody'),
|
||||||
|
cancelLabel: this.translate.instant('core.h5p.cancellabel'),
|
||||||
|
confirmLabel: this.translate.instant('core.h5p.confirmlabel'),
|
||||||
|
licenseU: this.translate.instant('core.h5p.undisclosed'),
|
||||||
|
licenseCCBY: this.translate.instant('core.h5p.ccattribution'),
|
||||||
|
licenseCCBYSA: this.translate.instant('core.h5p.ccattributionsa'),
|
||||||
|
licenseCCBYND: this.translate.instant('core.h5p.ccattributionnd'),
|
||||||
|
licenseCCBYNC: this.translate.instant('core.h5p.ccattributionnc'),
|
||||||
|
licenseCCBYNCSA: this.translate.instant('core.h5p.ccattributionncsa'),
|
||||||
|
licenseCCBYNCND: this.translate.instant('core.h5p.ccattributionncnd'),
|
||||||
|
licenseCC40: this.translate.instant('core.h5p.licenseCC40'),
|
||||||
|
licenseCC30: this.translate.instant('core.h5p.licenseCC30'),
|
||||||
|
licenseCC25: this.translate.instant('core.h5p.licenseCC25'),
|
||||||
|
licenseCC20: this.translate.instant('core.h5p.licenseCC20'),
|
||||||
|
licenseCC10: this.translate.instant('core.h5p.licenseCC10'),
|
||||||
|
licenseGPL: this.translate.instant('core.h5p.licenseGPL'),
|
||||||
|
licenseV3: this.translate.instant('core.h5p.licenseV3'),
|
||||||
|
licenseV2: this.translate.instant('core.h5p.licenseV2'),
|
||||||
|
licenseV1: this.translate.instant('core.h5p.licenseV1'),
|
||||||
|
licensePD: this.translate.instant('core.h5p.pd'),
|
||||||
|
licenseCC010: this.translate.instant('core.h5p.licenseCC010'),
|
||||||
|
licensePDM: this.translate.instant('core.h5p.pdm'),
|
||||||
|
licenseC: this.translate.instant('core.h5p.copyrightstring'),
|
||||||
|
contentType: this.translate.instant('core.h5p.contenttype'),
|
||||||
|
licenseExtras: this.translate.instant('core.h5p.licenseextras'),
|
||||||
|
changes: this.translate.instant('core.h5p.changelog'),
|
||||||
|
contentCopied: this.translate.instant('core.h5p.contentCopied'),
|
||||||
|
connectionLost: this.translate.instant('core.h5p.connectionLost'),
|
||||||
|
connectionReestablished: this.translate.instant('core.h5p.connectionReestablished'),
|
||||||
|
resubmitScores: this.translate.instant('core.h5p.resubmitScores'),
|
||||||
|
offlineDialogHeader: this.translate.instant('core.h5p.offlineDialogHeader'),
|
||||||
|
offlineDialogBody: this.translate.instant('core.h5p.offlineDialogBody'),
|
||||||
|
offlineDialogRetryMessage: this.translate.instant('core.h5p.offlineDialogRetryMessage'),
|
||||||
|
offlineDialogRetryButtonLabel: this.translate.instant('core.h5p.offlineDialogRetryButtonLabel'),
|
||||||
|
offlineSuccessfulSubmit: this.translate.instant('core.h5p.offlineSuccessfulSubmit'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert list of library parameter values to csv.
|
* Convert list of library parameter values to csv.
|
||||||
*
|
*
|
||||||
|
@ -68,4 +338,71 @@ export class CoreH5PUtilsProvider {
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert strings of text into simple kebab case slugs. Based on H5PCore::slugify.
|
||||||
|
*
|
||||||
|
* @param input The string to slugify.
|
||||||
|
* @return Slugified text.
|
||||||
|
*/
|
||||||
|
slugify(input: string): string {
|
||||||
|
input = input || '';
|
||||||
|
|
||||||
|
input = input.toLowerCase();
|
||||||
|
|
||||||
|
// Replace common chars.
|
||||||
|
let newInput = '';
|
||||||
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
const char = input[i];
|
||||||
|
|
||||||
|
newInput += this.SLUGIFY_MAP[char] || char;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace everything else.
|
||||||
|
newInput = newInput.replace(/[^a-z0-9]/g, '-');
|
||||||
|
|
||||||
|
// Prevent double hyphen
|
||||||
|
newInput = newInput.replace(/-{2,}/g, '-');
|
||||||
|
|
||||||
|
// Prevent hyphen in beginning or end.
|
||||||
|
newInput = newInput.replace(/(^-+|-+$)/g, '');
|
||||||
|
|
||||||
|
// Prevent too long slug.
|
||||||
|
if (newInput.length > 91) {
|
||||||
|
newInput = newInput.substr(0, 92);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent empty slug
|
||||||
|
if (newInput === '') {
|
||||||
|
newInput = 'interactive';
|
||||||
|
}
|
||||||
|
|
||||||
|
return newInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if params contain any match.
|
||||||
|
*
|
||||||
|
* @param params Parameters.
|
||||||
|
* @param pattern Regular expression to identify pattern.
|
||||||
|
* @return True if params matches pattern.
|
||||||
|
*/
|
||||||
|
textAddonMatches(params: any, pattern: string): boolean {
|
||||||
|
|
||||||
|
if (typeof params == 'string') {
|
||||||
|
if (params.match(pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (typeof params == 'object') {
|
||||||
|
for (const key in params) {
|
||||||
|
const value = params[key];
|
||||||
|
|
||||||
|
if (this.textAddonMatches(value, pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1239,4 +1239,19 @@ export class CoreFileProvider {
|
||||||
isFileInAppFolder(path: string): boolean {
|
isFileInAppFolder(path: string): boolean {
|
||||||
return path.indexOf(this.basePath) != -1;
|
return path.indexOf(this.basePath) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the full path to the www folder at runtime.
|
||||||
|
*
|
||||||
|
* @return Path.
|
||||||
|
*/
|
||||||
|
getWWWPath(): string {
|
||||||
|
const position = window.location.href.indexOf('index.html');
|
||||||
|
|
||||||
|
if (position != -1) {
|
||||||
|
return window.location.href.substr(0, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue