diff --git a/README.md b/README.md index 176cb69..2df8dbf 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,6 @@ Caching of scripts cross domain only works if the CORS header is set on the remo ```javascript requireScript(name, version, url, callback) ``` -provides the external API. The internal API consits of 3 functions. -```javascript -_loadScript(url, name, version, callback) -_injectScript(content, name, version, callback) -_cacheScript(name, version, url) -``` -Please read the code to learn how they work (they are very short!). ## License diff --git a/cached-webpgr.js b/cached-webpgr.js index 0f11b45..b7aae76 100644 --- a/cached-webpgr.js +++ b/cached-webpgr.js @@ -12,102 +12,113 @@ * ``` */ +(function() { -/** - * ##_cacheScript - * This function requires IE7+, Firefox, Chrome, Opera, Safari. - * It will make an ajax call to retrive the desired script from the provided url and store it - * in the localStorage under the provided name. The stored script will be wrapped like in this example: - * `{content: '// scrip content $(document).ready(...)', version: '1.02.03'}` - * @param {string} name localStorage identifier; shoud be the same as on the server-side - * @param {string} url `path/to/script.js`; shoud be on the same server (or with remove with CORS header access-control-allow-origin:*) - */ -function _cacheScript(name, version, url) { - var xmlhttp = new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari - xmlhttp.onreadystatechange = function() { - if (xmlhttp.readyState == 4) { - if (xmlhttp.status == 200) { - localStorage.setItem(name, JSON.stringify({ - content: xmlhttp.responseText, - version: version - })); - } else { - console.warn('error loading '+url); - } + /** + * ##_lsTest + * This function tests the functionality of Local Storage + **/ + function _lsTest(){ + try { + localStorage.setItem('_', '_'); + localStorage.removeItem('_'); + return true; + } catch(e) { + return false; } - } - xmlhttp.open("GET", url, true); - xmlhttp.send(); } + /** - * ##_loadScript - * For loading external scripts (local or cross domain with CORS) + * ##_cacheScript + * This function requires IE7+, Firefox, Chrome, Opera, Safari. + * It will make an ajax call to retrive the desired script from the provided url and store it + * in the localStorage under the provided name. The stored script will be wrapped like in this example: + * `{content: '// scrip content $(document).ready(...)', version: '1.02.03'}` + * @param {string} name (see `requireScript`) + * @param {string} version (see `requireScript`) * @param {string} url (see `requireScript`) + * @param {Function} callback (see `requireScript`) + */ + function _cacheScript(name, version, url, callback) { + var xmlhttp = new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState == 4) { + if (xmlhttp.status == 200) { + localStorage.setItem(name, JSON.stringify({ + content: xmlhttp.responseText, + version: version + })); + requireScript(name, version, url, callback); + } else { + console.warn('error loading '+url); + } + } + } + xmlhttp.open("GET", url, true); + xmlhttp.send(); + } + + /** + * ##_injectScript + * Injects a script loaded from localStorage into the DOM. + * If the script version is differnt than the requested one, the localStorage key is cleared and a new version will be loaded next time. * @param {string} name (see `requireScript`) * @param {string} version (see `requireScript`) + * @param {string} url (see `requireScript`) + * @param {object} content wrapped serialized code `{content: '// scrip content $(document).ready(...)', version: '1.02.03'}` * @param {Function} callback (see `requireScript`) */ -function _loadScript(url, name, version, callback) { - var s = document.createElement('script'); + function _injectScript(name, version, url, content, callback) { + var content = JSON.parse(content); + if (content.version != version) { + localStorage.removeItem(name); + _cacheScript(name, version, url, callback); + requireScript(name, version, url, callback); + return; + } + var el = document.createElement('script'); + el.type = "text/javascript"; + var scriptContent = document.createTextNode(content.content); + el.appendChild(scriptContent); + document.getElementsByTagName("head")[0].appendChild(el); + if (callback) callback(); + } - if (s.readyState) { //IE - s.onreadystatechange = function() { - if (s.readyState == "loaded" || s.readyState == "complete") { - s.onreadystatechange = null; - _cacheScript(name, version, url); - if (callback) callback(); + /** + * ##requireScript + * If the requested script is not available in the localStorage it will be loaded from the provided url (see `_cacheScript`). + * If the script is present in the localStorage it will be injected (see `_injectScript`) into the DOM. + * @param {string} name identifier of the script in the local cache + * @param {string} version version string that is used to check if the script needs to be updated + * @param {string} url `path/to/script.js` that should be caced; can be local (or cross domain with CORS header allowing cross domain access) + * @param {Function} callback function that is extecuted once the script is loaded + */ + function requireScript(name, version, url, callback) { + if (_lsTest()) { + var content = localStorage.getItem(name); + if (content == null) { + _cacheScript(name, version, url, callback) + } else { + _injectScript(name, version, url, content, callback); + } + } else { + var el = document.createElement('script'); + if (el.readyState) { //IE + el.onreadystatechange = function() { + if (el.readyState == "loaded" || el.readyState == "complete") { + if (callback) callback(); + } + }; + } else { //Others + el.onload = function() { + if (callback) callback(); + }; } - }; - } else { //Others - s.onload = function() { - _cacheScript(name, version, url); - if (callback) callback(); - }; + el.setAttribute("src", url); + document.getElementsByTagName("head")[0].appendChild(el) + } } + window.requireScript = requireScript; +})(); - s.setAttribute("src", url); - document.getElementsByTagName("head")[0].appendChild(s) -} - -/** - * ##_injectScript - * Injects a script loaded from localStorage into the DOM. - * If the script version is differnt than the requested one, the localStorage key is cleared and a new version will be loaded next time. - * @param {object} content wrapped serialized code `{content: '// scrip content $(document).ready(...)', version: '1.02.03'}` - * @param {string} name (see `requireScript`) - * @param {string} version (see `requireScript`) - * @param {Function} callback (see `requireScript`) - */ -function _injectScript(content, url, name, version, callback) { - var c = JSON.parse(content); - // cached version is not the request version, clear the cache, this will trigger a reload next time - if (c.version != version) { - localStorage.removeItem(name); - _loadScript(url, name, version, callback); - return; - } - var s = document.createElement('script'); - s.type = "text/javascript"; - var scriptContent = document.createTextNode(c.content); - s.appendChild(scriptContent); - document.getElementsByTagName("head")[0].appendChild(s); - if (callback) callback(); -} -/** - * ##requireScript - * If the requested script is not available in the localStorage it will be loaded from the provided url (see `_loadScript`). - * If the script is present in the localStorage it will be injected (see `_injectScript`) into the DOM. - * @param {string} name identifier of the script in the local cache - * @param {string} version version string that is used to check if the script needs to be updated - * @param {string} url `path/to/script.js` that should be caced; can be local (or cross domain with CORS header allowing cross domain access) - * @param {Function} callback function that is extecuted once the script is loaded - */ -function requireScript(name, version, url, callback) { - var c = localStorage.getItem(name); - if (c == null) { - _loadScript(url, name, version, callback); - } else { - _injectScript(c, url, name, version, callback); - } -} diff --git a/cached-webpgr.min.js b/cached-webpgr.min.js index 80f5c2a..df4adce 100644 --- a/cached-webpgr.min.js +++ b/cached-webpgr.min.js @@ -4,4 +4,4 @@ * Author: Webpgr http://webpgr.com by Falko Krause * License: MIT */ -function _cacheScript(c,a,b){var d=new XMLHttpRequest();d.onreadystatechange=function(){if(d.readyState==4){if(d.status==200){localStorage.setItem(c,JSON.stringify({content:d.responseText,version:a}))}else{console.warn("error loading "+b)}}};d.open("GET",b,true);d.send()}function _loadScript(c,b,a,e){var d=document.createElement("script");if(d.readyState){d.onreadystatechange=function(){if(d.readyState=="loaded"||d.readyState=="complete"){d.onreadystatechange=null;_cacheScript(b,a,c);if(e){e()}}}}else{d.onload=function(){_cacheScript(b,a,c);if(e){e()}}}d.setAttribute("src",c);document.getElementsByTagName("head")[0].appendChild(d)}function _injectScript(g,e,d,b,i){var h=JSON.parse(g);if(h.version!=b){localStorage.removeItem(d);_loadScript(e,d,b,i);return}var f=document.createElement("script");f.type="text/javascript";var a=document.createTextNode(h.content);f.appendChild(a);document.getElementsByTagName("head")[0].appendChild(f);if(i){i()}}function requireScript(d,a,b,f){var e=localStorage.getItem(d);if(e==null){_loadScript(b,d,a,f)}else{_injectScript(e,b,d,a,f)}}; +!function(){function e(){try{return localStorage.setItem("_","_"),localStorage.removeItem("_"),!0}catch(e){return!1}}function t(e,t,n,r){var o=new XMLHttpRequest;o.onreadystatechange=function(){4==o.readyState&&(200==o.status?(localStorage.setItem(e,JSON.stringify({content:o.responseText,version:t})),a(e,t,n,r)):console.warn("error loading "+n))},o.open("GET",n,!0),o.send()}function n(e,n,r,o,c){var o=JSON.parse(o);if(o.version!=n)return localStorage.removeItem(e),t(e,n,r,c),void a(e,n,r,c);var d=document.createElement("script");d.type="text/javascript";var i=document.createTextNode(o.content);d.appendChild(i),document.getElementsByTagName("head")[0].appendChild(d),c&&c()}function a(a,r,o,c){if(e()){var d=localStorage.getItem(a);null==d?t(a,r,o,c):n(a,r,o,d,c)}else{var i=document.createElement("script");i.readyState?i.onreadystatechange=function(){("loaded"==i.readyState||"complete"==i.readyState)&&c&&c()}:i.onload=function(){c&&c()},i.setAttribute("src",o),document.getElementsByTagName("head")[0].appendChild(i)}}window.requireScript=a}();