diff --git a/plugin.xml b/plugin.xml index 01bff31f6..10ded3a1b 100644 --- a/plugin.xml +++ b/plugin.xml @@ -171,6 +171,7 @@ to config.xml in order for the application to find previously stored files. + diff --git a/src/ios/CDVFile.m b/src/ios/CDVFile.m index 59e7d6407..574d46df0 100644 --- a/src/ios/CDVFile.m +++ b/src/ios/CDVFile.m @@ -194,6 +194,53 @@ @implementation CDVFile @synthesize rootDocsPath, appDocsPath, appLibraryPath, appTempPath, userHasAllowed, fileSystems=fileSystems_; +// If the url matches the cdvfile:// format, +// will return the equivalent file:// url format if possible +// else, return nil +- (NSString*)nativeUrlFromCdvfileUrl:(NSURL*) uri +{ + // If the url matches the cdvfile format (cdvfile://) + if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix]) { + NSString *cdvfileUrl = [uri absoluteString]; + // Try to get the native Url from the cdvfile url + if (cdvfileUrl != nil) { + CDVFilesystemURL* inputURI = [self fileSystemURLforArg:cdvfileUrl]; + // If the cdvfile url is valid + if (inputURI != nil && inputURI.fileSystemName != nil) { + // Get the filesystem + NSObject *fs = [self filesystemForURL:inputURI]; + if (fs != nil) { + // Get the file Entry + NSDictionary *entry = [fs makeEntryForLocalURL:inputURI]; + if (entry != nil) { + // Return the file URL + return [entry objectForKey:@"nativeURL"]; + } + } + } + } + } + return nil; +} +// Checks if we are trying to load a url that we should override. +// If we should override we send out a new load request and +// return NO to stop loading the original request. +// Note: When the lowest cordova supported iOS version is 11.0 this can +// potentially be removed. WKWebview for iOS 11+ supports WKURLSchemeHandler +// and setURLSchemeHandler which should allow support for the cdvfile scheme. +- (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType +{ + // check if the url matches the httpsCdvfileUrl and gets the equivalent file:// url + NSString *fileUrl = [self nativeUrlFromCdvfileUrl:[request URL]]; + if (fileUrl != nil) { + // Create a new request for the file:// url instead + NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:fileUrl]]; + [[self webViewEngine] loadRequest:req]; + return NO; + } + return YES; +} + - (void)registerFilesystem:(NSObject *)fs { __weak CDVFile* weakSelf = self; SEL sel = NSSelectorFromString(@"urlTransformer"); diff --git a/tests/tests.js b/tests/tests.js index a9ae20aa7..8a7f7e7c0 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -4160,4 +4160,30 @@ exports.defineManualTests = function (contentEl, createActionButton) { createActionButton('show-contact-image', function () { resolveFsContactImage(); }, 'contactButton'); + + // This tests that we are allowed to navigate to cdvfile:// urls and + // that plugins are allowed to 'exec' on cdvfile urls. + // For exec details, see Issue 329 https://github.com/apache/cordova-plugin-file/issues/329\ + div = document.createElement('h2'); + div.appendChild(document.createTextNode('cdvfile:// url')); + div.setAttribute('align', 'center'); + contentEl.appendChild(div); + div = document.createElement('div'); + div.setAttribute('align', 'center'); + div.innerHTML = 'clicking this button should re-load the tests page.' + + '
You should be able to run all the tests successfully after the page re-load.' + + '
NOTE: This will not work if you are not on file:// url to start.' + + '
eg. You are using an http server to hot re-load client-side files.'; + contentEl.appendChild(div); + div = document.createElement('div'); + div.setAttribute('id', 'cdvfilePageTests'); + div.setAttribute('align', 'center'); + contentEl.appendChild(div); + createActionButton('Navigate to cdvfile:// url', function () { + // Get current page's cdvfile Url + window.resolveLocalFileSystemURL(window.location.href, function (entry) { + var cdvfileUrl = entry.toInternalURL(); + window.location.href = cdvfileUrl; + }); + }, 'cdvfilePageTests'); };