Commit a5f113ee authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

erp5_cribjs_bootloader: Introduce first version of CribJS bootloader in ERP5

parent b4c6d186
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Jio Gadget</title>
<link rel="http://www.renderjs.org/rel/interface" href="interface_jio.html">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="crib-enable.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
/*global window, rJS, jIO, FormData, navigator, RSVP */
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS, jIO) {
"use strict";
function waitForServiceWorkerActive(registration) {
var serviceWorker;
if (registration.installing) {
serviceWorker = registration.installing;
} else if (registration.waiting) {
serviceWorker = registration.waiting;
} else if (registration.active) {
serviceWorker = registration.active;
}
if (serviceWorker.state !== "activated") {
return RSVP.Promise(function (resolve, reject) {
serviceWorker.addEventListener('statechange', function (e) {
if (e.target.state === "activated") {
resolve();
}
});
RSVP.delay(500).then(function () {
reject(new Error("Timeout service worker install"));
});
});
}
}
rJS(window)
.ready(function (gadget) {
// Initialize the gadget local parameters
var path = "", path_list = window.location.pathname.split("/");
if (path_list) {
if (path_list[path_list.length - 1] !== "") {
if (path_list[path_list.length - 1].endsWith(".html")) {
path_list[path_list.length - 1] = "";
} else {
path_list.push("");
}
}
path = path_list.join("/");
}
gadget.state_parameter_dict = {};
gadget.state_parameter_dict.default_document = window.location.protocol +
"//" + window.location.host + path;
this.state_parameter_dict.jio_storage = jIO.createJIO({
"type": "indexeddb",
"database": "ojs_source_code"
});
return this.state_parameter_dict.jio_storage.put(gadget.state_parameter_dict.default_document, {});
})
.ready(function (gadget) {
var jio_storage;
return RSVP.Queue()
.push(function () {
jio_storage = jIO.createJIO({
type: "indexeddb",
database: "setting"
});
return jio_storage.get("setting");
})
.push(function (result) {
if (result.site_editor_gadget_url) {
return;
}
result.site_editor_gadget_url = window.location.href;
return jio_storage.put("setting", result);
}, function (error) {
if (error.status_code === 404) {
return jio_storage.put(
"setting", {
site_editor_gadget_url: window.location.href
});
}
});
})
.ready(function () {
if ('serviceWorker' in navigator) {
// XXX Hack to not add a new service worker when one is already declared
if (!navigator.serviceWorker.controller) {
return new RSVP.Queue()
.push(function () {
return navigator.serviceWorker.register(
'gadget_cribjs_bootloader_serviceworker.js',
{scope: './'}
);
})
.push(function (registration) {
return waitForServiceWorkerActive(registration);
});
}
} else {
throw "Service Worker are not available in your browser";
}
})
.declareMethod('get', function (url) {
var storage = this.state_parameter_dict.jio_storage;
return storage.getAttachment(this.state_parameter_dict.default_document, url)
.push(function (result) {
return jIO.util.readBlobAsDataURL(result);
})
.push(function (e) {
return e.target.result;
});
})
.declareMethod('put', function (url, data_uri) {
var storage = this.state_parameter_dict.jio_storage;
data_uri = jIO.util.dataURItoBlob(data_uri);
return storage.putAttachment(
this.state_parameter_dict.default_document,
url,
data_uri
);
})
.declareMethod('allDocs', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.allAttachments(this.state_parameter_dict.default_document)
.push(function (result) {
return result;
});
})
.declareMethod('remove', function (url) {
var storage = this.state_parameter_dict.jio_storage;
return storage.removeAttachment(
this.state_parameter_dict.default_document,
url
);
});
}(window, rJS, jIO));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>CribJS Loader</title>
<style>
.loader{
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 64px;
height: 64px;
z-index:9999;
animation: spin 1s linear infinite;
-webkit-animation: spin 1s linear infinite;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
header{
background-color:#085078;
color: #f8fff3;
padding: 0.6em;
}
.main {
padding-top: 11%;
}
</style>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="jiodev.js"></script>
<script src="jszip.js" type="text/javascript"></script>
<script src="./landing.js"></script>
</head>
<body>
<center>
<header> CribJS Bootloader </header>
<div class="main">
<!--img src="officejs_logo.png"-->
<div class="app-name"> Preparing</div>
<div class="loader"></div>
</div>
</center>
<div class="storage-access" style="display:none;"></div>
</body>
</html>
/*jslint indent: 2*/
/*global self, fetch, Request, Response, URL */
var global = self, window = self;
(function (self, fetch, Response) {
"use strict";
self.DOMParser = {};
self.sessionStorage = {};
self.localStorage = {};
self.openDatabase = {};
self.DOMError = {};
self.Node = {};
self.XMLSerializer = Object;
self.DOMParser = Object;
self.postMessage = function () {return; };
self.importScripts('rsvp.js', 'jiodev.js');
self.storage = {};
self.cache_list = [];
function createStorage(database) {
return self.jIO.createJIO({
type: "indexeddb",
database: database
});
}
function getFromLocal(relative_url) {
if (self.storage.get === undefined) {
self.storage = createStorage("ojs_source_code");
}
return self.storage.getAttachment(self.registration.scope, relative_url)
.push(function (blob) {
return new Response(blob, {
'headers': {
'content-type': blob.type
}
});
});
}
self.addEventListener('install', function (event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', function (event) {
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", function (event) {
var relative_url = decodeURI(event.request.url.split("#")[0])
.replace(self.registration.scope, "");
if (relative_url[relative_url.length - 1] === "/" || relative_url === "") {
relative_url = relative_url + "index.html";
}
if (relative_url === './no-cache') {
event.respondWith(new Response(self.cache_list));
return;
}
if (event.request !== undefined &&
new URL(event.request.url).hostname !== window.location.hostname) {
event.respondWith(
new self.RSVP.Queue()
.push(function () {
return fetch(event.request);
})
.push(undefined, function (error) {
if (error.name === 'TypeError' &&
error.message === 'Failed to fetch') {
return {};
}
throw error;
})
.push(function (response) {
if (response.status === 200) {
return response;
}
return getFromLocal(relative_url);
})
.push(undefined, function (error) {
return new Response(error, {"statusText": error.message, "status": 500});
})
);
} else {
event.respondWith(
new self.RSVP.Queue()
.push(function () {
return getFromLocal(relative_url);
})
.push(undefined, function (error) {
if (error instanceof self.jIO.util.jIOError) {
if (relative_url.indexOf('http') === -1) {
if (self.cache_list.indexOf(relative_url) === -1) {
self.cache_list.push(relative_url);
}
}
return fetch(event.request);
}
return new Response(error, {"statusText": error.message, "status": 500});
})
);
}
});
}(self, fetch, Response));
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, RSVP, jIO, fetch, Promise, document, console, Blob
, JSZip */
(function (rJS, RSVP, JSZip, jIO) {
"use strict";
function getStorageGadget(gadget) {
var getURL = window.location;
return new RSVP.Queue()
.push(function () {
var url = "crib-enable.html";
if (gadget.props.storage_gadget_url === url) {
return gadget.getDeclaredGadget("storage")
.push(undefined, function () {
return gadget.declareGadget(
url,
{
"scope": "storage",
"sandbox": "iframe",
"element": gadget.props.element
.querySelector('.storage-access')
}
);
});
}
gadget.props.storage_gadget_url = url;
return gadget.dropGadget("storage")
.push(function () {}, function () {})
.push(function () {
return gadget.declareGadget(
url,
{
"scope": "storage",
"sandbox": "iframe",
"element": gadget.props.element
.querySelector('.storage-access')
}
);
});
})
.push(undefined, function (e) {
// Ugly Hack to reload page and make service worker available
if (e &&
e.toString()
.indexOf("Please reload this page to allow Service Worker to control this page") > -1) {
window.location.reload(false);
throw e;
}
throw e;
});
}
function getParameterDict() {
var hash = window.location.hash.substring(1),
params = {};
hash.split('&').map(hk => {
let temp = hk.split('=');
params[temp[0]] = temp[1];
});
return params;
}
function loadZipIntoCrib(gadget, zip, from_path) {
var promise_list = [];
zip.forEach(function (relativePath, zipEntry) {
var end_url;
if (zipEntry.dir) {
return;
}
if (!relativePath.startsWith(from_path)) {
return;
}
relativePath = relativePath.substring(from_path.length);
if (relativePath.startsWith("/")) {
end_url = relativePath.substring(1);
} else {
end_url = relativePath;
}
promise_list.push(
new RSVP.Queue()
.push(function () {
return zipEntry.async('blob');
})
.push(function (result) {
if (end_url.endsWith(".js")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "application/javascript");
} else if (end_url.endsWith(".html")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/html");
} else if (end_url.endsWith(".css")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/css");
}
return gadget.put(end_url, {blob: result});
})
);
});
return RSVP.all(promise_list);
}
function loadContentFromZIPURL(gadget, options) {
var path_to_load = options.to_path,
from_path = options.from_path,
zip_url = options.zip_url;
return new RSVP.Queue()
.push(function () {
return fetch(zip_url)
.then(function (response) { // 2) filter on 200 OK
if (response.status === 200 || response.status === 0) {
return Promise.resolve(response.blob());
}
return Promise.reject(new Error(response.statusText));
});
})
.push(JSZip.loadAsync)
.push(function (zip) {
return loadZipIntoCrib(gadget, zip, from_path, path_to_load);
});
}
function loadCribJSFromZipUrl(gadget, data) {
return loadContentFromZIPURL(gadget, {
path: document.location.href,
zip_url: data.zip_url,
from_path: data.from_path,
to_path: data.to_path,
application_id: "cribjs"
})
.push(function () {
document.location = data.redirect_url;
})
.push(console.log, console.log);
}
rJS(window)
.declareMethod('render', function () {
var gadget = this,
getURL = window.location,
site = getURL.protocol + "//" + getURL.host,
params = getParameterDict(),
data = {
from_path: "cribjs-editor-master/",
to_path: site,
zip_url: "https://lab.nexedi.com/cedric.leninivin/cribjs-editor/" +
"-/archive/master/cribjs-editor-master.zip",
redirect_url: window.location.href
};
if (params.hasOwnProperty("from_path")) {
data.from_path = params.from_path;
}
if (params.hasOwnProperty("to_path")) {
data.to_path = params.to_path;
}
if (params.hasOwnProperty("zip_url")) {
data.zip_url = params.zip_url;
}
if (params.hasOwnProperty("redirect_url")) {
data.redirect_url = decodeURIComponent(params.redirect_url);
}
return RSVP.Queue()
.push(function () {
return loadCribJSFromZipUrl(gadget, data);
});
})
.declareMethod('put', function (url, parameter) {
var blob, gadget = this;
if (parameter.blob !== undefined) {
blob = parameter.blob;
} else {
blob = new Blob(
[parameter.content],
{type: parameter.type}
);
}
return RSVP.Queue()
.push(function () {
return RSVP.all([
getStorageGadget(gadget),
jIO.util.readBlobAsDataURL(blob)
]);
})
.push(function (result_list) {
return result_list[0].put(url, result_list[1].target.result);
})
.push(console.log, console.log);
})
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
})
.push(function () {
return RSVP.all([
getStorageGadget(g),
g.render({})
]);
});
});
}(rJS, RSVP, JSZip, jIO));
\ No newline at end of file
erp5_officejs
\ No newline at end of file
Contains CribJS Bootloader
\ No newline at end of file
web_page_module/cribjs_bootloader_*
web_site_module/cribjs_bootloader
web_site_module/cribjs_bootloader/**
\ No newline at end of file
web_page_module/cribjs_bootloader_*
web_site_module/cribjs_bootloader
web_site_module/cribjs_bootloader/**
\ No newline at end of file
web_page_module/cribjs_bootloader_*
web_site_module/cribjs_bootloader
web_site_module/cribjs_bootloader/**
\ No newline at end of file
erp5_cribjs_bootloader
\ 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