MOBILE-2235 h5p: Implement and use content validator
parent
3da7c99fd8
commit
56faa66adc
|
@ -1552,6 +1552,94 @@
|
||||||
"core.group": "moodle",
|
"core.group": "moodle",
|
||||||
"core.groupsseparate": "moodle",
|
"core.groupsseparate": "moodle",
|
||||||
"core.groupsvisible": "moodle",
|
"core.groupsvisible": "moodle",
|
||||||
|
"core.h5p.additionallicenseinfo": "h5p",
|
||||||
|
"core.h5p.author": "h5p",
|
||||||
|
"core.h5p.authorcomments": "h5p",
|
||||||
|
"core.h5p.authorcommentsdescription": "h5p",
|
||||||
|
"core.h5p.authorname": "h5p",
|
||||||
|
"core.h5p.authorrole": "h5p",
|
||||||
|
"core.h5p.by": "h5p",
|
||||||
|
"core.h5p.cancellabel": "h5p",
|
||||||
|
"core.h5p.ccattribution": "h5p",
|
||||||
|
"core.h5p.ccattributionnc": "h5p",
|
||||||
|
"core.h5p.ccattributionncnd": "h5p",
|
||||||
|
"core.h5p.ccattributionncsa": "h5p",
|
||||||
|
"core.h5p.ccattributionnd": "h5p",
|
||||||
|
"core.h5p.ccattributionsa": "h5p",
|
||||||
|
"core.h5p.ccpdd": "h5p",
|
||||||
|
"core.h5p.changedby": "h5p",
|
||||||
|
"core.h5p.changedescription": "h5p",
|
||||||
|
"core.h5p.changelog": "h5p",
|
||||||
|
"core.h5p.changeplaceholder": "h5p",
|
||||||
|
"core.h5p.close": "h5p",
|
||||||
|
"core.h5p.confirmdialogbody": "h5p",
|
||||||
|
"core.h5p.confirmdialogheader": "h5p",
|
||||||
|
"core.h5p.confirmlabel": "h5p",
|
||||||
|
"core.h5p.connectionLost": "h5p",
|
||||||
|
"core.h5p.connectionReestablished": "h5p",
|
||||||
|
"core.h5p.contentCopied": "h5p",
|
||||||
|
"core.h5p.contentchanged": "h5p",
|
||||||
|
"core.h5p.contenttype": "h5p",
|
||||||
|
"core.h5p.copyright": "h5p",
|
||||||
|
"core.h5p.copyrightinfo": "h5p",
|
||||||
|
"core.h5p.copyrightstring": "h5p",
|
||||||
|
"core.h5p.copyrighttitle": "h5p",
|
||||||
|
"core.h5p.creativecommons": "h5p",
|
||||||
|
"core.h5p.date": "h5p",
|
||||||
|
"core.h5p.disablefullscreen": "h5p",
|
||||||
|
"core.h5p.download": "h5p",
|
||||||
|
"core.h5p.downloadtitle": "h5p",
|
||||||
|
"core.h5p.editor": "h5p",
|
||||||
|
"core.h5p.embed": "h5p",
|
||||||
|
"core.h5p.embedtitle": "h5p",
|
||||||
|
"core.h5p.fullscreen": "h5p",
|
||||||
|
"core.h5p.gpl": "h5p",
|
||||||
|
"core.h5p.h5ptitle": "h5p",
|
||||||
|
"core.h5p.hideadvanced": "h5p",
|
||||||
|
"core.h5p.license": "h5p",
|
||||||
|
"core.h5p.licenseCC010": "h5p",
|
||||||
|
"core.h5p.licenseCC010U": "h5p",
|
||||||
|
"core.h5p.licenseCC10": "h5p",
|
||||||
|
"core.h5p.licenseCC20": "h5p",
|
||||||
|
"core.h5p.licenseCC25": "h5p",
|
||||||
|
"core.h5p.licenseCC30": "h5p",
|
||||||
|
"core.h5p.licenseCC40": "h5p",
|
||||||
|
"core.h5p.licenseGPL": "h5p",
|
||||||
|
"core.h5p.licenseV1": "h5p",
|
||||||
|
"core.h5p.licenseV2": "h5p",
|
||||||
|
"core.h5p.licenseV3": "h5p",
|
||||||
|
"core.h5p.licensee": "h5p",
|
||||||
|
"core.h5p.licenseextras": "h5p",
|
||||||
|
"core.h5p.licenseversion": "h5p",
|
||||||
|
"core.h5p.nocopyright": "h5p",
|
||||||
|
"core.h5p.offlineDialogBody": "h5p",
|
||||||
|
"core.h5p.offlineDialogHeader": "h5p",
|
||||||
|
"core.h5p.offlineDialogRetryButtonLabel": "h5p",
|
||||||
|
"core.h5p.offlineDialogRetryMessage": "h5p",
|
||||||
|
"core.h5p.offlineSuccessfulSubmit": "h5p",
|
||||||
|
"core.h5p.originator": "h5p",
|
||||||
|
"core.h5p.pd": "h5p",
|
||||||
|
"core.h5p.pddl": "h5p",
|
||||||
|
"core.h5p.pdm": "h5p",
|
||||||
|
"core.h5p.resizescript": "h5p",
|
||||||
|
"core.h5p.resubmitScores": "h5p",
|
||||||
|
"core.h5p.reuse": "h5p",
|
||||||
|
"core.h5p.reuseContent": "h5p",
|
||||||
|
"core.h5p.reuseDescription": "h5p",
|
||||||
|
"core.h5p.showadvanced": "h5p",
|
||||||
|
"core.h5p.showless": "h5p",
|
||||||
|
"core.h5p.showmore": "h5p",
|
||||||
|
"core.h5p.size": "h5p",
|
||||||
|
"core.h5p.source": "h5p",
|
||||||
|
"core.h5p.startingover": "h5p",
|
||||||
|
"core.h5p.sublevel": "h5p",
|
||||||
|
"core.h5p.thumbnail": "h5p",
|
||||||
|
"core.h5p.title": "h5p",
|
||||||
|
"core.h5p.undisclosed": "h5p",
|
||||||
|
"core.h5p.year": "h5p",
|
||||||
|
"core.h5p.years": "h5p",
|
||||||
|
"core.h5p.yearsfrom": "h5p",
|
||||||
|
"core.h5p.yearsto": "h5p",
|
||||||
"core.hasdatatosync": "local_moodlemobileapp",
|
"core.hasdatatosync": "local_moodlemobileapp",
|
||||||
"core.help": "moodle",
|
"core.help": "moodle",
|
||||||
"core.hide": "moodle",
|
"core.hide": "moodle",
|
||||||
|
|
|
@ -1550,7 +1550,12 @@
|
||||||
"core.group": "Group",
|
"core.group": "Group",
|
||||||
"core.groupsseparate": "Separate groups",
|
"core.groupsseparate": "Separate groups",
|
||||||
"core.groupsvisible": "Visible groups",
|
"core.groupsvisible": "Visible groups",
|
||||||
|
"core.h5p.additionallicenseinfo": "Any additional information about the license",
|
||||||
"core.h5p.author": "Author",
|
"core.h5p.author": "Author",
|
||||||
|
"core.h5p.authorcomments": "Author comments",
|
||||||
|
"core.h5p.authorcommentsdescription": "Comments for the editor of the content. (This text will not be published as a part of the copyright info.)",
|
||||||
|
"core.h5p.authorname": "Author's name",
|
||||||
|
"core.h5p.authorrole": "Author's role",
|
||||||
"core.h5p.by": "by",
|
"core.h5p.by": "by",
|
||||||
"core.h5p.cancellabel": "Cancel",
|
"core.h5p.cancellabel": "Cancel",
|
||||||
"core.h5p.ccattribution": "Attribution (CC BY)",
|
"core.h5p.ccattribution": "Attribution (CC BY)",
|
||||||
|
@ -1559,7 +1564,11 @@
|
||||||
"core.h5p.ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
"core.h5p.ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
||||||
"core.h5p.ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
"core.h5p.ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
||||||
"core.h5p.ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
"core.h5p.ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
||||||
|
"core.h5p.ccpdd": "Public Domain Dedication (CC0)",
|
||||||
|
"core.h5p.changedby": "Changed by",
|
||||||
|
"core.h5p.changedescription": "Description of change",
|
||||||
"core.h5p.changelog": "Changelog",
|
"core.h5p.changelog": "Changelog",
|
||||||
|
"core.h5p.changeplaceholder": "Photo cropped, text changed, etc.",
|
||||||
"core.h5p.close": "Close",
|
"core.h5p.close": "Close",
|
||||||
"core.h5p.confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
"core.h5p.confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
||||||
"core.h5p.confirmdialogheader": "Confirm action",
|
"core.h5p.confirmdialogheader": "Confirm action",
|
||||||
|
@ -1570,18 +1579,24 @@
|
||||||
"core.h5p.contentchanged": "This content has changed since you last used it.",
|
"core.h5p.contentchanged": "This content has changed since you last used it.",
|
||||||
"core.h5p.contenttype": "Content Type",
|
"core.h5p.contenttype": "Content Type",
|
||||||
"core.h5p.copyright": "Rights of use",
|
"core.h5p.copyright": "Rights of use",
|
||||||
|
"core.h5p.copyrightinfo": "Copyright information",
|
||||||
"core.h5p.copyrightstring": "Copyright",
|
"core.h5p.copyrightstring": "Copyright",
|
||||||
"core.h5p.copyrighttitle": "View copyright information for this content.",
|
"core.h5p.copyrighttitle": "View copyright information for this content.",
|
||||||
|
"core.h5p.creativecommons": "Creative Commons",
|
||||||
|
"core.h5p.date": "Date",
|
||||||
"core.h5p.disablefullscreen": "Disable fullscreen",
|
"core.h5p.disablefullscreen": "Disable fullscreen",
|
||||||
"core.h5p.download": "Download",
|
"core.h5p.download": "Download",
|
||||||
"core.h5p.downloadtitle": "Download this content as a H5P file.",
|
"core.h5p.downloadtitle": "Download this content as a H5P file.",
|
||||||
|
"core.h5p.editor": "Editor",
|
||||||
"core.h5p.embed": "Embed",
|
"core.h5p.embed": "Embed",
|
||||||
"core.h5p.embedtitle": "View the embed code for this content.",
|
"core.h5p.embedtitle": "View the embed code for this content.",
|
||||||
"core.h5p.fullscreen": "Fullscreen",
|
"core.h5p.fullscreen": "Fullscreen",
|
||||||
|
"core.h5p.gpl": "General Public License v3",
|
||||||
"core.h5p.h5ptitle": "Visit H5P.org to check out more cool content.",
|
"core.h5p.h5ptitle": "Visit H5P.org to check out more cool content.",
|
||||||
"core.h5p.hideadvanced": "Hide advanced",
|
"core.h5p.hideadvanced": "Hide advanced",
|
||||||
"core.h5p.license": "License",
|
"core.h5p.license": "License",
|
||||||
"core.h5p.licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
"core.h5p.licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
||||||
|
"core.h5p.licenseCC010U": "CC0 1.0 Universal",
|
||||||
"core.h5p.licenseCC10": "1.0 Generic",
|
"core.h5p.licenseCC10": "1.0 Generic",
|
||||||
"core.h5p.licenseCC20": "2.0 Generic",
|
"core.h5p.licenseCC20": "2.0 Generic",
|
||||||
"core.h5p.licenseCC25": "2.5 Generic",
|
"core.h5p.licenseCC25": "2.5 Generic",
|
||||||
|
@ -1591,14 +1606,18 @@
|
||||||
"core.h5p.licenseV1": "Version 1",
|
"core.h5p.licenseV1": "Version 1",
|
||||||
"core.h5p.licenseV2": "Version 2",
|
"core.h5p.licenseV2": "Version 2",
|
||||||
"core.h5p.licenseV3": "Version 3",
|
"core.h5p.licenseV3": "Version 3",
|
||||||
|
"core.h5p.licensee": "Licensee",
|
||||||
"core.h5p.licenseextras": "License Extras",
|
"core.h5p.licenseextras": "License Extras",
|
||||||
|
"core.h5p.licenseversion": "License version",
|
||||||
"core.h5p.nocopyright": "No copyright information available for this content.",
|
"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.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.offlineDialogHeader": "Your connection to the server was lost",
|
||||||
"core.h5p.offlineDialogRetryButtonLabel": "Retry now",
|
"core.h5p.offlineDialogRetryButtonLabel": "Retry now",
|
||||||
"core.h5p.offlineDialogRetryMessage": "Retrying in :num....",
|
"core.h5p.offlineDialogRetryMessage": "Retrying in :num....",
|
||||||
"core.h5p.offlineSuccessfulSubmit": "Successfully submitted results.",
|
"core.h5p.offlineSuccessfulSubmit": "Successfully submitted results.",
|
||||||
|
"core.h5p.originator": "Originator",
|
||||||
"core.h5p.pd": "Public Domain",
|
"core.h5p.pd": "Public Domain",
|
||||||
|
"core.h5p.pddl": "Public Domain Dedication and Licence",
|
||||||
"core.h5p.pdm": "Public Domain Mark (PDM)",
|
"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.resizescript": "Include this script on your website if you want dynamic sizing of the embedded content:",
|
||||||
|
@ -1617,6 +1636,9 @@
|
||||||
"core.h5p.title": "Title",
|
"core.h5p.title": "Title",
|
||||||
"core.h5p.undisclosed": "Undisclosed",
|
"core.h5p.undisclosed": "Undisclosed",
|
||||||
"core.h5p.year": "Year",
|
"core.h5p.year": "Year",
|
||||||
|
"core.h5p.years": "Year(s)",
|
||||||
|
"core.h5p.yearsfrom": "Years (from)",
|
||||||
|
"core.h5p.yearsto": "Years (to)",
|
||||||
"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",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -129,8 +129,12 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
// Local package.
|
// Local package.
|
||||||
this.playerSrc = url;
|
this.playerSrc = url;
|
||||||
} else {
|
} else {
|
||||||
|
// Never allow downloading in the app. This will only work if the user is allowed to change the params.
|
||||||
|
const src = this.src && this.src.replace(CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD + '=1',
|
||||||
|
CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD + '=0');
|
||||||
|
|
||||||
// Get auto-login URL so the user is automatically authenticated.
|
// Get auto-login URL so the user is automatically authenticated.
|
||||||
return this.sitesProvider.getCurrentSite().getAutoLoginUrl(this.src, false).then((url) => {
|
return this.sitesProvider.getCurrentSite().getAutoLoginUrl(src, false).then((url) => {
|
||||||
// Add the preventredirect param so the user can authenticate.
|
// Add the preventredirect param so the user can authenticate.
|
||||||
this.playerSrc = this.urlUtils.addParamsToUrl(url, {preventredirect: false});
|
this.playerSrc = this.urlUtils.addParamsToUrl(url, {preventredirect: false});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
{
|
{
|
||||||
|
"additionallicenseinfo": "Any additional information about the license",
|
||||||
"author": "Author",
|
"author": "Author",
|
||||||
|
"authorcomments": "Author comments",
|
||||||
|
"authorcommentsdescription": "Comments for the editor of the content. (This text will not be published as a part of the copyright info.)",
|
||||||
|
"authorname": "Author's name",
|
||||||
|
"authorrole": "Author's role",
|
||||||
"by": "by",
|
"by": "by",
|
||||||
"cancellabel": "Cancel",
|
"cancellabel": "Cancel",
|
||||||
"ccattribution": "Attribution (CC BY)",
|
"ccattribution": "Attribution (CC BY)",
|
||||||
|
@ -8,7 +13,11 @@
|
||||||
"ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
"ccattributionncsa": "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)",
|
||||||
"ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
"ccattributionnd": "Attribution-NoDerivs (CC BY-ND)",
|
||||||
"ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
"ccattributionsa": "Attribution-ShareAlike (CC BY-SA)",
|
||||||
|
"ccpdd": "Public Domain Dedication (CC0)",
|
||||||
|
"changedby": "Changed by",
|
||||||
|
"changedescription": "Description of change",
|
||||||
"changelog": "Changelog",
|
"changelog": "Changelog",
|
||||||
|
"changeplaceholder": "Photo cropped, text changed, etc.",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
"confirmdialogbody": "Please confirm that you wish to proceed. This action is not reversible.",
|
||||||
"confirmdialogheader": "Confirm action",
|
"confirmdialogheader": "Confirm action",
|
||||||
|
@ -19,18 +28,24 @@
|
||||||
"contentchanged": "This content has changed since you last used it.",
|
"contentchanged": "This content has changed since you last used it.",
|
||||||
"contenttype": "Content Type",
|
"contenttype": "Content Type",
|
||||||
"copyright": "Rights of use",
|
"copyright": "Rights of use",
|
||||||
|
"copyrightinfo": "Copyright information",
|
||||||
"copyrightstring": "Copyright",
|
"copyrightstring": "Copyright",
|
||||||
"copyrighttitle": "View copyright information for this content.",
|
"copyrighttitle": "View copyright information for this content.",
|
||||||
|
"creativecommons": "Creative Commons",
|
||||||
|
"date": "Date",
|
||||||
"disablefullscreen": "Disable fullscreen",
|
"disablefullscreen": "Disable fullscreen",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"downloadtitle": "Download this content as a H5P file.",
|
"downloadtitle": "Download this content as a H5P file.",
|
||||||
|
"editor": "Editor",
|
||||||
"embed": "Embed",
|
"embed": "Embed",
|
||||||
"embedtitle": "View the embed code for this content.",
|
"embedtitle": "View the embed code for this content.",
|
||||||
"fullscreen": "Fullscreen",
|
"fullscreen": "Fullscreen",
|
||||||
|
"gpl": "General Public License v3",
|
||||||
"h5ptitle": "Visit H5P.org to check out more cool content.",
|
"h5ptitle": "Visit H5P.org to check out more cool content.",
|
||||||
"hideadvanced": "Hide advanced",
|
"hideadvanced": "Hide advanced",
|
||||||
"license": "License",
|
"license": "License",
|
||||||
"licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
"licenseCC010": "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
|
||||||
|
"licenseCC010U": "CC0 1.0 Universal",
|
||||||
"licenseCC10": "1.0 Generic",
|
"licenseCC10": "1.0 Generic",
|
||||||
"licenseCC20": "2.0 Generic",
|
"licenseCC20": "2.0 Generic",
|
||||||
"licenseCC25": "2.5 Generic",
|
"licenseCC25": "2.5 Generic",
|
||||||
|
@ -40,14 +55,18 @@
|
||||||
"licenseV1": "Version 1",
|
"licenseV1": "Version 1",
|
||||||
"licenseV2": "Version 2",
|
"licenseV2": "Version 2",
|
||||||
"licenseV3": "Version 3",
|
"licenseV3": "Version 3",
|
||||||
|
"licensee": "Licensee",
|
||||||
"licenseextras": "License Extras",
|
"licenseextras": "License Extras",
|
||||||
|
"licenseversion": "License version",
|
||||||
"nocopyright": "No copyright information available for this content.",
|
"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.",
|
"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",
|
"offlineDialogHeader": "Your connection to the server was lost",
|
||||||
"offlineDialogRetryButtonLabel": "Retry now",
|
"offlineDialogRetryButtonLabel": "Retry now",
|
||||||
"offlineDialogRetryMessage": "Retrying in :num....",
|
"offlineDialogRetryMessage": "Retrying in :num....",
|
||||||
"offlineSuccessfulSubmit": "Successfully submitted results.",
|
"offlineSuccessfulSubmit": "Successfully submitted results.",
|
||||||
|
"originator": "Originator",
|
||||||
"pd": "Public Domain",
|
"pd": "Public Domain",
|
||||||
|
"pddl": "Public Domain Dedication and Licence",
|
||||||
"pdm": "Public Domain Mark (PDM)",
|
"pdm": "Public Domain Mark (PDM)",
|
||||||
"play": "Play H5P",
|
"play": "Play H5P",
|
||||||
"resizescript": "Include this script on your website if you want dynamic sizing of the embedded content:",
|
"resizescript": "Include this script on your website if you want dynamic sizing of the embedded content:",
|
||||||
|
@ -65,5 +84,8 @@
|
||||||
"thumbnail": "Thumbnail",
|
"thumbnail": "Thumbnail",
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"undisclosed": "Undisclosed",
|
"undisclosed": "Undisclosed",
|
||||||
"year": "Year"
|
"year": "Year",
|
||||||
|
"years": "Year(s)",
|
||||||
|
"yearsfrom": "Years (from)",
|
||||||
|
"yearsto": "Years (to)"
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
||||||
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { CoreH5PUtilsProvider } from './utils';
|
import { CoreH5PUtilsProvider } from './utils';
|
||||||
|
import { CoreH5PContentValidator } from '../classes/content-validator';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { FileEntry } from '@ionic-native/file';
|
import { FileEntry } from '@ionic-native/file';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,7 +306,8 @@ export class CoreH5PProvider {
|
||||||
private h5pUtils: CoreH5PUtilsProvider,
|
private h5pUtils: CoreH5PUtilsProvider,
|
||||||
private filepoolProvider: CoreFilepoolProvider,
|
private filepoolProvider: CoreFilepoolProvider,
|
||||||
private utils: CoreUtilsProvider,
|
private utils: CoreUtilsProvider,
|
||||||
private urlUtils: CoreUrlUtilsProvider) {
|
private urlUtils: CoreUrlUtilsProvider,
|
||||||
|
private translate: TranslateService) {
|
||||||
|
|
||||||
this.logger = logger.getInstance('CoreH5PProvider');
|
this.logger = logger.getInstance('CoreH5PProvider');
|
||||||
|
|
||||||
|
@ -415,6 +418,7 @@ export class CoreH5PProvider {
|
||||||
* @return Promise resolved with all of the files content in one string.
|
* @return Promise resolved with all of the files content in one string.
|
||||||
*/
|
*/
|
||||||
protected concatenateFiles(assets: CoreH5PDependencyAsset[], type: string): Promise<string> {
|
protected concatenateFiles(assets: CoreH5PDependencyAsset[], type: string): Promise<string> {
|
||||||
|
const basePath = this.fileProvider.getBasePathInstant();
|
||||||
let content = '',
|
let content = '',
|
||||||
promise = Promise.resolve(); // Use a chain of promises so the order is kept.
|
promise = Promise.resolve(); // Use a chain of promises so the order is kept.
|
||||||
|
|
||||||
|
@ -433,39 +437,42 @@ export class CoreH5PProvider {
|
||||||
|
|
||||||
if (matches && matches.length) {
|
if (matches && matches.length) {
|
||||||
matches.forEach((match) => {
|
matches.forEach((match) => {
|
||||||
let url = match.replace(/(url\([\'"]?|[\'"]?\)$)/i, '');
|
let url = match.replace(/(url\(['"]?|['"]?\)$)/ig, '');
|
||||||
|
|
||||||
if (treated[url] || url.match(/^(data:|([a-z0-9]+:)?\/)/i)) {
|
if (treated[url] || url.match(/^(data:|([a-z0-9]+:)?\/)/i)) {
|
||||||
return; // Not relative or already treated, skip.
|
return; // Not relative or already treated, skip.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pathSplit = assetPath.split('/');
|
||||||
treated[url] = url;
|
treated[url] = url;
|
||||||
|
|
||||||
/* Find "../" in the URL. If it exists, we have to remove "../" and switch the last folder in the
|
/* Find "../" in the URL. If it exists, we have to remove "../" and switch the last folder in the
|
||||||
filepath for the first folder in the url.
|
filepath for the first folder in the url. */
|
||||||
For instance:
|
|
||||||
Path: /H5P.Question-1.4/styles/
|
|
||||||
Url: ../images/plus-one.svg
|
|
||||||
We want this: H5P.Question-1.4/images/ITEMID/minus-one.svg. */
|
|
||||||
if (url.match(/^\.\.\//)) {
|
if (url.match(/^\.\.\//)) {
|
||||||
const pathSplit = assetPath.split('/'),
|
const urlSplit = url.split('/').filter((i) => {
|
||||||
urlSplit = url.split('/').filter((i) => {
|
|
||||||
return i; // Remove empty values.
|
return i; // Remove empty values.
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove the first element: ../.
|
// Remove the file name from the asset path.
|
||||||
urlSplit.unshift();
|
pathSplit.pop();
|
||||||
|
|
||||||
|
// Remove the first element from the file URL: ../ .
|
||||||
|
urlSplit.shift();
|
||||||
|
|
||||||
// Put the url's first folder into the asset path.
|
// Put the url's first folder into the asset path.
|
||||||
pathSplit[pathSplit.length - 1] = urlSplit[0];
|
pathSplit[pathSplit.length - 1] = urlSplit[0];
|
||||||
urlSplit.shift();
|
urlSplit.shift();
|
||||||
|
|
||||||
// Create the new URL and replace it in the file contents.
|
// Create the new URL and replace it in the file contents.
|
||||||
url = '/' + pathSplit.join('/') + '/' + urlSplit.join('/');
|
url = pathSplit.join('/') + '/' + urlSplit.join('/');
|
||||||
|
|
||||||
fileContent = fileContent.replace(new RegExp(this.textUtils.escapeForRegex(match), 'g'),
|
} else {
|
||||||
'url("' + url + '")');
|
pathSplit[pathSplit.length - 1] = url; // Put the whole path to the end of the asset path.
|
||||||
|
url = pathSplit.join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileContent = fileContent.replace(new RegExp(this.textUtils.escapeForRegex(match), 'g'),
|
||||||
|
'url("' + this.textUtils.concatenatePaths(basePath, url) + '")');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,11 +517,11 @@ export class CoreH5PProvider {
|
||||||
url: this.getEmbedUrl(site.getURL(), h5pUrl),
|
url: this.getEmbedUrl(site.getURL(), h5pUrl),
|
||||||
contentUrl: contentUrl,
|
contentUrl: contentUrl,
|
||||||
metadata: content.metadata,
|
metadata: content.metadata,
|
||||||
contentUserData: {
|
contentUserData: [
|
||||||
0: {
|
{
|
||||||
state: '{}'
|
state: '{}'
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the core H5P assets, needed by the H5P classes to render the H5P content.
|
// Get the core H5P assets, needed by the H5P classes to render the H5P content.
|
||||||
|
@ -859,8 +866,7 @@ export class CoreH5PProvider {
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dependencies = {}, // In web, dependencies are built by the validator.
|
const params = {
|
||||||
params = {
|
|
||||||
library: this.libraryToString(content.library),
|
library: this.libraryToString(content.library),
|
||||||
params: this.textUtils.parseJSON(content.params, false)
|
params: this.textUtils.parseJSON(content.params, false)
|
||||||
};
|
};
|
||||||
|
@ -869,90 +875,65 @@ export class CoreH5PProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the main library data.
|
const validator = new CoreH5PContentValidator(this, this.h5pUtils, this.textUtils, this.utils, this.translate, siteId);
|
||||||
return this.loadLibrary(content.library.name, content.library.majorVersion, content.library.minorVersion, siteId)
|
|
||||||
.then((library) => {
|
|
||||||
|
|
||||||
library.semantics = this.textUtils.parseJSON(library.semantics, '');
|
// Validate the main library and its dependencies.
|
||||||
|
return validator.validateLibrary(params, {options: [params.library]}).then(() => {
|
||||||
|
|
||||||
const depKey = 'preloaded-' + library.machineName;
|
// Handle addons.
|
||||||
let nextWeight;
|
return this.loadAddons(siteId);
|
||||||
|
}).then((addons) => {
|
||||||
|
// Validate addons. Use a chain of promises to calculate the weight properly.
|
||||||
|
let promise = Promise.resolve();
|
||||||
|
|
||||||
if (!dependencies[depKey]) {
|
addons.forEach((addon) => {
|
||||||
dependencies[depKey] = {
|
const addTo = addon.addTo;
|
||||||
library: library,
|
|
||||||
type: 'preloaded'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the whole library dependency tree.
|
if (addTo && addTo.content && addTo.content.types && addTo.content.types.length) {
|
||||||
return this.findLibraryDependencies(dependencies, library, 1, false, siteId).then((weight) => {
|
for (let i = 0; i < addTo.content.types.length; i++) {
|
||||||
nextWeight = weight;
|
const type = addTo.content.types[i];
|
||||||
dependencies[depKey].weight = nextWeight++;
|
|
||||||
|
|
||||||
// Handle addons.
|
if (type && type.text && type.text.regex &&
|
||||||
return this.loadAddons(siteId);
|
this.h5pUtils.textAddonMatches(params.params, type.text.regex)) {
|
||||||
}).then((addons) => {
|
|
||||||
// Get the dependencies of all the addons. Use a chain of promises to calculate the weight properly.
|
|
||||||
let promise = Promise.resolve();
|
|
||||||
|
|
||||||
addons.forEach((addon) => {
|
promise = promise.then(() => {
|
||||||
const addTo = this.textUtils.parseJSON(addon.addTo, null);
|
return validator.addon(addon);
|
||||||
|
});
|
||||||
|
|
||||||
if (addTo && addTo.content && addTo.content.types && addTo.content.types.length) {
|
// An addon shall only be added once.
|
||||||
for (let i = 0; i < addTo.content.types.length; i++) {
|
break;
|
||||||
const type = addTo.content.types[i];
|
|
||||||
|
|
||||||
if (type && type.text && type.text.regex &&
|
|
||||||
this.h5pUtils.textAddonMatches(params.params, type.text.regex)) {
|
|
||||||
|
|
||||||
const addonDepKey = 'preloaded-' + addon.machineName;
|
|
||||||
dependencies[addonDepKey] = {
|
|
||||||
library: addon,
|
|
||||||
type: 'preloaded'
|
|
||||||
};
|
|
||||||
|
|
||||||
promise = promise.then(() => {
|
|
||||||
return this.findLibraryDependencies(dependencies, addon, nextWeight).then((weight) => {
|
|
||||||
nextWeight = weight;
|
|
||||||
dependencies[addonDepKey].weight = nextWeight++;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
}).then(() => {
|
|
||||||
// Update content dependencies.
|
|
||||||
content.dependencies = dependencies;
|
|
||||||
|
|
||||||
const paramsStr = JSON.stringify(params.params);
|
|
||||||
|
|
||||||
// Sometimes the parameters are filtered before content has been created
|
|
||||||
if (content.id) {
|
|
||||||
// Update library usage.
|
|
||||||
return this.deleteLibraryUsage(content.id, siteId).catch(() => {
|
|
||||||
// Ignore errors.
|
|
||||||
}).then(() => {
|
|
||||||
return this.saveLibraryUsage(content.id, content.dependencies, siteId);
|
|
||||||
}).then(() => {
|
|
||||||
if (!content.slug) {
|
|
||||||
content.slug = this.h5pUtils.slugify(content.title);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache.
|
|
||||||
return this.updateContentFields(content.id, {filtered: paramsStr}, siteId).then(() => {
|
|
||||||
return paramsStr;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return paramsStr;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}).then(() => {
|
||||||
|
// Update content dependencies.
|
||||||
|
content.dependencies = validator.getDependencies();
|
||||||
|
|
||||||
|
const paramsStr = JSON.stringify(params.params);
|
||||||
|
|
||||||
|
// Sometimes the parameters are filtered before content has been created
|
||||||
|
if (content.id) {
|
||||||
|
// Update library usage.
|
||||||
|
return this.deleteLibraryUsage(content.id, siteId).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
}).then(() => {
|
||||||
|
return this.saveLibraryUsage(content.id, content.dependencies, siteId);
|
||||||
|
}).then(() => {
|
||||||
|
if (!content.slug) {
|
||||||
|
content.slug = this.h5pUtils.slugify(content.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache.
|
||||||
|
return this.updateContentFields(content.id, {filtered: paramsStr}, siteId).then(() => {
|
||||||
|
return paramsStr;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return paramsStr;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -990,12 +971,13 @@ export class CoreH5PProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
library[property].forEach((dependency: CoreH5PLibraryBasicData) => {
|
library[property].forEach((dependency: CoreH5PLibraryBasicData) => {
|
||||||
const dependencyKey = type + '-' + dependency.machineName;
|
|
||||||
if (dependencies[dependencyKey]) {
|
|
||||||
return; // Skip, already have this.
|
|
||||||
}
|
|
||||||
|
|
||||||
promise = promise.then(() => {
|
promise = promise.then(() => {
|
||||||
|
const dependencyKey = type + '-' + dependency.machineName;
|
||||||
|
if (dependencies[dependencyKey]) {
|
||||||
|
return; // Skip, already have this.
|
||||||
|
}
|
||||||
|
|
||||||
// Get the dependency library data and its subdependencies.
|
// Get the dependency library data and its subdependencies.
|
||||||
return this.loadLibrary(dependency.machineName, dependency.majorVersion, dependency.minorVersion, siteId)
|
return this.loadLibrary(dependency.machineName, dependency.majorVersion, dependency.minorVersion, siteId)
|
||||||
.then((dependencyLibrary) => {
|
.then((dependencyLibrary) => {
|
||||||
|
@ -1424,7 +1406,7 @@ export class CoreH5PProvider {
|
||||||
// Aggregate and store assets.
|
// Aggregate and store assets.
|
||||||
return this.cacheAssets(files, cachedAssetsHash, folderName, siteId).then(() => {
|
return this.cacheAssets(files, cachedAssetsHash, folderName, siteId).then(() => {
|
||||||
// Keep track of which libraries have been cached in case they are updated.
|
// Keep track of which libraries have been cached in case they are updated.
|
||||||
return this.saveCachedAssets(cachedAssetsHash, dependencies, siteId);
|
return this.saveCachedAssets(cachedAssetsHash, dependencies, folderName, siteId);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return files;
|
return files;
|
||||||
});
|
});
|
||||||
|
@ -1652,12 +1634,12 @@ export class CoreH5PProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.getRecords(this.LIBRARIES_TABLE, conditions);
|
return db.getRecords(this.LIBRARIES_TABLE, conditions);
|
||||||
}).then((libraries) => {
|
}).then((libraries): any => {
|
||||||
if (!libraries.length) {
|
if (!libraries.length) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return libraries[0];
|
return this.parseLibDBData(libraries[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1681,7 +1663,9 @@ export class CoreH5PProvider {
|
||||||
*/
|
*/
|
||||||
protected getLibraryById(id: number, siteId?: string): Promise<CoreH5PLibraryDBData> {
|
protected getLibraryById(id: number, siteId?: string): Promise<CoreH5PLibraryDBData> {
|
||||||
return this.sitesProvider.getSiteDb(siteId).then((db) => {
|
return this.sitesProvider.getSiteDb(siteId).then((db) => {
|
||||||
return db.getRecord(this.LIBRARIES_TABLE, {id: id});
|
return db.getRecord(this.LIBRARIES_TABLE, {id: id}).then((library) => {
|
||||||
|
return this.parseLibDBData(library);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1946,7 +1930,7 @@ export class CoreH5PProvider {
|
||||||
const addons = [];
|
const addons = [];
|
||||||
|
|
||||||
for (let i = 0; i < result.rows.length; i++) {
|
for (let i = 0; i < result.rows.length; i++) {
|
||||||
addons.push(result.rows.item(i));
|
addons.push(this.parseLibAddonData(result.rows.item(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return addons;
|
return addons;
|
||||||
|
@ -1963,6 +1947,8 @@ export class CoreH5PProvider {
|
||||||
* @return Promise resolved with the content data.
|
* @return Promise resolved with the content data.
|
||||||
*/
|
*/
|
||||||
protected loadContentData(id?: number, fileUrl?: string, siteId?: string): Promise<CoreH5PContentData> {
|
protected loadContentData(id?: number, fileUrl?: string, siteId?: string): Promise<CoreH5PContentData> {
|
||||||
|
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||||
|
|
||||||
let promise: Promise<CoreH5PContentDBData>;
|
let promise: Promise<CoreH5PContentDBData>;
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
|
@ -1978,31 +1964,35 @@ export class CoreH5PProvider {
|
||||||
// Load the main library data.
|
// Load the main library data.
|
||||||
return this.getLibraryById(contentData.mainlibraryid, siteId).then((libData) => {
|
return this.getLibraryById(contentData.mainlibraryid, siteId).then((libData) => {
|
||||||
|
|
||||||
// Map the values to the names used by the H5P core (it's the same Moodle web does).
|
// Validate metadata.
|
||||||
return {
|
const validator = new CoreH5PContentValidator(this, this.h5pUtils, this.textUtils, this.utils, this.translate,
|
||||||
id: contentData.id,
|
siteId);
|
||||||
params: contentData.jsoncontent,
|
|
||||||
// The embedtype will be always set to 'iframe' to prevent conflicts with JS and CSS.
|
// Validate empty metadata, like Moodle web does.
|
||||||
embedType: 'iframe',
|
return validator.validateMetadata({}).then((metadata) => {
|
||||||
disable: null,
|
// Map the values to the names used by the H5P core (it's the same Moodle web does).
|
||||||
folderName: contentData.foldername,
|
return {
|
||||||
title: libData.title,
|
id: contentData.id,
|
||||||
slug: this.h5pUtils.slugify(libData.title) + '-' + contentData.id,
|
params: contentData.jsoncontent,
|
||||||
filtered: contentData.filtered,
|
embedType: 'iframe', // Always use iframe.
|
||||||
libraryMajorVersion: libData.majorversion,
|
disable: null,
|
||||||
libraryMinorVersion: libData.minorversion,
|
folderName: contentData.foldername,
|
||||||
metadata: {
|
title: libData.title,
|
||||||
license: 'U' // Stop "invalid selected option in select" for old content without license chosen.
|
slug: this.h5pUtils.slugify(libData.title) + '-' + contentData.id,
|
||||||
},
|
filtered: contentData.filtered,
|
||||||
library: {
|
libraryMajorVersion: libData.majorversion,
|
||||||
id: libData.id,
|
libraryMinorVersion: libData.minorversion,
|
||||||
name: libData.machinename,
|
metadata: metadata,
|
||||||
majorVersion: libData.majorversion,
|
library: {
|
||||||
minorVersion: libData.minorversion,
|
id: libData.id,
|
||||||
embedTypes: libData.embedtypes,
|
name: libData.machinename,
|
||||||
fullscreen: libData.fullscreen
|
majorVersion: libData.majorversion,
|
||||||
}
|
minorVersion: libData.minorversion,
|
||||||
};
|
embedTypes: libData.embedtypes,
|
||||||
|
fullscreen: libData.fullscreen
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2113,6 +2103,31 @@ export class CoreH5PProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse library addon data.
|
||||||
|
*
|
||||||
|
* @param library Library addon data.
|
||||||
|
* @return Parsed library.
|
||||||
|
*/
|
||||||
|
parseLibAddonData(library: any): CoreH5PLibraryAddonData {
|
||||||
|
library.addto = this.textUtils.parseJSON(library.addto, null);
|
||||||
|
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse library DB data.
|
||||||
|
*
|
||||||
|
* @param library Library DB data.
|
||||||
|
* @return Parsed library.
|
||||||
|
*/
|
||||||
|
parseLibDBData(library: any): CoreH5PLibraryDBData {
|
||||||
|
library.semantics = this.textUtils.parseJSON(library.semantics, null);
|
||||||
|
library.addto = this.textUtils.parseJSON(library.addto, null);
|
||||||
|
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process libraries from an H5P library, getting the required data to save them.
|
* Process libraries from an H5P library, getting the required data to save them.
|
||||||
* This code was copied from the isValidPackage function in Moodle's H5PValidator.
|
* This code was copied from the isValidPackage function in Moodle's H5PValidator.
|
||||||
|
@ -2172,12 +2187,13 @@ export class CoreH5PProvider {
|
||||||
* know which cache file to delete when a library is updated.
|
* know which cache file to delete when a library is updated.
|
||||||
*
|
*
|
||||||
* @param key Hash key for the given libraries.
|
* @param key Hash key for the given libraries.
|
||||||
* @param libraries List of dependencies used to create the key
|
* @param libraries List of dependencies used to create the key.
|
||||||
|
* @param folderName The name of the folder that contains the H5P.
|
||||||
* @param siteId The site ID.
|
* @param siteId The site ID.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected saveCachedAssets(hash: string, dependencies: {[machineName: string]: CoreH5PContentDependencyData},
|
protected saveCachedAssets(hash: string, dependencies: {[machineName: string]: CoreH5PContentDependencyData},
|
||||||
siteId?: string): Promise<any> {
|
folderName: string, siteId?: string): Promise<any> {
|
||||||
|
|
||||||
return this.sitesProvider.getSiteDb(siteId).then((db) => {
|
return this.sitesProvider.getSiteDb(siteId).then((db) => {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
@ -2185,7 +2201,8 @@ export class CoreH5PProvider {
|
||||||
for (const key in dependencies) {
|
for (const key in dependencies) {
|
||||||
const data = {
|
const data = {
|
||||||
hash: key,
|
hash: key,
|
||||||
libraryid: dependencies[key].libraryId
|
libraryid: dependencies[key].libraryId,
|
||||||
|
foldername: folderName
|
||||||
};
|
};
|
||||||
|
|
||||||
promises.push(db.insertRecord(this.LIBRARIES_CACHEDASSETS_TABLE, data));
|
promises.push(db.insertRecord(this.LIBRARIES_CACHEDASSETS_TABLE, data));
|
||||||
|
@ -2279,7 +2296,7 @@ export class CoreH5PProvider {
|
||||||
for (const libString in librariesJsonData) {
|
for (const libString in librariesJsonData) {
|
||||||
const libraryData = librariesJsonData[libString];
|
const libraryData = librariesJsonData[libString];
|
||||||
|
|
||||||
// Find local library identifier
|
// Find local library identifier.
|
||||||
promises.push(this.getLibraryByData(libraryData).catch(() => {
|
promises.push(this.getLibraryByData(libraryData).catch(() => {
|
||||||
// Not found.
|
// Not found.
|
||||||
}).then((dbData) => {
|
}).then((dbData) => {
|
||||||
|
@ -2422,7 +2439,7 @@ export class CoreH5PProvider {
|
||||||
preloadedjs: preloadedJS,
|
preloadedjs: preloadedJS,
|
||||||
preloadedcss: preloadedCSS,
|
preloadedcss: preloadedCSS,
|
||||||
droplibrarycss: dropLibraryCSS,
|
droplibrarycss: dropLibraryCSS,
|
||||||
semantics: libraryData.semantics,
|
semantics: typeof libraryData.semantics != 'undefined' ? JSON.stringify(libraryData.semantics) : null,
|
||||||
addto: typeof libraryData.addTo != 'undefined' ? JSON.stringify(libraryData.addTo) : null,
|
addto: typeof libraryData.addTo != 'undefined' ? JSON.stringify(libraryData.addTo) : null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2497,8 +2514,8 @@ export class CoreH5PProvider {
|
||||||
for (const key in librariesInUse) {
|
for (const key in librariesInUse) {
|
||||||
const dependency = librariesInUse[key];
|
const dependency = librariesInUse[key];
|
||||||
|
|
||||||
if (dependency.library.dropLibraryCss) {
|
if ((<CoreH5PLibraryData> dependency.library).dropLibraryCss) {
|
||||||
const split = dependency.library.dropLibraryCss.split(', ');
|
const split = (<CoreH5PLibraryData> dependency.library).dropLibraryCss.split(', ');
|
||||||
|
|
||||||
split.forEach((css) => {
|
split.forEach((css) => {
|
||||||
dropLibraryCssList[css] = css;
|
dropLibraryCssList[css] = css;
|
||||||
|
@ -2739,7 +2756,7 @@ export type CoreH5PContentDependencyData = {
|
||||||
* Data for each content dependency in the dependency tree.
|
* Data for each content dependency in the dependency tree.
|
||||||
*/
|
*/
|
||||||
export type CoreH5PContentDepsTreeDependency = {
|
export type CoreH5PContentDepsTreeDependency = {
|
||||||
library: CoreH5PLibraryData; // Library data.
|
library: CoreH5PLibraryData | CoreH5PLibraryAddonData; // Library data.
|
||||||
type: string; // Dependency type.
|
type: string; // Dependency type.
|
||||||
weight?: number; // An integer determining the order of the libraries when they are loaded.
|
weight?: number; // An integer determining the order of the libraries when they are loaded.
|
||||||
};
|
};
|
||||||
|
@ -2786,7 +2803,7 @@ export type CoreH5PLibraryAddonData = {
|
||||||
patchVersion: number; // Patch version.
|
patchVersion: number; // Patch version.
|
||||||
preloadedJs?: string; // Comma separated list of scripts to load.
|
preloadedJs?: string; // Comma separated list of scripts to load.
|
||||||
preloadedCss?: string; // Comma separated list of stylesheets to load.
|
preloadedCss?: string; // Comma separated list of stylesheets to load.
|
||||||
addTo?: string; // Plugin configuration data.
|
addTo?: any; // Plugin configuration data.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2805,8 +2822,8 @@ export type CoreH5PLibraryDBData = {
|
||||||
preloadedjs?: string; // Comma separated list of scripts to load.
|
preloadedjs?: string; // Comma separated list of scripts to load.
|
||||||
preloadedcss?: string; // Comma separated list of stylesheets to load.
|
preloadedcss?: string; // Comma separated list of stylesheets to load.
|
||||||
droplibrarycss?: string; // List of libraries that should not have CSS included if this library is used. Comma separated list.
|
droplibrarycss?: string; // List of libraries that should not have CSS included if this library is used. Comma separated list.
|
||||||
semantics?: string; // The semantics definition in json format.
|
semantics?: any; // The semantics definition.
|
||||||
addto?: string; // Plugin configuration data.
|
addto?: any; // Plugin configuration data.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -313,6 +313,27 @@ export class CoreH5PUtilsProvider {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses library data from a string on the form {machineName} {majorVersion}.{minorVersion}.
|
||||||
|
*
|
||||||
|
* @param libraryString On the form {machineName} {majorVersion}.{minorVersion}
|
||||||
|
* @return Object with keys machineName, majorVersion and minorVersion. Null if string is not parsable.
|
||||||
|
*/
|
||||||
|
libraryFromString(libraryString: string): {machineName: string, majorVersion: number, minorVersion: number} {
|
||||||
|
|
||||||
|
const matches = libraryString.match(/^([\w0-9\-\.]{1,255})[\-\ ]([0-9]{1,5})\.([0-9]{1,5})$/i);
|
||||||
|
|
||||||
|
if (matches && matches.length >= 4) {
|
||||||
|
return {
|
||||||
|
machineName: matches[1],
|
||||||
|
majorVersion: Number(matches[2]),
|
||||||
|
minorVersion: Number(matches[3])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert list of library parameter values to csv.
|
* Convert list of library parameter values to csv.
|
||||||
*
|
*
|
||||||
|
|
|
@ -135,17 +135,19 @@ export class CoreUtilsProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an array of objects to an object, using a property of each entry as the key.
|
* Converts an array of objects to an object, using a property of each entry as the key.
|
||||||
|
* It can also be used to convert an array of strings to an object where the keys are the elements of the array.
|
||||||
* E.g. [{id: 10, name: 'A'}, {id: 11, name: 'B'}] => {10: {id: 10, name: 'A'}, 11: {id: 11, name: 'B'}}
|
* E.g. [{id: 10, name: 'A'}, {id: 11, name: 'B'}] => {10: {id: 10, name: 'A'}, 11: {id: 11, name: 'B'}}
|
||||||
*
|
*
|
||||||
* @param array The array to convert.
|
* @param array The array to convert.
|
||||||
* @param propertyName The name of the property to use as the key.
|
* @param propertyName The name of the property to use as the key. If not provided, the whole item will be used.
|
||||||
* @param result Object where to put the properties. If not defined, a new object will be created.
|
* @param result Object where to put the properties. If not defined, a new object will be created.
|
||||||
* @return The object.
|
* @return The object.
|
||||||
*/
|
*/
|
||||||
arrayToObject(array: any[], propertyName: string, result?: any): any {
|
arrayToObject(array: any[], propertyName?: string, result?: any): any {
|
||||||
result = result || {};
|
result = result || {};
|
||||||
array.forEach((entry) => {
|
array.forEach((entry) => {
|
||||||
result[entry[propertyName]] = entry;
|
const key = propertyName ? entry[propertyName] : entry;
|
||||||
|
result[key] = entry;
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in New Issue