kopia lustrzana https://github.com/backface/turtlestitch
added "export as JSON" capability
rodzic
56c5971aae
commit
dab03fac5d
|
@ -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
|
||||
|
|
54
src/lists.js
54
src/lists.js
|
@ -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) ||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Ładowanie…
Reference in New Issue