Fixed offline injection and added Error support
This commit is contained in:
parent
1679782085
commit
2010e420d8
|
@ -77,7 +77,7 @@ A javascript library providing server defined loading of assets for a single pag
|
|||
* debug.handler = Prints/log debug message. (default: console.log)
|
||||
* debug.prefix = Debug message prefix. (default: 'FFSpaLoader.')
|
||||
* error.handler = The error handler. (default: internal error handler ui)
|
||||
* error.title = The error title. (default: 'Loader Error');
|
||||
* error.title = The error title. (default: 'Loader ');
|
||||
* error.style = The error ui css style. (default: red border box)
|
||||
* boot.cordova.enable = Use deviceready event to boot when cordova is detected. (default: true)
|
||||
* boot.cordova.timeout = Boot after (if<0=no-)timeout when deviceready event is not received. (default: -1)
|
||||
|
@ -143,6 +143,7 @@ A javascript library providing server defined loading of assets for a single pag
|
|||
* Chromium 46
|
||||
* Iceweasel 43
|
||||
* Opera 12 Presto
|
||||
* IE 11 Edge
|
||||
* Android 5 in Cordova
|
||||
|
||||
## Todo
|
||||
|
@ -167,6 +168,7 @@ Add unit tests for any new or changed functionality. Lint and test your code.
|
|||
### 0.0.4
|
||||
* Disable cordova timeout per default.
|
||||
* Remove unused mobileAgent detect.
|
||||
* Fixed cached resources loading.
|
||||
|
||||
|
||||
### 0.0.3
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
},
|
||||
error: {
|
||||
handler: null, // auto filled
|
||||
title: 'Loader Error',
|
||||
title: 'Loader ',
|
||||
style: '.ffError { margin: auto;width: 90%;border: 3px solid red;padding-left: 1em;padding-bottom: 1em;}'
|
||||
},
|
||||
boot: {
|
||||
|
@ -158,20 +158,20 @@
|
|||
cb(null);
|
||||
};
|
||||
};
|
||||
var sqlErrorHandler = function(cb) {
|
||||
return function (tx, err) {
|
||||
cb(err.message+' code: '+err.code);
|
||||
};
|
||||
var executeSql = function(tx, query, values, resultHandler, errorHandler) {
|
||||
tx.executeSql(query, values, resultHandler, function(tx,err) {
|
||||
errorHandler(new Error('Code: '+err.code+' '+err.message+' by query: '+query));
|
||||
});
|
||||
};
|
||||
var cacheDBInit = function(cb) {
|
||||
cacheDB.transaction(function(tx) {
|
||||
var query = 'CREATE TABLE cache_store(id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL, value TEXT NOT NULL)';
|
||||
utilDebug('websql.init query '+query);
|
||||
tx.executeSql(query, [], function(tx) {
|
||||
executeSql(tx, query, [], function(tx) {
|
||||
var query = 'CREATE UNIQUE INDEX cache_store__key__udx ON cache_store (key)';
|
||||
utilDebug('websql.init query '+query);
|
||||
tx.executeSql(query, [], function() {cb(null);}, sqlErrorHandler(cb));
|
||||
}, sqlErrorHandler(cb));
|
||||
executeSql(tx, query, [], nullDataHandler(cb), cb);
|
||||
}, cb);
|
||||
});
|
||||
};
|
||||
return {
|
||||
|
@ -187,7 +187,7 @@
|
|||
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() {
|
||||
executeSql(tx, query, [], function() {
|
||||
cb(null);
|
||||
}, function() {
|
||||
cacheDBInit(cb);
|
||||
|
@ -198,40 +198,40 @@
|
|||
cacheDB.transaction(function(tx) {
|
||||
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
||||
utilDebug('websql.cacheGetValue query '+query);
|
||||
tx.executeSql(query,[key], function(tx, res) {
|
||||
executeSql(tx, query,[key], function(tx, res) {
|
||||
if (res.rows.length === 0) {
|
||||
cb(null, null);
|
||||
} else {
|
||||
var value = res.rows.item(0).value;
|
||||
cb(null, JSON.parse(value));
|
||||
}
|
||||
}, sqlErrorHandler(cb));
|
||||
}, cb);
|
||||
});
|
||||
},
|
||||
cacheSetValue: function(key, value, cb) {
|
||||
cacheDB.transaction(function(tx) {
|
||||
var query = 'SELECT value FROM cache_store WHERE key = ?';
|
||||
utilDebug('websql.cacheSetValue query '+query);
|
||||
tx.executeSql(query,[key], function(tx, res) {
|
||||
executeSql(tx, query,[key], function(tx, res) {
|
||||
if (res.rows.length === 0) {
|
||||
var queryInsert = 'INSERT INTO cache_store (key,value) VALUES (?,?)';
|
||||
utilDebug('websql.cacheSetValue query '+queryInsert);
|
||||
tx.executeSql(queryInsert, [key,JSON.stringify(value)], nullDataHandler(cb), sqlErrorHandler(cb));
|
||||
executeSql(tx, queryInsert, [key,JSON.stringify(value)], nullDataHandler(cb), cb);
|
||||
} else {
|
||||
var queryUpdate = 'UPDATE cache_store SET value = ? WHERE key = ?';
|
||||
utilDebug('websql.cacheSetValue query '+queryUpdate);
|
||||
tx.executeSql(queryUpdate, [JSON.stringify(value),key], nullDataHandler(cb), sqlErrorHandler(cb));
|
||||
executeSql(tx, queryUpdate, [JSON.stringify(value),key], nullDataHandler(cb), cb);
|
||||
}
|
||||
}, sqlErrorHandler(cb));
|
||||
}, cb);
|
||||
});
|
||||
},
|
||||
cacheDeleteValue: function(key, cb) {
|
||||
cacheDB.transaction(function(tx) {
|
||||
var query = 'DELETE FROM cache_store WHERE key = ?';
|
||||
utilDebug('websql.cacheDeleteValue query '+query);
|
||||
tx.executeSql(query, [key], function () {
|
||||
setTimeout(function() {cb(null);}); // return next tick so transaction is flushed before location.reload
|
||||
}, sqlErrorHandler(cb));
|
||||
executeSql(tx, query, [key], function () {
|
||||
setTimeout(nullDataHandler(cb)); // return next tick so transaction is flushed before location.reload
|
||||
}, cb);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -257,10 +257,14 @@
|
|||
* @private
|
||||
*/
|
||||
var utilErrorHandler = function(err) {
|
||||
utilDebug('utilErrorHandler error '+err); // TODO: Add Error object support
|
||||
if (!(err instanceof Error)) {
|
||||
err = new Error(err);
|
||||
}
|
||||
utilDebug('utilErrorHandler error '+err.name+' '+err.message);
|
||||
|
||||
var rootTag = document.createElement('div');
|
||||
rootTag.setAttribute('class','ffError');
|
||||
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
||||
|
||||
var cssTag = document.createElement('style');
|
||||
cssTag.type = 'text/css';
|
||||
|
@ -268,14 +272,24 @@
|
|||
rootTag.appendChild(cssTag);
|
||||
|
||||
var titleTag = document.createElement('h1');
|
||||
titleTag.appendChild(document.createTextNode(options.error.title));
|
||||
titleTag.appendChild(document.createTextNode(options.error.title+err.name));
|
||||
rootTag.appendChild(titleTag);
|
||||
|
||||
var questionTag = document.createElement('p');
|
||||
questionTag.appendChild(document.createTextNode(err));
|
||||
questionTag.appendChild(document.createTextNode(err.message));
|
||||
rootTag.appendChild(questionTag);
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(rootTag);
|
||||
try {
|
||||
var stack = err.stack || '';
|
||||
stack = stack.split('\n').map(function (line) { return line.trim(); });
|
||||
var stackText = stack.splice(stack[0] == 'Error' ? 2 : 1);
|
||||
|
||||
var traceTag = document.createElement('div');
|
||||
traceTag.appendChild(document.createTextNode(stackText));
|
||||
rootTag.appendChild(traceTag);
|
||||
} catch (stackError) {
|
||||
utilDebug('No stack: '+stackError);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -315,7 +329,7 @@
|
|||
};
|
||||
|
||||
var cacheCheckType = function (type, cb, action) {
|
||||
cacheHasService(type)?action():cb('No caching for '+type);
|
||||
cacheHasService(type)?action():cb(new Error('No caching for '+type));
|
||||
};
|
||||
|
||||
var cacheGetValue = function(type, key , cb) {
|
||||
|
@ -450,33 +464,27 @@
|
|||
loadResource(resourceStack[0],resourceLoader);
|
||||
};
|
||||
|
||||
var injectResource = function(resource, cb) {
|
||||
cacheGetValue(resource.type,resource.hash,function(err,item) {
|
||||
injectResourceData(resource,item.data,cb);
|
||||
});
|
||||
}
|
||||
|
||||
var injectResources = function(resources, cb) {
|
||||
var startTime = new Date().getTime();
|
||||
utilDebug('injectResources');
|
||||
resources.forEach(function (resource) {
|
||||
cacheGetValue(resource.type,resource.hash,function(err,item) {
|
||||
// TODO reuse injectResourceData
|
||||
|
||||
var tag = null;
|
||||
if (resource.type === 'css' || resource.type === 'cssData') {
|
||||
tag = document.createElement('style');
|
||||
tag.type = 'text/css';
|
||||
}
|
||||
if (resource.type === 'js') {
|
||||
tag = document.createElement('script');
|
||||
tag.type = 'text/javascript';
|
||||
}
|
||||
utilDebug('injectResources from '+JSON.stringify(resource));
|
||||
|
||||
tag.appendChild(document.createTextNode(item.data));
|
||||
|
||||
//document.getElementsByTagName('head')[0].appendChild(tag);
|
||||
var ref = document.getElementsByTagName('script')[0];
|
||||
ref.parentNode.insertBefore(tag, ref); // note in reverse order
|
||||
});
|
||||
});
|
||||
utilDebug('injectResources done in '+(new Date().getTime()-startTime)+' ms.');
|
||||
cb(null); // FIXME async
|
||||
var resourceStack = resources;
|
||||
var resourceLoader = function(err) {
|
||||
if (err !== null) { return cb(err); }
|
||||
resourceStack = resourceStack.slice(1);
|
||||
if (resourceStack.length === 0) {
|
||||
utilDebug('injectResources done in '+(new Date().getTime()-startTime)+' ms.');
|
||||
cb(null);
|
||||
} else {
|
||||
injectResource(resourceStack[0],resourceLoader);
|
||||
}
|
||||
};
|
||||
injectResource(resourceStack[0],resourceLoader);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -488,11 +496,11 @@
|
|||
*/
|
||||
var startLoader = function (cb) {
|
||||
if (options.server.url === null) {
|
||||
cb('Missing options.server.url');
|
||||
cb(new Error('No url'));
|
||||
return;
|
||||
}
|
||||
if (options.server.assets === null) {
|
||||
cb('Missing options.server.assets');
|
||||
cb(new Error('No assets'));
|
||||
return;
|
||||
}
|
||||
rootWindow[options.server.flag] = options.server.url;
|
||||
|
@ -507,13 +515,13 @@
|
|||
if (err !== null) {
|
||||
cb(err);
|
||||
} else if (value === null) {
|
||||
cb('Have no cache of server resouces from '+options.server.url);
|
||||
cb(new Error('Have no cache of server resouces from '+options.server.url));
|
||||
} else {
|
||||
injectResources(value, cb);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cb('Could not fetch server resouces from '+options.server.url);
|
||||
cb(new Error('Could not fetch server resouces from '+options.server.url));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ var morgan = require('morgan');
|
|||
|
||||
// example options;
|
||||
var serverUrl = 'http://localhost:8080';
|
||||
var useInline = true; // or false
|
||||
var useInline = false; // or false
|
||||
|
||||
var clientResourcesWeb = [];
|
||||
var clientResources = {
|
||||
|
@ -123,7 +123,11 @@ server.use('/static/module/angular', express.static(path.join(__dirname,'n
|
|||
server.use('/static/module/angular-route', express.static(path.join(__dirname,'node_modules/angular-route')));
|
||||
|
||||
server.get('/static/es5-ff-spa-loader.js', function (req,res) {
|
||||
res.write(fs.readFileSync(__dirname+'/../dist/es5-ff-spa-loader.js', 'utf8'));
|
||||
if (fs.existsSync(__dirname+'/../es5-ff-spa-loader.js')) {
|
||||
res.write(fs.readFileSync(__dirname+'/../es5-ff-spa-loader.js', 'utf8'));
|
||||
} else {
|
||||
res.write(fs.readFileSync(__dirname+'/../dist/es5-ff-spa-loader.js', 'utf8'));
|
||||
}
|
||||
res.end();
|
||||
});
|
||||
server.get('/static/spa-client-resources', function (req,res) {
|
||||
|
|
Loading…
Reference in a new issue