Skip to content

Fixed issue where scripts are downloaded twice #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
181 changes: 96 additions & 85 deletions cached-webpgr.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
2 changes: 1 addition & 1 deletion cached-webpgr.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.