Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Rename AppBundle -> UrlRemap
  • Loading branch information
agrieve committed Oct 24, 2013
1 parent 951d8ee commit e7190bcd06199f32360429d98b4d5728bb7047e8
Showing 9 changed files with 47 additions and 101 deletions.
@@ -1,4 +1,4 @@
AppBundle
UrlRemap
=========

Enables dynamic rerouting of URLs.
@@ -18,40 +18,35 @@
under the License.
-->
<plugin xmlns="http://phonegap.com/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="org.apache.cordova.AppBundle"
id="org.apache.cordova.UrlRemap"
version="1.0.0">
<engines>
<engine name="cordova" version=">=3.0.0" />
</engines>

<name>App Bundle URLs</name>
<name>URL Remapper</name>

<js-module src="appBundle.js" name="AppBundle">
<clobbers target="cordova.plugins.appBundle" />
<js-module src="urlremap.js" name="UrlRemap">
<clobbers target="cordova.plugins.urlremap" />
</js-module>

<platform name="android">
<source-file src="src/android/AppBundle.java" target-dir="src/org/apache/cordova/appbundle" />
<source-file src="src/android/UrlRemap.java" target-dir="src/org/apache/cordova/urlremap" />

<config-file target="res/xml/config.xml" parent="/*">
<feature name="AppBundle">
<param name="android-package" value="org.apache.cordova.appbundle.AppBundle"/>
<param name="onload" value="true"/>
<feature name="UrlRemap">
<param name="android-package" value="org.apache.cordova.urlremap.UrlRemap"/>
</feature>
<access origin="app-bundle://*" />
</config-file>
</platform>

<platform name="ios">
<source-file src="src/ios/AppBundle.m" />
<source-file src="src/ios/UrlRemap.m" />

<config-file target="config.xml" parent="/*">
<feature name="AppBundle">
<param name="ios-package" value="AppBundle"/>
<param name="onload" value="true"/>
<feature name="UrlRemap">
<param name="ios-package" value="UrlRemap"/>
</feature>
<access origin="app-bundle://*" />
</config-file>
</platform>
</plugin>
@@ -16,7 +16,7 @@ Licensed to the Apache Software Foundation (ASF) under one
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova.appbundle;
package org.apache.cordova.urlremap;

import java.util.ArrayList;
import java.util.List;
@@ -29,58 +29,9 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.net.Uri.Builder;
import android.util.Log;

public class AppBundle extends CordovaPlugin {

/*
This plugin allows any uri's that are loaded to be replaced with modified uri's
These include uri's being loaded by the browser such as page navigation, script tags, as well as file uris being opened by file api etc.
There are 4 parameters here that affect the replacement.
The matchRegex, replaceRegex, replacerString, shouldRedirect
The algorithm operates as follows
currently loading 'url'
if(url matches matchRegex){
newUrl = url.replace(replaceRegex, replacerString)
if(this is topLevelRequest){
stopLoadingUrl()
loadUrl(newUrl)
return
} else {
url = newUrl
}
}
continue loading 'url'
There are some implementation details involved here such as the ability to distinguish between top level requests and other requests.
Please see the code for details regarding this.
There is an array of {matchRegex, replaceRegex, replacerString, shouldRedirect} stored referred to as the reroute map
"app-bundle:" uri's are absolute uri's that point to your bundle.
By default the rerouteMap contains the parameters required to redirect
app-bundle:///blah -> file:///android_asset/www/blah
The rerouteMap can be modified from javascript by calling the addAlias and clearAlias methods
Recursive replacements are supported by this plugin as well.
Consider the reroute map contains
1) http://mysite.com/ -> file:///android_asset/www/
2) file:///android_asset/www/blah -> file:///storage/www/
3) http://mysite.com/ -> http:///mysiteproxy.com/
4) http://mysiteproxy.com/ -> http:///mysiteproxy2.com/
A request to http://mysite.com/blah should give http:///mysiteproxy2.com/blah
Also note that the recursive replacements apply the rules last to first.
CAVEAT: Recursive replacements to app-bundle: should not occur
For example lets say the we have the rerouteParams set up as
1) app-bundle:/// -> file:///android_asset/www/
2) file:///android_asset/www/ -> file:///storage/www/
A request to app-bundle:///blah should give file:///android_asset/www/ NOT file:///storage/www/
This requirement is required by the definition of app-bundle: uris.
*/
private static final String LOG_TAG = "AppBundle";
private static final String APP_BUNDLE_REPLACED = "AppBundleReplaced";
public class UrlRemap extends CordovaPlugin {
private static final String LOG_TAG = "UrlRemap";
private static final String APP_BUNDLE_REPLACED = "UrlRemapReplaced";

private static class RouteParams {
public String matchRegex;
@@ -24,14 +24,14 @@ Licensed to the Apache Software Foundation (ASF) under one
static UIWebView* gWebView = nil;
static NSMutableArray* gRerouteParams = nil;

@interface AppBundle : CDVPlugin {
@interface UrlRemap : CDVPlugin {
RouteParams* _resetUrlParams;
}
- (void)addAlias:(CDVInvokedUrlCommand*)command;
- (void)clearAllAliases:(CDVInvokedUrlCommand*)command;
@end

@interface AppBundle() {}
@interface UrlRemap() {}
@end

@interface RouteParams : NSObject {
@@ -52,25 +52,25 @@ - (BOOL)matches:(NSString*)uriString {
}
@end

@interface AppBundleURLProtocol : NSURLProtocol
@interface UrlRemapURLProtocol : NSURLProtocol
+ (RouteParams*)getChosenParams:(NSString*)uriString forInjection:(BOOL)forInjection;
@end


#pragma mark AppBundle
#pragma mark UrlRemap

@implementation AppBundle
@implementation UrlRemap

- (void)pluginInitialize {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:self.webView];
gWebView = self.webView;
[NSURLProtocol registerClass:[AppBundleURLProtocol class]];
[NSURLProtocol registerClass:[UrlRemapURLProtocol class]];
gRerouteParams = [[NSMutableArray alloc] init];
}

- (void)pageDidLoad {
NSString* url = [self.webView stringByEvaluatingJavaScriptFromString:@"location.href.replace(/#.*/, '')"];
RouteParams* params = [AppBundleURLProtocol getChosenParams:url forInjection:YES];
RouteParams* params = [UrlRemapURLProtocol getChosenParams:url forInjection:YES];
if (params != nil) {
[gWebView stringByEvaluatingJavaScriptFromString:params->_jsToInject];
}
@@ -135,9 +135,9 @@ - (void)setResetUrl:(CDVInvokedUrlCommand*)command {
}
@end

#pragma mark AppBundleURLProtocol
#pragma mark UrlRemapURLProtocol

@implementation AppBundleURLProtocol
@implementation UrlRemapURLProtocol

+ (RouteParams*)getChosenParams:(NSString*)uriString forInjection:(BOOL)forInjection {
for (RouteParams* param in gRerouteParams) {
@@ -154,7 +154,7 @@ + (RouteParams*)getChosenParams:(NSString*)uriString forInjection:(BOOL)forInjec
+ (BOOL)canInitWithRequest:(NSURLRequest*)request {
NSURL* url = [request URL];
NSString* urlString = [url absoluteString];
RouteParams* params = [AppBundleURLProtocol getChosenParams:urlString forInjection:NO];
RouteParams* params = [UrlRemapURLProtocol getChosenParams:urlString forInjection:NO];
return params != nil;
}

@@ -213,7 +213,7 @@ - (void)startLoading {
NSURLRequest* request = [self request];
NSString* urlString = [[request URL] absoluteString];

RouteParams* params = [AppBundleURLProtocol getChosenParams:urlString forInjection:NO];
RouteParams* params = [UrlRemapURLProtocol getChosenParams:urlString forInjection:NO];
NSRange wholeStringRange = NSMakeRange(0, [urlString length]);
NSString* newUrlString = [params->_replaceRegex stringByReplacingMatchesInString:urlString options:0 range:wholeStringRange withTemplate:params->_replacer];
NSURL* newUrl = [NSURL URLWithString:newUrlString];
@@ -24,20 +24,20 @@ exports.addAlias = function(sourceUriMatchRegex, sourceUriReplaceRegex, replaceS
callback(true);
};
var fail = callback && function(error) {
console.error("AppBundle error: " + error);
console.error("UrlRemap error: " + error);
callback(false);
};
exec(win, fail, 'AppBundle', 'addAlias', [sourceUriMatchRegex, sourceUriReplaceRegex, replaceString, redirectToReplacedUrl]);
exec(win, fail, 'UrlRemap', 'addAlias', [sourceUriMatchRegex, sourceUriReplaceRegex, replaceString, redirectToReplacedUrl]);
};

exports.setResetUrl = function(urlRegex, callback) {
exec(callback, null, 'AppBundle', 'setResetUrl', [urlRegex]);
exec(callback, null, 'UrlRemap', 'setResetUrl', [urlRegex]);
};

exports.injectJsForUrl = function(urlRegex, jsSnippet, callback) {
exec(callback, null, 'AppBundle', 'injectJs', [urlRegex, jsSnippet]);
exec(callback, null, 'UrlRemap', 'injectJs', [urlRegex, jsSnippet]);
};

exports.clearAllAliases = function(callback){
exec(callback, null, 'AppBundle', 'clearAllAliases', []);
exec(callback, null, 'UrlRemap', 'clearAllAliases', []);
};
@@ -39,7 +39,7 @@ ln -s ../www www
$CORDOVA platform add ios
../../cordova-ios/bin/update_cordova_subproject platforms/ios/CordovaAppHarness.xcodeproj

$CORDOVA plugin add ../AppBundle
$CORDOVA plugin add ../UrlRemap
$CORDOVA plugin add ../../../mobile_chrome_apps/zip
$CORDOVA plugin add ../../../BarcodeScanner # https://github.com/wildabeast/BarcodeScanner.git
$CORDOVA plugin add ../../cordova-plugin-file
@@ -11,7 +11,7 @@
<script type="text/javascript" src="js/ServeInstaller.js"></script>
<script type="text/javascript" src="js/ResourcesLoader.js"></script>
<script type="text/javascript" src="js/AppsService.js"></script>
<script type="text/javascript" src="js/AppBundleAlias.js"></script>
<script type="text/javascript" src="js/UrlRemap.js"></script>
<script type="text/javascript" src="js/ListCtrl.js"></script>
<script type="text/javascript" src="js/AddCtrl.js"></script>
<script type="text/javascript" src="js/Notify.js"></script>
@@ -1,7 +1,7 @@
(function(){
"use strict";
/* global myApp */
myApp.factory("Installer", ["$q", "AppBundle", "ResourcesLoader", "ContextMenuInjectScript", function($q, AppBundle, ResourcesLoader, ContextMenuInjectScript) {
myApp.factory("Installer", ["$q", "UrlRemap", "ResourcesLoader", "ContextMenuInjectScript", function($q, UrlRemap, ResourcesLoader, ContextMenuInjectScript) {

function getAppStartPageFromConfig(configFile) {
return ResourcesLoader.readFileContents(configFile)
@@ -87,19 +87,19 @@
}

// Inject the context menu script for all pages except the harness menu.
AppBundle.injectJsForUrl('^(?!' + harnessUrl + ')', injectString);
UrlRemap.injectJsForUrl('^(?!' + harnessUrl + ')', injectString);
// Allow navigations back to the menu.
AppBundle.setResetUrl('^' + harnessUrl);
UrlRemap.setResetUrl('^' + harnessUrl);
// Override cordova.js, cordova_plugins.js, and www/plugins to point at bundled plugins.
AppBundle.aliasUri('/cordova\\.js.*', '.+', harnessDir + '/cordova.js', false /* redirect */);
AppBundle.aliasUri('/cordova_plugins\\.js.*', '.+', harnessDir + '/cordova_plugins.js', false /* redirect */);
UrlRemap.aliasUri('/cordova\\.js.*', '.+', harnessDir + '/cordova.js', false /* redirect */);
UrlRemap.aliasUri('/cordova_plugins\\.js.*', '.+', harnessDir + '/cordova_plugins.js', false /* redirect */);
var pluginsUrl = startLocation.replace(/\/www\/.*/, '/www/plugins/');
AppBundle.aliasUri('^' + pluginsUrl, '^' + pluginsUrl, harnessDir + '/plugins/', false /* redirect */);
UrlRemap.aliasUri('^' + pluginsUrl, '^' + pluginsUrl, harnessDir + '/plugins/', false /* redirect */);
// Make any references to www/ point to the app's install location.
AppBundle.aliasUri('^' + harnessDir, '^' + harnessDir, installUrl + '/www', false /* redirect */);
UrlRemap.aliasUri('^' + harnessDir, '^' + harnessDir, installUrl + '/www', false /* redirect */);
// Set-up app-harness: scheme to point at the harness.
AppBundle.aliasUri('^app-harness:///cdvah/index.html', '^app-harness://', harnessDir, true);
return AppBundle.aliasUri('^app-harness:', '^app-harness://', harnessDir, false)
UrlRemap.aliasUri('^app-harness:///cdvah/index.html', '^app-harness://', harnessDir, true);
return UrlRemap.aliasUri('^app-harness:', '^app-harness://', harnessDir, false)
.then(function() {
return startLocation;
});
@@ -1,14 +1,14 @@
(function() {
"use strict";
/* global myApp */
myApp.factory("AppBundle", ['$q', '$window', function($q, $window) {
myApp.factory("UrlRemap", ['$q', '$window', function($q, $window) {

// URI aliasing : the ability to launch an app in the harness, query the document.location and get the same location as would have been got if you run the app separately
// Without URI aliasing, document.location in the harness would give something like file:///APP_HARNESS_INSTALLED_APPS_LOCATION/www/index.html

function aliasUri(sourceUriMatchRegex, sourceUriReplaceRegex, replaceString, redirectToReplacedUrl){
var deferred = $q.defer();
cordova.plugins.appBundle.addAlias(sourceUriMatchRegex, sourceUriReplaceRegex, replaceString, redirectToReplacedUrl, function(succeded) {
cordova.plugins.urlremap.addAlias(sourceUriMatchRegex, sourceUriReplaceRegex, replaceString, redirectToReplacedUrl, function(succeded) {
if (succeded){
deferred.resolve();
} else {
@@ -20,19 +20,19 @@

function setResetUrl(url) {
var deferred = $q.defer();
cordova.plugins.appBundle.setResetUrl(url, deferred.resolve);
cordova.plugins.urlremap.setResetUrl(url, deferred.resolve);
return deferred.promise;
}

function injectJsForUrl(url, js) {
var deferred = $q.defer();
cordova.plugins.appBundle.injectJsForUrl(url, js, deferred.resolve);
cordova.plugins.urlremap.injectJsForUrl(url, js, deferred.resolve);
return deferred.promise;
}

function reset() {
var deferred = $q.defer();
cordova.plugins.appBundle.clearAllAliases(deferred.resolve);
cordova.plugins.urlremap.clearAllAliases(deferred.resolve);
return deferred.promise;
}

0 comments on commit e7190bc

Please sign in to comment.