MOBILE-2235 h5p: Save content and create player
parent
ef5f96a643
commit
fb898f6f05
|
@ -1550,7 +1550,73 @@
|
|||
"core.group": "Group",
|
||||
"core.groupsseparate": "Separate 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.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.help": "Help",
|
||||
"core.hide": "Hide",
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Component, Input, ElementRef, OnInit, OnDestroy, OnChanges, SimpleChang
|
|||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { CoreFilepoolProvider } from '@providers/filepool';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
|
@ -23,6 +24,7 @@ import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
|||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreH5PProvider } from '@core/h5p/providers/h5p';
|
||||
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
|
||||
/**
|
||||
* Component to render an H5P package.
|
||||
|
@ -47,8 +49,10 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
protected siteCanDownload: boolean;
|
||||
protected observer;
|
||||
protected urlParams;
|
||||
protected logger;
|
||||
|
||||
constructor(public elementRef: ElementRef,
|
||||
constructor(loggerProvider: CoreLoggerProvider,
|
||||
public elementRef: ElementRef,
|
||||
protected sitesProvider: CoreSitesProvider,
|
||||
protected urlUtils: CoreUrlUtilsProvider,
|
||||
protected utils: CoreUtilsProvider,
|
||||
|
@ -60,6 +64,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
protected domUtils: CoreDomUtilsProvider,
|
||||
protected pluginFileDelegate: CorePluginFileDelegate) {
|
||||
|
||||
this.logger = loggerProvider.getInstance('CoreH5PPlayerComponent');
|
||||
this.siteId = sitesProvider.getCurrentSiteId();
|
||||
this.siteCanDownload = this.sitesProvider.getCurrentSite().canDownloadFiles();
|
||||
}
|
||||
|
@ -92,11 +97,30 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
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.
|
||||
this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
||||
this.playerSrc = url;
|
||||
if (this.canDownload && (this.state == CoreConstants.DOWNLOADED || this.state == CoreConstants.OUTDATED)) {
|
||||
// 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;
|
||||
} 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.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.
|
||||
|
||||
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.
|
||||
|
@ -20,9 +24,120 @@ import { Injectable } from '@angular/core';
|
|||
@Injectable()
|
||||
export class CoreH5PUtilsProvider {
|
||||
|
||||
constructor() {
|
||||
// Nothing to do.
|
||||
}
|
||||
// Map to slugify characters.
|
||||
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.
|
||||
|
@ -43,6 +158,161 @@ export class CoreH5PUtilsProvider {
|
|||
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.
|
||||
*
|
||||
|
@ -68,4 +338,71 @@ export class CoreH5PUtilsProvider {
|
|||
|
||||
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 {
|
||||
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