forked from CIT/Vmeda.Online
		
	MOBILE-2235 h5p: Save content and create player
This commit is contained in:
		
							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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user