Commit 8600259f authored by Boris Kocherov's avatar Boris Kocherov

add file's erp5package's metadata, support js,html,json,ttf

parent 3e38f2ea
(function(r){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=r()}else if(typeof define==="function"&&define.amd){define([],r)}else{var e;if(typeof window!=="undefined"){e=window}else if(typeof global!=="undefined"){e=global}else if(typeof self!=="undefined"){e=self}else{e=this}e.base64js=r()}})(function(){var r,e,t;return function r(e,t,n){function o(i,a){if(!t[i]){if(!e[i]){var u=typeof require=="function"&&require;if(!a&&u)return u(i,!0);if(f)return f(i,!0);var d=new Error("Cannot find module '"+i+"'");throw d.code="MODULE_NOT_FOUND",d}var c=t[i]={exports:{}};e[i][0].call(c.exports,function(r){var t=e[i][1][r];return o(t?t:r)},c,c.exports,r,e,t,n)}return t[i].exports}var f=typeof require=="function"&&require;for(var i=0;i<n.length;i++)o(n[i]);return o}({"/":[function(r,e,t){"use strict";t.byteLength=c;t.toByteArray=v;t.fromByteArray=s;var n=[];var o=[];var f=typeof Uint8Array!=="undefined"?Uint8Array:Array;var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var a=0,u=i.length;a<u;++a){n[a]=i[a];o[i.charCodeAt(a)]=a}o["-".charCodeAt(0)]=62;o["_".charCodeAt(0)]=63;function d(r){var e=r.length;if(e%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}return r[e-2]==="="?2:r[e-1]==="="?1:0}function c(r){return r.length*3/4-d(r)}function v(r){var e,t,n,i,a;var u=r.length;i=d(r);a=new f(u*3/4-i);t=i>0?u-4:u;var c=0;for(e=0;e<t;e+=4){n=o[r.charCodeAt(e)]<<18|o[r.charCodeAt(e+1)]<<12|o[r.charCodeAt(e+2)]<<6|o[r.charCodeAt(e+3)];a[c++]=n>>16&255;a[c++]=n>>8&255;a[c++]=n&255}if(i===2){n=o[r.charCodeAt(e)]<<2|o[r.charCodeAt(e+1)]>>4;a[c++]=n&255}else if(i===1){n=o[r.charCodeAt(e)]<<10|o[r.charCodeAt(e+1)]<<4|o[r.charCodeAt(e+2)]>>2;a[c++]=n>>8&255;a[c++]=n&255}return a}function l(r){return n[r>>18&63]+n[r>>12&63]+n[r>>6&63]+n[r&63]}function h(r,e,t){var n;var o=[];for(var f=e;f<t;f+=3){n=(r[f]<<16)+(r[f+1]<<8)+r[f+2];o.push(l(n))}return o.join("")}function s(r){var e;var t=r.length;var o=t%3;var f="";var i=[];var a=16383;for(var u=0,d=t-o;u<d;u+=a){i.push(h(r,u,u+a>d?d:u+a))}if(o===1){e=r[t-1];f+=n[e>>2];f+=n[e<<4&63];f+="=="}else if(o===2){e=(r[t-2]<<8)+r[t-1];f+=n[e>>10];f+=n[e>>4&63];f+=n[e<<2&63];f+="="}i.push(f);return i.join("")}},{}]},{},[])("/")});
{
"name": "erp5_officejs_fs2erp5_gadget",
"scopes": [
{
"prefix": "fs2erp5",
"paths": [
""
]
}
]
"description": "RenderJs gadget allow export github published repos as bt for import in erp5.",
"version": "001",
"authors": [
"Copyright (c) 2017 Nexedi SA"
],
"license": "LGPL3",
"id_prefix": "fs2erp5_"
}
\ No newline at end of file
......@@ -13,6 +13,8 @@
<script src="gadget_officejs_page_export2erp5.js"></script>
<script src="zipfilestorage-with-jszip.js"></script>
<script src="jstoxml.js"></script>
<script src="base64js.min.js"></script>
<script src="jio_fs2erp5storage.js"></script>
<script src="jio_appcachestorage.js"></script>
</head>
......
/*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO, RSVP, window, console, Blob */
(function (window, jIO, RSVP, console, Blob) {
/*global jIO, RSVP, window, console, Blob,
jstoxml, base64js */
(function (window, jIO, RSVP, console, Blob, jstoxml, base64js) {
"use strict";
function string2blob(s) {
var l = s.length,
array = new Uint8Array(l);
for (var i = 0; i < l; i++) {
array[i] = s.charCodeAt(i);
}
return new Blob([array], {type: 'application/octet-stream'});
}
function generateZopeData(obj) {
var records = [];
function pickle(obj) {
var type = typeof obj,
items = [];
if (Array.isArray(obj)) {
type = 'array';
}
switch (type) {
case "string":
// TODO cdata fix
obj = obj
.replace(/\r\n/g, '\\r\\n')
.replace(/\n/g, '\\n')
.replace(/\\n/g, '\\n\n');
// .replace(/</g, '&lt;')
// .replace(/>/g, '&gt;')
// .replace(/&/g, '&amp;')
// .replace(/"/g, '&quot;')
// .replace(/'/g, '&apos;');
return {string: obj};
case "array":
for (var i = 0; i < obj.length; i += 1) {
items.push(pickle(obj[i]));
}
return {tuple: items};
// case "function": return obj.name || obj.toString();
case "object":
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
items.push({
item: {
key: {
string: key
},
value: pickle(obj[key])
}
});
}
}
return {dictionary: items};
default:
return obj.toString();
}
}
function longToByteArray(/*long*/long) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for (var index = byteArray.length - 1; index !== 0; index--) {
var byte;
/* jshint -W016 */
byte = long & 0xff;
byteArray[index] = byte;
long = (long - byte) / 256;
}
return byteArray;
}
function add_record(name, module, obj) {
var id = records.length + 1;
records.push({
_name: "record",
_attrs: {
id: id,
aka: base64js.fromByteArray(longToByteArray(id))
},
_content: [
{
pickle: {
_name: "global",
_attrs: {
name: name,
module: module
}
}
},
{
pickle: pickle(obj)
}
]
});
}
add_record(obj.portal_type, "erp5.portal_type", obj);
return jstoxml.toXML({
ZopeData: records
}, {header: true, indent: ' '});
}
function Fs2Erp5Storage(spec) {
this._document = spec.document;
this._sub_storage = jIO.createJIO(spec.sub_storage);
......@@ -19,11 +124,34 @@
};
Fs2Erp5Storage.prototype.getAttachment = function (doc_id, attachment_id) {
// doc_id + ((attachment_id === "index.html") ?
// (doc_id.endsWith("imagelib/") ? "index.html" : "") : attachment_id)
return this._sub_storage.getAttachment(
this._document, this._id_dict[doc_id][attachment_id]
);
var obj = this._id_dict[doc_id][attachment_id],
type = typeof obj;
if (obj instanceof Blob) {
type = "blob";
}
switch (type) {
// case "undefined":
// return new Blob();
case "blob":
return obj;
case "object":
if (obj.text_content) {
return this._sub_storage.getAttachment(this._document,
obj.text_content)
.push(function (blob) {
return jIO.util.readBlobAsText(blob);
})
.push(function (evt) {
obj.text_content = evt.target.result;
return string2blob(generateZopeData(obj));
});
} else {
return string2blob(generateZopeData(obj));
}
break;
default:
return this._sub_storage.getAttachment(this._document, obj);
}
};
Fs2Erp5Storage.prototype.allAttachments = function (doc_id) {
......@@ -31,13 +159,13 @@
};
Fs2Erp5Storage.prototype.buildQuery = function (options) {
var id, result = [], context = this;
for (id in context._id_dict) {
if (context._id_dict.hasOwnProperty(id)) {
result.push({id: id});
}
}
return result;
var id, result = [], context = this;
for (id in context._id_dict) {
if (context._id_dict.hasOwnProperty(id)) {
result.push({id: id});
}
}
return result;
};
Fs2Erp5Storage.prototype.repair = function () {
......@@ -45,35 +173,75 @@
var context = this;
return context._sub_storage.repair()
.push(function () {
return jIO.util.ajax({
type: "GET",
dataType: "json",
url: context._document + "erp5_/erp5.json"
});
return jIO.util.ajax({
type: "GET",
dataType: "json",
url: context._document + "erp5_/erp5.json"
});
})
.push(function (response) {
var scopes, i, x, scope, bt_folder = {}, size= 0;
context._id_dict["/bt/"] = bt_folder;
function add_metafile(fname, body) {
var type = typeof body,
new_body;
if (Array.isArray(body)) {
type = 'array';
}
switch (type) {
case "undefined":
return;
case "array":
new_body = body.join("\n");
break;
// case "object":
// break;
default:
new_body = body;
}
bt_folder[fname] = string2blob(new_body);
}
context._options = response.target.response;
context._options.id_prefix = context._options.id_prefix || "";
context._options.version = context._options.version || "001";
context._path_templates = {};
scopes = context._options.scopes || {};
for (i = 0; i < scopes.length; i += 1) {
size++;
scope = scopes[i];
for (x = 0; x < scope.paths.length; x += 1) {
context._paths[scope.paths[x]] = scope;
}
context._path_templates[context._options.id_prefix +
scope.prefix.split("/").join("_").split(".").join("_") + "*"] = 1;
}
if (size === 0) {
context._path_templates[context._options.id_prefix + "*"] = 1;
}
add_metafile("title", context._options.name);
add_metafile("version", context._options.version);
add_metafile("description", context._options.description);
add_metafile("copyright_list", context._options.authors);
add_metafile("license", context._options.license);
})
.push(function (response) {
var scopes, i, x, scope;
context._options = response.target.response;
scopes = context._options.scopes;
for (i = 0; i < scopes.length; i += 1) {
scope = scopes[i];
for (x = 0; x < scope.paths.length; x += 1) {
context._paths[scope.paths[x]] = scope;
}
}
})
.push(function () {
return context._sub_storage.allAttachments(context._document);
})
.push(function (result) {
var id, path, last_index, filename, filename_xml, ext, new_id, i;
var id, path, last_index, filename, ext, i, size,
xmldoc = {}, bt_links = {}, path_templates = [],
generated_appcache = [];
for (id in result) {
if (
result.hasOwnProperty(id) &&
!id.startsWith("http") &&
!id.startsWith("/erp5_/") && //rmove meta of package
!id.startsWith("/assets/") // remove github added assets
) {
if (
result.hasOwnProperty(id) &&
id !== "/" &&
!id.startsWith("http") &&
!id.startsWith("erp5_/") && //rmove meta of package
!id.startsWith("assets/") // remove github added assets
) {
last_index = id.lastIndexOf("/") + 1;
if (last_index === id.length) {
path = id || "/";
......@@ -82,39 +250,113 @@
path = id.substring(0, last_index);
filename = id.substring(last_index);
}
new_id = path + filename;
xmldoc = {
version: context._options.version
};
path = path + filename;
size = 0;
for (i in context._paths) {
if (context._paths.hasOwnProperty(i)) {
size++;
if (path.startsWith(i)) {
if (context._paths[i].prefix) {
path = context._paths[i].prefix + path;
}
xmldoc.default_reference = path;
break;
}
}
}
if (size > 0 && !xmldoc.default_reference) {
continue;
} else {
xmldoc.default_reference = path;
}
if (!context._options.id_prefix && path === "index.html") {
continue;
}
xmldoc.id = context._options.id_prefix + path;
xmldoc.id = xmldoc.id.split("/").join("_").split(".").join("_");
ext = filename.substring(filename.lastIndexOf('.') + 1);
// TODO: all filetype support
switch (ext) {
case "js":
path = "/PathTemplateItem/web_page_module/";
break;
case "ttf":
path = "/PathTemplateItem/document_module/";
ext = "bin";
break;
case "template":
case "html":
path = "web_page_module";
xmldoc.portal_type = "Web Page";
xmldoc.content_type = "text/html";
break;
case "js":
path = "web_page_module";
xmldoc.portal_type = "Web Script";
xmldoc.content_type = "text/javascript";
break;
case "appcache":
path = "web_page_module";
xmldoc.portal_type = "Web Manifest";
xmldoc.content_type = "application/json";
xmldoc.text_content = id;
break;
case "gif":
case "jpg":
path = "image_module";
xmldoc.portal_type = "Image";
xmldoc.title = filename;
xmldoc.filename = filename;
xmldoc.content_type = "image/" + ext;
break;
case "json":
xmldoc.portal_type = "File";
xmldoc.content_type = "application/json";
break;
case "ttf":
xmldoc.portal_type = "File";
xmldoc.content_type = "font/truetype";
break;
default:
continue;
}
for (i in context._paths) {
if (new_id.startsWith(i)) {
if (context._paths[i].prefix) {
new_id = context._paths[i].prefix + "/" + new_id;
}
}
if (xmldoc.portal_type === "File") {
path = "document_module";
xmldoc.title = filename;
}
if (!bt_links.hasOwnProperty(path)) {
bt_links[path] = 1;
for (i in context._path_templates) {
if (context._path_templates.hasOwnProperty(i)) {
path_templates.push(path + '/' + i);
}
}
}
filename = new_id.split("/")
.join("_").split(".").join("_") + '.' + ext;
filename_xml = new_id.split("/")
.join("_").split(".").join("_") + '.xml';
path = "/PathTemplateItem/" + path + "/";
if (!context._id_dict.hasOwnProperty(path)) {
context._id_dict[path] = {};
}
context._id_dict[path][filename] = id;
context._id_dict[path][filename_xml] = id;
if (!xmldoc.text_content) {
context._id_dict[path][xmldoc.id + '.' + ext] = id;
}
generated_appcache.push(xmldoc.default_reference);
context._id_dict[path][xmldoc.id + '.xml'] = xmldoc;
}
}
context._id_dict["/bt/"].template_path_list =
string2blob(path_templates.join("\n"));
// generate appcache as list of all packaged files
xmldoc = {
version: context._options.version,
id: context._options.id_prefix + context._options.name + "_appcache",
default_reference: "",
portal_type: "Web Manifest",
content_type: "application/json",
text_content: "CACHE MANIFEST\nCACHE:\n" +
generated_appcache.join("\n") + "\nNETWORK:\n*"
};
context._id_dict["/PathTemplateItem/web_page_module/"]
[xmldoc.id + ".appcache"] = string2blob(generateZopeData(xmldoc));
});
};
jIO.addStorage('fs2erp5', Fs2Erp5Storage);
}(window, jIO, RSVP, console, Blob));
\ No newline at end of file
}(window, jIO, RSVP, console, Blob, jstoxml, base64js));
\ No newline at end of file
/*jslint indent:2, nomen: true */
/*global exports */
(function(exports) {
"use strict";
var toXML = function(obj, config){
// include XML header
config = config || {};
var out = '';
if(config.header) {
if(typeof config.header === 'string') {
out = config.header;
} else {
out = '<?xml version="1.0" encoding="UTF-8"?>\n';
}
}
var origIndent = config.indent || '';
var indent = '';
var filter = function customFilter(txt) {
if(!config.filter) {
return txt;
}
var mappings = config.filter;
var replacements = [];
for(var map in mappings) {
if(!mappings.hasOwnProperty(map)) {
continue;
}
replacements.push(map);
}
return String(txt).replace(new RegExp('(' + replacements.join('|') + ')', 'g'), function(str, entity) {
return mappings[entity] || '';
});
};
// helper function to push a new line to the output
var push = function(string){
out += string + (origIndent ? '\n' : '');
};
/* create a tag and add it to the output
Example:
outputTag({
name: 'myTag', // creates a tag <myTag>
indent: ' ', // indent string to prepend
closeTag: true, // starts and closes a tag on the same line
selfCloseTag: true,
attrs: { // attributes
foo: 'bar', // results in <myTag foo="bar">
foo2: 'bar2'
}
});
*/
var outputTag = function(tag){
var attrsString = '';
var outputString = '';
var attrs = tag.attrs || '';
// turn the attributes object into a string with key="value" pairs
for(var attr in attrs){
if(attrs.hasOwnProperty(attr)) {
attrsString += ' ' + attr + '="' + attrs[attr] + '"';
}
}
// assemble the tag
outputString += (tag.indent || '') + '<' + (tag.closeTag ? '/' : '') + tag.name + (!tag.closeTag ? attrsString : '') + (tag.selfCloseTag ? '/' : '') + '>';
// if the tag only contains a text string, output it and close the tag
if(tag.text || tag.text === ''){
outputString += filter(tag.text) + '</' + tag.name + '>';
}
push(outputString);
};
// custom-tailored iterator for input arrays/objects (NOT a general purpose iterator)
var every = function(obj, fn, indent){
// array
if(Array.isArray(obj)){
obj.every(function(elt){ // for each element in the array
fn(elt, indent);
return true; // continue to iterate
});
return;
}
// object with tag name
if(obj._name){
fn(obj, indent);
return;
}
// iterable object
for(var key in obj){
if (obj.hasOwnProperty(key)) {
var type = typeof obj[key];
if(obj[key] || type === 'boolean' || type === 'number') {
fn({_name: key, _content: obj[key]}, indent);
//} else if(!obj[key]) { // null value (foo:'')
} else if(obj[key] === null) { // null value (foo:null)
fn(key, indent); // output the keyname as a string ('foo')
} else if(obj[key] === '') {
// blank string
outputTag({
name: key,
text: ''
});
}
}
}
};
var convert = function convert(input, indent){
var type = typeof input;
if(!indent) {
indent = '';
}
if(Array.isArray(input)) {
type = 'array';
}
var path = {
'string': function(){
push(indent + filter(input));
},
'boolean': function(){
push(indent + (input ? 'true' : 'false'));
},
'number': function(){
push(indent + input);
},
'array': function(){
every(input, convert, indent);
},
'function': function(){
push(indent + input());
},
'object': function(){
if(!input._name){
every(input, convert, indent);
return;
}
var outputTagObj = {
name: input._name,
indent: indent,
attrs: input._attrs
};
var type = typeof input._content;
if(type === 'undefined' || input._content._selfCloseTag === true){
if (input._content && input._content._attrs) {
outputTagObj.attrs = input._content._attrs;
}
outputTagObj.selfCloseTag = true;
outputTag(outputTagObj);
return;
}
var objContents = {
'string': function(){
outputTagObj.text = input._content;
outputTag(outputTagObj);
},
'boolean': function(){
outputTagObj.text = (input._content ? 'true' : 'false');
outputTag(outputTagObj);
},
'number': function(){
outputTagObj.text = input._content.toString();
outputTag(outputTagObj);
},
'object': function(){ // or Array
outputTag(outputTagObj);
every(input._content, convert, indent + origIndent);
outputTagObj.closeTag = true;
outputTag(outputTagObj);
},
'function': function(){
outputTagObj.text = input._content(); // () to execute the fn
outputTag(outputTagObj);
}
};
if(objContents[type]) {
objContents[type]();
}
}
};
if(path[type]) {
path[type]();
}
};
convert(obj, indent);
return out;
};
exports.toXML = toXML;
})(typeof exports === 'undefined' ? this.jstoxml={} : exports);
\ 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