MOBILE-2235 h5p: Fix issues identified during PeerReview

main
Dani Palou 2019-12-04 13:37:00 +01:00
parent 1a2ea9485f
commit 5dae06ff81
9 changed files with 141 additions and 165 deletions

View File

@ -1620,6 +1620,7 @@
"core.h5p.originator": "h5p", "core.h5p.originator": "h5p",
"core.h5p.pd": "h5p", "core.h5p.pd": "h5p",
"core.h5p.pddl": "h5p", "core.h5p.pddl": "h5p",
"core.h5p.play": "local_moodlemobileapp",
"core.h5p.pdm": "h5p", "core.h5p.pdm": "h5p",
"core.h5p.resizescript": "h5p", "core.h5p.resizescript": "h5p",
"core.h5p.resubmitScores": "h5p", "core.h5p.resubmitScores": "h5p",

View File

@ -172,11 +172,6 @@ export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHand
return this.filepoolProvider.downloadUrl(siteId, packageUrl, true, this.component, scorm.coursemodule, return this.filepoolProvider.downloadUrl(siteId, packageUrl, true, this.component, scorm.coursemodule,
undefined, this.downloadProgress.bind(this, true, onProgress)); undefined, this.downloadProgress.bind(this, true, onProgress));
} }
}).then(() => {
// Remove the destination folder to prevent having old unused files.
return this.fileProvider.removeDir(dirPath).catch(() => {
// Ignore errors, it might have failed because the folder doesn't exist.
});
}).then(() => { }).then(() => {
// Get the ZIP file path. // Get the ZIP file path.
return this.filepoolProvider.getFilePathByUrl(siteId, packageUrl); return this.filepoolProvider.getFilePathByUrl(siteId, packageUrl);

View File

@ -148,7 +148,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
if (this.canDownload && (this.state == CoreConstants.OUTDATED || this.state == CoreConstants.NOT_DOWNLOADED)) { if (this.canDownload && (this.state == CoreConstants.OUTDATED || this.state == CoreConstants.NOT_DOWNLOADED)) {
// Download the package in background if the size is low. // Download the package in background if the size is low.
this.downloadInBg().catch((error) => { this.attemptDownloadInBg().catch((error) => {
this.logger.error('Error downloading H5P in background', error); this.logger.error('Error downloading H5P in background', error);
}); });
} }
@ -188,7 +188,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
* *
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
protected downloadInBg(): Promise<any> { protected attemptDownloadInBg(): Promise<any> {
if (this.urlParams && this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() && if (this.urlParams && this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() &&
this.appProvider.isOnline()) { this.appProvider.isOnline()) {
@ -225,8 +225,6 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
if (this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() && this.site.containsUrl(this.src)) { if (this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() && this.site.containsUrl(this.src)) {
this.calculating = true;
this.calculateState(); this.calculateState();
// Listen for changes in the state. // Listen for changes in the state.
@ -238,19 +236,21 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
// An error probably means the file cannot be downloaded or we cannot check it (offline). // An error probably means the file cannot be downloaded or we cannot check it (offline).
}); });
return; } else {
this.calculating = false;
this.canDownload = false;
} }
this.calculating = false;
this.canDownload = false;
} }
/** /**
* Calcuñate state of the file. * Calculate state of the file.
* *
* @param fileUrl The H5P file URL. * @param fileUrl The H5P file URL.
*/ */
protected calculateState(): void { protected calculateState(): void {
this.calculating = true;
// Get the status of the file. // Get the status of the file.
this.filepoolProvider.getFileStateByUrl(this.siteId, this.urlParams.url).then((state) => { this.filepoolProvider.getFileStateByUrl(this.siteId, this.urlParams.url).then((state) => {
this.canDownload = true; this.canDownload = true;

View File

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreEventsProvider } from '@providers/events';
import { CoreFileProvider } from '@providers/file'; import { CoreFileProvider } from '@providers/file';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
@ -81,6 +80,10 @@ export class CoreH5PProvider {
protected siteSchema: CoreSiteSchema = { protected siteSchema: CoreSiteSchema = {
name: 'CoreH5PProvider', name: 'CoreH5PProvider',
version: 1, version: 1,
canBeCleared: [
this.CONTENT_TABLE, this.LIBRARIES_TABLE, this.LIBRARY_DEPENDENCIES_TABLE, this.CONTENTS_LIBRARIES_TABLE,
this.LIBRARIES_CACHEDASSETS_TABLE
],
tables: [ tables: [
{ {
name: this.CONTENT_TABLE, name: this.CONTENT_TABLE,
@ -101,10 +104,6 @@ export class CoreH5PProvider {
type: 'INTEGER', type: 'INTEGER',
notNull: true notNull: true
}, },
{
name: 'displayoptions', // Not used right now, but we keep the field to be consistent with Moodle web.
type: 'INTEGER'
},
{ {
name: 'foldername', name: 'foldername',
type: 'TEXT', type: 'TEXT',
@ -293,12 +292,11 @@ export class CoreH5PProvider {
] ]
}; };
protected ROOT_CACHE_KEY = 'mmH5P:'; protected ROOT_CACHE_KEY = 'CoreH5P:';
protected logger; protected logger;
constructor(logger: CoreLoggerProvider, constructor(logger: CoreLoggerProvider,
eventsProvider: CoreEventsProvider,
private sitesProvider: CoreSitesProvider, private sitesProvider: CoreSitesProvider,
private textUtils: CoreTextUtilsProvider, private textUtils: CoreTextUtilsProvider,
private fileProvider: CoreFileProvider, private fileProvider: CoreFileProvider,
@ -312,12 +310,6 @@ export class CoreH5PProvider {
this.logger = logger.getInstance('CoreH5PProvider'); this.logger = logger.getInstance('CoreH5PProvider');
this.sitesProvider.registerSiteSchema(this.siteSchema); this.sitesProvider.registerSiteSchema(this.siteSchema);
eventsProvider.on(CoreEventsProvider.SITE_STORAGE_DELETED, (data) => {
this.deleteAllData(data.siteId).catch((error) => {
this.logger.error('Error deleting all H5P data from site.', error);
});
});
} }
/** /**
@ -568,24 +560,6 @@ export class CoreH5PProvider {
}); });
} }
/**
* Delete all the H5P data from the DB of a certain site.
*
* @param siteId Site ID.
* @return Promise resolved when done.
*/
protected deleteAllData(siteId: string): Promise<any> {
return this.sitesProvider.getSiteDb(siteId).then((db) => {
return Promise.all([
db.deleteRecords(this.CONTENT_TABLE),
db.deleteRecords(this.LIBRARIES_TABLE),
db.deleteRecords(this.LIBRARY_DEPENDENCIES_TABLE),
db.deleteRecords(this.CONTENTS_LIBRARIES_TABLE),
db.deleteRecords(this.LIBRARIES_CACHEDASSETS_TABLE)
]);
});
}
/** /**
* Delete cached assets from DB and filesystem. * Delete cached assets from DB and filesystem.
* *
@ -784,14 +758,8 @@ export class CoreH5PProvider {
const folderName = this.mimeUtils.removeExtension(file.name), const folderName = this.mimeUtils.removeExtension(file.name),
destFolder = this.textUtils.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName); destFolder = this.textUtils.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
// Make sure the dest dir doesn't exist already. // Unzip the file.
return this.fileProvider.removeDir(destFolder).catch(() => { return this.fileProvider.unzipFile(file.toURL(), destFolder).then(() => {
// Ignore errors.
}).then(() => {
return this.fileProvider.createDir(destFolder);
}).then(() => {
return this.fileProvider.unzipFile(file.toURL(), destFolder);
}).then(() => {
// Read the contents of the unzipped dir. // Read the contents of the unzipped dir.
return this.fileProvider.getDirectoryContents(destFolder); return this.fileProvider.getDirectoryContents(destFolder);
}).then((contents) => { }).then((contents) => {
@ -830,11 +798,6 @@ export class CoreH5PProvider {
return Promise.reject(error); return Promise.reject(error);
}); });
}); });
}).then(() => {
// Remove tmp folder.
return this.fileProvider.removeDir(destFolder).catch(() => {
// Ignore errors, it will be deleted eventually.
});
}).then(() => { }).then(() => {
// Create the content player. // Create the content player.
@ -843,6 +806,11 @@ export class CoreH5PProvider {
return this.createContentIndex(content.id, fileUrl, contentData, embedType, siteId); return this.createContentIndex(content.id, fileUrl, contentData, embedType, siteId);
}); });
}).finally(() => {
// Remove tmp folder.
return this.fileProvider.removeDir(destFolder).catch(() => {
// Ignore errors, it will be deleted eventually.
});
}); });
}); });
}); });
@ -1002,6 +970,40 @@ export class CoreH5PProvider {
}); });
} }
/**
* Validate and fix display options, updating them if needed.
*
* @param displayOptions The display options to validate.
* @param id Package ID.
*/
fixDisplayOptions(displayOptions: CoreH5PDisplayOptions, id: number): CoreH5PDisplayOptions {
// Never allow downloading in the app.
displayOptions[CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD] = false;
// Embed - force setting it if always on or always off. In web, this is done when storing in DB.
const embed = this.getOption(CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
if (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW || embed == CoreH5PDisplayOptionBehaviour.NEVER_SHOW) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
}
if (!this.getOption(CoreH5PProvider.DISPLAY_OPTION_FRAME, true)) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_FRAME] = false;
} else {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = this.setDisplayOptionOverrides(
CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PPermission.EMBED_H5P, id,
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED]);
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT, true) == false) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT] = false;
}
}
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPY] = this.hasPermission(CoreH5PPermission.COPY_H5P, id);
return displayOptions;
}
/** /**
* Get the assets of a package. * Get the assets of a package.
* *
@ -1215,7 +1217,7 @@ export class CoreH5PProvider {
}).then((url) => { }).then((url) => {
// Add display options to the URL. // Add display options to the URL.
return this.getContentDataByUrl(fileUrl, siteId).then((data) => { return this.getContentDataByUrl(fileUrl, siteId).then((data) => {
const options = this.validateDisplayOptions(this.getDisplayOptionsFromUrlParams(urlParams), data.id); const options = this.fixDisplayOptions(this.getDisplayOptionsFromUrlParams(urlParams), data.id);
return this.urlUtils.addParamsToUrl(url, options, undefined, true); return this.urlUtils.addParamsToUrl(url, options, undefined, true);
}); });
@ -1478,7 +1480,7 @@ export class CoreH5PProvider {
* @return Display options as object. * @return Display options as object.
*/ */
getDisplayOptionsForView(disable: number, id: number): CoreH5PDisplayOptions { getDisplayOptionsForView(disable: number, id: number): CoreH5PDisplayOptions {
return this.validateDisplayOptions(this.getDisplayOptionsAsObject(disable), id); return this.fixDisplayOptions(this.getDisplayOptionsAsObject(disable), id);
} }
/** /**
@ -1733,8 +1735,8 @@ export class CoreH5PProvider {
* @return Return the value for this display option. * @return Return the value for this display option.
*/ */
getOption(name: string, defaultValue: any = false): any { getOption(name: string, defaultValue: any = false): any {
// For now, all them are disabled by default, so only will be rendered when defined in the displayoptions DB field. // For now, all them are disabled by default, so only will be rendered when defined in the display options.
return CoreH5PDisplayOptionBehaviour.CONTROLLED_BY_AUTHOR_DEFAULT_OFF; // CONTROLLED_BY_AUTHOR_DEFAULT_OFF. return CoreH5PDisplayOptionBehaviour.CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
} }
/** /**
@ -1776,7 +1778,7 @@ export class CoreH5PProvider {
* *
* @param url The file URL. * @param url The file URL.
* @param options Options. * @param options Options.
* @param ignoreCache Whether to ignore cache.. * @param ignoreCache Whether to ignore cache.
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file data. * @return Promise resolved with the file data.
*/ */
@ -2135,7 +2137,6 @@ export class CoreH5PProvider {
* *
* @param fileUrl The file URL used to download the file. * @param fileUrl The file URL used to download the file.
* @param file The file entry of the downloaded file. * @param file The file entry of the downloaded file.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
protected processH5PFiles(destFolder: string, entries: (DirectoryEntry | FileEntry)[]) protected processH5PFiles(destFolder: string, entries: (DirectoryEntry | FileEntry)[])
@ -2227,7 +2228,6 @@ export class CoreH5PProvider {
const data: any = { const data: any = {
jsoncontent: content.params, jsoncontent: content.params,
displayoptions: null,
mainlibraryid: content.library.libraryId, mainlibraryid: content.library.libraryId,
timemodified: Date.now(), timemodified: Date.now(),
filtered: null, filtered: null,
@ -2597,40 +2597,6 @@ export class CoreH5PProvider {
return db.updateRecords(this.CONTENT_TABLE, data, {id: id}); return db.updateRecords(this.CONTENT_TABLE, data, {id: id});
}); });
} }
/**
* Validate display options, updating them if needed.
*
* @param displayOptions The display options to validate.
* @param id Package ID.
*/
validateDisplayOptions(displayOptions: CoreH5PDisplayOptions, id: number): CoreH5PDisplayOptions {
// Never allow downloading in the app.
displayOptions[CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD] = false;
// Embed - force setting it if always on or always off. In web, this is done when storing in DB.
const embed = this.getOption(CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
if (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW || embed == CoreH5PDisplayOptionBehaviour.NEVER_SHOW) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
}
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_FRAME, true) == false) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_FRAME] = false;
} else {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = this.setDisplayOptionOverrides(
CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PPermission.EMBED_H5P, id,
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED]);
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT, true) == false) {
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT] = false;
}
}
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPY] = this.hasPermission(CoreH5PPermission.COPY_H5P, id);
return displayOptions;
}
} }
/** /**
@ -2701,7 +2667,6 @@ export type CoreH5PContentDBData = {
id: number; // The id of the content. id: number; // The id of the content.
jsoncontent: string; // The content in json format. jsoncontent: string; // The content in json format.
mainlibraryid: number; // The library we first instantiate for this node. mainlibraryid: number; // The library we first instantiate for this node.
displayoptions: number; // H5P Button display options. Not used right now.
foldername: string; // Name of the folder that contains the contents. foldername: string; // Name of the folder that contains the contents.
fileurl: string; // The online URL of the H5P package. fileurl: string; // The online URL of the H5P package.
filtered: string; // Filtered version of json_content. filtered: string; // Filtered version of json_content.

View File

@ -37,17 +37,6 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
protected fileProvider: CoreFileProvider, protected fileProvider: CoreFileProvider,
protected h5pProvider: CoreH5PProvider) { } protected h5pProvider: CoreH5PProvider) { }
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
canDownloadFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
return this.h5pProvider.getTrustedH5PFile(file.fileurl, {}, false, siteId);
}
/** /**
* React to a file being deleted. * React to a file being deleted.
* *
@ -61,6 +50,17 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
return this.h5pProvider.deleteContentByUrl(fileUrl, siteId); return this.h5pProvider.deleteContentByUrl(fileUrl, siteId);
} }
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
getDownloadableFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
return this.h5pProvider.getTrustedH5PFile(file.fileurl, {}, false, siteId);
}
/** /**
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by * Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml. * CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
@ -68,7 +68,7 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
* @param container Container where to get the URLs from. * @param container Container where to get the URLs from.
* @return {string[]} List of URLs. * @return {string[]} List of URLs.
*/ */
getDownloadableFiles(container: HTMLElement): string[] { getDownloadableFilesFromHTML(container: HTMLElement): string[] {
const iframes = <HTMLIFrameElement[]> Array.from(container.querySelectorAll('iframe.h5p-iframe')); const iframes = <HTMLIFrameElement[]> Array.from(container.querySelectorAll('iframe.h5p-iframe'));
const urls = []; const urls = [];

View File

@ -762,7 +762,7 @@ export class CoreFileProvider {
* @return Promise resolved when the entry is moved. * @return Promise resolved when the entry is moved.
*/ */
moveDir(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> { moveDir(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
return this.moveFileOrDir(originalPath, newPath, true); return this.moveFileOrDir(originalPath, newPath, true, destDirExists);
} }
/** /**
@ -775,7 +775,7 @@ export class CoreFileProvider {
* @return Promise resolved when the entry is moved. * @return Promise resolved when the entry is moved.
*/ */
moveFile(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> { moveFile(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
return this.moveFileOrDir(originalPath, newPath, false); return this.moveFileOrDir(originalPath, newPath, false, destDirExists);
} }
/** /**
@ -991,11 +991,26 @@ export class CoreFileProvider {
* @param destFolder Path to the destination folder. If not defined, a new folder will be created with the * @param destFolder Path to the destination folder. If not defined, a new folder will be created with the
* same location and name as the ZIP file (without extension). * same location and name as the ZIP file (without extension).
* @param onProgress Function to call on progress. * @param onProgress Function to call on progress.
* @param recreateDir Delete the dest directory before unzipping. Defaults to true.
* @return Promise resolved when the file is unzipped. * @return Promise resolved when the file is unzipped.
*/ */
unzipFile(path: string, destFolder?: string, onProgress?: Function): Promise<any> { unzipFile(path: string, destFolder?: string, onProgress?: Function, recreateDir: boolean = true): Promise<any> {
// Get the source file. // Get the source file.
return this.getFile(path).then((fileEntry) => { let fileEntry: FileEntry;
return this.getFile(path).then((fe) => {
fileEntry = fe;
if (destFolder && recreateDir) {
// Make sure the dest dir doesn't exist already.
return this.removeDir(destFolder).catch(() => {
// Ignore errors.
}).then(() => {
// Now create the dir, otherwise if any of the ancestor dirs doesn't exist the unzip would fail.
return this.createDir(destFolder);
});
}
}).then(() => {
// If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath). // If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath).
destFolder = this.addBasePathIfNeeded(destFolder || this.mimeUtils.removeExtension(path)); destFolder = this.addBasePathIfNeeded(destFolder || this.mimeUtils.removeExtension(path));

View File

@ -1339,7 +1339,7 @@ export class CoreFilepoolProvider {
*/ */
protected fixPluginfileURL(siteId: string, fileUrl: string, timemodified: number = 0): Promise<CoreWSExternalFile> { protected fixPluginfileURL(siteId: string, fileUrl: string, timemodified: number = 0): Promise<CoreWSExternalFile> {
return this.pluginFileDelegate.canDownloadFile({fileurl: fileUrl, timemodified: timemodified}).then((file) => { return this.pluginFileDelegate.getDownloadableFile({fileurl: fileUrl, timemodified: timemodified}).then((file) => {
return this.sitesProvider.getSite(siteId).then((site) => { return this.sitesProvider.getSite(siteId).then((site) => {
return site.checkAndFixPluginfileURL(file.fileurl); return site.checkAndFixPluginfileURL(file.fileurl);

View File

@ -48,15 +48,6 @@ export interface CorePluginFileHandler {
*/ */
getComponentRevisionReplace?(args: string[]): string; getComponentRevisionReplace?(args: string[]): string;
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
canDownloadFile?(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile>;
/** /**
* React to a file being deleted. * React to a file being deleted.
* *
@ -67,6 +58,15 @@ export interface CorePluginFileHandler {
*/ */
fileDeleted?(fileUrl: string, path: string, siteId?: string): Promise<any>; fileDeleted?(fileUrl: string, path: string, siteId?: string): Promise<any>;
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
getDownloadableFile?(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile>;
/** /**
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by * Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml. * CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
@ -74,7 +74,7 @@ export interface CorePluginFileHandler {
* @param container Container where to get the URLs from. * @param container Container where to get the URLs from.
* @return {string[]} List of URLs. * @return {string[]} List of URLs.
*/ */
getDownloadableFiles?(container: HTMLElement): string[]; getDownloadableFilesFromHTML?(container: HTMLElement): string[];
/** /**
* Get a file size. * Get a file size.
@ -116,39 +116,6 @@ export class CorePluginFileDelegate {
this.logger = logger.getInstance('CorePluginFileDelegate'); this.logger = logger.getInstance('CorePluginFileDelegate');
} }
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
canDownloadFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
const handler = this.getHandlerForFile(file);
return this.canHandlerDownloadFile(file, handler, siteId);
}
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param handler The handler to use.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
protected canHandlerDownloadFile(file: CoreWSExternalFile, handler: CorePluginFileHandler, siteId?: string)
: Promise<CoreWSExternalFile> {
if (handler && handler.canDownloadFile) {
return handler.canDownloadFile(file, siteId).then((newFile) => {
return newFile || file;
});
}
return Promise.resolve(file);
}
/** /**
* React to a file being deleted. * React to a file being deleted.
* *
@ -167,6 +134,39 @@ export class CorePluginFileDelegate {
return Promise.resolve(); return Promise.resolve();
} }
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
getDownloadableFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
const handler = this.getHandlerForFile(file);
return this.getHandlerDownloadableFile(file, handler, siteId);
}
/**
* Check whether a file can be downloaded. If so, return the file to download.
*
* @param file The file data.
* @param handler The handler to use.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the file to use. Rejected if cannot download.
*/
protected getHandlerDownloadableFile(file: CoreWSExternalFile, handler: CorePluginFileHandler, siteId?: string)
: Promise<CoreWSExternalFile> {
if (handler && handler.getDownloadableFile) {
return handler.getDownloadableFile(file, siteId).then((newFile) => {
return newFile || file;
});
}
return Promise.resolve(file);
}
/** /**
* Get the handler for a certain pluginfile url. * Get the handler for a certain pluginfile url.
* *
@ -201,14 +201,14 @@ export class CorePluginFileDelegate {
* @param container Container where to get the URLs from. * @param container Container where to get the URLs from.
* @return List of URLs. * @return List of URLs.
*/ */
getDownloadableFiles(container: HTMLElement): string[] { getDownloadableFilesFromHTML(container: HTMLElement): string[] {
let files = []; let files = [];
for (const component in this.handlers) { for (const component in this.handlers) {
const handler = this.handlers[component]; const handler = this.handlers[component];
if (handler && handler.getDownloadableFiles) { if (handler && handler.getDownloadableFilesFromHTML) {
files = files.concat(handler.getDownloadableFiles(container)); files = files.concat(handler.getDownloadableFilesFromHTML(container));
} }
} }
@ -256,8 +256,8 @@ export class CorePluginFileDelegate {
const handler = this.getHandlerForFile(file); const handler = this.getHandlerForFile(file);
// First of all check if file can be downloaded. // First of all check if file can be downloaded.
return this.canHandlerDownloadFile(file, handler, siteId).then((canDownload) => { return this.getHandlerDownloadableFile(file, handler, siteId).then((file) => {
if (!canDownload) { if (!file) {
return 0; return 0;
} }

View File

@ -286,7 +286,7 @@ export class CoreDomUtilsProvider {
} }
// Now get other files from plugin file handlers. // Now get other files from plugin file handlers.
urls = urls.concat(this.pluginFileDelegate.getDownloadableFiles(element)); urls = urls.concat(this.pluginFileDelegate.getDownloadableFilesFromHTML(element));
return urls; return urls;
} }