diff --git a/README.md b/README.md index f73fd8a..6fee42a 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ A javascript library providing server defined loading of assets for a single pag * boot.cleanup.timeout = Cleanup after timeout(in ms) so css effects are done. (default: 1000) * boot.cleanup.tags = The array of tag ids to remove. (default: empty) * server.url = The server url like 'https://myhost', when null the user will get promted to input it. (default: null) + * server.depath = Strip this path from the server.url needed when the ui has prefix from application root. * server.assets = The server path to the assets resources definition file, is required (default: null) * server.timeout = The timeout to download the server resources. (default: 4096) * server.flag = The window flag which is set when the server.url is know. (default: 'FFServerUrl') @@ -209,6 +210,7 @@ A javascript library providing server defined loading of assets for a single pag * css: add media in resouces * Add in browser tests * example: Cache angular template for offline mode. + * cache limits for soft fallback to injecting ? ## Contributing @@ -217,6 +219,14 @@ Add unit tests for any new or changed functionality. Lint and test your code. ## Release History +### 0.2.2 +* Fixed clearServerUrl() to also clean the cached server resources json. +* Auto clean option.server.url from # and ? endings for: FFSpaLoader.options.server.url = window.location.href; +* Added server.depath option to strip the ui-prefix from the server.url. +* Added auto resetting server.url when is file:// for "Page save as" feature. +* Fixed askUrl to accept host and context path with auto clean/depathing. +* Fixed duplicate starts on askUrl submit multiple clicks. + ### 0.2.1 * Fixed clearCache method to added json header. * Added url to non 200 http status error message. diff --git a/es5-ff-spa-loader.js b/es5-ff-spa-loader.js index ab82a1e..adb73fc 100644 --- a/es5-ff-spa-loader.js +++ b/es5-ff-spa-loader.js @@ -72,6 +72,7 @@ }, server: { url: null, + depath: null, assets: null, timeout: 4096, flag: 'FFServerUrl', @@ -139,6 +140,12 @@ * @private */ var delayedResources = []; + + /** + * Ask Url submit lock. + * @private + */ + var askUrlSubmitLock = false; /** * The factory which contains detection helpers and cache backend builders. @@ -348,7 +355,6 @@ httpRequest.onreadystatechange = function() { if (httpRequest.readyState === 4 && httpRequest.status === 200) { utilDebug('utilHttpFetch url \"'+url+'\" done in '+(new Date().getTime()-startTime)+' ms.'); - var headerResponseKeys = Object.keys(options.server.header.response); for (var headerResponseKeyIdx in headerResponseKeys) { var headerResponseKey = headerResponseKeys[headerResponseKeyIdx]; @@ -414,6 +420,25 @@ }; step(runStack[0],runStackStep); }; + + var utilCleanServerUrl = function() { + var index1 = options.server.url.indexOf('#'); + if (index1 > 0){ + options.server.url = options.server.url.substring(0,index1); + } + var index2 = options.server.url.indexOf('?'); + if (index2 > 0){ + options.server.url = options.server.url.substring(0,index2); + } + if (options.server.depath !== null && options.server.url.indexOf(options.server.depath) > 0) { + utilDebug('start server url depathing'); + options.server.url = options.server.url.substring(0,options.server.url.indexOf(options.server.depath) - 1); + } + if (options.server.url.indexOf('file://') === 0) { + utilDebug('start server url cleared because is file uri'); + options.server.url = null; + } + } var cacheGetService = function (type) { if (options.cache[type]) { @@ -593,7 +618,7 @@ }; var loadResource = function (resource, cb, loadDelayed) { - if (options.loader.delayDss === true && resource.type === 'css' && loadDelayed === undefined) { + if (options.loader.delayDss === true && resource.type === 'dss' && loadDelayed === undefined) { utilDebug('loadResource delay '+JSON.stringify(resource)); delayedResources.push(resource); return cb(null); @@ -835,6 +860,12 @@ * @private */ var askUrlValidate = function (deleteTag, cb) { + + if (askUrlSubmitLock === true) { + return; + } + askUrlSubmitLock = true; + var inputTag = document.getElementById('serverInput'); var inputErrorTag = document.getElementById('serverInputError'); var inputValueRaw = inputTag.value; @@ -849,19 +880,23 @@ } else { inputValueHost = inputValueRaw.split('/')[0]; } + var inputValuePath = inputValueRaw.split(inputValueHost)[1]; if (options.question.validate.min.value !== false && inputValueHost.length < options.question.validate.min.value) { inputErrorTag.appendChild(document.createTextNode(options.question.validate.min.message)); + askUrlSubmitLock = false; return; } if (options.question.validate.max.value !== false && inputValueHost.length > options.question.validate.max.value) { inputErrorTag.appendChild(document.createTextNode(options.question.validate.max.message)); + askUrlSubmitLock = false; return; } if (options.question.validate.regex.value !== false && options.question.validate.regex.value.length !== 0) { var regex = new RegExp(options.question.validate.regex.value); if (inputValueHost.match(regex) === null) { inputErrorTag.appendChild(document.createTextNode(options.question.validate.regex.message)); + askUrlSubmitLock = false; return; } } @@ -871,6 +906,9 @@ } else { options.server.url = options.question.transport + inputValueHost; } + options.server.url = options.server.url + inputValuePath; + + utilCleanServerUrl(); var resourcesUrl = options.server.url + options.server.assets; utilDebug('askUrlStart check assets '+resourcesUrl); @@ -878,10 +916,12 @@ utilHttpFetch(resourcesUrl,function(err, httpRequest) { if (err !== null) { inputErrorTag.appendChild(document.createTextNode('Error '+err)); + askUrlSubmitLock = false; return; } if (httpRequest.responseText.length === 0) { inputErrorTag.appendChild(document.createTextNode('Error Got empty data.')); + askUrlSubmitLock = false; return; } @@ -1044,6 +1084,11 @@ } }; utilDebug('start spa loader'); // first debug line TODO: Add version + + if (options.server.url !== null) { + utilCleanServerUrl(); + } + if (options.debug.enable === true) { var optionsKeys = Object.keys(options); for (var keyId in optionsKeys) { @@ -1089,7 +1134,11 @@ if (cacheHasService('meta')) { 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 + cacheDeleteValue('meta','server_resources',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); diff --git a/example/app_server/example.js b/example/app_server/example.js index 57b626f..6c06ba8 100644 --- a/example/app_server/example.js +++ b/example/app_server/example.js @@ -9,6 +9,7 @@ var cors = require('cors'); var morgan = require('morgan'); var UglifyJS = require("uglify-js"); var Hashes = require('jshashes'); +var minify = require('minify'); var clientResourcesWeb = []; var clientResources = { @@ -80,8 +81,11 @@ function renderTemplatePath(viewPath) { function renderIndex() { return function (req, res) { var inlineScript = UglifyJS.minify(__dirname+'/../../es5-ff-spa-loader.js'); - res.render('index', { - inlineScript: inlineScript.code + minify(__dirname+'/../../es5-ff-spa-loader.css', {}, function(err, data) { + res.render('index', { + inlineScript: inlineScript.code, + inlineStyle: data + }); }); }; } @@ -99,22 +103,24 @@ addClientResource('/static/js/controller/page-bar.js','js'); // deps: example-ap addClientResource('/static/js/controller/page-foo.js','js'); addClientResource('/static/js/controller/page-index.js','js'); +var appPath = '/test'; var server = express(); server.use(morgan('dev')); -server.use(cors({credentials: true, origin: '*'})); +server.use(cors({credentials: true, origin: '*', exposedHeaders: ['X-My-Api']})); server.set('view engine', 'ejs'); -server.set('views', path.join(__dirname,'www_views')); -server.use(function(req, res, next) { res.header('X-My-Api', 'noknok');next(); }); -server.use('/static', express.static(path.join(__dirname,'www_static'))); -server.use('/static/module/bootstrap', express.static(path.join(__dirname,'../node_modules/bootstrap/dist'))); -server.use('/static/module/jquery', express.static(path.join(__dirname,'../node_modules/jquery/dist'))); -server.use('/static/module/angular', express.static(path.join(__dirname,'../node_modules/angular'))); -server.use('/static/module/angular-route', express.static(path.join(__dirname,'../node_modules/angular-route'))); -server.get('/static/spa-client-resources', function (req,res) {res.json({data: {resources: clientResourcesWeb}});}); -server.get('/static/spa-loader.css', function (req,res) {res.sendFile('es5-ff-spa-loader.css', { root: path.join(__dirname, '/../../') });}); -server.get('/', function (req, res) {res.redirect('/example-ui');}); -server.get('/example-ui/thtml/*', renderTemplatePath('thtml/')); -server.get('/example-ui', renderIndex()); +server.set('views', path.join(__dirname,'www_views')); +server.use(function(req, res, next) { res.header('X-My-Api', 'noknok');next(); }); +server.use(appPath+'/static', express.static(path.join(__dirname,'www_static'))); +server.use(appPath+'/static/module/bootstrap', express.static(path.join(__dirname,'../node_modules/bootstrap/dist'))); +server.use(appPath+'/static/module/jquery', express.static(path.join(__dirname,'../node_modules/jquery/dist'))); +server.use(appPath+'/static/module/angular', express.static(path.join(__dirname,'../node_modules/angular'))); +server.use(appPath+'/static/module/angular-route', express.static(path.join(__dirname,'../node_modules/angular-route'))); +server.get(appPath+'/static/spa-client-resources', function (req,res) {res.json({data: {resources: clientResourcesWeb}});}); +server.get(appPath+'/static/spa-loader.css', function (req,res) {res.sendFile('es5-ff-spa-loader.css', { root: path.join(__dirname, '/../../') });}); +server.get(appPath+'/', function (req, res) {res.redirect(appPath+'/example-ui');}); +server.get(appPath+'/example-ui/thtml/*', renderTemplatePath('thtml/')); +server.get(appPath+'/example-ui', renderIndex()); +server.get('/', function (req, res) {res.redirect(appPath);}); server.listen(httpPort); console.info('Server started on port '+httpPort); diff --git a/example/app_server/www_views/index.ejs b/example/app_server/www_views/index.ejs index 4bf35f1..c230f77 100644 --- a/example/app_server/www_views/index.ejs +++ b/example/app_server/www_views/index.ejs @@ -3,17 +3,19 @@