Fixed websql init async,cleanup options,add tested browsers
This commit is contained in:
parent
ec4e9a0dae
commit
e5e2dfc56f
34
README.md
34
README.md
|
@ -13,29 +13,23 @@ A javascript library providing server defined loading of resources for a single
|
||||||
|
|
||||||
Single index.html
|
Single index.html
|
||||||
|
|
||||||
FFSpaLoader.options.debug = true;
|
FFSpaLoader.options.debug.enable = true;
|
||||||
|
FFSpaLoader.options.boot.angular.modules.push('exampleUI');
|
||||||
FFSpaLoader.options.server.url = 'http://myserver';
|
FFSpaLoader.options.server.url = 'http://myserver';
|
||||||
FFSpaLoader.options.server.urlPath = '/api/path/to/spa/client/resources';
|
FFSpaLoader.options.server.assets = '/api/path/to/spa/client/resources';
|
||||||
FFSpaLoader.bootDevice(function() {
|
FFSpaLoader.start();
|
||||||
FFSpaLoader.options.cache.factory = FFSpaLoader.autoSelectCache();// need deviceready via bootDevice for sqllite.
|
|
||||||
FFSpaLoader.start(function() {
|
|
||||||
console.log('FFExample.bootstrap angular');
|
|
||||||
angular.bootstrap( $('body'), ['exampleUI']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
## Usage Web
|
## Usage Web
|
||||||
|
|
||||||
Single index.html
|
Single index.html
|
||||||
|
|
||||||
FFSpaLoader.options.debug = true;
|
FFSpaLoader.options.debug.enable = true;
|
||||||
FFSpaLoader.options.server.url = '';
|
FFSpaLoader.options.boot.angular.modules.push('exampleUI');
|
||||||
FFSpaLoader.options.server.urlPath = '/api/path/to/spa/client/resources';
|
FFSpaLoader.options.server.url = 'http://myserver';
|
||||||
FFSpaLoader.options.cache.factory = FFSpaLoader.autoSelectCache();
|
FFSpaLoader.options.server.assets = '/api/path/to/spa/client/resources';
|
||||||
FFSpaLoader.start(function() {
|
FFSpaLoader.start(function() {
|
||||||
console.log('FFExample.bootstrap angular');
|
console.log('FFExample.boot done');
|
||||||
angular.bootstrap( $('body'), ['exampleUI']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
## Usage Multi Server
|
## Usage Multi Server
|
||||||
|
@ -45,12 +39,20 @@ A javascript library providing server defined loading of resources for a single
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
* options.debug = Enable console debug output.
|
* options.debug.enable = Enable console debug output.
|
||||||
|
* TODO
|
||||||
|
|
||||||
## Example Application
|
## Example Application
|
||||||
|
|
||||||
There is a fully working express example application in the example folder.
|
There is a fully working express example application in the example folder.
|
||||||
|
|
||||||
|
## Tested Browsers
|
||||||
|
|
||||||
|
* Chromium 46
|
||||||
|
* Iceweasel 43
|
||||||
|
* Opera 12 Presto
|
||||||
|
* Android 5 in Cordova
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
In lieu of a formal styleguide, take care to maintain the existing coding style.
|
In lieu of a formal styleguide, take care to maintain the existing coding style.
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// TODO:
|
// TODO:
|
||||||
// set tag.media = 'only you';
|
// set tag.media = 'only you';
|
||||||
// add media in resouces
|
// add media in resouces
|
||||||
// check supported browsers
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FFSpaLoader is an assets loader for single page applications.
|
* FFSpaLoader is an assets loader for single page applications.
|
||||||
|
@ -38,40 +37,57 @@
|
||||||
* - Assets hashing for fast syncing.
|
* - Assets hashing for fast syncing.
|
||||||
* - Assets types: js,css,cssData
|
* - Assets types: js,css,cssData
|
||||||
* - Caching backends: null,localStorage,webSqlDB,sqllite
|
* - Caching backends: null,localStorage,webSqlDB,sqllite
|
||||||
* - Optional ask and cache server assets url.
|
* - Server url question ui.
|
||||||
* - Cordova deviceready event booting.
|
* - Loader error ui.
|
||||||
|
* - Build-in Cordova booting.
|
||||||
|
* - Build-in AngularJS booting.
|
||||||
*
|
*
|
||||||
* @module FFSpaLoader
|
* @module FFSpaLoader
|
||||||
*/
|
*/
|
||||||
var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
debug: false,
|
debug: {
|
||||||
errorHandler: null,
|
enable: false,
|
||||||
bootDevice: {
|
handler: null, // auto filled
|
||||||
timeout: 4096,
|
prefix: 'FFSpaLoader.'
|
||||||
windowFlag: 'FFCordovaDevice'
|
|
||||||
},
|
},
|
||||||
askUrl: {
|
error: {
|
||||||
urlTransport: 'http://',
|
handler: null, // auto filled
|
||||||
questionText: 'Please provide the server name;',
|
title: 'Loader Error',
|
||||||
cssText: '.ffAskUrl { font-size: 1em;margin: auto;width: 50%;border: 3px solid #73AD21;padding: 1em;} .ffAskUrl > div {font-size: 0.8em;color: #ccc;} .ffAskUrl > div > * {} .ffAskUrl > div > input {} .ffAskUrlError{ color: red}',
|
style: '.ffError { margin: auto;width: 90%;border: 3px solid red;padding-left: 1em;padding-bottom: 1em;}'
|
||||||
|
},
|
||||||
|
boot: {
|
||||||
|
cordova: {
|
||||||
|
enable: true,
|
||||||
|
timeout: 4096, // FIXME: Test really slow devices -> increase ? or add support -1 for disable or ?
|
||||||
|
flag: 'FFCordovaDevice'
|
||||||
|
},
|
||||||
|
angular: {
|
||||||
|
enable: true,
|
||||||
|
modules: []
|
||||||
|
},
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
url: null,
|
url: null,
|
||||||
urlPath: null,
|
assets: null,
|
||||||
timeout: 4096,
|
timeout: 4096,
|
||||||
windowFlag: 'FFServerUrl',
|
flag: 'FFServerUrl',
|
||||||
header: {
|
header: {
|
||||||
request: {
|
request: { // TODO: add header support
|
||||||
'X-FFSpaLoader': '42'
|
'X-FFSpaLoader': '42'
|
||||||
},
|
},
|
||||||
response: {
|
response: {
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
question: {
|
||||||
|
transport: 'http://',
|
||||||
|
title: 'Server',
|
||||||
|
text: 'Please provide the server name;', // TODO: rename .ffAskUrl
|
||||||
|
style: '.ffAskUrl { font-size: 1em;margin: auto;width: 90%;border: 3px solid #73AD21;padding-left: 1em;padding-bottom: 1em;} .ffAskUrl > div {font-size: 0.8em;color: #ccc;} .ffAskUrl > div > * {} .ffAskUrl > div > input {} .ffAskUrlError{ color: red}',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cache: {
|
cache: {
|
||||||
factory: null,
|
|
||||||
meta: null,
|
meta: null,
|
||||||
js: null,
|
js: null,
|
||||||
css: null,
|
css: null,
|
||||||
|
@ -79,18 +95,8 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
var cacheDB = null; // single instance for websql
|
||||||
* Prints debug message to the console if options.debug is true.
|
|
||||||
* @param {String} message The message to log.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var utilDebug = function (message) {
|
|
||||||
if (options.debug !== true) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log('FFSpaLoader.'+message);
|
|
||||||
};
|
|
||||||
|
|
||||||
var factory = {
|
var factory = {
|
||||||
detect: {
|
detect: {
|
||||||
localStorage: function() {
|
localStorage: function() {
|
||||||
|
@ -113,7 +119,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
return 'cordova' in window;
|
return 'cordova' in window;
|
||||||
},
|
},
|
||||||
cordovaDevice: function() {
|
cordovaDevice: function() {
|
||||||
return options.bootDevice.windowFlag in window;
|
return options.boot.cordova.flag in window;
|
||||||
},
|
},
|
||||||
mobileAgent: function() {
|
mobileAgent: function() {
|
||||||
return navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/);
|
return navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/);
|
||||||
|
@ -165,25 +171,38 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
cb(err.message+' code: '+err.code);
|
cb(err.message+' code: '+err.code);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
var cacheDB = window.openDatabase(opt.name, opt.version, opt.name, opt.size);
|
var cacheDBInit = function(cb) {
|
||||||
cacheDB.transaction(function(tx) {
|
cacheDB.transaction(function(tx) {
|
||||||
var query = 'SELECT value FROM cache_store WHERE key = \"test-for-table\"';
|
|
||||||
utilDebug('websql.init query: '+query);
|
|
||||||
tx.executeSql(query, [], function(tx,res) {}, function(tx,errorNoTable) {
|
|
||||||
var query = 'CREATE TABLE cache_store(id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL, value TEXT NOT NULL)';
|
var query = 'CREATE TABLE cache_store(id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL, value TEXT NOT NULL)';
|
||||||
utilDebug('websql.init query: '+query);
|
utilDebug('websql.init query '+query);
|
||||||
tx.executeSql(query, [], function(tx,res) {
|
tx.executeSql(query, [], function(tx,res) {
|
||||||
var query = 'CREATE UNIQUE INDEX cache_store__key__udx ON cache_store (key)';
|
var query = 'CREATE UNIQUE INDEX cache_store__key__udx ON cache_store (key)';
|
||||||
utilDebug('websql.init query: '+query);
|
utilDebug('websql.init query '+query);
|
||||||
tx.executeSql(query, [], function(tx,res) {}, sqlErrorHandler(options.errorHandler)); // FIX<E: asyns error ?
|
tx.executeSql(query, [], function(tx,res) {cb(null)}, sqlErrorHandler(cb));
|
||||||
}, sqlErrorHandler(options.errorHandler));
|
}, sqlErrorHandler(cb));
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
return {
|
return {
|
||||||
|
cacheOpen: function(cb) {
|
||||||
|
if (cacheDB !== null) {
|
||||||
|
cb(null); // open once.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cacheDB = window.openDatabase(opt.name, opt.version, opt.name, opt.size);
|
||||||
|
cacheDB.transaction(function(tx) {
|
||||||
|
var query = 'SELECT value FROM cache_store WHERE key = \"test-for-table\"';
|
||||||
|
utilDebug('websql.cacheOpen query '+query);
|
||||||
|
tx.executeSql(query, [], function(tx,res) {
|
||||||
|
cb(null);
|
||||||
|
}, function(tx,errorNoTable) {
|
||||||
|
cacheDBInit(cb);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
cacheGetValue: function(key, cb) {
|
cacheGetValue: function(key, cb) {
|
||||||
cacheDB.transaction(function(tx) {
|
cacheDB.transaction(function(tx) {
|
||||||
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
||||||
utilDebug('websql.cacheGetValue query: '+query);
|
utilDebug('websql.cacheGetValue query '+query);
|
||||||
tx.executeSql(query,[key], function(tx, res) {
|
tx.executeSql(query,[key], function(tx, res) {
|
||||||
if (res.rows.length === 0) {
|
if (res.rows.length === 0) {
|
||||||
cb(null, null);
|
cb(null, null);
|
||||||
|
@ -197,15 +216,15 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
cacheSetValue: function(key, value, cb) {
|
cacheSetValue: function(key, value, cb) {
|
||||||
cacheDB.transaction(function(tx) {
|
cacheDB.transaction(function(tx) {
|
||||||
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
||||||
utilDebug('websql.cacheSetValue query: '+query);
|
utilDebug('websql.cacheSetValue query '+query);
|
||||||
tx.executeSql(query,[key], function(tx, res) {
|
tx.executeSql(query,[key], function(tx, res) {
|
||||||
if (res.rows.length === 0) {
|
if (res.rows.length === 0) {
|
||||||
var query = 'INSERT INTO cache_store (key,value) VALUES (?,?)';
|
var query = 'INSERT INTO cache_store (key,value) VALUES (?,?)';
|
||||||
utilDebug('websql.cacheSetValue query: '+query);
|
utilDebug('websql.cacheSetValue query '+query);
|
||||||
tx.executeSql(query, [key,JSON.stringify(value)], nullDataHandler(cb), sqlErrorHandler(cb));
|
tx.executeSql(query, [key,JSON.stringify(value)], nullDataHandler(cb), sqlErrorHandler(cb));
|
||||||
} else {
|
} else {
|
||||||
var query = 'UPDATE cache_store SET value = ? WHERE key = ?';
|
var query = 'UPDATE cache_store SET value = ? WHERE key = ?';
|
||||||
utilDebug('websql.cacheSetValue query: '+query);
|
utilDebug('websql.cacheSetValue query '+query);
|
||||||
tx.executeSql(query, [JSON.stringify(value),key], nullDataHandler(cb), sqlErrorHandler(cb));
|
tx.executeSql(query, [JSON.stringify(value),key], nullDataHandler(cb), sqlErrorHandler(cb));
|
||||||
}
|
}
|
||||||
}, sqlErrorHandler(cb));
|
}, sqlErrorHandler(cb));
|
||||||
|
@ -214,8 +233,10 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
cacheDeleteValue: function(key, cb) {
|
cacheDeleteValue: function(key, cb) {
|
||||||
cacheDB.transaction(function(tx) {
|
cacheDB.transaction(function(tx) {
|
||||||
var query = 'DELETE FROM cache_store WHERE key = ?';
|
var query = 'DELETE FROM cache_store WHERE key = ?';
|
||||||
utilDebug('websql.cacheDeleteValue query: '+query);
|
utilDebug('websql.cacheDeleteValue query '+query);
|
||||||
tx.executeSql(query, [key], nullDataHandler(cb), sqlErrorHandler(cb));
|
tx.executeSql(query, [key], function (tx, res) {
|
||||||
|
setTimeout(function() {cb(null);}); // return next tick so transaction is flushed before location.reload
|
||||||
|
}, sqlErrorHandler(cb));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,24 +244,36 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the debug message with prefix to the options.debug.handler if options.debug.enable is true.
|
||||||
|
* @param {String} message The message to log.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
var utilDebug = function (message) {
|
||||||
|
if (options.debug.enable !== true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
options.debug.handler(options.debug.prefix+message);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default error handler which renders the error in the browser.
|
* The default error handler which renders the error in the browser.
|
||||||
* @param {String|Error} err The error message.
|
* @param {String|Error} err The error message.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var utilErrorHandler = function(err) {
|
var utilErrorHandler = function(err) {
|
||||||
utilDebug('utilErrorHandler error: '+err);
|
utilDebug('utilErrorHandler error '+err); // TODO: Add Error object support
|
||||||
|
|
||||||
var rootTag = document.createElement('div');
|
var rootTag = document.createElement('div');
|
||||||
rootTag.setAttribute('class','ffError');
|
rootTag.setAttribute('class','ffError');
|
||||||
|
|
||||||
var cssTag = document.createElement("style");
|
var cssTag = document.createElement("style");
|
||||||
cssTag.type = "text/css";
|
cssTag.type = "text/css";
|
||||||
cssTag.innerHTML = '.ffError { margin: auto;width: 50%;border: 3px solid red;padding: 1em;} .ffAskUrl > div {font-size: 0.8em;color: red;}';
|
cssTag.innerHTML = options.error.style;
|
||||||
rootTag.appendChild(cssTag);
|
rootTag.appendChild(cssTag);
|
||||||
|
|
||||||
var titleTag = document.createElement('h1');
|
var titleTag = document.createElement('h1');
|
||||||
titleTag.appendChild(document.createTextNode('Error'));
|
titleTag.appendChild(document.createTextNode(options.error.title));
|
||||||
rootTag.appendChild(titleTag);
|
rootTag.appendChild(titleTag);
|
||||||
|
|
||||||
var questionTag = document.createElement('p');
|
var questionTag = document.createElement('p');
|
||||||
|
@ -249,7 +282,6 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
||||||
};
|
};
|
||||||
options.errorHandler = utilErrorHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches an url resource with a XMLHttpRequest.
|
* Fetches an url resource with a XMLHttpRequest.
|
||||||
|
@ -262,16 +294,16 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
var httpRequest = new XMLHttpRequest();
|
var httpRequest = new XMLHttpRequest();
|
||||||
httpRequest.onreadystatechange = function() {
|
httpRequest.onreadystatechange = function() {
|
||||||
if (httpRequest.readyState == 4 && httpRequest.status === 200) {
|
if (httpRequest.readyState == 4 && httpRequest.status === 200) {
|
||||||
utilDebug('utilHttpFetch url: '+url+' done in '+(new Date().getTime()-startTime)+' ms.');
|
utilDebug('utilHttpFetch url \"'+url+'\" done in '+(new Date().getTime()-startTime)+' ms.');
|
||||||
cb(null, httpRequest);
|
cb(null, httpRequest);
|
||||||
} else if (httpRequest.readyState == 4) {
|
} else if (httpRequest.readyState == 4) {
|
||||||
cb('Wrong status: '+httpRequest.status);
|
cb('Wrong status '+httpRequest.status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
httpRequest.open('GET', url, true);
|
httpRequest.open('GET', url, true);
|
||||||
httpRequest.timeout = options.server.timeout; // ieX: after open()
|
httpRequest.timeout = options.server.timeout; // ieX: after open()
|
||||||
httpRequest.ontimeout = function() {
|
httpRequest.ontimeout = function() {
|
||||||
cb('timeout after '+options.server.timeout+' of url: '+url);
|
cb('timeout after '+options.server.timeout+' of url '+url);
|
||||||
};
|
};
|
||||||
httpRequest.send();
|
httpRequest.send();
|
||||||
};
|
};
|
||||||
|
@ -280,9 +312,6 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
if (options.cache[type]) {
|
if (options.cache[type]) {
|
||||||
return options.cache[type];
|
return options.cache[type];
|
||||||
}
|
}
|
||||||
if (options.cache['factory']) {
|
|
||||||
return options.cache['factory'];
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -291,13 +320,13 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
var cacheCheckType = function (type, cb, action) {
|
var cacheCheckType = function (type, cb, action) {
|
||||||
cacheHasService(type)?action():cb('No caching for: '+type);
|
cacheHasService(type)?action():cb('No caching for '+type);
|
||||||
};
|
};
|
||||||
|
|
||||||
var cacheGetValue = function(type, key , cb) {
|
var cacheGetValue = function(type, key , cb) {
|
||||||
cacheCheckType(type, cb, function() {
|
cacheCheckType(type, cb, function() {
|
||||||
var cacheKey = type+'_'+key;
|
var cacheKey = type+'_'+key;
|
||||||
utilDebug('cacheGetValue key: '+cacheKey);
|
utilDebug('cacheGetValue key '+cacheKey);
|
||||||
cacheGetService(type).cacheGetValue(cacheKey,cb);
|
cacheGetService(type).cacheGetValue(cacheKey,cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -305,7 +334,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
var cacheSetValue = function(type, key, value, cb) {
|
var cacheSetValue = function(type, key, value, cb) {
|
||||||
cacheCheckType(type, cb, function() {
|
cacheCheckType(type, cb, function() {
|
||||||
var cacheKey = type+'_'+key;
|
var cacheKey = type+'_'+key;
|
||||||
utilDebug('cacheSetValue key: '+cacheKey);
|
utilDebug('cacheSetValue key '+cacheKey);
|
||||||
cacheGetService(type).cacheSetValue(cacheKey,value,cb);
|
cacheGetService(type).cacheSetValue(cacheKey,value,cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -313,20 +342,20 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
var cacheDeleteValue = function(type, key, cb) {
|
var cacheDeleteValue = function(type, key, cb) {
|
||||||
cacheCheckType(type, cb, function() {
|
cacheCheckType(type, cb, function() {
|
||||||
var cacheKey = type+'_'+key;
|
var cacheKey = type+'_'+key;
|
||||||
utilDebug('cacheDeleteValue key: '+cacheKey);
|
utilDebug('cacheDeleteValue key '+cacheKey);
|
||||||
cacheGetService(type).cacheDeleteValue(cacheKey,cb);
|
cacheGetService(type).cacheDeleteValue(cacheKey,cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var cleanupCache = function (resources, cb) {
|
var cleanupCache = function (resources, cb) {
|
||||||
utilDebug('cleanupCache TODO cacheList: '+0+' resources: '+resources.length);
|
utilDebug('cleanupCache TODO cacheList '+0+' resources '+resources.length);
|
||||||
|
|
||||||
// TODO: impl for removes in resource lists
|
// TODO: impl for removes in resource lists
|
||||||
cb(null);
|
cb(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
var injectResourceData = function(resource, data, cb) {
|
var injectResourceData = function(resource, data, cb) {
|
||||||
utilDebug('injectResourceData resource: '+JSON.stringify(resource)+' data: '+data.length);
|
utilDebug('injectResourceData resource '+JSON.stringify(resource)+' data '+data.length);
|
||||||
var tag = null;
|
var tag = null;
|
||||||
if (resource.type === 'css' || resource.type === 'cssData') {
|
if (resource.type === 'css' || resource.type === 'cssData') {
|
||||||
tag = document.createElement('style');
|
tag = document.createElement('style');
|
||||||
|
@ -347,7 +376,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
var storeResourceKey = function (resource, cb) {
|
var storeResourceKey = function (resource, cb) {
|
||||||
// Add all cache keys in central list so we can clear the cache item if resources are removed.
|
// Add all cache keys in central list so we can clear the cache item if resources are removed.
|
||||||
var cacheKey = resource.type+'_keys';
|
var cacheKey = resource.type+'_keys';
|
||||||
cacheGetValue('meta',cacheKey,function (err,value) {
|
cacheGetValue('meta',cacheKey,function (err,value) { // TODO: move to resource.type
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
cb(err);
|
cb(err);
|
||||||
return;
|
return;
|
||||||
|
@ -361,7 +390,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
var storeResource = function (resource, httpRequest, cb) {
|
var storeResource = function (resource, httpRequest, cb) {
|
||||||
utilDebug('storeResource url: '+resource.url+' hash: '+resource.hash);
|
utilDebug('storeResource url '+resource.url+' hash '+resource.hash);
|
||||||
var item = {
|
var item = {
|
||||||
resource: resource,
|
resource: resource,
|
||||||
data: httpRequest.responseText
|
data: httpRequest.responseText
|
||||||
|
@ -388,11 +417,9 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
utilDebug('loadResource cache miss');
|
utilDebug('loadResource cache miss'); // + hash mismatch as its the key
|
||||||
} else if (value.resource === undefined) {
|
} else if (value.resource === undefined) {
|
||||||
utilDebug('loadResource cache wrong obj');
|
utilDebug('loadResource cache wrong obj');
|
||||||
} else if (value.resource.hash !== resource.hash) {
|
|
||||||
utilDebug('loadResource cache hash mismatch');
|
|
||||||
} else {
|
} else {
|
||||||
utilDebug('loadResource cache hit');
|
utilDebug('loadResource cache hit');
|
||||||
injectResourceData(value.resource,value.data,cb);
|
injectResourceData(value.resource,value.data,cb);
|
||||||
|
@ -456,7 +483,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
tag = document.createElement('script');
|
tag = document.createElement('script');
|
||||||
tag.type = 'text/javascript';
|
tag.type = 'text/javascript';
|
||||||
}
|
}
|
||||||
utilDebug('injectResources resource: '+JSON.stringify(resource));
|
utilDebug('injectResources from '+JSON.stringify(resource));
|
||||||
|
|
||||||
tag.appendChild(document.createTextNode(item.data));
|
tag.appendChild(document.createTextNode(item.data));
|
||||||
|
|
||||||
|
@ -481,29 +508,29 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
cb('Missing options.server.url');
|
cb('Missing options.server.url');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (options.server.urlPath === null) {
|
if (options.server.assets === null) {
|
||||||
cb('Missing options.server.urlPath');
|
cb('Missing options.server.assets');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window[options.server.windowFlag] = options.server.url;
|
window[options.server.flag] = options.server.url;
|
||||||
|
|
||||||
var resourcesUrl = options.server.url + options.server.urlPath;
|
var resourcesUrl = options.server.url + options.server.assets;
|
||||||
utilDebug('startLoader serverUrl: '+resourcesUrl);
|
utilDebug('startLoader assets \"'+resourcesUrl+'\"');
|
||||||
utilHttpFetch(resourcesUrl, function(err, httpRequest) {
|
utilHttpFetch(resourcesUrl, function(err, httpRequest) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
utilDebug('startLoader fetch error: '+err);
|
utilDebug('startLoader fetch error '+err);
|
||||||
if (cacheHasService('meta')) {
|
if (cacheHasService('meta')) {
|
||||||
cacheGetValue('meta','server_resources',function(err, value) {
|
cacheGetValue('meta','server_resources',function(err, value) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else if (value === null) {
|
} else if (value === null) {
|
||||||
cb('Have no cache of server resouces from: '+options.server.url);
|
cb('Have no cache of server resouces from '+options.server.url);
|
||||||
} else {
|
} else {
|
||||||
injectResources(value, cb);
|
injectResources(value, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cb('Could not fetch server resouces from: '+options.server.url);
|
cb('Could not fetch server resouces from '+options.server.url);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +538,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
JSON.parse(httpRequest.responseText).data.resources.forEach(function (r) {
|
JSON.parse(httpRequest.responseText).data.resources.forEach(function (r) {
|
||||||
resources.push(r);
|
resources.push(r);
|
||||||
});
|
});
|
||||||
utilDebug('startLoader resources: '+resources.length);
|
utilDebug('startLoader resources '+resources.length);
|
||||||
if (cacheHasService('meta')) {
|
if (cacheHasService('meta')) {
|
||||||
cacheSetValue('meta','server_resources',resources, function (err) {
|
cacheSetValue('meta','server_resources',resources, function (err) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
|
@ -542,13 +569,13 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
options.server.url = '';
|
options.server.url = '';
|
||||||
if (options.askUrl.urlTransport !== undefined) {
|
if (options.server.question.transport !== undefined) {
|
||||||
options.server.url += options.askUrl.urlTransport;
|
options.server.url += options.server.question.transport;
|
||||||
}
|
}
|
||||||
options.server.url += inputTag.value;
|
options.server.url += inputTag.value;
|
||||||
|
|
||||||
var resourcesUrl = options.server.url + options.server.urlPath;
|
var resourcesUrl = options.server.url + options.server.assets;
|
||||||
utilDebug('askUrlStart check url: '+resourcesUrl);
|
utilDebug('askUrlStart check assets '+resourcesUrl);
|
||||||
|
|
||||||
// TODO: add+check headers
|
// TODO: add+check headers
|
||||||
utilHttpFetch(resourcesUrl,function(err, req) {
|
utilHttpFetch(resourcesUrl,function(err, req) {
|
||||||
|
@ -560,7 +587,7 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
if (cacheHasService('meta')) {
|
if (cacheHasService('meta')) {
|
||||||
cacheSetValue('meta','server_url',options.server.url, function(err) {
|
cacheSetValue('meta','server_url',options.server.url, function(err) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
startLoader(cb);
|
startLoader(cb);
|
||||||
}
|
}
|
||||||
|
@ -585,20 +612,24 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
|
|
||||||
var cssTag = document.createElement("style");
|
var cssTag = document.createElement("style");
|
||||||
cssTag.type = "text/css";
|
cssTag.type = "text/css";
|
||||||
cssTag.innerHTML = options.askUrl.cssText;
|
cssTag.innerHTML = options.server.question.style;
|
||||||
rootTag.appendChild(cssTag);
|
rootTag.appendChild(cssTag);
|
||||||
|
|
||||||
|
var titleTag = document.createElement('h1');
|
||||||
|
titleTag.appendChild(document.createTextNode(options.server.question.title));
|
||||||
|
rootTag.appendChild(titleTag);
|
||||||
|
|
||||||
var questionTag = document.createElement('p');
|
var questionTag = document.createElement('p');
|
||||||
questionTag.appendChild(document.createTextNode(options.askUrl.questionText));
|
questionTag.appendChild(document.createTextNode(options.server.question.text));
|
||||||
rootTag.appendChild(questionTag);
|
rootTag.appendChild(questionTag);
|
||||||
|
|
||||||
var formTag = document.createElement('div');
|
var formTag = document.createElement('div');
|
||||||
rootTag.appendChild(formTag);
|
rootTag.appendChild(formTag);
|
||||||
|
|
||||||
if (options.askUrl.urlTransport !== undefined) {
|
if (options.server.question.transport !== undefined) {
|
||||||
var transportTag = document.createElement('label');
|
var transportTag = document.createElement('label');
|
||||||
rootTag.setAttribute('for','serverInput');
|
rootTag.setAttribute('for','serverInput');
|
||||||
transportTag.appendChild(document.createTextNode(options.askUrl.urlTransport));
|
transportTag.appendChild(document.createTextNode(options.server.question.transport));
|
||||||
formTag.appendChild(transportTag);
|
formTag.appendChild(transportTag);
|
||||||
}
|
}
|
||||||
var inputTag = document.createElement('input');
|
var inputTag = document.createElement('input');
|
||||||
|
@ -626,6 +657,46 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var startCacheType = function (type,cb) {
|
||||||
|
if (options.cache[type] !== null && options.cache[type] === false) {
|
||||||
|
utilDebug('startCacheType '+type+' disabled');
|
||||||
|
options.cache[type] = null;
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
if (options.cache[type] === null) {
|
||||||
|
if (factory.detect.cordovaDevice() && factory.detect.sqlitePlugin()) {
|
||||||
|
utilDebug('startCacheType auto sqlitePlugin for '+type);
|
||||||
|
options.cache[type] = factory.cache.websql({openDatabase: window.sqlitePlugin});
|
||||||
|
} else if (factory.detect.openDatabase()) {
|
||||||
|
utilDebug('startCacheType auto openDatabase for '+type);
|
||||||
|
options.cache[type] = factory.cache.websql();
|
||||||
|
} else if (factory.detect.localStorage()) {
|
||||||
|
utilDebug('startCacheType auto localStorage for '+type);
|
||||||
|
options.cache[type] = factory.cache.localStorage();
|
||||||
|
} else {
|
||||||
|
utilDebug('startCacheType '+type+' none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.cache[type] !== null && typeof options.cache[type]['cacheOpen'] === "function") {
|
||||||
|
options.cache[type].cacheOpen(cb);
|
||||||
|
} else {
|
||||||
|
cb(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var startCache = function (cb) {
|
||||||
|
startCacheType('meta', function(err) {
|
||||||
|
if (err !== null) { return cb(err); }
|
||||||
|
startCacheType('js', function(err) {
|
||||||
|
if (err !== null) { return cb(err); }
|
||||||
|
startCacheType('css', function(err) {
|
||||||
|
if (err !== null) { return cb(err); }
|
||||||
|
startCacheType('cssData', cb);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the loader.
|
* Starts the loader.
|
||||||
*
|
*
|
||||||
|
@ -635,72 +706,73 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
var startTime = new Date().getTime();
|
var startTime = new Date().getTime();
|
||||||
var cb = function(err) {
|
var cb = function(err) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
options.errorHandler(err);
|
options.error.handler(err);
|
||||||
} else {
|
} else {
|
||||||
utilDebug('start done in '+(new Date().getTime()-startTime)+' ms.');
|
utilDebug('start done in '+(new Date().getTime()-startTime)+' ms.');
|
||||||
if (typeof cbArgu === "function") {
|
bootAngular(function(err) {
|
||||||
cbArgu();
|
if (err !== null) { return options.error.handler(err); }
|
||||||
}
|
if (typeof cbArgu === "function") {
|
||||||
|
cbArgu();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utilDebug('start serverUrl: '+options.server.url);
|
if (options.debug.enable === true) {
|
||||||
if (options.server.url !== null) {
|
var optionsKeys = Object.keys(options);
|
||||||
startLoader(cb);
|
for (var keyId in optionsKeys) {
|
||||||
return;
|
var key = optionsKeys[keyId];
|
||||||
|
utilDebug('start config '+key+' '+JSON.stringify(options[key]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cacheHasService('meta')) {
|
bootCordova(function(err) {
|
||||||
cacheGetValue('meta','server_url',function(err, value) {
|
if (err !== null) { return cb(err); }
|
||||||
if (err !== null) {
|
startCache(function(err) {
|
||||||
cb(err);
|
if (err !== null) { return cb(err); }
|
||||||
} else if (value === undefined || value === null || value === '') {
|
if (options.server.url !== null) {
|
||||||
askUrl(cb);
|
|
||||||
} else {
|
|
||||||
options.server.url = value;
|
|
||||||
startLoader(cb);
|
startLoader(cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cacheHasService('meta')) {
|
||||||
|
cacheGetValue('meta','server_url',function(err, value) {
|
||||||
|
if (err !== null) {
|
||||||
|
cb(err);
|
||||||
|
} else if (value === undefined || value === null || value === '') {
|
||||||
|
askUrl(cb);
|
||||||
|
} else {
|
||||||
|
options.server.url = value;
|
||||||
|
startLoader(cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
askUrl(cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
});
|
||||||
askUrl(cb);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var clearServer = function(cb) {
|
var clearServerUrl = function(cb) {
|
||||||
if (cb === undefined) {
|
if (cb === undefined) {
|
||||||
cb = function() {};
|
cb = function() {};
|
||||||
}
|
}
|
||||||
if (cacheHasService('meta')) {
|
if (cacheHasService('meta')) {
|
||||||
cacheDeleteValue('meta','server_url',function(err) {
|
cacheDeleteValue('meta','server_url',cb);
|
||||||
if (err !== null) {
|
|
||||||
cb(err);
|
|
||||||
} else {
|
|
||||||
cb(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
cb(null);
|
cb(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
var bootAngular = function(cb) {
|
||||||
* Helper for automatic selecting the best to none cache backend option.
|
if (options.boot.angular.enable !== true) {
|
||||||
*
|
utilDebug('bootAngular disabled by options');
|
||||||
* Order of detection; sqllite,openDatabase,localStorage,none.
|
return cb(null);
|
||||||
*/
|
|
||||||
var autoSelectCache = function() {
|
|
||||||
if (factory.detect.cordovaDevice() && factory.detect.sqlitePlugin()) {
|
|
||||||
utilDebug('autoSelectCache sqlitePlugin');
|
|
||||||
return factory.cache.websql({openDatabase: window.sqlitePlugin});
|
|
||||||
}
|
}
|
||||||
if (factory.detect.openDatabase()) {
|
if (options.boot.angular.modules.length === 0) {
|
||||||
utilDebug('autoSelectCache openDatabase');
|
utilDebug('bootAngular disabled by no modules');
|
||||||
return factory.cache.websql();
|
return cb(null);
|
||||||
}
|
}
|
||||||
if (factory.detect.localStorage()) {
|
utilDebug('bootAngular start '+options.boot.angular.modules);
|
||||||
utilDebug('autoSelectCache localStorage');
|
angular.bootstrap(document, options.boot.angular.modules);
|
||||||
return factory.cache.localStorage();
|
cb(null);
|
||||||
}
|
|
||||||
utilDebug('autoSelectCache none');
|
|
||||||
return null; // no caching
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -709,40 +781,43 @@ var FFSpaLoader = (/** @lends module:FFSpaLoader */function () {
|
||||||
* Note: On none cordova device page is will timeout.
|
* Note: On none cordova device page is will timeout.
|
||||||
*
|
*
|
||||||
* @param {function} cb Callback gets called device is ready to use.
|
* @param {function} cb Callback gets called device is ready to use.
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
var bootDevice = function(cb) {
|
var bootCordova = function(cb) {
|
||||||
|
if (options.boot.cordova.enable !== true) {
|
||||||
|
utilDebug('bootCordova disabled by options');
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
if (factory.detect.cordova() !== true) {
|
||||||
|
utilDebug('bootCordova disabled by detect');
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
var startTime = new Date().getTime();
|
var startTime = new Date().getTime();
|
||||||
var bootOnce = function() {
|
var bootOnce = function() {
|
||||||
if (typeof cb === "function") {
|
var callback = cb;
|
||||||
var callback = cb;
|
cb = null;
|
||||||
cb = null;
|
utilDebug('bootCordova done in '+(new Date().getTime()-startTime)+' ms.');
|
||||||
utilDebug('bootDevice done in '+(new Date().getTime()-startTime)+' ms.');
|
callback();
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if (!factory.detect.cordova()) {
|
utilDebug('bootCordova timeout '+options.boot.cordova.timeout);
|
||||||
utilDebug('bootDevice webapp');
|
|
||||||
bootOnce();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
utilDebug('bootDevice timeout: '+options.bootDeviceTimeout);
|
|
||||||
setTimeout ( function () {
|
setTimeout ( function () {
|
||||||
utilDebug('bootDevice timeout');
|
utilDebug('bootCordova timeout');
|
||||||
bootOnce();
|
bootOnce();
|
||||||
}, options.bootDevice.timeout);
|
}, options.boot.cordova.timeout);
|
||||||
document.addEventListener("deviceready", function () {
|
document.addEventListener("deviceready", function () {
|
||||||
window[options.bootDevice.windowFlag] = true;
|
window[options.boot.cordova.flag] = true;
|
||||||
utilDebug('bootDevice '+options.bootDevice.windowFlag);
|
utilDebug('bootCordova '+options.boot.cordova.flag);
|
||||||
bootOnce();
|
bootOnce();
|
||||||
}, false);
|
}, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Auto fill handlers and return public object.
|
||||||
|
options.debug.handler = function(msg) {console.log(msg);};
|
||||||
|
options.error.handler = utilErrorHandler;
|
||||||
return {
|
return {
|
||||||
options: options,
|
options: options,
|
||||||
factory: factory,
|
factory: factory,
|
||||||
start: start,
|
start: start,
|
||||||
bootDevice: bootDevice,
|
clearServerUrl: clearServerUrl
|
||||||
autoSelectCache: autoSelectCache,
|
|
||||||
clearServer: clearServer
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
var tpl = '<div><h2>Foo</h2><p>Welcome to the foo.</p></div>';
|
var tpl = '<div><h2>Foo</h2><p>Welcome to the foo.</p></div>';
|
||||||
tpl += '<input type=\"button\" class=\"btn btn-default\" ng-click=\"doReboot()\" value=\"Reboot\"></input>';
|
tpl += '<input type=\"button\" class=\"btn btn-default\" ng-click=\"doReboot()\" value=\"Reboot\"></input>';
|
||||||
tpl += '<input type=\"button\" class=\"btn btn-default\" ng-click=\"doClearServer()\" value=\"Clear Server\"></input>';
|
tpl += '<input type=\"button\" class=\"btn btn-default\" ng-click=\"doClearServerUrl()\" value=\"Clear Server\"></input>';
|
||||||
|
|
||||||
pageRouteInit.push(function ($routeProvider, $locationProvider) {
|
pageRouteInit.push(function ($routeProvider, $locationProvider) {
|
||||||
$routeProvider.when('/example-ui/foo', {
|
$routeProvider.when('/example-ui/foo', {
|
||||||
|
@ -15,8 +15,13 @@ function PageFoo($scope) {
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.doClearServer = function ( path ) {
|
$scope.doClearServerUrl = function ( path ) {
|
||||||
FFSpaLoader.clearServer();
|
FFSpaLoader.clearServerUrl(function(err) {
|
||||||
window.location.reload(true);
|
if (err) {
|
||||||
|
window.alert(err);
|
||||||
|
} else {
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
document.title = 'FF-Spa-Loader Example';
|
document.title = 'FFSpaLoader Example';
|
||||||
|
|
||||||
var serverUrl = window.FFServerUrl;
|
var serverUrl = window.FFServerUrl;
|
||||||
console.log('FF provided serverUrl: '+serverUrl);
|
console.log('FFExample provided serverUrl \"'+serverUrl+'\"');
|
||||||
|
|
||||||
$(document.createElement('div')).attr('id', 'wrapper').appendTo($('body'));
|
$(document.createElement('div')).attr('id', 'wrapper').appendTo($('body'));
|
||||||
$(document.createElement('div')).attr('ng-controller', 'ApplicationController').attr('ng-include', '\''+serverUrl+'/example-ui/thtml/header\'').appendTo($('#wrapper'));
|
$(document.createElement('div')).attr('ng-controller', 'ApplicationController').attr('ng-include', '\''+serverUrl+'/example-ui/thtml/header\'').appendTo($('#wrapper'));
|
||||||
|
|
|
@ -6,13 +6,10 @@
|
||||||
</head>
|
</head>
|
||||||
<body><%- inline %>
|
<body><%- inline %>
|
||||||
<script>
|
<script>
|
||||||
FFSpaLoader.options.debug = true;
|
FFSpaLoader.options.debug.enable = true;
|
||||||
FFSpaLoader.options.server.urlPath = '/static/spa-client-resources';
|
FFSpaLoader.options.boot.angular.modules.push('exampleUI');
|
||||||
FFSpaLoader.options.cache.factory = FFSpaLoader.autoSelectCache();
|
FFSpaLoader.options.server.assets = '/static/spa-client-resources';
|
||||||
FFSpaLoader.start(function() {
|
FFSpaLoader.start();
|
||||||
console.log('FFExample.bootstrap angular');
|
|
||||||
angular.bootstrap( $('body'), ['exampleUI']);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue