added "export as JSON" capability

pull/89/head
jmoenig 2019-01-09 16:51:36 +01:00
rodzic 56c5971aae
commit dab03fac5d
3 zmienionych plików z 86 dodań i 1 usunięć

Wyświetl plik

@ -6,7 +6,8 @@
* Store: tweaked format for serializing atomic data lists
* Morphic: added option to include alpha in color comparison
* Objects: fixed "set pen color (color picker)" to observe, i.e. overwrite transparency
* Lists, Threads, Objects: added (Bernat's) JSON parser to SPLIT block
* Lists, Threads, Objects: added (Bernat's) JSON parser to SPLIT block
* Lists, Objects: added "export as JSON" capability
### 2019-01-08
* Objects: automatically parse csv files on import, experimental "raw data" and "parse" ops

Wyświetl plik

@ -443,6 +443,50 @@ List.prototype.asCSV = function () {
return items.map(encodeCell).join(',');
};
List.prototype.asJSON = function (guessObjects) {
// Caution, no error catching!
// this method assumes that the list.canBeJSON()
function objectify(list, guessObjects) {
var items = list.itemsArray(),
obj = {};
if (canBeObject(items)) {
items.forEach(function (pair) {
var value = pair.length() === 2 ? pair.at(2) : undefined;
obj[pair.at(1)] = (value instanceof List ?
objectify(value, guessObjects) : value);
});
return obj;
}
return items.map(function (element) {
return element instanceof List ?
objectify(element, guessObjects) : element;
});
}
function canBeObject(array) {
// try to determine whether the contents of a list
// might be better represented as dictionary/object
// than as array
var keys;
if (array.every(function (element) {
return element instanceof List && (element.length() < 3);
})) {
keys = array.map(function (each) {return each.at(1); });
return keys.every(function (each) {
return isString(each) &&
isUniqueIn(each, keys);
});
}
}
function isUniqueIn(element, array) {
return array.indexOf(element) === array.lastIndexOf(element);
}
return JSON.stringify(objectify(this, guessObjects));
};
// List testing
List.prototype.equalTo = function (other) {
@ -501,6 +545,16 @@ List.prototype.canBeCSV = function () {
});
};
List.prototype.canBeJSON = function () {
return this.itemsArray().every(function (value) {
return !isNaN(+value) ||
isString(value) ||
value === true ||
value === false ||
(value instanceof List && value.canBeJSON);
});
};
List.prototype.hasOnlyAtomicData = function () {
return this.itemsArray().every(function (value) {
return !isNaN(+value) ||

Wyświetl plik

@ -9538,6 +9538,36 @@ WatcherMorph.prototype.userMenu = function () {
'do not attempt to\nparse or format data',
new Color(100, 0, 0)
);
if (this.currentValue instanceof List &&
this.currentValue.canBeCSV()) {
menu.addItem(
'export as CSV...',
function () {
var ide = myself.parentThatIsA(IDE_Morph);
ide.saveFileAs(
myself.currentValue.asCSV(),
'text/csv;charset=utf-8', // RFC 4180
myself.getter // variable name
);
}
);
}
if (this.currentValue instanceof List &&
this.currentValue.canBeJSON()) {
menu.addItem(
'export as JSON...',
function () {
var ide = myself.parentThatIsA(IDE_Morph);
ide.saveFileAs(
myself.currentValue.asJSON(true), // guess objects
'text/json;charset=utf-8',
myself.getter // variable name
);
},
null,
new Color(100, 0, 0)
);
}
}
if (isString(this.currentValue) || !isNaN(+this.currentValue)) {
if (shiftClicked) {