Commit 82b09fe8 authored by Vincent Bechu's avatar Vincent Bechu Committed by Vincent Bechu

erp5_officejs: add generic installer gadget

parent 16489906
<!DOCTYPE html>
<html manifest="gadget_officejs_install.appcache">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="gadget_erp5_nojqm.css">
<title> OfficeJS Install </title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="jiodev.js"></script>
<script src="gadget_officejs_install.js"></script>
</head>
<body>
<script data-install-configuration="document_version" type="text/x-renderjs-configuration">${latest_document_version}</script>
<script data-install-configuration="version_url" type="text/x-renderjs-configuration">${latest_version}/</script>
<script data-install-configuration="redirect_url" type="text/x-renderjs-configuration">${redirect_url}/</script>
<script data-install-configuration="cache_file" type="text/x-renderjs-configuration">${cache_file}</script>
<script data-install-configuration="app_name" type="text/x-renderjs-configuration">${application_name}</script>
<script data-install-configuration="sub_app_installer" type="text/x-renderjs-configuration">${sub_gadget_installer}</script>
</body>
</html>
\ No newline at end of file
/*globals window, document, RSVP, rJS, navigator, jIO, MessageChannel, ProgressEvent*/
/*jslint indent: 2, maxlen: 80, nomen: true*/
var repair = false;
(function (window, document, RSVP, rJS, jIO, navigator, MessageChannel,
ProgressEvent) {
"use strict";
var serviceWorker_setting_storage = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "indexeddb",
database: "serviceWorker_settings"
}
});
function createStorage(version) {
return jIO.createJIO({
type: "replicate",
conflict_handling: 2,
check_remote_modification: false,
check_remote_deletion: false,
check_local_creation: false,
check_local_deletion: false,
check_local_modification: false,
query: {
query: 'portal_type: ("Web Illustration",' +
'"Web Manifest","Web Script","Web Style","Web Page")' +
'AND version:"' + version + '"',
"limit": [0, 27131],
"select_list": ["url_string"]
},
signature_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: version + "_hash"
}
},
local_sub_storage: {
type: "mapping",
map_all_property: true,
mapping_dict: {
"id": {"equal": "relative_url"},
"url_string": {"equal": "id"}
},
sub_storage: {
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: version
}
}
}
},
remote_sub_storage: {
type: "erp5",
url: window.location.href + "/hateoasnoauth",
default_view_reference: "jio_view"
}
});
}
function postMessage(gadget, message) {
return new RSVP.Promise(function (resolve, reject) {
var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function (event) {
if (event.data.error) {
reject(event.data.error);
} else {
return resolve(event.data);
}
};
gadget.props.serviceWorker.postMessage(
JSON.stringify(message),
[messageChannel.port2]
);
});
}
rJS(window)
.ready(function (gadget) {
var element_list =
gadget.element.querySelectorAll("[data-install-configuration]"),
i,
key,
value,
gadget_list = [];
gadget.props = {};
gadget.props.cached_url = [];
gadget.gadget_list = [];
function pushGadget(url, i) {
var element = document.createElement("div");
element.setAttribute("style", "display: none");
gadget.element.appendChild(element);
return gadget.declareGadget(url,
{
"scope": "sub_app_installer_" + i,
"element": element,
"sandbox": "iframe"
})
.push(function (sub_gadget) {
gadget.gadget_list.push(sub_gadget);
return sub_gadget.setSubInstall();
});
}
for (i = 0; i < element_list.length; i += 1) {
key = element_list[i].getAttribute('data-install-configuration');
value = element_list[i].textContent;
if (key === "sub_app_installer") {
if (value !== "") {
gadget_list = value.split('\n');
}
} else {
gadget.props[key] = value;
}
}
return gadget.render()
.push(function () {
var promise_list = [];
for (i = 0; i < gadget_list.length; i += 1) {
promise_list.push(pushGadget(gadget_list[i], i + 1));
}
return RSVP.all(promise_list);
});
})
.declareMethod("render", function () {
var gadget = this,
element = document.createElement("div");
element.className = "presentation";
gadget.element.insertBefore(element, gadget.element.firstChild);
return gadget.declareGadget(
"gadget_officejs_install_presentation.html",
{"scope": "presentation", "element": element}
)
.push(function (presentation_gadget) {
return presentation_gadget.render(
{"app_name": gadget.props.app_name}
);
});
})
.declareMethod("setSubInstall", function () {
this.props.sub = true;
})
.declareMethod("mainInstall", function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
if (gadget.props.document_version) {
return gadget.install();
}
})
.push(function () {
var promise_list = [], i;
for (i = 0; i < gadget.gadget_list.length; i += 1) {
promise_list.push(gadget.gadget_list[i].waitInstall());
}
return RSVP.all(promise_list);
})
.push(function () {
gadget.props.is_installed = true;
if (gadget.installing !== undefined) {
gadget.installing.resolve();
}
if (!gadget.props.sub) {
window.location.href = gadget.props.version_url;
}
})
.push(undefined, function (error) {
if (error instanceof ProgressEvent) {
if (gadget.props.sub === undefined) {
window.location.href = gadget.props.version_url;
}
return;
}
throw error;
});
})
.declareMethod("waitInstall", function () {
if (this.props.is_installed) {
return;
}
this.installing = RSVP.defer();
return this.installing.promise;
})
.declareMethod("install", function () {
var gadget = this;
return serviceWorker_setting_storage.put(
window.location.href + gadget.props.version_url,
{"version": gadget.props.document_version}
)
.push(function () {
gadget.props.storage = createStorage(gadget.props.document_version);
return gadget.props.storage.repair();
})
.push(function () {
// transform a cache to url_list
if (gadget.props.cache_file && gadget.props.cache_file !== "") {
gadget.props.storage = jIO.createJIO({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: gadget.props.document_version
}
}
});
return gadget.props.storage.get(gadget.props.cache_file)
.push(function (doc) {
var url_list = doc.text_content.split('\n'),
i,
start = url_list.indexOf("CACHE:") + 1,
len = url_list.indexOf("NETWORK:");
for (i = start; i < len; i += 1) {
if (url_list[i] !== "" &&
url_list[i].charAt(0) !== '#' &&
url_list[i].charAt(0) !== ' ') {
gadget.props.cached_url.push(url_list[i]);
}
}
});
}
})
.push(function () {
// remove base if present
if (document.querySelector("base")) {
document.querySelector("head").removeChild(
document.querySelector("base")
);
}
return navigator.serviceWorker.register(
"gadget_officejs_install_serviceworker.js",
{"scope": gadget.props.version_url }
);
})
.push(function (registration) {
if (registration.installing) {
gadget.props.serviceWorker = registration.installing;
} else if (registration.waiting) {
gadget.props.serviceWorker = registration.waiting;
} else if (registration.active) {
gadget.props.serviceWorker = registration.active;
}
})
.push(function () {
return postMessage(
gadget,
{
"action": "install",
"url_list": gadget.props.cached_url,
"version": gadget.props.document_version
}
);
});
})
.declareService(function () {
var gadget = this;
function redirect() {
window.location.href = gadget.props.redirect_url;
}
if (!("serviceWorker" in navigator)) {
window.applicationCache.addEventListener("cached", redirect);
window.applicationCache.addEventListener('noupdate', redirect);
window.setTimeout(redirect, 10000);
} else {
return this.mainInstall();
}
});
}(window, document, RSVP, rJS, jIO, navigator, MessageChannel, ProgressEvent));
\ No newline at end of file
/*jslint indent: 2*/
/*global self, fetch, Request, Response, console */
var global = self, window = self;
(function (self, fetch, Request, Response, console) {
"use strict";
self.DOMParser = {};
self.sessionStorage = {};
self.localStorage = {};
self.openDatabase = {};
self.DOMError = {};
self.postMessage = function () {return; };
self.importScripts('rsvp.js', 'jiodev.js');
self.storage = {};
self.setting_storage = self.jIO.createJIO({
type: "uuid",
sub_storage: {
type: "indexeddb",
database: "serviceWorker_settings"
}
});
function createStorage(version) {
return self.jIO.createJIO({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: version
}
}
});
}
self.addEventListener("message", function (event) {
event.waitUntil(new self.RSVP.Queue()
.push(function () {
var data = JSON.parse(event.data);
if (data.action === "install" &&
data.url_list !== undefined) {
self.storage = createStorage(data.version);
return new self.RSVP.Queue()
.push(function () {
var promise_list = [];
data.url_list.map(function (url) {
promise_list.push(
new self.RSVP.Queue()
.push(function () {
return self.storage.get(url);
})
.push(undefined, function () {
return new self.RSVP.Queue()
.push(function () {
return fetch(new Request(url));
})
.push(function (response) {
if (response.status === 200) {
return self.RSVP.all([
self.storage.put(
url,
{"content_type": "blob"}
),
response.blob()
]);
}
throw new Error(response.statusText);
})
.push(function (result) {
return self.storage.putAttachment(
url,
"body",
result[1]
);
})
.push(function () {
console.log("Saved: ", url);
})
.push(undefined, function (error) {
console.log(
"error on",
url,
"cause: ",
error.message
);
});
})
);
});
return self.RSVP.all(promise_list);
})
.push(function () {
event.ports[0].postMessage("success");
});
}
}));
});
self.addEventListener("fetch", function (event) {
var relative_url = event.request.url.replace(self.registration.scope, "")
.replace(self.version_url, "");
if (relative_url === "") {
relative_url = "/";
}
event.respondWith(
new self.RSVP.Queue()
.push(function () {
if (self.storage.get === undefined) {
return self.setting_storage.get(self.registration.scope)
.push(function (doc) {
self.storage = createStorage(doc.version);
});
}
return;
})
.push(function () {
return self.storage.get(relative_url);
})
.push(function (doc) {
if (doc.content_type !== "blob") {
return new Response(doc.text_content, {
'headers': {
'content-type': doc.content_type
}
});
}
return self.storage.getAttachment(relative_url, "body")
.push(function (blob) {
return new Response(blob, {
'headers': {
'content-type': blob.type
}
});
});
})
.push(undefined, function (error) {
console.log("Relative_Url: ", relative_url, "\nCause: ", error.message);
return fetch(event.request);
})
);
});
}(self, fetch, Request, Response, console));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment