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.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.
 | ||||||
|             this.playerSrc = 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.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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user