Using HTML5 manifest file and cache is working fine.
I use window.applicationCache.update() to download the updated version. works fine.
How can I check to see if the manifest file has been updated so an update is available but not start downloading. Reason for this I want the user to allow the update or not as they may be in a bad network connection area.
Try this:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('ondownloading', function(e) {
window.applicationCache.abort();
}, false);
}, false);
Just abort the download when you catch the ondownloading event.
You can see all the available events here
There is not an event like that.
Browser checks the update of the manifest file and download the new added files automatically. You can check current state of the cache using its status property. It may have six different values. You can see the available status properties here. Then you can use applicationCache.swapCache() for swapping according to Your/User need.
Related
I have an angularjs based web application with some functionality deployed to users that I need to hide. I've added the code to hide it and successfully verified the controls are hidden when appropriate but there are still users who have the old version of the file and can perform the undesired activities. Is there a way I can control from the server the view file to refresh on the client? (The tester was able to clear their cache but it's a burden to the users in the field)
Thanks!
Scott
One way to handle this would be to version the files. For example, the following line in your index.html
<script src="abc.js" />
could be rewritten as
<script src="abc.js?v1" />
v1 is the current file version and should be changed for each deployment of your application when abc.js has changed.
Since index.html(the initial page) is obtained from the server, updations to abc.js will now be reflected on all your clients.
This would need to be automated in a huge application. You could use Grunt for this. You can refer the following answer on StackOverflow for automating this:
https://stackoverflow.com/a/20446748/802651
UPDATE
HTML views/templates are cached using $templateCache in AngularJS. Basically, when you request templates for the first time, browser requests the template from the server and puts it in the template cache. Any subsequent requests to the same template are served from the template cache.
If you do not want these to be cached, you could listen to the $routeChangeStart event inside app.run block to remove the specific templates.
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (typeof(current) !== 'undefined'){
$templateCache.remove(current.templateUrl);
}
});
});
Reference: http://opensourcesoftwareandme.blogspot.in/2014/02/safely-prevent-template-caching-in-angularjs.html
I am new to chrome extensions.I used chrome.runtime.onInstalled to load a html page whenever the extension is installed or updated.But when i am testing it in chrome, whenever i check/uncheck Allow in incognito the same html page loads each time.How to avoid this behaviour? I used "incognito":"split" in manifest.
I wish you'd posted the code so I could try to replicate the problem and give a specific solution but the easy solution is to use chrome storage API to save the extension's version when welcome.html is opened and compare it to the current version next time onInstalled is fired.
If the stored version is the same don't open it. If it's undefined or older, open it.
Get your extension's version by extracting it from chrome.extension.getURL("manifest.json")
Edit:
After a bit of googling it seems you can access the manifest more directly. Get the version number using the code below.
var version = chrome.runtime.getManifest().version;
Edit:
It seems the previous version is supplied in the callback when you update so you don't need to store anything. The object provided can be compared to the current version using chrome.runtime.getManifest().version
Something like this:
chrome.runtime.onInstalled.addListener(function (details) {
if(details.reason === "install"){
chrome.tabs.create({url: "welcome.html"});
}
else if(details.reason === "update"){
var currentVersion = chrome.runtime.getManifest().version;
var previousVersion = details.previousVersion;
if(previousVersion !== currentVersion){
chrome.tabs.create({url: "welcome.html"});
}
}
});
I don't think you can. I assume that when you uncheck "Allow in incognito", Chrome nukes the local state of the (split) incognito instance.
I've been experiencing what initially appeared to be an intermittent issue where my application wouldn't work offline.
A few details regarding my application:
The entry point into my application is a Login page
All of the pages in my application, w/ the exception of the Login page, display dynamic data. And to ensure the pages that display dynamic data aren't cached, I chose to only have the Login page include the manifest attribute in it's html element.
The total size of the assets listed in my manifest file is roughly 1MB.
The steps I take to reproduce the issue (assume I do not have the applicationCache resources cached on my browser/device):
Navigate to the Login Page (applicationCache resources will begin downloading)
Immediately Login to the application
Go offline and request an offline resource
Notice the browser failed to serve the resource from applicationCache
While I do not have any concrete proof, what I ultimately discovered is navigating away from the Login page, while the browser is in the process of retrieving applicationCache assets, interrupts the download of appCache assets and leads to offline resources not being served up when offline. Is this expected browser behavior? If I wait a sufficient amount of time and give the browser a chance to download assets, offline functionality works.
In order to insure offline functionality, do I need to prevent the user from navigating away from the Login page until the applicationCache cache event is fired?
Is this expected browser behavior?
It is indeed intended behaviour. See http://diveintohtml5.info/offline.html#debugging
if even a single resource listed in your cache manifest file fails to download properly, the entire process of caching your offline web application will fail. Your browser will fire the error event, but there is no indication of what the actual problem was.
One solution I could think of would be to check on beforeunload if the the window.applicationCache.status is either checking or downloading.
Or you might be able to set a flag in the users localStorage, indicating that the last attempt was not successfull, using the error event (see below) and try to refetch the files until everything was loaded successfully.
If you've got lots of stuff to cache, you can show a progress bar and some text asking the user to be patient while the page is loading. For the progress bar you can use event.loaded and event.total in the progress event of your cache handling function.
var appCache = window.applicationCache;
// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);
// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);
// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);
// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);
// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);
// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);
// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);
// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);
function handleCacheEvent(e){
if(e.type && (e.type=='progress' || e.type=='ProgressEvent')){
console.log('percent:', Math.round(e.loaded/e.total*100)+'%', 'total:', e.total, 'loaded:',e.loaded);
}
}
I'm playing with the IndexedDB API from html5 spec in both Firefox and Chrome.
There something that's not working as expected I and want to share it here because I don't know if it's my fault or a browser bug.
According to the API, there's an event called onversionchange that's fired when you open a connection to a local database and the version number used is greater than the databases one.
My problem is that this event is being fired in Firefox but not in Chrome.
Some sample code trying several modes:
var db;
var DB_VERSION = 5;
var openRequest = indexedDB.open("test_db", DB_VERSION);
openRequest.onsuccess = function(event) {
db = openRequest.result;
};
openRequest.onversionchange = function(event) {
console.log("This is the place where I can change db structure");
};
openRequest.onupgradeneeded = function(event) {
console.log("This is the place where I can change db structure");
};
onversionchage event is not being fired even when I change the version number.
UPDATE
As ebidel has answered, Chrome implementation does not follow the currently specification so, in order to have a cross browser client code, we need to handle two situations: onversionchange event and database.version manual comparison.
Here are a couple on links with code example:
Chromium google group and
HTML5 Rocks!
Chrome's IndexedDB implementation is based off an older version of the spec which uses the older setVersion call rather than onversionchange/onupgradeneeded. Please star this issue: http://crbug.com/108223
Is there a Chrome extension post install hook/API function that will let me perform an action after the plugin is installed or updated?
I would like to perform an action after my extension is installed, and only right after it is installed. This action should only be performed once (post-install or post-update) of the extension.
Update
Some people have proposed setting the version of the extension in localStorage, the problem that I have is that the content script that has access to localStorage is not loaded into the page when the plugin is first installed.
AFAIK after a plugin is installed, and it makes use of a content script injected into the tab/page, the page has to be reloaded.
I don't know how to access localStorage from the background page; localStorage can only be accessed from a content script.
To get the version number from the background page to the content script requires the use of chrome API function to execute scripts:
chrome.tabs.executeScript(null, {code:function_to_execute}, function() { // callback });
However, when you install a plugin, and the page that this plugin needs to inject a content script into is already loaded, it does not inject the content script, you have to reload the page.
update 2
Looking at some of the tips provided in more detail, for the purpose of saving the version number, it is possible to access the localStorage of the background page. However, for what I need to do, which is reload a specific tab at a specific URL (in order to make sure the content script is the newest version) after installing or updating a plugin, it ended up being unnecessary to bother with localStorage.
For the sake of staying on topic, the advice given about writing the version number to localStorage (in the background page) and then checking against the version number in the manifest file is good enough to allow someone to run a script the first time it is installed/or updated.
HowTo
Make manifest file available to the background page (note: this is taken from somewhere else, I don't take credit for it, but I can't remember the source, if you know, let me know and I will add it).
// MAKE MANIFEST FILE AVAILABLE
chrome.manifest = (function() {
var manifestObject = false;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
manifestObject = JSON.parse(xhr.responseText);
}
};
xhr.open("GET", chrome.extension.getURL('/manifest.json'), false);
try {
xhr.send();
} catch(e) {
console.log('Couldn\'t load manifest.json');
}
return manifestObject;
})();
Now you can access your version number like this: chrome.manifest.version
To write to localStorage just pass it in like so: localStorage['my_plugin_version'] = chrome.manifest.version
You can do this using a background page. When the extension is installed, the background page is opened in the background, and thus executed. To make sure it's not executed every time, simply store a value in localStorage.