Is there any way to defer HTML5 manifest checking? - html

Given that there is a way to invoke an update directly using window.applicationCache.update(), is there any way to omit the update that is performed automatically by the browser when the page is loaded?
I've been experimenting with offline mode in Google Chrome, and so far it appears that
1) If a manifest file is specified, it will be loaded, and there is nothing I can do in JavaScript to stop it.
2) If the manifest file has changed, the entire cache is going to be updated, and there is nothing I can do to stop it.
In my experience, window.applicationCache.abort() has no effect regardless of when I invoke it. I've tried invoking it on the first line of javascript, and in the checking and downloading events, but it always downloads everything. It may have something to do with timing since the files are small and load very quickly.

Listen for the checking event and cancel it. The abort() method doesn't come into things until step 17 of the application cache download process, I don't think you're going to be able to stop the process with it.

This is a Chrome bug at the time of writing: https://code.google.com/p/chromium/issues/detail?id=175063 (please vote it up)
Just tried this on iOS Safari:
window.applicationCache.addEventListener('checking', function(event) {
window.applicationCache.abort();
}, false);
It works. In Safari debugger console:
Application Cache download process was aborted.
Chrome ignores the same code.

Related

open an URL upon my extension has been installed or uninstalled

As for open an URL upon my extension has been uninstalled, I found the easiest way to do is using chrome.runtime.setUninstallURL, (1) any other good ways?
As for open an URL upon my extension has been first time installed, I don't find something like chrome.runtime.setInstallURL, I implemented the feature with
chrome.runtime.onInstalled.addListener(function(details){
if (details.reason=="install"){chrome.tabs.create({ url: homePage});}
})
I saw AdBlock opens its options page upon first time installed, but it doesn't even used chrome.runtime.onInstalled, its source code is so much complicated , I cannot figure out how it implement the feature ,(2) how it do it ? any other ways to open an URL or its options page upon the extension has been first time installed?
(3) what are the common ways to do something when an extension has been installed or uninstalled?
SetUninstallURL seems to be specifically designed for your task, so it's certainly the right way.
Regarding the installation page, not sure how AdBlock does it, but if you have a persistent background page, one of the simpler ways would be to show the page on every launch if a certain localStorage key is not set.
// background.html startup, for example DOMContentLoaded handler
if ( !localStorage.getItem('intro_shown') ) {
localStorage.setItem('intro_shown', true);
showIntroPage();
}
Local storage of the extension's background page will be persistent, apart from several corner cases (incognito mode in FF, etc).
Upd by Makyen:
chrome.storage seems to be a much better option specifically designed for extension storage needs. It could also be automatically synced with Chrome sync (using chrome.storage.sync)

HTML5 App Cache: Manifest ist updated but files are taken from appcache one more time

I have a cache manifest with a comment in it
# Version 3.2
in order to update all the App I simply change the Version number. It works, but:
When I update the manifest, everything is updated correctly (new cache is filled) but the actual files are taken ONE more time from the (old) cache. when I reload twice everything is updated. Is this behaviour correct? Using chrome 21.
Thanks
Yes, this is the current "correct" behaviour. This is what happens:
When you just made changes to the manifest file, and you refresh the browser, this is what happens (assuming you're online)
the browser first loads back all the files in the cache
then the browser check online for your manifest file
it detects that the manifest file has changed, it will then proceed to download the new files
however, keep in mind, at this time, you will still be looking at your 'old files' because the browser has loaded the old files before going online to download the 'new files'
if at this point, if you hit refresh again (2nd time), you should get the 'new files'
This is currently the standard behaviour. Some people put some event handlers to prompt the user to do another refresh (after the 1st refresh)
Personally, I think the browser should be responsible to alert the user to make another refresh after finish downloading the new files, but right now, most people put in event handlers from the "window.applicationCache" to fire events to help manage this.
To look at an example of using window.applicationCache, go here : http://www.html5rocks.com/en/tutorials/appcache/beginner/
it's under the "Updating the Cache" section.
It is possible to instantly swap the cache as described here:
function updateSite(event) {
window.applicationCache.swapCache();
}
window.applicationCache.addEventListener('updateready', updateSite, false);

Can Google Chrome be made to auto reload after network outage in kiosk scenario?

I have an unattended touch screen kiosk application which needs to be able to automatically reload the browser home page after a network outage has occurred. At the moment the browser will display an "Unable to connect to the internet" error and will wait for a manual reload to be carried out before proceeding. Can this be automated?
I've searched for plugins and have found some plugins which deal with auto-reload but they don't seem to work in this context. I am guessing that the plugin is only active when a page is loaded so in this case with an error condition, perhaps the plugin is not active.
One alternative might be to override the error page which is displayed by Chrome but I don't know if this is possible. I could then instantiate a Javascript timer to try a reload every n seconds for example. Is this possible?
I saw a suggestion to use frames to allow the outer frame (which is never refreshed) to keep trying the loading of an inner frame but I'm not keen to use frames unless there is no alternative. I also saw a suggestion to use AJAX calls to check if the network was working before attempting a page load but this seems overkill if there is a way to correct the error only when it has occurred rather than pre-empt an error for every page load.
Host system is Windows 7 by the way. I'm keen to keep the browser running if possible rather than kill and create a new browser process.
If you don't want to tackle chrome extension development, you could wrap your site in an iframe, and then periodically refresh the iframe from the parent frame. That way you don't need to worry about OS issues.
if the content were loaded from ajax from the start then the it could simply output a custom message on the page as it does a check via AJAX. Probably prevention over remedy is always recommended
Assuming linux, you could create an ifup script to simply relaunch the browser with something like
#!/bin/sh
killall google-chrome
DISPLAY=:0 google-chrome
On debian/ubuntu, edit /etc/network/interfaces to include a post-up line; Google ifupdown for other distros.
On windows, you'd do roughly the same with a PowerShell script.
If you really want the precise behaviour you describe (without restarting the whole browser), I suggest you develop a plugin/extension: http://code.google.com/chrome/extensions/getstarted.html
I know you are using Chrome, but in Firefox this is trivial by overriding the netError.xhtml page to do a setTimeout(location.reload, 10000);.

HTML5 offline "Application Cache Error event: Manifest fetch failed (-1)"

I'm trying to write an HTML5 offline application but can't seem to get Chrome to accept the cache manifest file.
Chrome logs the following output to its console while loading the application:
Creating Application Cache with manifest http://localhost/cache.manifest
Application Cache Checking event
Application Cache Error event: Manifest fetch failed (-1) http://localhost/cache.manifest
However, if I remove all lines from the manifest file except for the first line (i.e. "CACHE MANIFEST") Chrome accepts the manifest:
Creating Application Cache with manifest http://localhost/cache.manifest
Application Cache Checking event
Application Cache Downloading event
Application Cache Progress event (0 of 0)
Application Cache Cached event
But, as soon as I add a new line to the manifest (even if that next line is empty) Chrome reverts to complaining that the fetch failed.
All files are being served locally from a Windows 7 PC via Python using SimpleHTTPServer on port 80. I've updated the types_map in %PYTHON%/Lib/mimetypes.py with the following line:
'.manifest': 'text/cache-manifest',
The manifest should contain the following:
CACHE MANIFEST
scripts/africa.js
scripts/main.js
scripts/offline.js
scripts/libs/raphael-min.js
favicon.ico
apple-touch-icon.png
To cache a website offline (HTML5) you need to specify all the files needed for it to run. In short specify the site main components needed.
Easy way to create a manifest is in Note Pad.
Note: CACHE MANIFEST needs to be first line and your files will follow after a line space as follows:
CACHE MANIFEST
Scripts/script.js
Content/Site.css
Scripts/jquery-ui-1.8.20.min.js
Scripts/modernizr-2.5.3.js
SESOL.png
Scripts/jquery.formatCurrency-1.4.0.min.js
http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css
http://code.jquery.com/jquery-1.8.2.min.js
http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js
Content/themes/images/icons-18-white.png
Controllers/AccountController
Controllers/HomeController
Models/AccountModels
Account/Login
Home/CheckOut
Note2: remove all spaces after each line.
Note:3 you need to follow the exact format FOLDER/File or FOLDER/FOLDER/FILE ect....
Just because you have a manifest file doesnt mean it will load. you need to add the following to the Tag:
<html manifest="~/cache.manifest" type="text/cache-manifest">
Don't forget that after you add this it's cached the first time the page loads. So you need to register a cache event in the 'mobileinit' event.
$(document).on("mobileinit", function () {
//register event to cache site for offline use
cache = window.applicationCache;
cache.addEventListener('updateready', cacheUpdatereadyListener, false);
cache.addEventListener('error', cacheErrorListener, false);
function cacheUpdatereadyListener (){
window.applicationCache.update();
window.applicationCache.swapCache();
}
function cacheErrorListener() {
alert('site not availble offline')
}
}
Download Safari and use the web inspector to find errors.
http://developer.apple.com/library/safari/#documentation/appleapplications/Conceptual/Safari_Developer_Guide/1Introduction/Introduction.html#//apple_ref/doc/uid/TP40007874-CH1-SW1
Tip: Chrome's developer tools "F12" will show you the errors in the manifest load. ie the files you still need to add.
Hope this helps, covers the entire process. I assuming if you are at this stage in development you new to add these to the mobile init:
$.mobile.allowCrossDomainPages = true; // cross domain page loading
$.mobile.phonegapNavigationEnabled = true; //Android enabled mobile
$.mobile.page.prototype.options.domCache = true; //page caching prefech rendering
$.support.touchOverflow = true; //Android enhanced scrolling
$.mobile.touchOverflowEnabled = true; // enhanced scrolling transition availible in iOS 5
Safari Developer Guide:
https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/Client-SideStorage/Client-SideStorage.html#//apple_ref/doc/uid/TP40002051-CH4-SW4
Have you tried anything like https://manifest-validator.appspot.com/ to validate your manifest?
I've struggled with my manifest file for quite a while, it is really hard to pinpoint what is wrong. Could be something as simple as wrong encoding to an extra line break at the start.
Today I experienced exactly the same problem. After hours of working I came the the key point: the format of manifest file. In short, the file must begin a new line ONLY with ascii(0A), not ascii(0D), or ascii(0D + 0A). Only in this way can I live with Chrome, or I will get a blank page, and the error info in the console window.
According to w3c, (http://www.w3.org/TR/html5/offline.html), in “5.6.3.2 Writing cache manifests”,both 0A, 0D and 0D + 0A are all acceptable. So, my opinion is: Chrome is not compatible with w3c in the point.
Further more, say, if myapp.js is to be cached, it MUST follow the same rule: begins a new line only with ascii(0A), or Chrome will throw the same info in the console windows.
My Chrome is 13.0.782.107
I have now resolved this issue by switching to CherryPy for serving these files :)
If anyone else becomes similarly stuck but wants to keep the server part simple, the following Python may be sufficient for getting started:
import cherrypy
class SimpleStaticServer:
#cherrypy.expose
def index(self):
return '<html><body>Go to the static index page</body></html>'
cherrypy.config.update({
# global
'server.socket_host': '192.168.0.3',
'server.socket_port': 80,
# /static
'tools.staticdir.on': True,
'tools.staticdir.dir': "(directory where static files are stored)",
})
cherrypy.quickstart(SimpleStaticServer())
If you want to visit the "site" from another device, you'll need to use the external IP address (for me this was 192.168.0.3). Otherwise, you can just use '127.0.0.1' for the 'server.socket_host' value. I then point my browser to http://192.168.0.3/index.html to get my static index page.
I have resolved this issue in visual studio for MVC application.
follow below steps:
I have created .appcache file in notepad and copy manifest file content into it.
(you don't need to create .Manifest file OR not create Manifest.cshtml view. just create .appcache file in notepad.)
give reference as
<html manifest="~/example.appcache"> in view
and issue will be resolved
I think the line
CACHE:
is missing in the manifest file (should be the 2nd line, before the list of files.

Offline iOS web app: loads my manifest, but doesn't work offline

I'm writing a web app to be used offline on iOS. I've created a manifest, am serving it up as text/cache-manifest, and it usually works fine, when running inside Safari.
If I add it as an app to my home screen, then turn on Airplane mode, it can't open the app at all -- I get an error and it offers to close the app. (I thought this was the entire purpose of an offline app!)
When I load the app a first time when online, I can see in my logs that it's requesting every page listed in the manifest.
If I turn off Airplane mode, and load the app, I can see the first file it's requesting is my main.html file (which is both listed in the manifest, and has the manifest=... attribute). It then requests the manifest, and all my other files, getting 200's for all (and 304's for anything requested a second time during this load).
When I load the page in Chrome, and click around, the logs show the only thing it's trying to reach on the server is "/favicon.ico" (which is a 404, and which I don't think iOS Safari tries to load, anyway). All of the files listed in the manifest are valid and served without error.
The Chrome inspector lists, under "APPLICATION CACHE", all the cached files I've listed which I expect. The entire set of files is about 50 KB, way under any limit on offline resources that I've found.
Is this supposed to work, i.e., am I supposed to be able to create an offline iOS app using only HTML/CSS/JS? And where do I go about figuring out why it's failing to work offline?
(Related but doesn't sound quite the same to me, since it's about Safari and not a standalone app: "Can't get a web app to work offline on iPod")
I confirm that name 'cache.manifest' solved the offline caching problem in IOS 4.3. Other name simply did not work.
I found debugging HTML5 offline apps to be a pain. I found the code from this article helped me figure out what was wrong with my app:
http://jonathanstark.com/blog/2009/09/27/debugging-html-5-offline-application-cache/
Debugging HTML 5 Offline Application Cache
by Jonathan Stark
If you are looking to provide offline access to your web app, the Offline Application Cache available in HTML5 is killer. However, it’s a giant PITA to debug, especially if you’re still trying to get your head around it.
If you are struggling with the cache manifest, add the following JavaScript to your main HTML page and view the output in the console using Firebug in Firefox or Debug > Show Error Console in Safari.
If you have any questions, PLMK in the comments.
HTH,
j
var cacheStatusValues = [];
cacheStatusValues[0] = 'uncached';
cacheStatusValues[1] = 'idle';
cacheStatusValues[2] = 'checking';
cacheStatusValues[3] = 'downloading';
cacheStatusValues[4] = 'updateready';
cacheStatusValues[5] = 'obsolete';
var cache = window.applicationCache;
cache.addEventListener('cached', logEvent, false);
cache.addEventListener('checking', logEvent, false);
cache.addEventListener('downloading', logEvent, false);
cache.addEventListener('error', logEvent, false);
cache.addEventListener('noupdate', logEvent, false);
cache.addEventListener('obsolete', logEvent, false);
cache.addEventListener('progress', logEvent, false);
cache.addEventListener('updateready', logEvent, false);
function logEvent(e) {
var online, status, type, message;
online = (navigator.onLine) ? 'yes' : 'no';
status = cacheStatusValues[cache.status];
type = e.type;
message = 'online: ' + online;
message+= ', event: ' + type;
message+= ', status: ' + status;
if (type == 'error' && navigator.onLine) {
message+= ' (prolly a syntax error in manifest)';
}
console.log(message);
}
window.applicationCache.addEventListener(
'updateready',
function(){
window.applicationCache.swapCache();
console.log('swap cache has been called');
},
false
);
setInterval(function(){cache.update()}, 10000);
Sometimes an application cache group gets into a bad state in MobileSafari — it downloads every item in the cache and then fires a generic cache error event at the end. An application cache group, as per the spec, is based on the absolute URL of the manifest. I've found that when this error occurs, changing the path to the manifest (eg, cache2.manifest, etc) gives you a fresh cache group and circumvents the problem. I can vouch that all of our web apps work offline in full-screen with 4.2 and 4.3.
No offline web app (as of iOS 4.2) can run without an internet connection (which means Airplane mode, too) when using <meta name="apple-mobile-web-app-capable" content="yes" /> in the html head section. I have verified this with every example I've seen and the ones that use Safari to render the site work fine, but when you throw in that meta tag, it won't work. Try your app without it and you'll see what I mean.
I have found that clearing the Safari cache after enabling Airplane mode to be an effective way of testing whether the app is really functioning offline.
I have sometimes been fooled into thinking that the application cache was working when it wasn't.
I had struggled with this iOS 4.3 "no offline cache" problem since I updated my iPad to 4.3.1 from 4.2. I saw in another post in this site that it was working again in 4.3.2. So I updated by iPad again, now to iOS 4.3.3. But still couldn't get the offline caching to work until I renamed my manifest file to "cache.manifest". Then the caching started working again and I could run my HTML5 offline app from the Home Screen. I did not need to put the favicon.ico in to the cache manifest. And I also had full screen going (setting the "apple-mobile-web-app-capable" to "yes").
I have several working offline and on/offline web apps.
When I turn off airport mode, I get a request for the manifest and some other files.
I don't get requests for images, JavaScript, CSS or cached AJAX files.
If you see requests for your resources, IOS doesn't have them cached.
Safari in general is more picky with manifests.
I suggest you try Safari on your computer.
I have run into the same problem today on iOS 4.3. I was able to fix the problem by adding a favicon.ico file and also adding it to the manifest.
I've written an offline app that still seems to work in 4.2 and 4.2.1; the post is a little dusty, but the code still runs:
http://kentbrewster.com/backchannel/
Remy Sharp has a newer post with code that also works, here:
http://remysharp.com/2011/01/31/simple-offline-application/
His app:
http://rem.im/boggle/
After days of messing with getting offline web apps to work on an iPhone/iPod Touch using the Webserver's HTTP authentication, I discovered these useful nuggets:
Make sure Safari is at the URL root of the web app when tapping "Add to Home Screen". I used jQuery Mobile and was sometimes adding the link with"/#pageId". Caused trouble.
Run your Ajax calls in serial. This might only be important if your web app is using HTTP authentication, but my app was firing a whole slew of Ajax calls on page load in parallel and it caused the app to hang on the "apple-touch-startup-image".
Ajax calls are "successful" when offline (at least using Prototype.js). Test for an actual piece of data in the Ajax response, not just on the HTTP status. I used this to test for displaying cached (SQL) or live data.
In the manifest use "NETWORK:\n*\n". From what I could muster, this is a catch-all statement for anything not explicit in the "CACHE:" section. Use Chrome to make sure your manifest is correct. Look at Chrome's console for errors.
Not directly related, but tripped me up for a bit, openDatabase.transaction() calls are ASYNCHRONOUS! Meaning, the line of JS code after transaction (execute(), error(), success()) will execute BEFORE the success() function.
Good luck!
I found this solution that seemed to work for me, since I also ran into this problem during my development. This fix has worked fine for me so far and also for other people that I've asked to test it with, and I'm able to get it running offline (in airplane mode) and off the home screen after caching and whatnot. I've written a post about it on my site:
http://www.offlinewebapp.com/solved-apple-mobile-web-app-capable-manifest-error/
Delete your current web app icon on the home screen.
Go to settings and clear your Safari browser cache.
Double tap your home button to open the multitasking bar. Find the Safari one, hold your
finger down on it, and exit it.
Please let me know if this works for you also! Good luck!
I've written an app and it works fine through the mobile browser, but when adding the desktop... Doesnt work. I guess apple have given up on IOS4 and all efforts are now on OS5. Shame :(
I have one potential workaround for this - it seems a bit crazy, but here goes... I work with the cache.manifest and full screen apps a lot (here's a test if you need: http://www.mrspeaker.net/2010/07/12/argy-bargy/ - add to home screen then turn on flight mode and it launches - at least, as of iOS 4.2.1)
One weird thing I found is that sometimes it seems that some kind of "meta" information in files can mess them up from being cached - Have you ever noticed that in bash that if you do a "ls" some files (depending on your colour settings) are highlighted for no apparent reason? Files can have meta data that the operating system (I think) adds automagically - and there are ways to remove it... I can't remember why but here's some more details: Strip metadata from files in Snow Leopard
After tearing my hair out one day - and refusing to give up because I knew it SHOULD have worked... Chrome was saying it loaded all the files, but ended with a generic error. In the end I recreated the project structure with blank files and copy/pasted the contents over. It worked - started caching as it was supposed to!
When I looked at the files I noticed there was some meta info. I tried scrubbing this info and the original project worked again. I'm not sure this was the reason it worked again - perhaps it was just a coincidence.
Because it worked, I didn't think too much about it. The same problem happened again some months later and the copy/paste trick worked again. I was busy, so I didn't investigate further - but vowed I would get to the bottom of it the next time it happened.... but I haven't had to yet.
Phew. Anyway, glad I got to write that down somewhere...
[UPDATE: months and months later - I've not been able to reproduce this, so I don't think it's the metadata]