forked from EVOgeek/Vmeda.Online
		
	MOBILE-3101 core: Fix embedded files
This commit is contained in:
		
							parent
							
								
									38e3e88ed6
								
							
						
					
					
						commit
						47decde520
					
				| @ -17,6 +17,7 @@ import { | ||||
| } from '@angular/core'; | ||||
| import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; | ||||
| import { NavController } from 'ionic-angular'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreUrlUtilsProvider } from '@providers/utils/url'; | ||||
| @ -49,7 +50,8 @@ export class CoreIframeComponent implements OnInit, OnChanges { | ||||
|             protected navCtrl: NavController, | ||||
|             protected urlUtils: CoreUrlUtilsProvider, | ||||
|             protected utils: CoreUtilsProvider, | ||||
|             @Optional() protected svComponent: CoreSplitViewComponent) { | ||||
|             @Optional() protected svComponent: CoreSplitViewComponent, | ||||
|             protected fileProvider: CoreFileProvider) { | ||||
| 
 | ||||
|         this.logger = logger.getInstance('CoreIframe'); | ||||
|         this.loaded = new EventEmitter<HTMLIFrameElement>(); | ||||
| @ -93,8 +95,8 @@ export class CoreIframeComponent implements OnInit, OnChanges { | ||||
|      */ | ||||
|     ngOnChanges(changes: {[name: string]: SimpleChange }): void { | ||||
|         if (changes.src) { | ||||
|             const youtubeUrl = this.urlUtils.getYoutubeEmbedUrl(changes.src.currentValue); | ||||
|             this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(youtubeUrl || changes.src.currentValue); | ||||
|             const url = this.urlUtils.getYoutubeEmbedUrl(changes.src.currentValue) || changes.src.currentValue; | ||||
|             this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.fileProvider.convertFileSrc(url)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -93,5 +93,6 @@ | ||||
|     "statusbarbgremotetheme": "#000000", | ||||
|     "statusbarlighttextremotetheme": true, | ||||
|     "enableanalytics": false, | ||||
|     "forceColorScheme": "" | ||||
|     "forceColorScheme": "", | ||||
|     "webviewscheme": "moodleappfs" | ||||
| } | ||||
| @ -16,6 +16,7 @@ import { Directive, Input, AfterViewInit, ElementRef, OnChanges, SimpleChange, O | ||||
| import { Platform } from 'ionic-angular'; | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreFile } from '@providers/file'; | ||||
| import { CoreFilepoolProvider } from '@providers/filepool'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| @ -52,9 +53,15 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges { | ||||
| 
 | ||||
|     invalid = false; | ||||
| 
 | ||||
|     constructor(element: ElementRef, logger: CoreLoggerProvider, private filepoolProvider: CoreFilepoolProvider, | ||||
|             private platform: Platform, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider, | ||||
|             private urlUtils: CoreUrlUtilsProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider) { | ||||
|     constructor(element: ElementRef, | ||||
|             logger: CoreLoggerProvider, | ||||
|             protected filepoolProvider: CoreFilepoolProvider, | ||||
|             protected platform: Platform, | ||||
|             protected sitesProvider: CoreSitesProvider, | ||||
|             protected domUtils: CoreDomUtilsProvider, | ||||
|             protected urlUtils: CoreUrlUtilsProvider, | ||||
|             protected appProvider: CoreAppProvider, | ||||
|             protected utils: CoreUtilsProvider) { | ||||
|         // This directive can be added dynamically. In that case, the first param is the HTMLElement.
 | ||||
|         this.element = element.nativeElement || element; | ||||
|         this.logger = logger.getInstance('CoreExternalContentDirective'); | ||||
| @ -179,7 +186,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges { | ||||
|      * @param siteId Site ID. | ||||
|      * @return Promise resolved if the element is successfully treated. | ||||
|      */ | ||||
|     protected handleExternalContent(targetAttr: string, url: string, siteId?: string): Promise<any> { | ||||
|     protected async handleExternalContent(targetAttr: string, url: string, siteId?: string): Promise<any> { | ||||
| 
 | ||||
|         const tagName = this.element.tagName; | ||||
| 
 | ||||
| @ -214,72 +221,70 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges { | ||||
|                 this.addSource(url); | ||||
|             } | ||||
| 
 | ||||
|             return Promise.reject(null); | ||||
|             throw 'Non-downloadable URL'; | ||||
|         } | ||||
| 
 | ||||
|         // Get the webservice pluginfile URL, we ignore failures here.
 | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             if (!site.canDownloadFiles() && this.urlUtils.isPluginFileUrl(url)) { | ||||
|                 this.element.parentElement.removeChild(this.element); // Remove element since it'll be broken.
 | ||||
|         const site = await this.sitesProvider.getSite(siteId); | ||||
| 
 | ||||
|                 return Promise.reject(null); | ||||
|         if (!site.canDownloadFiles() && this.urlUtils.isPluginFileUrl(url)) { | ||||
|             this.element.parentElement.removeChild(this.element); // Remove element since it'll be broken.
 | ||||
| 
 | ||||
|             throw 'Site doesn\'t allow downloading files.'; | ||||
|         } | ||||
| 
 | ||||
|         // Download images, tracks and posters if size is unknown.
 | ||||
|         const dwnUnknown = tagName == 'IMG' || tagName == 'TRACK' || targetAttr == 'poster'; | ||||
|         let finalUrl: string; | ||||
| 
 | ||||
|         if (targetAttr === 'src' && tagName !== 'SOURCE' && tagName !== 'TRACK' && tagName !== 'VIDEO' && tagName !== 'AUDIO') { | ||||
|             finalUrl = await this.filepoolProvider.getSrcByUrl(siteId, url, this.component, this.componentId, 0, true, dwnUnknown); | ||||
|         } else { | ||||
|             finalUrl = await this.filepoolProvider.getUrlByUrl(siteId, url, this.component, this.componentId, 0, true, dwnUnknown); | ||||
| 
 | ||||
|             finalUrl = CoreFile.instance.convertFileSrc(finalUrl); | ||||
|         } | ||||
| 
 | ||||
|         if (finalUrl.match(/^https?:\/\//i)) { | ||||
|             /* In iOS, if we use the same URL in embedded file and background download then the download only | ||||
|                downloads a few bytes (cached ones). Add a hash to the URL so both URLs are different. */ | ||||
|             finalUrl = finalUrl + '#moodlemobile-embedded'; | ||||
|         } | ||||
| 
 | ||||
|         this.logger.debug('Using URL ' + finalUrl + ' for ' + url); | ||||
|         if (tagName === 'SOURCE') { | ||||
|             // The browser does not catch changes in SRC, we need to add a new source.
 | ||||
|             this.addSource(finalUrl); | ||||
|         } else { | ||||
|             if (tagName === 'IMG') { | ||||
|                 this.loaded = false; | ||||
|                 this.waitForLoad(); | ||||
|             } | ||||
|             this.element.setAttribute(targetAttr, finalUrl); | ||||
|             this.element.setAttribute('data-original-' + targetAttr, url); | ||||
|         } | ||||
| 
 | ||||
|         // Set events to download big files (not downloaded automatically).
 | ||||
|         if (finalUrl.indexOf('http') === 0 && targetAttr != 'poster' && | ||||
|             (tagName == 'VIDEO' || tagName == 'AUDIO' || tagName == 'A' || tagName == 'SOURCE')) { | ||||
|             const eventName = tagName == 'A' ? 'click' : 'play'; | ||||
|             let clickableEl = this.element; | ||||
| 
 | ||||
|             if (tagName == 'SOURCE') { | ||||
|                 clickableEl = <HTMLElement> this.domUtils.closest(this.element, 'video,audio'); | ||||
|                 if (!clickableEl) { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // Download images, tracks and posters if size is unknown.
 | ||||
|             const dwnUnknown = tagName == 'IMG' || tagName == 'TRACK' || targetAttr == 'poster'; | ||||
|             let promise; | ||||
| 
 | ||||
|             if (targetAttr === 'src' && tagName !== 'SOURCE' && tagName !== 'TRACK' && tagName !== 'VIDEO' && | ||||
|                     tagName !== 'AUDIO') { | ||||
|                 promise = this.filepoolProvider.getSrcByUrl(siteId, url, this.component, this.componentId, 0, true, dwnUnknown); | ||||
|             } else { | ||||
|                 promise = this.filepoolProvider.getUrlByUrl(siteId, url, this.component, this.componentId, 0, true, dwnUnknown); | ||||
|             } | ||||
| 
 | ||||
|             return promise.then((finalUrl) => { | ||||
|                 if (finalUrl.match(/^https?:\/\//i)) { | ||||
|                     /* In iOS, if we use the same URL in embedded file and background download then the download only | ||||
|                        downloads a few bytes (cached ones). Add a hash to the URL so both URLs are different. */ | ||||
|                     finalUrl = finalUrl + '#moodlemobile-embedded'; | ||||
|                 } | ||||
| 
 | ||||
|                 this.logger.debug('Using URL ' + finalUrl + ' for ' + url); | ||||
|                 if (tagName === 'SOURCE') { | ||||
|                     // The browser does not catch changes in SRC, we need to add a new source.
 | ||||
|                     this.addSource(finalUrl); | ||||
|                 } else { | ||||
|                     if (tagName === 'IMG') { | ||||
|                         this.loaded = false; | ||||
|                         this.waitForLoad(); | ||||
|                     } | ||||
|                     this.element.setAttribute(targetAttr, finalUrl); | ||||
|                     this.element.setAttribute('data-original-' + targetAttr, url); | ||||
|                 } | ||||
| 
 | ||||
|                 // Set events to download big files (not downloaded automatically).
 | ||||
|                 if (finalUrl.indexOf('http') === 0 && targetAttr != 'poster' && | ||||
|                     (tagName == 'VIDEO' || tagName == 'AUDIO' || tagName == 'A' || tagName == 'SOURCE')) { | ||||
|                     const eventName = tagName == 'A' ? 'click' : 'play'; | ||||
|                     let clickableEl = this.element; | ||||
| 
 | ||||
|                     if (tagName == 'SOURCE') { | ||||
|                         clickableEl = <HTMLElement> this.domUtils.closest(this.element, 'video,audio'); | ||||
|                         if (!clickableEl) { | ||||
|                             return; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     clickableEl.addEventListener(eventName, () => { | ||||
|                         // User played media or opened a downloadable link.
 | ||||
|                         // Download the file if in wifi and it hasn't been downloaded already (for big files).
 | ||||
|                         if (this.appProvider.isWifi()) { | ||||
|                             // We aren't using the result, so it doesn't matter which of the 2 functions we call.
 | ||||
|                             this.filepoolProvider.getUrlByUrl(siteId, url, this.component, this.componentId, 0, false); | ||||
|                         } | ||||
|                     }); | ||||
|             clickableEl.addEventListener(eventName, () => { | ||||
|                 // User played media or opened a downloadable link.
 | ||||
|                 // Download the file if in wifi and it hasn't been downloaded already (for big files).
 | ||||
|                 if (this.appProvider.isWifi()) { | ||||
|                     // We aren't using the result, so it doesn't matter which of the 2 functions we call.
 | ||||
|                     this.filepoolProvider.getUrlByUrl(siteId, url, this.component, this.componentId, 0, false); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -74,26 +74,27 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|     protected loadingChangedListener; | ||||
| 
 | ||||
|     constructor(element: ElementRef, | ||||
|             private sitesProvider: CoreSitesProvider, | ||||
|             private domUtils: CoreDomUtilsProvider, | ||||
|             private textUtils: CoreTextUtilsProvider, | ||||
|             private translate: TranslateService, | ||||
|             private platform: Platform, | ||||
|             private utils: CoreUtilsProvider, | ||||
|             private urlUtils: CoreUrlUtilsProvider, | ||||
|             private loggerProvider: CoreLoggerProvider, | ||||
|             private filepoolProvider: CoreFilepoolProvider, | ||||
|             private appProvider: CoreAppProvider, | ||||
|             private contentLinksHelper: CoreContentLinksHelperProvider, | ||||
|             @Optional() private navCtrl: NavController, | ||||
|             @Optional() private content: Content, @Optional() | ||||
|             private svComponent: CoreSplitViewComponent, | ||||
|             private iframeUtils: CoreIframeUtilsProvider, | ||||
|             private eventsProvider: CoreEventsProvider, | ||||
|             private filterProvider: CoreFilterProvider, | ||||
|             private filterHelper: CoreFilterHelperProvider, | ||||
|             private filterDelegate: CoreFilterDelegate, | ||||
|             private viewContainerRef: ViewContainerRef) { | ||||
|             protected sitesProvider: CoreSitesProvider, | ||||
|             protected domUtils: CoreDomUtilsProvider, | ||||
|             protected textUtils: CoreTextUtilsProvider, | ||||
|             protected translate: TranslateService, | ||||
|             protected platform: Platform, | ||||
|             protected utils: CoreUtilsProvider, | ||||
|             protected urlUtils: CoreUrlUtilsProvider, | ||||
|             protected loggerProvider: CoreLoggerProvider, | ||||
|             protected filepoolProvider: CoreFilepoolProvider, | ||||
|             protected appProvider: CoreAppProvider, | ||||
|             protected contentLinksHelper: CoreContentLinksHelperProvider, | ||||
|             @Optional() protected navCtrl: NavController, | ||||
|             @Optional() protected content: Content, @Optional() | ||||
|             protected svComponent: CoreSplitViewComponent, | ||||
|             protected iframeUtils: CoreIframeUtilsProvider, | ||||
|             protected eventsProvider: CoreEventsProvider, | ||||
|             protected filterProvider: CoreFilterProvider, | ||||
|             protected filterHelper: CoreFilterHelperProvider, | ||||
|             protected filterDelegate: CoreFilterDelegate, | ||||
|             protected viewContainerRef: ViewContainerRef, | ||||
|             ) { | ||||
| 
 | ||||
|         this.element = element.nativeElement; | ||||
|         this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
 | ||||
|  | ||||
| @ -92,7 +92,7 @@ export class CoreLinkDirective implements OnInit { | ||||
|     protected navigate(href: string): void { | ||||
|         const contentLinksScheme = CoreConfigConstants.customurlscheme + '://link='; | ||||
| 
 | ||||
|         if (href.indexOf('cdvfile://') === 0 || href.indexOf('file://') === 0 || href.indexOf('filesystem:') === 0) { | ||||
|         if (this.urlUtils.isLocalFileUrl(href)) { | ||||
|             // We have a local file.
 | ||||
|             this.utils.openFile(href).catch((error) => { | ||||
|                 this.domUtils.showErrorModal(error); | ||||
|  | ||||
| @ -20,6 +20,7 @@ import { CoreAppProvider } from './app'; | ||||
| import { CoreLoggerProvider } from './logger'; | ||||
| import { CoreMimetypeUtilsProvider } from './utils/mimetype'; | ||||
| import { CoreTextUtilsProvider } from './utils/text'; | ||||
| import { CoreConfigConstants } from '../configconstants'; | ||||
| import { Zip } from '@ionic-native/zip'; | ||||
| import { makeSingleton } from '@singletons/core.singletons'; | ||||
| 
 | ||||
| @ -946,6 +947,7 @@ export class CoreFileProvider { | ||||
| 
 | ||||
|     /** | ||||
|      * Get the internal URL of a file. | ||||
|      * Please notice that with WKWebView these URLs no longer work in mobile. Use fileEntry.toURL() along with convertFileSrc. | ||||
|      * | ||||
|      * @param fileEntry File Entry. | ||||
|      * @return Internal URL. | ||||
| @ -1270,6 +1272,31 @@ export class CoreFileProvider { | ||||
| 
 | ||||
|         return window.location.href; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Helper function to call Ionic WebView convertFileSrc only in the needed platforms. | ||||
|      * This is needed to make files work with the Ionic WebView plugin. | ||||
|      * | ||||
|      * @param src Source to convert. | ||||
|      * @return Converted src. | ||||
|      */ | ||||
|     convertFileSrc(src: string): string { | ||||
|         return this.appProvider.isMobile() ? (<any> window).Ionic.WebView.convertFileSrc(src) : src; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Undo the conversion of convertFileSrc. | ||||
|      * | ||||
|      * @param src Source to unconvert. | ||||
|      * @return Unconverted src. | ||||
|      */ | ||||
|     unconvertFileSrc(src: string): string { | ||||
|         if (!this.appProvider.isMobile()) { | ||||
|             return src; | ||||
|         } | ||||
| 
 | ||||
|         return src.replace(CoreConfigConstants.webviewscheme + '://localhost/_app_file_', 'file://'); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class CoreFile extends makeSingleton(CoreFileProvider) {} | ||||
|  | ||||
| @ -412,11 +412,21 @@ export class CoreFilepoolProvider { | ||||
|     protected packagesPromises = {}; | ||||
|     protected filePromises: { [s: string]: { [s: string]: Promise<any> } } = {}; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private appProvider: CoreAppProvider, private fileProvider: CoreFileProvider, | ||||
|             private sitesProvider: CoreSitesProvider, private wsProvider: CoreWSProvider, private textUtils: CoreTextUtilsProvider, | ||||
|             private utils: CoreUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider, private urlUtils: CoreUrlUtilsProvider, | ||||
|             private timeUtils: CoreTimeUtilsProvider, private eventsProvider: CoreEventsProvider, initDelegate: CoreInitDelegate, | ||||
|             network: Network, private pluginFileDelegate: CorePluginFileDelegate, private domUtils: CoreDomUtilsProvider, | ||||
|     constructor(logger: CoreLoggerProvider, | ||||
|             protected appProvider: CoreAppProvider, | ||||
|             protected fileProvider: CoreFileProvider, | ||||
|             protected sitesProvider: CoreSitesProvider, | ||||
|             protected wsProvider: CoreWSProvider, | ||||
|             protected textUtils: CoreTextUtilsProvider, | ||||
|             protected utils: CoreUtilsProvider, | ||||
|             protected mimeUtils: CoreMimetypeUtilsProvider, | ||||
|             protected urlUtils: CoreUrlUtilsProvider, | ||||
|             protected timeUtils: CoreTimeUtilsProvider, | ||||
|             protected eventsProvider: CoreEventsProvider, | ||||
|             initDelegate: CoreInitDelegate, | ||||
|             network: Network, | ||||
|             protected pluginFileDelegate: CorePluginFileDelegate, | ||||
|             protected domUtils: CoreDomUtilsProvider, | ||||
|             zone: NgZone) { | ||||
|         this.logger = logger.getInstance('CoreFilepoolProvider'); | ||||
| 
 | ||||
| @ -1796,8 +1806,7 @@ export class CoreFilepoolProvider { | ||||
|         if (this.fileProvider.isAvailable()) { | ||||
|             return Promise.resolve(this.getFilePath(siteId, fileId)).then((path) => { | ||||
|                 return this.fileProvider.getFile(path).then((fileEntry) => { | ||||
|                     // We use toInternalURL so images are loaded in iOS8 using img HTML tags.
 | ||||
|                     return this.fileProvider.getInternalURL(fileEntry); | ||||
|                     return this.fileProvider.convertFileSrc(fileEntry.toURL()); | ||||
|                 }); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
| @ -225,7 +225,7 @@ export class CoreIframeUtilsProvider { | ||||
|                     } else { | ||||
|                         element.setAttribute('src', url); | ||||
|                     } | ||||
|                 } else if (url.indexOf('cdvfile://') === 0 || url.indexOf('file://') === 0) { | ||||
|                 } else if (this.urlUtils.isLocalFileUrl(url)) { | ||||
|                     // It's a local file.
 | ||||
|                     this.utils.openFile(url).catch((error) => { | ||||
|                         this.domUtils.showErrorModal(error); | ||||
| @ -353,16 +353,14 @@ export class CoreIframeUtilsProvider { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (scheme && scheme != 'file' && scheme != 'filesystem') { | ||||
|         if (!this.urlUtils.isLocalFileUrlScheme(scheme)) { | ||||
|             // Scheme suggests it's an external resource.
 | ||||
|             event.preventDefault(); | ||||
| 
 | ||||
|             const frameSrc = (<HTMLFrameElement> element).src || (<HTMLObjectElement> element).data, | ||||
|                 frameScheme = this.urlUtils.getUrlScheme(frameSrc); | ||||
|             const frameSrc = (<HTMLFrameElement> element).src || (<HTMLObjectElement> element).data; | ||||
| 
 | ||||
|             // If the frame is not local, check the target to identify how to treat the link.
 | ||||
|             if (frameScheme && frameScheme != 'file' && frameScheme != 'filesystem' && | ||||
|                     (!link.target || link.target == '_self')) { | ||||
|             if (!this.urlUtils.isLocalFileUrl(frameSrc) && (!link.target || link.target == '_self')) { | ||||
|                 // Load the link inside the frame itself.
 | ||||
|                 if (element.tagName.toLowerCase() == 'object') { | ||||
|                     element.setAttribute('data', link.href); | ||||
|  | ||||
| @ -14,6 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { HttpClient } from '@angular/common/http'; | ||||
| import { CoreFile } from '../file'; | ||||
| import { CoreLoggerProvider } from '../logger'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreTextUtilsProvider } from './text'; | ||||
| @ -165,7 +166,7 @@ export class CoreMimetypeUtilsProvider { | ||||
|         if (this.canBeEmbedded(ext)) { | ||||
|             file.embedType = this.getExtensionType(ext); | ||||
| 
 | ||||
|             path = path || file.fileurl || (file.toURL && file.toURL()); | ||||
|             path = CoreFile.instance.convertFileSrc(path || file.fileurl || (file.toURL && file.toURL())); | ||||
| 
 | ||||
|             if (file.embedType == 'image') { | ||||
|                 return '<img src="' + path + '">'; | ||||
|  | ||||
| @ -16,6 +16,7 @@ import { Injectable } from '@angular/core'; | ||||
| import { CoreLangProvider } from '../lang'; | ||||
| import { CoreTextUtilsProvider } from './text'; | ||||
| import { makeSingleton } from '@singletons/core.singletons'; | ||||
| import { CoreConfigConstants } from '../../configconstants'; | ||||
| 
 | ||||
| /* | ||||
|  * "Utils" service with helper functions for URLs. | ||||
| @ -424,6 +425,26 @@ export class CoreUrlUtilsProvider { | ||||
|         return /^https?\:\/\/.+/i.test(url); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check whether an URL belongs to a local file. | ||||
|      * | ||||
|      * @param url URL to check. | ||||
|      * @return Whether the URL belongs to a local file. | ||||
|      */ | ||||
|     isLocalFileUrl(url: string): boolean { | ||||
|         return this.isLocalFileUrlScheme(this.getUrlScheme(url)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check whether a URL scheme belongs to a local file. | ||||
|      * | ||||
|      * @param scheme Scheme to check. | ||||
|      * @return Whether the scheme belongs to a local file. | ||||
|      */ | ||||
|     isLocalFileUrlScheme(scheme: string): boolean { | ||||
|         return scheme == 'cdvfile' || scheme == 'file' || scheme == 'filesystem' || scheme == CoreConfigConstants.webviewscheme; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns if a URL is a pluginfile URL. | ||||
|      * | ||||
|  | ||||
| @ -27,6 +27,7 @@ import { CoreLoggerProvider } from '../logger'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreLangProvider } from '../lang'; | ||||
| import { CoreWSProvider, CoreWSError } from '../ws'; | ||||
| import { CoreFile } from '../file'; | ||||
| import { makeSingleton } from '@singletons/core.singletons'; | ||||
| 
 | ||||
| /** | ||||
| @ -863,8 +864,11 @@ export class CoreUtilsProvider { | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     openFile(path: string): Promise<any> { | ||||
|         const extension = this.mimetypeUtils.getFileExtension(path), | ||||
|             mimetype = this.mimetypeUtils.getMimeType(extension); | ||||
|         // Convert the path to a native path if needed.
 | ||||
|         path = CoreFile.instance.unconvertFileSrc(path); | ||||
| 
 | ||||
|         const extension = this.mimetypeUtils.getFileExtension(path); | ||||
|         const mimetype = this.mimetypeUtils.getMimeType(extension); | ||||
| 
 | ||||
|         // Path needs to be decoded, the file won't be opened if the path has %20 instead of spaces and so.
 | ||||
|         try { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user