diff --git a/README.md b/README.md index 16a28c3..a755c98 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ A javascript library providing server defined loading of assets for a single pag * 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.style = The error ui css style. (default: red border box) + * error.style = The error ui css style. (default: red error) * 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) * boot.cordova.flag = The window flag which is set when cordova is booted. (default: 'FFCordovaDevice') @@ -93,7 +93,7 @@ A javascript library providing server defined loading of assets for a single pag * question.title = The question ui title. (default: 'Server') * question.submit = The start button text. (default: 'Start') * question.text = The question ui text. (default: 'Please provide the server name;') - * question.style = The question ui css style. (default: green border box) + * question.style = The question ui css style. (default: blue input) * question.validate.min.value = The minimal hostname length, false is disabled (default: 3) * question.validate.min.message = The error message (default: 'Server name is to short.') * question.validate.max.value = The maximal hostname length, false is disabled (default: 255) @@ -114,17 +114,26 @@ A javascript library providing server defined loading of assets for a single pag * detect.openDatabase() = Checks if openDatabase is defined. * detect.sqlitePlugin() = Checks if sqlitePlugin is defined. * detect.cordova() = Checks if cordova is defined. - * detect.cordovaDevice() = Checks if cordovaDevive window flag is defined which will be set by the buildin cordova boot code. + * detect.cordovaDevice() = Checks if the options.boot.cordova.flag is defined in the window.(NOTE: is always false before calling start();) * cache.localStorage() = Creates an localStorage service. * cache.websql(opt) = Creates an websql service. +## Cache Types + + The cache types in FFSpaLoader.options.cache.* store different types data; + + * meta = Stores server.url and server.assets data. + * js = Store application javascript data. + * css = Stores application css data. + * cssData = Stores application css large data like base64 fonts/svg/etc. + ## Cache Config - Per default all cache type as in auto select mode which detect and used the following; + Per default all cache types are auto selected in the following order; - * sqlitePlugin - * openDatabase - * localStorage + * detect.sqlitePlugin() and detect.cordovaDevice() + * detect.openDatabase() + * detect.localStorage() * none More custom schemas are possible like; (todo: needs testing) @@ -137,7 +146,8 @@ A javascript library providing server defined loading of assets for a single pag if (FFSpaLoader.factory.detect.localStorage()) { FFSpaLoader.options.cache.css = FFSpaLoader.factory.cache.localStorage(); FFSpaLoader.options.cache.cssData = FFSpaLoader.factory.cache.localStorage(); - } + } + FFSpaLoader.options.server.url = 'http://myserver'; FFSpaLoader.options.server.assets = '/api/path/to/spa/client/resources'; FFSpaLoader.start(); @@ -159,6 +169,7 @@ A javascript library providing server defined loading of assets for a single pag * test in production * Server header check support * Add table+instance websql options so it can also be used in application code. + * Split assets per type so do js first then boot then css + cssData. * Move css to file ? * Add more tests * css: set tag.media = 'only you'; @@ -172,6 +183,10 @@ Add unit tests for any new or changed functionality. Lint and test your code. ## Release History +### 0.1.1 +* Moved websql delete timeout to cleanServerlUrl for faster boot. +* Added more jsdoc + ### 0.1.0 * Moved options.server.question to options.question * Added question.validate.[min|max|regex].value|message options. diff --git a/es5-ff-spa-loader.js b/es5-ff-spa-loader.js index 60dc6aa..427e028 100644 --- a/es5-ff-spa-loader.js +++ b/es5-ff-spa-loader.js @@ -41,6 +41,9 @@ })(this || window, /** @lends module:FFSpaLoader */ function (rootWindow) { 'use strict'; + /** + * The options to customize the loader. + */ var options = { debug: { enable: false, @@ -105,8 +108,15 @@ } }; - var cacheDB = null; // single instance for websql - + /** + * Use single instance for websql + * @private + */ + var cacheDB = null; + + /** + * The factory which contains detection helpers and cache backend builders. + */ var factory = { detect: { localStorage: function() { @@ -232,10 +242,8 @@ }, cacheDeleteValue: function(key, cb) { cacheDB.transaction(function(tx) { - executeSql(tx, 'DELETE FROM cache_store WHERE key = ?', [key], function () { - setTimeout(nullDataHandler(cb)); // return next tick so transaction is flushed before location.reload - }, cb); - }); + executeSql(tx, 'DELETE FROM cache_store WHERE key = ?', [key], nullDataHandler(cb), cb); + }); } }; }, @@ -256,7 +264,7 @@ /** * The default error handler which renders the error in the browser. - * @param {String|Error} err The error message. + * @param {Error|String} err The error object or message. * @private */ var utilErrorHandler = function(err) { @@ -298,7 +306,7 @@ /** * Fetches an url resource with a XMLHttpRequest. * @param {String} url The url to fetch. - * @param {function} cb The callback for error and request if ready. + * @param {function} cb Error first callback when done. * @private */ var utilHttpFetch = function (url, cb) { @@ -326,6 +334,14 @@ httpRequest.send(); }; + /** + * Async helper to run each step from the stack. + * @param {String} runType The runType used for debug logging. + * @param {Array} stack The stack to run all steps on. + * @param {function} step Stack Item + Error first callback when done function callback. + * @param {function} cb Error first callback when done. + * @private + */ var utilRunStack = function(runType, stack, step, cb) { if (stack.length === 0) { return cb(null); @@ -361,6 +377,13 @@ cacheHasService(type)?action():cb(new Error('No caching for '+type)); }; + /** + * Retreive a cached value. + * @param {String} type The cache type to use. + * @param {String} key The key to get the value for. + * @param {function} cb Error first callback + value callback. + * @private + */ var cacheGetValue = function(type, key , cb) { cacheCheckType(type, cb, function() { var cacheKey = type+'_'+key; @@ -369,6 +392,14 @@ }); }; + /** + * Store a value in cache. + * @param {String} type The cache type to use. + * @param {String} key The key to store the value for. + * @param {String} value The value to store. + * @param {function} cb Error first callback. + * @private + */ var cacheSetValue = function(type, key, value, cb) { cacheCheckType(type, cb, function() { var cacheKey = type+'_'+key; @@ -377,6 +408,13 @@ }); }; + /** + * Deletes an cache value. + * @param {String} type The cache type to use. + * @param {String} key The key to delete the value. + * @param {function} cb Error first callback. + * @private + */ var cacheDeleteValue = function(type, key, cb) { cacheCheckType(type, cb, function() { var cacheKey = type+'_'+key; @@ -465,8 +503,8 @@ /** * Add all cache keys in central list so we can clear the cache item if resources are removed. - * @param {Resource} resource The resource object with the type and hash. - * @param {function} cb The callback for error and request if ready. + * @param {Object} resource The resource object with the type and hash. + * @param {function} cb Error first callback when done. * @private */ var storeResourceKey = function (resource, cb) { @@ -537,7 +575,7 @@ * Starts loader by downloading resource list or using cache version to * load/refresh/inject the resources. * - * @param {function} cb Callback gets called when loader is done. + * @param {function} cb Error first callback when done. * @private */ var startLoader = function (cb) { @@ -597,11 +635,11 @@ /** * Validates the user input url by downloading it. * - * @param {function} cb Callback gets called when loader is done. - * @param {Element} deleteTag The dom element to remove from the body tag after success. + * @param {HTMLElement} deleteTag The dom element to remove from the body tag after success. + * @param {function} cb Error first callback when done. * @private */ - var askUrlValidate = function (cb,deleteTag) { + var askUrlValidate = function (deleteTag, cb) { var inputTag = document.getElementById('serverInput'); var inputErrorTag = document.getElementById('serverInputError'); var inputValueRaw = inputTag.value; @@ -714,7 +752,7 @@ submitTag.id = 'serverSubmit'; submitTag.type = 'submit'; submitTag.value = options.question.submit; - submitTag.onclick = function() {askUrlValidate(cb,rootTag);}; + submitTag.onclick = function() {askUrlValidate(rootTag,cb);}; formTag.appendChild(submitTag); var serverErrorTag = document.createElement('div'); @@ -725,6 +763,13 @@ document.getElementsByTagName('body')[0].appendChild(rootTag); }; + /** + * Starts an cache type by auto selecting if needed and opening it if needed. + * + * @param {String} type The cache type to start. + * @param {function} cb Callback gets called when loader is done. + * @private + */ var startCacheType = function (type,cb) { if (options.cache[type] !== null && options.cache[type] === false) { utilDebug('startCacheType '+type+' disabled'); @@ -752,6 +797,12 @@ } }; + /** + * Starts all cache types. + * + * @param {function} cb Callback gets called when loader is done. + * @private + */ var startCache = function (cb) { startCacheType('meta', function(err) { if (err !== null) { return cb(err); } @@ -768,7 +819,7 @@ /** * Starts the loader. * - * @param {function} cb Callback gets called when loader is done. + * @param {function} cb Optional callback gets called when loader is done. */ var start = function (cbArgu) { var startTime = new Date().getTime(); @@ -818,17 +869,31 @@ }); }; + /** + * Clears the server url. + * + * @param {function} cb Optional Error first callback gets called when value is deleted. + */ var clearServerUrl = function(cb) { if (cb === undefined) { cb = function() {}; } if (cacheHasService('meta')) { - cacheDeleteValue('meta','server_url',cb); + cacheDeleteValue('meta','server_url',function(err) { + if (err !== null) { return cb(err); } + setTimeout(function() {cb(null);}); // return next tick so (websql) transaction is flushed before location.reload + }); } else { cb(null); } }; + /** + * Boots angular modules if enabled. + * + * @param {function} cb Error first callback gets called done. + * @private + */ var bootAngular = function(cb) { if (options.boot.angular.enable !== true) { utilDebug('bootAngular disabled by options'); @@ -844,11 +909,11 @@ }; /** - * Helper for cordova applications which want to use the sqllite plugin as cache. + * Boots cordova applications which want to use the sqllite plugin as cache. * Note: On none cordova page it will callback directly. - * Note: On none cordova device page is will timeout. + * Note: On none cordova device page is will timeout if option is set. * - * @param {function} cb Callback gets called device is ready to use. + * @param {function} cb Error first callback gets called device is ready. * @private */ var bootCordova = function(cb) { diff --git a/gulpfile.js b/gulpfile.js index 304b305..84a8bc7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -37,12 +37,12 @@ gulp.task('testMocha',['clean'], function() { gulp.task('buildJSDoc', function (cb) { var jsdocConfig = { opts: { - destination: 'dist/jsdoc' + destination: 'dist/jsdoc', + encoding: 'utf8', + access: 'all' }, templates: { - thema: 'cerulean', - navType: 'vertical', - linenums: true + cleverLinks: true } }; gulp.src(srcFile, {read: false}).pipe(jsdoc(jsdocConfig, cb));