Commit 816085b3 authored by Boris Kocherov's avatar Boris Kocherov

erp5_json_form: update version from https://lab.nexedi.com/bk/rjs_json_form

parent dbaff65a
...@@ -346,6 +346,15 @@ ...@@ -346,6 +346,15 @@
x = {}; x = {};
} else if (!doesntcopy) { } else if (!doesntcopy) {
x = JSON.parse(JSON.stringify(x)); x = JSON.parse(JSON.stringify(x));
if (x.anyOf) {
delete x.anyOf;
}
if (x.oneOf) {
delete x.oneOf;
}
if (x.allOf) {
delete x.allOf;
}
} }
if (y === true) { if (y === true) {
y = {}; y = {};
...@@ -443,6 +452,7 @@ ...@@ -443,6 +452,7 @@
break; break;
case "allOf": case "allOf":
case "anyOf": case "anyOf":
case "oneOf":
case "$ref": case "$ref":
case "id": case "id":
case "$id": case "$id":
...@@ -456,6 +466,7 @@ ...@@ -456,6 +466,7 @@
switch (key) { switch (key) {
case "allOf": case "allOf":
case "anyOf": case "anyOf":
case "oneOf":
case "$ref": case "$ref":
break; break;
default: default:
...@@ -473,7 +484,7 @@ ...@@ -473,7 +484,7 @@
var i, var i,
arr = []; arr = [];
for (i = 0; i < schema_array.length; i += 1) { for (i = 0; i < schema_array.length; i += 1) {
arr.push(expandSchema(g, schema_array[i], schema_path + '/allOf/' + i.toString())); arr.push(expandSchema(g, schema_array[i], schema_path + '/' + i.toString()));
} }
return RSVP.all(arr); return RSVP.all(arr);
}) })
...@@ -507,14 +518,13 @@ ...@@ -507,14 +518,13 @@
}); });
} }
function anyOf(g, schema, schema_path) { function anyOf(g, schema_array, schema_path, base_schema) {
var schema_array = schema.anyOf;
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
var i, var i,
arr = []; arr = [];
for (i = 0; i < schema_array.length; i += 1) { for (i = 0; i < schema_array.length; i += 1) {
arr.push(expandSchema(g, mergeSchemas(schema_array[i], schema), schema_path + '/anyOf/' + i.toString())); arr.push(expandSchema(g, schema_array[i], schema_path + '/' + i.toString()));
} }
return RSVP.all(arr); return RSVP.all(arr);
}) })
...@@ -528,6 +538,13 @@ ...@@ -528,6 +538,13 @@
// or(any, restricted, restricted, .. ) simplify to any // or(any, restricted, restricted, .. ) simplify to any
return [arr[i][z]]; return [arr[i][z]];
} }
if (base_schema.title) {
arr[i][z].title = base_schema.title;
}
if (base_schema.description) {
arr[i][z].description = base_schema.description;
}
arr[i][z].schema = mergeSchemas(base_schema, arr[i][z].schema);
schema_arr.push(arr[i][z]); schema_arr.push(arr[i][z]);
} }
} }
...@@ -544,10 +561,13 @@ ...@@ -544,10 +561,13 @@
schema = true; schema = true;
} }
if (schema.anyOf !== undefined) { if (schema.anyOf !== undefined) {
return anyOf(g, schema, schema_path); return anyOf(g, schema.anyOf, schema_path + '/anyOf', schema);
}
if (schema.oneOf !== undefined) {
return anyOf(g, schema.oneOf, schema_path + '/oneOf', schema);
} }
if (schema.allOf !== undefined) { if (schema.allOf !== undefined) {
return allOf(g, schema.allOf, schema_path, schema); return allOf(g, schema.allOf, schema_path + '/allOf', schema);
} }
if (schema.$ref) { if (schema.$ref) {
return loadJSONSchema(g, schema.$ref, schema_path); return loadJSONSchema(g, schema.$ref, schema_path);
...@@ -573,13 +593,29 @@ ...@@ -573,13 +593,29 @@
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
return [{ return [{
title: ref || schema.title, title: schema.title,
ref: ref,
schema: schema, schema: schema,
schema_path: schema_path schema_path: schema_path
}]; }];
}); });
}; };
function schema_arr_marker(schema_arr) {
var i;
// XXX need cleanup false schema before
for (i = 0; i < schema_arr.length; i += 1) {
if (!schema_arr[i].schema.hasOwnProperty('const')) {
schema_arr[0].is_arr_of_const = false;
break;
}
if (i === schema_arr.length - 1) {
schema_arr[0].is_arr_of_const = true;
}
}
return schema_arr;
}
function expandSchemaForField(g, schema, schema_path, for_required) { function expandSchemaForField(g, schema, schema_path, for_required) {
var required_stack, var required_stack,
prev_field_path; prev_field_path;
...@@ -590,7 +626,8 @@ ...@@ -590,7 +626,8 @@
required_stack = []; required_stack = [];
} }
g.props.schema_required_urls[schema_path] = required_stack; g.props.schema_required_urls[schema_path] = required_stack;
return expandSchema(g, schema, schema_path); return expandSchema(g, schema, schema_path)
.push(schema_arr_marker);
} }
rJS(window) rJS(window)
...@@ -624,6 +661,7 @@ ...@@ -624,6 +661,7 @@
return json_document; return json_document;
}) })
.push(function (json_d) { .push(function (json_d) {
gadget.state.value = JSON.stringify(json_d);
return tv4.validateMultiple(json_d, gadget.props.schema[""]); return tv4.validateMultiple(json_d, gadget.props.schema[""]);
}) })
.push(function (validation) { .push(function (validation) {
...@@ -727,14 +765,17 @@ ...@@ -727,14 +765,17 @@
}) })
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
return this.changeState({ var z = {
key: options.key, key: options.key,
value: JSON.stringify(options.value),
schema: JSON.stringify(options.schema), schema: JSON.stringify(options.schema),
saveOrigValue: options.saveOrigValue, saveOrigValue: options.saveOrigValue,
schema_url: options.schema_url, schema_url: options.schema_url,
editable: options.editable === undefined ? true : options.editable editable: options.editable === undefined ? true : options.editable
}); };
if (options.value !== undefined) {
z.value = JSON.stringify(options.value);
}
return this.changeState(z);
}) })
.onStateChange(function () { .onStateChange(function () {
var g = this, var g = this,
...@@ -804,22 +845,21 @@ ...@@ -804,22 +845,21 @@
schema_url = g.state.schema_url || schema_url = g.state.schema_url ||
(json_document && json_document.$schema); (json_document && json_document.$schema);
if (schema_url) { if (schema_url) {
queue = loadJSONSchema(g, schema_url); queue = loadJSONSchema(g, schema_url)
.push(schema_arr_marker);
} }
} }
if (queue) { if (queue) {
return queue return queue;
.push(function (schema_arr) {
// XXX for root of form use first schema selection
return schema_arr[0].schema;
});
} }
return {}; return [{
schema: true,
schema_path: ""
}];
}) })
.push(function (schema) { .push(function (schema_arr) {
return g.props.form_gadget.renderForm({ return g.props.form_gadget.renderForm({
schema: schema, schema_arr: schema_arr,
schema_path: "",
document: json_document, document: json_document,
saveOrigValue: g.state.saveOrigValue, saveOrigValue: g.state.saveOrigValue,
required: true, required: true,
...@@ -836,6 +876,9 @@ ...@@ -836,6 +876,9 @@
}) })
.push(function () { .push(function () {
return g; return g;
})
.push(undefined, function (err) {
console.log(err);
}); });
}) })
.allowPublicAcquisition("expandSchema", function (arr) { .allowPublicAcquisition("expandSchema", function (arr) {
......
...@@ -178,6 +178,65 @@ ...@@ -178,6 +178,65 @@
return input; return input;
} }
function render_enum_with_title(g, schema_arr, json_document, selected_schema) {
var input = document.createElement("select"),
option,
i,
ser_value,
selected = false;
input.size = 1;
if (json_document === undefined && selected_schema !== undefined) {
json_document = selected_schema.schema.const;
}
if (schema_arr[0].schema.default) {
if (json_document === undefined) {
json_document = schema_arr[0].schema.default;
g.props.changed = true;
}
} else {
option = document.createElement("option");
option.value = "";
if (json_document === undefined) {
option.selected = true;
}
input.appendChild(option);
}
for (i = 0; i < schema_arr.length; i += 1) {
option = document.createElement("option");
// XXX use number id for speedup
ser_value = JSON.stringify(schema_arr[i].schema.const);
option.value = ser_value;
if (schema_arr[i].schema.title) {
option.textContent = schema_arr[i].schema.title;
} else if (typeof schema_arr[i].schema.const === "string") {
option.textContent = schema_arr[i].schema.const;
} else {
option.textContent = ser_value;
}
if (deepEqual(schema_arr[i].schema.const, json_document)) {
option.selected = true;
selected = true;
}
input.appendChild(option);
}
if (json_document !== undefined && !selected) {
// save original json_document even if it
// not support with schema
// XXX element should be removed on first user interact
option = document.createElement("option");
ser_value = JSON.stringify(json_document);
option.value = ser_value;
if (typeof json_document === "string") {
option.textContent = json_document;
} else {
option.textContent = ser_value;
}
option.selected = true;
input.appendChild(option);
}
return input;
}
function render_boolean(g, schema, json_document) { function render_boolean(g, schema, json_document) {
var input, var input,
schema_for_selection = { schema_for_selection = {
...@@ -209,7 +268,11 @@ ...@@ -209,7 +268,11 @@
g.props.changed = true; g.props.changed = true;
} }
input.setAttribute('data-origin-value', ser_const); input.setAttribute('data-origin-value', ser_const);
input.value = ser_const; if (schema.title) {
input.value = schema.title;
} else {
input.value = ser_const;
}
} else { } else {
input.value = ser_doc + '' + ser_const; input.value = ser_doc + '' + ser_const;
input.setAttribute('data-origin-value', ser_doc); input.setAttribute('data-origin-value', ser_doc);
...@@ -273,9 +336,9 @@ ...@@ -273,9 +336,9 @@
type: options.type, type: options.type,
required: options.required, required: options.required,
delete_button: options.delete_button, delete_button: options.delete_button,
schema: options.schema_part, selected_schema: options.selected_schema,
schema_path: options.schema_path, schema_arr: options.schema_arr,
document: options.default_dict, document: options.json_document,
display_label: options.parent_type !== "array", display_label: options.parent_type !== "array",
saveOrigValue: g.props.saveOrigValue, saveOrigValue: g.props.saveOrigValue,
scope: scope scope: scope
...@@ -338,7 +401,9 @@ ...@@ -338,7 +401,9 @@
if (schema_arr.length === 1) { if (schema_arr.length === 1) {
if (schema_arr[0].schema === true || if (schema_arr[0].schema === true ||
!(schema_arr[0].schema.hasOwnProperty('type') || !(schema_arr[0].schema.hasOwnProperty('type') ||
schema_arr[0].schema.hasOwnProperty('enum'))) { schema_arr[0].schema.hasOwnProperty('enum') ||
schema_arr[0].schema.hasOwnProperty('const')
)) {
return false; return false;
} }
if (schema_arr[0].schema.type instanceof Array) { if (schema_arr[0].schema.type instanceof Array) {
...@@ -346,17 +411,24 @@ ...@@ -346,17 +411,24 @@
} }
return true; return true;
} }
if (schema_arr[0].is_arr_of_const) {
return true;
}
return false; return false;
} }
function checkSchemaSimpleType(schema) { function checkSchemaSimpleType(schema_arr) {
return [ // return true if rendering are not recursive
'string', var schema = schema_arr[0].schema;
'integer', return schema_arr[0].is_arr_of_const ||
'number', schema.hasOwnProperty('const') ||
'boolean', [
'null' 'string',
].indexOf(schema.type) >= 0; 'integer',
'number',
'boolean',
'null'
].indexOf(schema.type) >= 0;
} }
function convertExpandedProperties2array(properties) { function convertExpandedProperties2array(properties) {
...@@ -371,6 +443,8 @@ ...@@ -371,6 +443,8 @@
// add propertyName to title // add propertyName to title
if (schema_array[i].title && schema_array.length > 1) { if (schema_array[i].title && schema_array.length > 1) {
schema_array[i].title = property_name + ' /' + schema_array[i].title; schema_array[i].title = property_name + ' /' + schema_array[i].title;
} else if (schema_array[i].ref && schema_array.length > 1) {
schema_array[i].title = property_name + ' /' + schema_array[i].ref;
} else { } else {
schema_array[i].title = property_name; schema_array[i].title = property_name;
} }
...@@ -386,10 +460,12 @@ ...@@ -386,10 +460,12 @@
function schemaArrFilteredByDocument(schema_arr, json_document) { function schemaArrFilteredByDocument(schema_arr, json_document) {
var i, var i,
flag, flag,
circular = schema_arr[0].circular,
ret_arr = [], ret_arr = [],
schema; schema;
if (schema_arr.length === 1) { if (schema_arr.length === 1 ||
return schema_arr[0]; schema_arr[0].is_arr_of_const) {
return schema_arr;
} }
if (json_document !== undefined) { if (json_document !== undefined) {
for (i = 0; i < schema_arr.length; i += 1) { for (i = 0; i < schema_arr.length; i += 1) {
...@@ -407,11 +483,12 @@ ...@@ -407,11 +483,12 @@
} }
if (ret_arr.length === 0) { if (ret_arr.length === 0) {
// XXX find schema more compatible with document // XXX find schema more compatible with document
return schema_arr[0]; return schema_arr;
} }
ret_arr[0].circular = circular;
return ret_arr;
} }
// XXX if (ret_arr.length > 1) notify user return schema_arr;
return ret_arr[0];
} }
function render_schema_selector(gadget, title, schema_arr, event, rerender) { function render_schema_selector(gadget, title, schema_arr, event, rerender) {
...@@ -455,7 +532,8 @@ ...@@ -455,7 +532,8 @@
description = schema_item.title; description = schema_item.title;
if (schema_item.schema === true || if (schema_item.schema === true ||
!(schema_item.schema.hasOwnProperty('type') || !(schema_item.schema.hasOwnProperty('type') ||
schema_item.schema.hasOwnProperty('enum'))) { schema_item.schema.hasOwnProperty('enum') ||
schema_item.schema.hasOwnProperty('const'))) {
generateItemsForAny(schema_item.property_name, schema_item.schema_path); generateItemsForAny(schema_item.property_name, schema_item.schema_path);
} else if (getDocumentType(schema_item.schema.type) === "array") { } else if (getDocumentType(schema_item.schema.type) === "array") {
description = description || schema_item.schema.description; description = description || schema_item.schema.description;
...@@ -658,7 +736,6 @@ ...@@ -658,7 +736,6 @@
.push(function (arr) { .push(function (arr) {
var queue = RSVP.Queue(), var queue = RSVP.Queue(),
i, i,
schema_path_item = schema_path + '/items',
schema_arr_arr = arr[0], schema_arr_arr = arr[0],
additionalItems = arr[1], additionalItems = arr[1],
schema_arr = schema_arr_arr, schema_arr = schema_arr_arr,
...@@ -669,10 +746,8 @@ ...@@ -669,10 +746,8 @@
if (is_items_arr) { if (is_items_arr) {
if (i < schema_arr_arr.length) { if (i < schema_arr_arr.length) {
schema_arr = schema_arr_arr[i]; schema_arr = schema_arr_arr[i];
schema_path_item = schema_path + '/items/' + i;
} else { } else {
schema_arr = additionalItems; schema_arr = additionalItems;
schema_path_item = schema_path + '/additionalItems';
} }
} }
queue queue
...@@ -680,9 +755,8 @@ ...@@ -680,9 +755,8 @@
addSubForm.bind(gadget, { addSubForm.bind(gadget, {
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
schema_path: schema_path_item, schema_arr: schema_arr,
schema_part: schema_arr, json_document: json_document[i],
default_dict: json_document[i],
required: i < minItems required: i < minItems
}) })
) )
...@@ -707,8 +781,7 @@ ...@@ -707,8 +781,7 @@
addSubForm.bind(gadget, { addSubForm.bind(gadget, {
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
schema_path: schema_arr[0].schema_path, schema_arr: schema_arr,
schema_part: schema_arr[0].schema,
required: true required: true
}) })
) )
...@@ -728,8 +801,8 @@ ...@@ -728,8 +801,8 @@
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
type: value.type, type: value.type,
schema_path: value.schema_path, selected_schema: value,
schema_part: value.schema schema_arr: schema_arr
}) })
.push(element_append); .push(element_append);
})); }));
...@@ -741,8 +814,7 @@ ...@@ -741,8 +814,7 @@
addSubForm.bind(gadget, { addSubForm.bind(gadget, {
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
schema_path: schema_arr[0].schema_path, schema_arr: schema_arr,
schema_part: schema_arr[0].schema,
required: true required: true
}) })
) )
...@@ -757,8 +829,8 @@ ...@@ -757,8 +829,8 @@
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
type: value.type, type: value.type,
schema_path: value.schema_path, selected_schema: value,
schema_part: value.schema schema_arr: schema_arr
}) })
.push(element_append); .push(element_append);
})); }));
...@@ -775,7 +847,7 @@ ...@@ -775,7 +847,7 @@
}); });
} }
function render_field(gadget, key, path, json_field, default_value, root, schema_path, options) { function render_field(gadget, property_name, path, schema_arr, json_document, root, options) {
var type, var type,
div, div,
delete_button, delete_button,
...@@ -785,64 +857,76 @@ ...@@ -785,64 +857,76 @@
span_info, span_info,
error_message, error_message,
input, input,
schema,
schema_path,
schema_ob,
first_path, first_path,
type_changed, type_changed,
queue = RSVP.Queue(); queue = RSVP.Queue();
if (json_field instanceof Array) { if (options.selected_schema) {
json_field = schemaArrFilteredByDocument(json_field, default_value); schema_ob = options.selected_schema;
schema_path = json_field.schema_path; } else {
json_field = json_field.schema; // XXX if (ret_arr.length > 1) notify user
schema_ob = schemaArrFilteredByDocument(schema_arr, json_document)[0];
}
schema = schema_ob.schema;
schema_path = schema_ob.schema_path;
if (schema_path === '/') {
schema_path = '';
} }
options = options || {}; options = options || {};
type = options.type; type = options.type;
if (path && key) { if (path && property_name) {
first_path = path + encodeJsonPointer(key); first_path = path + encodeJsonPointer(property_name);
} else { } else {
first_path = ""; first_path = "";
} }
if (json_field === undefined) { if (schema === undefined) {
json_field = getDocumentSchema(default_value); schema = getDocumentSchema(json_document);
} }
if (getDocumentType(json_field.type) === "string") { if (getDocumentType(schema.type) === "string") {
type = json_field.type; type = schema.type;
} else if (type === undefined && } else if (type === undefined &&
default_value === undefined && json_document === undefined &&
getDocumentType(json_field.type) === "array") { getDocumentType(schema.type) === "array") {
type = json_field.type[0]; type = schema.type[0];
} }
if (["object", "array"].indexOf(type) >= 0 && if (["object", "array"].indexOf(type) >= 0 &&
!(path !== "" && default_value === undefined) && !(path !== "" && json_document === undefined) &&
getDocumentType(default_value) !== type) { getDocumentType(json_document) !== type) {
if (gadget.props.saveOrigValue) { if (gadget.props.saveOrigValue) {
// XXX is not useful for user // XXX is not useful for user
// only for tests // only for tests
json_field = { schema = {
const: default_value const: json_document
}; };
} else { } else {
gadget.props.changed = true; gadget.props.changed = true;
} }
} }
if (type === undefined && default_value !== undefined) { if (type === undefined && json_document !== undefined) {
type = getDocumentType(default_value); type = getDocumentType(json_document);
} }
if (typeof type === "string") { if (typeof type === "string") {
// it's only for simple types so we not use // it's only for simple types so we not use
// complex type detection // complex type detection
type_changed = default_value !== undefined && type_changed = json_document !== undefined &&
typeof default_value !== type; typeof json_document !== type;
} }
div = document.createElement("div"); div = document.createElement("div");
div.setAttribute("class", "jsonformfield ui-field-contain"); div.setAttribute("class", "jsonformfield ui-field-contain");
div.title = json_field.description; if (schema.description) {
// if (key && !first_path) { div.title = schema.description;
}
// if (property_name && !first_path) {
if (options.delete_button === true) { if (options.delete_button === true) {
delete_button = createElement("span", delete_button = createElement("span",
{"class": "ui-btn-icon-top ui-icon-trash-o"} {"class": "ui-btn-icon-top ui-icon-trash-o"}
...@@ -861,77 +945,78 @@ ...@@ -861,77 +945,78 @@
div.appendChild(delete_button); div.appendChild(delete_button);
} }
} }
if (false) {
// XXX;
label = document.createElement("input");
label.value = key;
gadget.props.property_name_edit = label;
} else {
label_text = [key, json_field.title]
.filter(function (v) { return v; })
.join(" ")
// use non-breaking hyphen
.replace(/-/g, "");
if (label_text) {
if (options.top) {
label = document.createElement("span");
label.textContent = label_text;
root.appendChild(label);
} else {
label = document.createElement("label");
label.textContent = label_text;
div.appendChild(label);
}
label_text = [property_name, schema_ob.title]
.filter(function (v) { return v; })
.join(" ")
// use non-breaking hyphen
.replace(/-/g, "");
if (property_name || options.top) {
if (options.top) {
label = document.createElement("span");
label.textContent = label_text;
root.appendChild(label);
} else {
label = document.createElement("label");
label.textContent = label_text;
div.appendChild(label);
} }
} }
div_input = document.createElement("div"); div_input = document.createElement("div");
div_input.setAttribute("id", gadget.element.getAttribute("data-gadget-scope") + first_path + '/'); div_input.setAttribute("id", gadget.element.getAttribute("data-gadget-scope") + first_path + '/');
div_input.setAttribute("class", "input"); div_input.setAttribute("class", "input");
if (json_field.const !== undefined) { // render input begin
input = render_const(gadget, json_field, default_value);
} else if (json_field.enum !== undefined) { if (!input && schema_arr[0].is_arr_of_const) {
input = render_enum(gadget, json_field, default_value); input = render_enum_with_title(gadget, schema_arr, json_document, options.selected_schema);
}
if (!input && schema.const !== undefined) {
input = render_const(gadget, schema, json_document);
}
if (!input && schema.enum !== undefined) {
input = render_enum(gadget, schema, json_document);
// XXX take in account existing type with enum // XXX take in account existing type with enum
type_changed = false; type_changed = false;
} }
if (!input && type === "null") { if (!input && type === "null") {
input = render_const(gadget, {const: null}, default_value); input = render_const(gadget, {const: null}, json_document);
} }
if (!input && type === "boolean") { if (!input && type === "boolean") {
input = render_boolean(gadget, json_field, default_value); input = render_boolean(gadget, schema, json_document);
} }
if (!input && ["string", "integer", "number", "null"].indexOf(type) >= 0) { if (!input && ["string", "integer", "number", "null"].indexOf(type) >= 0) {
if (json_field.contentMediaType === "text/plain") { if (schema.contentMediaType === "text/plain") {
input = render_textarea(default_value, "string"); input = render_textarea(json_document, "string");
} else { } else {
input = document.createElement("input"); input = document.createElement("input");
if (default_value !== undefined) { if (json_document !== undefined) {
if (typeof default_value === "object") { if (typeof json_document === "object") {
input.value = JSON.stringify(default_value); input.value = JSON.stringify(json_document);
} else { } else {
input.value = default_value; input.value = json_document;
} }
} }
if (type === "integer" || type === "number") { if (type === "integer" || type === "number") {
if (default_value === undefined && typeof json_field.default === "number") { if (json_document === undefined && typeof schema.default === "number") {
input.value = json_field.default; input.value = schema.default;
gadget.props.changed = true; gadget.props.changed = true;
} }
input.setAttribute("data-json-type", type); input.setAttribute("data-json-type", type);
if (default_value === undefined || default_value === null || if (json_document === undefined || json_document === null ||
typeof default_value === "number") { typeof json_document === "number") {
input.type = "number"; input.type = "number";
} }
if (type === "integer") { if (type === "integer") {
input.setAttribute("step", "1"); input.setAttribute("step", "1");
if (typeof default_value === "number" && if (typeof json_document === "number" &&
parseInt(default_value, 10) !== default_value) { parseInt(json_document, 10) !== json_document) {
// original json_document contain float schema // original json_document contain float schema
// limit integer we can save original document // limit integer we can save original document
type_changed = true; type_changed = true;
...@@ -940,16 +1025,36 @@ ...@@ -940,16 +1025,36 @@
if (type === "number") { if (type === "number") {
input.setAttribute("step", "any"); input.setAttribute("step", "any");
} }
if (schema.multipleOf && schema.multipleOf >= 0) {
input.step = schema.multipleOf;
}
if (schema.minimum &&
// step work from min value so we can't
// use min if min not multipleOf step
!(schema.multipleOf &&
(schema.minimum % schema.multipleOf) !== 0)) {
input.min = schema.minimum;
}
if (schema.maximum) {
input.max = schema.maximum;
}
} else { } else {
if (default_value === undefined && typeof json_field.default === "string") { if (json_document === undefined && typeof schema.default === "string") {
input.value = json_field.default; input.value = schema.default;
gadget.props.changed = true; gadget.props.changed = true;
} }
input.type = "text"; input.type = "text";
if (json_field.pattern) { if (schema.pattern) {
input.pattern = json_field.pattern; input.pattern = schema.pattern;
} else if (schema.minLength) {
// minLength absent in html5 so
// use pattern for this task
input.pattern = ".{" + schema.minLength + ",}";
}
if (schema.maxLength) {
input.maxLength = schema.maxLength;
} }
if (json_field.format === 'uri') { if (schema.format === 'uri') {
input.type = "url"; input.type = "url";
input.spellcheck = false; input.spellcheck = false;
} }
...@@ -960,8 +1065,8 @@ ...@@ -960,8 +1065,8 @@
if (!input && type === "array") { if (!input && type === "array") {
queue = render_array( queue = render_array(
gadget, gadget,
json_field, schema,
default_value, json_document,
div_input, div_input,
first_path + '/', first_path + '/',
schema_path schema_path
...@@ -973,8 +1078,8 @@ ...@@ -973,8 +1078,8 @@
.push(function () { .push(function () {
return render_object( return render_object(
gadget, gadget,
json_field, schema,
default_value, json_document,
div_input, div_input,
first_path + '/', first_path + '/',
schema_path schema_path
...@@ -989,7 +1094,7 @@ ...@@ -989,7 +1094,7 @@
input.name = first_path; input.name = first_path;
input.required = options.required; input.required = options.required;
if (type_changed) { if (type_changed) {
input.setAttribute('data-origin-value', JSON.stringify(default_value)); input.setAttribute('data-origin-value', JSON.stringify(json_document));
} }
// XXX for gui // XXX for gui
//input.setAttribute("class", "slapos-parameter"); //input.setAttribute("class", "slapos-parameter");
...@@ -999,9 +1104,11 @@ ...@@ -999,9 +1104,11 @@
div.setAttribute("data-json-type", type); div.setAttribute("data-json-type", type);
} }
if (json_field.info !== undefined) { // render input end
if (schema.info !== undefined) {
span_info = document.createElement("span"); span_info = document.createElement("span");
span_info.textContent = json_field.info; span_info.textContent = schema.info;
div_input.appendChild(span_info); div_input.appendChild(span_info);
} }
error_message = document.createElement("span"); error_message = document.createElement("span");
...@@ -1024,7 +1131,7 @@ ...@@ -1024,7 +1131,7 @@
div = document.createElement("div"); div = document.createElement("div");
div.setAttribute("class", "jsonformfield"); div.setAttribute("class", "jsonformfield");
// div.title = json_field.description; // div.title = schema.description;
div_input = document.createElement("div"); div_input = document.createElement("div");
div_input.setAttribute("class", "input"); div_input.setAttribute("class", "input");
...@@ -1047,9 +1154,8 @@ ...@@ -1047,9 +1154,8 @@
gadget: g, gadget: g,
property_name: property_name, property_name: property_name,
path: path, path: path,
schema_path: schema_path, schema_arr: schema_arr,
schema_part: schema_arr, json_document: json_document[property_name]
default_dict: json_document[property_name]
}) })
) )
.push(element_append); .push(element_append);
...@@ -1062,8 +1168,7 @@ ...@@ -1062,8 +1168,7 @@
element: input, element: input,
path: path, path: path,
type: value.type, type: value.type,
schema_path: value.schema_path, schema_arr: [value]
schema_part: value.schema
}) })
.push(element_append); .push(element_append);
}); });
...@@ -1197,9 +1302,9 @@ ...@@ -1197,9 +1302,9 @@
return true; return true;
} }
render_object = function (g, json_field, default_dict, root, path, schema_path) { render_object = function (g, schema, json_document, root, path, schema_path) {
var required = json_field.required || [], var required = schema.required || [],
schema_editor = checkSchemaIsMetaSchema(json_field), schema_editor = checkSchemaIsMetaSchema(schema),
used_properties = {}, used_properties = {},
properties, properties,
selector = {}; selector = {};
...@@ -1217,57 +1322,56 @@ ...@@ -1217,57 +1322,56 @@
root.appendChild(child); root.appendChild(child);
} }
if (default_dict === undefined) { if (json_document === undefined) {
if (json_field.hasOwnProperty('default')) { if (schema.hasOwnProperty('default')) {
default_dict = json_field.default; json_document = schema.default;
g.props.changed = true; g.props.changed = true;
} else { } else {
default_dict = {}; json_document = {};
} }
} }
return expandProperties(g, json_field.properties, schema_path + '/properties/', required) return expandProperties(g, schema.properties, schema_path + '/properties/', required)
.push(function (ret) { .push(function (ret) {
var schema_arr, var schema_arr,
q = RSVP.Queue(), q = RSVP.Queue(),
s_o, filtered_schema_arr,
key; key;
properties = ret; properties = ret;
for (key in properties) { for (key in properties) {
if (properties.hasOwnProperty(key)) { if (properties.hasOwnProperty(key)) {
schema_arr = properties[key]; schema_arr = properties[key];
s_o = schemaArrFilteredByDocument(schema_arr, default_dict[key]); filtered_schema_arr = schemaArrFilteredByDocument(schema_arr, json_document[key]);
// XXX need schema merge with patternProperties passed key // XXX need schema merge with patternProperties passed key
if (checkSchemaArrOneChoise(schema_arr)) { if (checkSchemaArrOneChoise(schema_arr)) {
if (required.indexOf(key) >= 0) { if (required.indexOf(key) >= 0) {
used_properties[key] = false; used_properties[key] = false;
q.push(render_field.bind(g, g, key, path, q.push(render_field.bind(g, g, key, path,
s_o.schema, default_dict[key], root, s_o.schema_path, {required: true}) filtered_schema_arr, json_document[key], root, {required: true})
); );
} }
if (!used_properties.hasOwnProperty(key) && if (!used_properties.hasOwnProperty(key) &&
!schema_editor && !schema_editor &&
(checkSchemaSimpleType(s_o.schema) || !s_o.circular) (checkSchemaSimpleType(filtered_schema_arr) || !filtered_schema_arr[0].circular)
) { ) {
used_properties[key] = false; used_properties[key] = false;
q.push(render_field.bind(g, g, key, path, q.push(render_field.bind(g, g, key, path,
s_o.schema, default_dict[key], root, s_o.schema_path, { filtered_schema_arr, json_document[key], root, {
required: false, required: false,
delete_button: false delete_button: false
})); }));
} }
} }
if (!used_properties.hasOwnProperty(key) && if (!used_properties.hasOwnProperty(key) &&
default_dict.hasOwnProperty(key)) { json_document.hasOwnProperty(key)) {
used_properties[key] = ""; used_properties[key] = "";
q.push( q.push(
addSubForm.bind(g, { addSubForm.bind(g, {
gadget: g, gadget: g,
property_name: key, property_name: key,
path: path, path: path,
schema_path: s_o.schema_path, schema_arr: filtered_schema_arr,
schema_part: s_o.schema, json_document: json_document[key]
default_dict: default_dict[key]
}) })
) )
.push(root_append); .push(root_append);
...@@ -1285,8 +1389,7 @@ ...@@ -1285,8 +1389,7 @@
property_name: value.property_name, property_name: value.property_name,
path: path, path: path,
type: value.type, type: value.type,
schema_path: value.schema_path, schema_arr: [value]
schema_part: value.schema
}) })
.push(function (element) { .push(function (element) {
var s_e = selector.element; var s_e = selector.element;
...@@ -1333,9 +1436,9 @@ ...@@ -1333,9 +1436,9 @@
// XXX for pattern properties needs schemas merge for // XXX for pattern properties needs schemas merge for
// all passed patterns // all passed patterns
if (json_field.patternProperties !== undefined) { if (schema.patternProperties !== undefined) {
for (key in json_field.patternProperties) { for (key in schema.patternProperties) {
if (json_field.patternProperties.hasOwnProperty(key)) { if (schema.patternProperties.hasOwnProperty(key)) {
if (key === ".*" || if (key === ".*" ||
key === "^.*$" || key === "^.*$" ||
key === ".*$" || key === ".*$" ||
...@@ -1348,23 +1451,23 @@ ...@@ -1348,23 +1451,23 @@
.push(render_object_additionalProperty.bind(g, .push(render_object_additionalProperty.bind(g,
g, g,
key + " property", key + " property",
default_dict, json_document,
path, path,
json_field.patternProperties[key], schema.patternProperties[key],
schema_path + '/patternProperties/' + key, schema_path + '/patternProperties/' + key,
used_properties, used_properties,
element_append element_append
)) ))
.push(root_append); .push(root_append);
} }
} }
} }
if (additionalProperties === undefined) { if (additionalProperties === undefined) {
if (json_field.additionalProperties === undefined) { if (schema.additionalProperties === undefined) {
additionalProperties = true; additionalProperties = true;
} else { } else {
additionalProperties = json_field.additionalProperties; additionalProperties = schema.additionalProperties;
} }
} }
if (additionalProperties !== false) { if (additionalProperties !== false) {
...@@ -1372,7 +1475,7 @@ ...@@ -1372,7 +1475,7 @@
.push(render_object_additionalProperty.bind(g, .push(render_object_additionalProperty.bind(g,
g, g,
"additional property", "additional property",
default_dict, json_document,
path, path,
additionalProperties, additionalProperties,
schema_path + '/additionalProperties', schema_path + '/additionalProperties',
...@@ -1387,8 +1490,8 @@ ...@@ -1387,8 +1490,8 @@
.push(function () { .push(function () {
var key, var key,
queue = RSVP.Queue(); queue = RSVP.Queue();
for (key in default_dict) { for (key in json_document) {
if (default_dict.hasOwnProperty(key)) { if (json_document.hasOwnProperty(key)) {
if (!used_properties.hasOwnProperty(key)) { if (!used_properties.hasOwnProperty(key)) {
queue queue
.push( .push(
...@@ -1396,9 +1499,11 @@ ...@@ -1396,9 +1499,11 @@
gadget: g, gadget: g,
property_name: key, property_name: key,
path: path, path: path,
schema_path: "", schema_arr: [{
schema_part: undefined, schema: undefined,
default_dict: default_dict[key] schema_path: ""
}],
json_document: json_document[key]
}) })
) )
.push(root_append); .push(root_append);
...@@ -1583,42 +1688,6 @@ ...@@ -1583,42 +1688,6 @@
g.options = {}; g.options = {};
}) })
.declareAcquiredMethod("rootNotifyChange", "rootNotifyChange") .declareAcquiredMethod("rootNotifyChange", "rootNotifyChange")
.declareAcquiredMethod("renameChildrenParent", "renameChildren")
.allowPublicAcquisition("renameChildren", function (opt_arr, scope) {
var property_name,
objects = this.props.objects,
new_name = opt_arr[0],
element = getSubGadgetElement(this, scope),
parent = element.getAttribute('data-json-parent');
if (objects.hasOwnProperty(parent)) {
parent = objects[parent];
if (parent.hasOwnProperty(new_name)) {
throw new Error("property already exist");
}
// XXX validate property if property pattern
for (property_name in parent) {
if (parent.hasOwnProperty(property_name) && parent[property_name] === scope) {
delete parent[property_name];
parent[new_name] = scope;
return new_name;
}
}
throw new Error("gadget not found for renaming");
}
})
.declareMethod("rename", function (new_name, event) {
var g = this,
name = g.element.getAttribute('data-json-property-name');
return this.renameChildrenParent(new_name)
.push(function () {
return g.element.setAttribute('data-json-property-name', new_name);
})
.push(undefined, function () {
// XXX notify user
event.srcElement.value = name;
event.srcElement.focus();
});
})
.declareAcquiredMethod("selfRemove", "deleteChildren") .declareAcquiredMethod("selfRemove", "deleteChildren")
.allowPublicAcquisition("deleteChildren", function (arr, scope) { .allowPublicAcquisition("deleteChildren", function (arr, scope) {
var g = this, var g = this,
...@@ -1750,7 +1819,7 @@ ...@@ -1750,7 +1819,7 @@
.declareMethod('renderForm', function (options) { .declareMethod('renderForm', function (options) {
var g = this, var g = this,
property_name = g.element.getAttribute('data-json-property-name'), property_name = g.element.getAttribute('data-json-property-name'),
schema = options.schema, schema = options.schema_arr !== undefined && options.schema_arr[0].schema,
root; root;
g.props.changed = false; g.props.changed = false;
g.props.saveOrigValue = options.saveOrigValue; g.props.saveOrigValue = options.saveOrigValue;
...@@ -1787,10 +1856,11 @@ ...@@ -1787,10 +1856,11 @@
g.props.updatePropertySelectors = true; g.props.updatePropertySelectors = true;
g.props.current_document = options.document; g.props.current_document = options.document;
} }
return render_field(g, property_name, "", schema, return render_field(g, property_name, "", options.schema_arr,
options.document, root, options.schema_path, options.document, root,
{ {
type: options.type, type: options.type,
selected_schema: options.selected_schema,
required: options.required, required: options.required,
delete_button: options.delete_button, delete_button: options.delete_button,
top: options.top top: options.top
...@@ -1840,10 +1910,6 @@ ...@@ -1840,10 +1910,6 @@
}) })
.onEvent('input', function (evt) { .onEvent('input', function (evt) {
if (evt.target === this.props.property_name_edit) {
return this.rename(this.props.property_name_edit.value, evt);
}
var gadget = this, var gadget = this,
field_list = this.props.inputs, field_list = this.props.inputs,
i, i,
......
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