Skip to content

Commit

Permalink
AppCache runtime events
Browse files Browse the repository at this point in the history
  • Loading branch information
NekR committed Apr 29, 2016
1 parent 9020558 commit 0fc3e13
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 64 deletions.
26 changes: 24 additions & 2 deletions lib/app-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@ Object.defineProperty(exports, '__esModule', {

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _es6Promise = require('es6-promise');

var _miscUtils = require('./misc/utils');

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var AppCache = (function () {
function AppCache(options) {
_classCallCheck(this, AppCache);
Expand All @@ -20,6 +30,7 @@ var AppCache = (function () {
this.FALLBACK = options.FALLBACK;
this.name = 'manifest';
this.caches = options.caches;
this.events = !!options.events;

this.directory = options.directory.replace(/^\//, '').replace(/\/$/, '') + '/';
this.basePath = (0, _miscUtils.pathToBase)(this.directory, true);
Expand Down Expand Up @@ -59,7 +70,8 @@ var AppCache = (function () {

var path = this.directory + this.name;
var manifest = this.getManifestTemplate(cache, plugin);
var page = this.getPageTemplate(this.name);
var content = this.getPageContent();
var page = this.getPageTemplate(this.name, content);

compilation.assets[path + '.appcache'] = (0, _miscUtils.getSource)(manifest);
compilation.assets[path + '.html'] = (0, _miscUtils.getSource)(page);
Expand Down Expand Up @@ -91,12 +103,22 @@ var AppCache = (function () {
value: function getPageTemplate(name, content) {
return ('\n <!doctype html>\n <html manifest="' + name + '.appcache">' + (content || '') + '</html>\n ').trim().replace(/^ */gm, '');
}
}, {
key: 'getPageContent',
value: function getPageContent() {
if (this.events) {
return _fs2['default'].readFileSync(_path2['default'].join(__dirname, '../tpls/appcache-frame.tpl'), 'utf-8');
} else {
return '';
}
}
}, {
key: 'getConfig',
value: function getConfig(plugin) {
return {
directory: plugin.publicPath + this.directory,
name: this.name
name: this.name,
events: this.events
};
}
}]);
Expand Down
6 changes: 4 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,16 @@ var defaultOptions = {

ServiceWorker: {
output: 'sw.js',
entry: _path2['default'].join(__dirname, '../empty-entry.js')
entry: _path2['default'].join(__dirname, '../empty-entry.js'),
events: false
},

AppCache: {
NETWORK: '*',
FALLBACK: null,
directory: 'appcache/',
caches: ['main', 'additional']
caches: ['main', 'additional'],
events: false
}
};

Expand Down
4 changes: 3 additions & 1 deletion lib/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var ServiceWorker = (function () {
this.entry = options.entry;
this.output = options.output.replace(/^\//, '');
this.basePath = (0, _miscUtils.pathToBase)(this.output, true);
this.events = !!options.events;

this.ENTRY_NAME = 'serviceworker';
this.CACHE_NAME = 'webpack-offline';
Expand Down Expand Up @@ -175,7 +176,8 @@ var ServiceWorker = (function () {
key: 'getConfig',
value: function getConfig(plugin) {
return {
output: plugin.publicPath + this.output
output: plugin.publicPath + this.output,
events: this.events
};
}
}]);
Expand Down
3 changes: 2 additions & 1 deletion runtime.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
exports.install = function() {};
exports.install = function() {};
exports.applyUpdate = function() {};
17 changes: 15 additions & 2 deletions src/app-cache.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Promise } from 'es6-promise';
import { getSource, pathToBase } from './misc/utils';
import fs from 'fs';
import path from 'path';

export default class AppCache {
constructor(options) {
this.NETWORK = options.NETWORK;
this.FALLBACK = options.FALLBACK;
this.name = 'manifest';
this.caches = options.caches;
this.events = !!options.events;

this.directory = options.directory
.replace(/^\//, '')
Expand Down Expand Up @@ -41,7 +44,8 @@ export default class AppCache {

const path = this.directory + this.name;
const manifest = this.getManifestTemplate(cache, plugin);
const page = this.getPageTemplate(this.name);
const content = this.getPageContent();
const page = this.getPageTemplate(this.name, content);

compilation.assets[path + '.appcache'] = getSource(manifest);
compilation.assets[path + '.html'] = getSource(page);
Expand Down Expand Up @@ -84,10 +88,19 @@ export default class AppCache {
`.trim().replace(/^ */gm, '');
}

getPageContent() {
if (this.events) {
return fs.readFileSync(path.join(__dirname, '../tpls/appcache-frame.tpl'), 'utf-8');
} else {
return '';
}
}

getConfig(plugin) {
return {
directory: plugin.publicPath + this.directory,
name: this.name
name: this.name,
events: this.events
};
}
}
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ const defaultOptions = {

ServiceWorker: {
output: 'sw.js',
entry: path.join(__dirname, '../empty-entry.js')
entry: path.join(__dirname, '../empty-entry.js'),
events: false
},

AppCache: {
NETWORK: '*',
FALLBACK: null,
directory: 'appcache/',
caches: ['main', 'additional']
caches: ['main', 'additional'],
events: false
}
};

Expand Down
4 changes: 3 additions & 1 deletion src/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default class ServiceWorker {
this.entry = options.entry;
this.output = options.output.replace(/^\//, '');
this.basePath = pathToBase(this.output, true);
this.events = !!options.events;

this.ENTRY_NAME = 'serviceworker';
this.CACHE_NAME = 'webpack-offline';
Expand Down Expand Up @@ -139,7 +140,8 @@ export default class ServiceWorker {

getConfig(plugin) {
return {
output: plugin.publicPath + this.output
output: plugin.publicPath + this.output,
events: this.events
};
}
}
148 changes: 148 additions & 0 deletions tpls/appcache-frame.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<script>
(function() {
// ################################
var updateReadyInterval;
var updatingFired;
var downloadingInterval;
var obsoleteInterval;
var cleanUpTimer;
applicationCache.addEventListener('updateready', onUpdateReadyEvent);
applicationCache.addEventListener('cached', onInstalledEvent);
applicationCache.addEventListener('obsolete', onObsoleteEvent);
applicationCache.addEventListener('downloading', onDownloadingEvent);
applicationCache.addEventListener('progress', onDownloadingEvent);
switch (applicationCache.status) {
case applicationCache.DOWNLOADING: {
setTimeout(onDownloadingEvent, 1);
} break;
case applicationCache.OBSOLETE: {
setTimeout(onObsoleteEvent, 1);
} break;
case applicationCache.UPDATEREADY: {
setTimeout(onUpdateReadyEvent, 1);
} break;
default: {
downloadingInterval = setInterval(function() {
if (applicationCache.status === applicationCache.DOWNLOADING) {
onDownloadingEvent();
}
}, 50);
obsoleteInterval = setInterval(function() {
if (applicationCache.status === applicationCache.OBSOLETE) {
onObsoleteEvent();
}
}, 50);
updateReadyInterval = setInterval(function() {
if (applicationCache.status === applicationCache.UPDATEREADY) {
onUpdateReadyEvent();
}
}, 50);
}
}
cleanUpTimer = setTimeout(function() {
cleanUp();
}, 5000);

This comment has been minimized.

Copy link
@bolasblack

bolasblack May 3, 2017

@NekR Hi, my english if not good, so if my wording or tone offended you, excuse me.

Can you tell me why you call cleanUp here?

If I understand the code correctly, the cleanUp function will be called after Runtime be installed and 5 seconds later, then the function will remove updateready event listener.

So if I call applicationCache.update after Runtime installed and 5 seconds later, then the event onUpdateReady in Runtime option will never be called, right? Seems it's not what I expected, I hope the onUpdateReady will be called in any time, so long as updateready event be fired.

This comment has been minimized.

Copy link
@NekR

NekR May 3, 2017

Author Owner

@bolasblack hey! please see #241 and a follow up here #248

This comment has been minimized.

Copy link
@bolasblack

bolasblack May 4, 2017

@NekR Good job! Thanks for your work!

// ###############################
function onDownloadingEvent() {
if (!updatingFired) {
updatingFired = true;
onUpdating();
}
downloadingCleanUp();
}
function onUpdateReadyEvent() {
if (!updatingFired) {
updatingFired = true;
onUpdating();
setTimeout(onUpdateReady, 1);
} else {
onUpdateReady();
}
cleanUp();
}
function onInstalledEvent() {
onInstalled();
cleanUp();
}
function onObsoleteEvent() {
onUpdateFailed();
setTimeout(onUninstalled, 1);
cleanUp();
}
function downloadingCleanUp() {
if (downloadingInterval) {
clearInterval(downloadingInterval);
downloadingInterval = null;
}
applicationCache.removeEventListener('downloading', onDownloadingEvent);
applicationCache.removeEventListener('progress', onDownloadingEvent);
}
function cleanUp() {
if (cleanUpTimer) {
clearTimeout(cleanUpTimer);
cleanUpTimer = null;
}
downloadingCleanUp();
applicationCache.removeEventListener('updateready', onUpdateReadyEvent);
applicationCache.removeEventListener('cached', onInstalledEvent);
applicationCache.removeEventListener('obsolete', onObsoleteEvent);
if (updateReadyInterval) {
clearInterval(updateReadyInterval);
updateReadyInterval = null;
}
if (obsoleteInterval) {
clearInterval(obsoleteInterval);
obsoleteInterval = null;
}
}
// ################################
}());
function onUpdating() {
sendEvent('onUpdating');
}
function onUpdateReady() {
sendEvent('onUpdateReady');
}
function onUpdateFailed() {
sendEvent('onUpdateFailed');
}
function onUninstalled() {
sendEvent('onUninstalled');
}
function onInstalled() {
sendEvent('onInstalled');
}
function sendEvent(event) {
window.parent.postMessage('__offline-plugin_AppCacheEvent:' + event, '*');
}
</script>

0 comments on commit 0fc3e13

Please sign in to comment.