Commit e92d40b4 authored by Vincent Bechu's avatar Vincent Bechu

[erp5_officejs] Bootloader retry and inform on error

parent e01625fd
<!DOCTYPE html> <!DOCTYPE html>
<html manifest="gadget_officejs_bootloader.appcache"> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
...@@ -21,7 +21,5 @@ ...@@ -21,7 +21,5 @@
<script data-install-configuration="redirect_url" type="text/x-renderjs-configuration">${redirect_url}/</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="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="app_name" type="text/x-renderjs-configuration">${application_name}</script>
<script data-install-configuration="landing_page" type="text/x-renderjs-configuration">${landing_page}</script>
<script data-install-configuration="sub_app_installer" type="text/x-renderjs-configuration">${sub_gadget_installer}</script>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -241,7 +241,7 @@ ...@@ -241,7 +241,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>959.27737.62903.2116</string> </value> <value> <string>961.282.28573.14114</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1496242886.73</float> <float>1501754635.21</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Manifest" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>contributor/person_module/1</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_officejs_bootloader.appcache</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>gadget_officejs_bootloader_appcache</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Manifest</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string>CACHE MANIFEST\n
# generated on Wed, 26 Apr 2017 11:45:33 +0000\n
# XXX + fonts\n
# images/ajax-loader.gif\n
CACHE:\n
/\n
development/jiodev.js\n
development/rsvp.js\n
development/renderjs.js\n
gadget_erp5_nojqm.css\n
gadget_officejs_bootloader.js\n
gadget_officejs_bootloader_presentation.html\n
gadget_officejs_bootloader_presentation.js\n
gadget_officejs_bootloader_presentation.css\n
gadget_officejs_bootloader_serviceworker.js\n
jio_appcachestorage.js\n
NETWORK:\n
*</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Gadget Bootloader AppCache</string> </value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1493728283.88</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published</string> </value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>959.48233.9194.50227</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1496245831.78</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1493199934.66</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
/*globals window, document, RSVP, rJS, navigator, jIO, MessageChannel, ProgressEvent, console*/ /*globals window, document, RSVP, rJS, navigator, jIO, URL*/
/*jslint indent: 2, maxlen: 80, nomen: true*/ /*jslint indent: 2, maxlen: 80, nomen: true*/
var repair = false; var repair = false;
(function (window, document, RSVP, rJS, jIO, navigator, MessageChannel, (function (window, document, RSVP, rJS, jIO, navigator, URL) {
ProgressEvent, console) {
"use strict"; "use strict";
var remote_storage = { function createStorage(gadget) {
type: "erp5",
url: window.location.origin +
window.location.pathname + "hateoasnoauth",
default_view_reference: "jio_view"
};
function createStorage(version_url, manifest) {
return jIO.createJIO({ return jIO.createJIO({
type: "replicate", type: "replicate",
conflict_handling: 2,
parallel_operation_attachment_amount: 10, parallel_operation_attachment_amount: 10,
check_remote_attachment_modification: false, parallel_operation_amount: 1,
conflict_handling: 2,
signature_hash_key: 'hash',
check_remote_attachment_modification: true,
check_remote_attachment_creation: true, check_remote_attachment_creation: true,
check_remote_modification: false, check_remote_attachment_deletion: false,
check_remote_deletion: false, check_remote_deletion: false,
check_local_creation: false, check_local_creation: false,
check_local_deletion: false, check_local_deletion: false,
check_local_modification: false, check_local_modification: false,
signature_storage: { signature_sub_storage: {
type: "query",
sub_storage: {
type: "indexeddb", type: "indexeddb",
database: window.location.pathname + version_url + "_hash" database: "officejs-hash"
}
}, },
local_sub_storage: { local_sub_storage: {
type: "query", type: "query",
...@@ -34,185 +31,140 @@ var repair = false; ...@@ -34,185 +31,140 @@ var repair = false;
type: "uuid", type: "uuid",
sub_storage: { sub_storage: {
type: "indexeddb", type: "indexeddb",
database: window.location.origin + window.location.pathname + database: "ojs_source_code"
version_url
} }
} }
}, },
remote_sub_storage: { remote_sub_storage: {
type: "appcache", type: "appcache",
manifest: manifest, manifest: gadget.state.cache_file,
version: version_url version: gadget.state.version_url
} }
}); });
} }
rJS(window) rJS(window)
.ready(function (gadget) { .ready(function (gadget) {
var element_list = var i,
gadget.element.querySelectorAll("[data-install-configuration]"), state = {},
i, sub_gadget_list = [],
key, element_list =
value, gadget.element.querySelectorAll('[data-install-configuration]');
gadget_list = []; window.Bootloader = gadget;
gadget.props = {};
gadget.props.cached_url = [];
gadget.gadget_list = [];
gadget.props.query_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) { for (i = 0; i < element_list.length; i += 1) {
key = element_list[i].getAttribute('data-install-configuration'); state[element_list[i].getAttribute('data-install-configuration')] =
value = element_list[i].textContent; element_list[i].textContent;
if (key === "sub_app_installer") {
if (value !== "") {
gadget_list = value.split('\n');
}
} else {
gadget.props[key] = value;
}
} }
state.redirect_url = new URL(window.location);
return gadget.render() state.redirect_url.pathname += state.version_url;
.push(function () { return gadget.changeState(state);
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 () { .allowPublicAcquisition('isChildren', function () {
var gadget = this, return true;
element = document.createElement("div");
element.className = "presentation";
gadget.element.insertBefore(element, gadget.element.firstChild);
return gadget.declareGadget(
"gadget_officejs_bootloader_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;
}) })
.declareAcquiredMethod('isChildren', 'isChildren')
.declareMethod("mainInstall", function () { .declareService(function () {
var gadget = this; var gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
if (gadget.props.document_version) { /* Workaround for renderjs issue,
return gadget.install(); sub gadget does not have all aquired Method at this point*/
} return RSVP.delay(500);
}) })
.push(function () { .push(function () {
var promise_list = [], i; return gadget.isChildren();
for (i = 0; i < gadget.gadget_list.length; i += 1) {
promise_list.push(gadget.gadget_list[i].waitInstall());
}
return RSVP.all(promise_list);
}) })
.push(undefined, function (error) {
if (error instanceof rJS.AcquisitionError) {
return RSVP.all([
new RSVP.Queue()
.push(function () { .push(function () {
gadget.props.is_installed = true; return RSVP.delay(600);
if (gadget.installing !== undefined) {
gadget.installing.resolve();
}
if (!gadget.props.sub) {
window.location.pathname += gadget.props.version_url;
}
return;
}) })
.push(undefined, function (error) { .push(function () {
if (error instanceof ProgressEvent) { return gadget.changeState({retry: 0});
if (gadget.props.sub === undefined) { }),
window.location.pathname += gadget.props.version_url; gadget.install()
} .push(function () {
return; window.location = gadget.state.redirect_url;
})
]);
} }
throw error; throw error;
}); });
}) })
.declareMethod("waitInstall", function () { .onStateChange(function () {
if (this.props.is_installed) { var gadget = this, element;
return; if (gadget.state.retry !== undefined) {
return new RSVP.Queue()
.push(function () {
if (gadget.state.retry === 0) {
element = document.createElement("div");
element.className = "presentation";
gadget.element.insertBefore(element, gadget.element.firstChild);
return gadget.declareGadget(
"gadget_officejs_bootloader_presentation.html",
{"scope": "view_gadget", "element": element}
);
}
return gadget.getDeclaredGadget('view_gadget');
})
.push(function (view_gadget) {
return view_gadget.render({
app_name: gadget.state.app_name,
retry: gadget.state.retry,
error: gadget.state.error,
redirect_url: gadget.state.redirect_url
});
});
} }
this.installing = RSVP.defer();
return this.installing.promise;
}) })
.declareMethod("install", function () { .declareMethod('declareAndInstall', function (url) {
var gadget = this; var element = document.createElement("div");
element.setAttribute("style", "display: none");
this.element.appendChild(element);
return this.declareGadget(url,
{
"element": element,
"sandbox": "iframe"
})
.push(function (sub_gadget) {
return sub_gadget.install();
});
})
gadget.props.storage = createStorage( .declareMethod("install", function () {
gadget.props.version_url, var gadget = this,
gadget.props.cache_file storage = createStorage(gadget);
);
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return navigator.serviceWorker.register( return navigator.serviceWorker.register(
"gadget_officejs_bootloader_serviceworker.js", "gadget_officejs_bootloader_serviceworker.js"
{"scope": gadget.props.version_url}
); );
}) })
.push(function (registration) { .push(function () {
if (registration.installing) { return storage.repair();
gadget.props.serviceWorker = registration.installing; })
} else if (registration.waiting) { .push(undefined, function (error) {
gadget.props.serviceWorker = registration.waiting; if (gadget.state.retry !== undefined) {
} else if (registration.active) { return gadget.changeState({
gadget.props.serviceWorker = registration.active; retry: gadget.state.retry += 1,
} error: error
return gadget.props.storage.repair();
}) })
.push(function () { .push(function () {
// remove base if present return RSVP.delay(1000);
if (document.querySelector("base")) {
document.querySelector("head").removeChild(
document.querySelector("base")
);
}
});
}) })
.push(function () {
.declareService(function () { return gadget.install();
var gadget = this; });
function redirect() {
window.location.pathname += gadget.props.version_url;
}
if (navigator.serviceWorker === undefined) {
window.applicationCache.addEventListener("cached", redirect);
window.applicationCache.addEventListener('noupdate', redirect);
window.setTimeout(redirect, 10000);
} else {
return this.mainInstall();
} }
throw error;
});
}); });
}(window, document, RSVP, rJS, jIO, navigator, URL));
}(window, document, RSVP, rJS, jIO, navigator, MessageChannel, ProgressEvent, \ No newline at end of file
console));
\ No newline at end of file
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>960.25484.60987.38638</string> </value> <value> <string>961.10581.61261.18995</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1499245437.8</float> <float>1501763880.35</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -5,18 +5,8 @@ var IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABUCAYAAAACoiByA ...@@ -5,18 +5,8 @@ var IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABUCAYAAAACoiByA
"use strict"; "use strict";
rJS(window) rJS(window)
.ready(function (g) {
g.props = {};
})
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
this.props.element.querySelector("center") var inner =
.innerHTML =
"<header>OfficeJS Installer</header>" + "<header>OfficeJS Installer</header>" +
"<br>" + "<br>" +
"<br>" + "<br>" +
...@@ -27,10 +17,21 @@ var IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABUCAYAAAACoiByA ...@@ -27,10 +17,21 @@ var IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABUCAYAAAACoiByA
"<br>" + "<br>" +
'<img width="100" height="100" title="" alt="" src="' + IMAGE + '" />' + '<img width="100" height="100" title="" alt="" src="' + IMAGE + '" />' +
"<br>" + "<br>" +
'<div>Installing ' + options.app_name + '</div>' + '<div> Preparing ' + options.app_name + '</div>' +
"<br> We prepare your application for a 100 % offline mode" + "<br> We prepare your application for a 100 % offline mode" +
'<div class="loader"></div>'; '<div class="loader"></div>',
return {}; error_message;
if (options.retry > 0) {
error_message = options.error.message || 'Unknow Error';
inner += "<br>" +
"<div> Last Error: " + error_message + "</div>" +
"<div>Retry n° " + options.retry + "</div>";
}
inner += '<div><a href="' +
options.redirect_url + '">Skip</a></div>';
this.element.querySelector("center")
.innerHTML = inner;
return;
}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>956.64509.32061.2201</string> </value> <value> <string>961.10577.42640.30924</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1485770737.14</float> <float>1501764672.06</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -5,8 +5,6 @@ var global = self, window = self; ...@@ -5,8 +5,6 @@ var global = self, window = self;
(function (self, fetch, Request, Response) { (function (self, fetch, Request, Response) {
"use strict"; "use strict";
self.IDBTransaction = self.IDBTransaction || self.webkitIDBTransaction || self.msIDBTransaction || {READ_WRITE: "readwrite"};
self.IDBKeyRange = self.IDBKeyRange || self.webkitIDBKeyRange || self.msIDBKeyRange;
self.DOMParser = {}; self.DOMParser = {};
self.sessionStorage = {}; self.sessionStorage = {};
self.localStorage = {}; self.localStorage = {};
...@@ -41,13 +39,17 @@ var global = self, window = self; ...@@ -41,13 +39,17 @@ var global = self, window = self;
if (relative_url === "") { if (relative_url === "") {
relative_url = "/"; relative_url = "/";
} }
if (relative_url === 'no-cache') {
event.respondWith(new Response(self.cache_list));
return;
}
event.respondWith( event.respondWith(
new self.RSVP.Queue() new self.RSVP.Queue()
.push(function () { .push(function () {
if (self.storage.get === undefined) { if (self.storage.get === undefined) {
self.storage = createStorage(self.registration.scope); self.storage = createStorage("ojs_source_code");
} }
return self.storage.getAttachment("/", relative_url) return self.storage.getAttachment(self.registration.scope, relative_url)
.push(function (blob) { .push(function (blob) {
return new Response(blob, { return new Response(blob, {
'headers': { 'headers': {
...@@ -58,12 +60,11 @@ var global = self, window = self; ...@@ -58,12 +60,11 @@ var global = self, window = self;
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
if (error instanceof self.jIO.util.jIOError) { if (error instanceof self.jIO.util.jIOError) {
self.console.log( if (relative_url.indexOf('http') === -1) {
"Relative_Url: ", if (self.cache_list.indexOf(relative_url) === -1) {
relative_url, self.cache_list.push(relative_url);
"\nCause: ", }
error.message }
);
return fetch(event.request); return fetch(event.request);
} }
return new Response(error, {"statusText": error.message, "status": 500}); return new Response(error, {"statusText": error.message, "status": 500});
......
...@@ -227,7 +227,7 @@ ...@@ -227,7 +227,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>960.4199.25759.2730</string> </value> <value> <string>961.10426.22931.29952</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -245,7 +245,7 @@ ...@@ -245,7 +245,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1497613210.46</float> <float>1501754543.53</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint indent:2, maxlen: 80, nomen: true */ /*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO, RSVP, window, console, Blob */ /*global jIO, RSVP, window, Rusha, Blob, URL */
(function (window, jIO, RSVP, console, Blob) { (function (window, jIO, RSVP, Rusha, Blob, URL) {
"use strict"; "use strict";
var rusha = new Rusha();
function AppCacheStorage(spec) { function AppCacheStorage(spec) {
this._manifest = spec.manifest; this._manifest = spec.manifest;
this._gadget = spec.gadget;
this._take_installer = spec.take_installer || false; this._take_installer = spec.take_installer || false;
this._origin_url = spec.origin_url !== undefined ? spec.origin_url : this._origin_url = spec.origin_url !== undefined ?
(window.location.origin + window.location.pathname + spec.origin_url : new URL(window.location);
(window.location.pathname.endsWith('/') ? '' : '/') + this._version = spec.version || "";
((spec.version !== undefined) ? this._gadget_list = [];
(spec.version + (spec.version.endsWith('/') ? '' : '/')) : "")); this._documents = {};
this._prefix = spec.prefix || ""; // Harcoded here, find a better way.
this._relative_url_list = ["/", this._prefix + spec.manifest];
if (this._take_installer) {
this._relative_url_list = [ this._relative_url_list = [
this._prefix || "/", "/",
this._prefix + "development/" + spec.manifest, "gadget_officejs_bootloader.js",
this._prefix + "development/", "gadget_officejs_bootloader_presentation.html",
this._prefix + "gadget_officejs_bootloader.js", "gadget_officejs_bootloader_presentation.js",
this._prefix + "gadget_officejs_bootloader.appcache", "gadget_officejs_bootloader_presentation.css",
this._prefix + "gadget_officejs_bootloader_presentation.html", "gadget_officejs_bootloader_serviceworker.js",
this._prefix + "gadget_officejs_bootloader_presentation.js", "gadget_erp5_nojqm.css",
this._prefix + "gadget_officejs_bootloader_presentation.css", "jio_appcachestorage.js"
this._prefix + "gadget_officejs_bootloader_serviceworker.js",
this._prefix + "gadget_erp5_nojqm.css",
this._prefix + "jio_appcachestorage.js"
]; ];
} }
}
AppCacheStorage.prototype.get = function (id) { AppCacheStorage.prototype.get = function (id) {
return {}; if (this._documents.hasOwnProperty(id)) {
return this._documents[id];
}
throw new jIO.util.jIOError('can not find document : ' + id, 404);
}; };
AppCacheStorage.prototype.hasCapacity = function (name) { AppCacheStorage.prototype.hasCapacity = function () {
return (name === "list"); return true;
}; };
AppCacheStorage.prototype.getAttachment = function (doc_id, attachment_id) { AppCacheStorage.prototype.getAttachment = function (origin_url,
var storage = this, url = attachment_id; relative_url) {
var storage = this;
if (storage._gadget_list.indexOf(relative_url) >= 0) {
return window.Bootloader.declareAndInstall(relative_url)
.push(function () {
return new Blob([]);
});
}
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", type: "GET",
url: ((url.startsWith("http") || url.startsWith("//")) ? url: (relative_url.startsWith("http") ||
url : storage._origin_url) + url, relative_url.startsWith("//")) ?
relative_url : origin_url + relative_url,
dataType: "blob" dataType: "blob"
}); });
}) })
...@@ -54,57 +62,77 @@ ...@@ -54,57 +62,77 @@
}); });
}; };
AppCacheStorage.prototype.allAttachments = function (url) { AppCacheStorage.prototype.allAttachments = function () {
var result = {}, i, len = this._relative_url_list.length; var result = {}, i, len = this._relative_url_list.length;
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
result[this._relative_url_list[i]] = {}; result[this._relative_url_list[i]] = {};
} }
for (i = 0; i < this._gadget_list.length; i += 1) {
result[this._gadget_list[i]] = {};
}
return result; return result;
}; };
AppCacheStorage.prototype.buildQuery = function (options) { AppCacheStorage.prototype.buildQuery = function () {
return [{id: "/", doc: {}, value: {}}]; var result = [], id;
for (id in this._documents) {
if (this._documents.hasOwnProperty(id)) {
result.push({
'id': id,
'value': this._documents[id],
'doc': this._documents[id]
});
}
}
return result;
}; };
AppCacheStorage.prototype.repair = function () { AppCacheStorage.prototype.repair = function () {
var storage = this, var storage = this;
prefix = storage._prefix +
(storage._take_installer ? "development/" : "");
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", type: "GET",
url: storage._origin_url + storage._prefix + storage._manifest url: storage._origin_url + storage._version + storage._manifest
}); });
}) })
.push(function (response) { .push(function (response) {
var text = response.target.responseText, var text = response.target.responseText,
relative_url_list = text.split('\r\n'), relative_url_list = text.split('\n'),
i, i,
take = false; take = false,
if (relative_url_list.length === 1) { hash = rusha.digestFromString(text);
relative_url_list = text.split('\n'); storage._documents[storage._origin_url] = {'hash': hash};
} storage._relative_url_list.push(storage._version);
if (relative_url_list.length === 1) { storage._relative_url_list.push(storage._version + storage._manifest);
relative_url_list = text.split('\r');
}
for (i = 0; i < relative_url_list.length; i += 1) { for (i = 0; i < relative_url_list.length; i += 1) {
if (relative_url_list[i].indexOf("NETWORK:") >= 0) { if (relative_url_list[i].indexOf("NETWORK:") >= 0) {
take = false; take = 3;
} } else if (relative_url_list[i].indexOf('GADGET:') >= 0) {
if (take && take = 2;
relative_url_list[i] !== "" && } else if (relative_url_list[i] !== "" &&
relative_url_list[i].charAt(0) !== '#' && relative_url_list[i].charAt(0) !== '#' &&
relative_url_list[i].charAt(0) !== ' ') { relative_url_list[i].charAt(0) !== ' ') {
relative_url_list[i].replace("\r", ""); if (take === 1) {
storage._relative_url_list.push(prefix + relative_url_list[i]); storage._relative_url_list.push(
storage._version + relative_url_list[i]
);
} else if (take === 2) {
storage._gadget_list.push(relative_url_list[i]);
}
} }
if (relative_url_list[i].indexOf("CACHE:") >= 0) { if (relative_url_list[i].indexOf("CACHE:") >= 0) {
take = true; take = 1;
} }
} }
})
.push(undefined, function (error) {
if (!error.message) {
error.message = "Can't get manifest";
}
throw error;
}); });
}; };
jIO.addStorage('appcache', AppCacheStorage); jIO.addStorage('appcache', AppCacheStorage);
}(window, jIO, RSVP, console, Blob)); }(window, jIO, RSVP, Rusha, Blob, URL));
\ No newline at end of file
...@@ -239,7 +239,7 @@ ...@@ -239,7 +239,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>960.14254.57744.3293</string> </value> <value> <string>961.10590.54524.11827</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -257,7 +257,7 @@ ...@@ -257,7 +257,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1498139825.46</float> <float>1501764524.91</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
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