kopia lustrzana https://github.com/backface/turtlestitch
directly export and import lists as csv files, under construction
rodzic
8e7a9a4bef
commit
a681880965
|
@ -2,6 +2,9 @@
|
|||
|
||||
## in development
|
||||
|
||||
### 2019-01-07
|
||||
* Lists, Objects: directly export and import lists as csv files, under construction
|
||||
|
||||
### 2019-01-04
|
||||
* Objects, Blocks, Threads: new feature/block: sense colors and sprites anywhere
|
||||
* updated German translation
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
<script type="text/javascript" src="src/widgets.js?version=2018-10-02"></script>
|
||||
<script type="text/javascript" src="src/blocks.js?version=2019-01-04"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-01-04"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-01-04"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-01-07"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-01-02"></script>
|
||||
<script type="text/javascript" src="src/paint.js?version=2018-10-02"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2018-10-02"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-01-07"></script>
|
||||
<script type="text/javascript" src="src/byob.js?version=2018-11-12"></script>
|
||||
<script type="text/javascript" src="src/tables.js?version=2018-10-02"></script>
|
||||
<script type="text/javascript" src="src/symbols.js?version=2018-10-02"></script>
|
||||
|
|
89
src/lists.js
89
src/lists.js
|
@ -7,7 +7,7 @@
|
|||
written by Jens Mönig and Brian Harvey
|
||||
jens@moenig.org, bh@cs.berkeley.edu
|
||||
|
||||
Copyright (C) 2018 by Jens Mönig and Brian Harvey
|
||||
Copyright (C) 2019 by Jens Mönig and Brian Harvey
|
||||
|
||||
This file is part of Snap!.
|
||||
|
||||
|
@ -58,11 +58,11 @@
|
|||
|
||||
/*global modules, BoxMorph, HandleMorph, PushButtonMorph, SyntaxElementMorph,
|
||||
Color, Point, WatcherMorph, StringMorph, SpriteMorph, ScrollFrameMorph,
|
||||
CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize,
|
||||
CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize, isString,
|
||||
MorphicPreferences, TableDialogMorph, SpriteBubbleMorph, SpeechBubbleMorph,
|
||||
TableFrameMorph, TableMorph, Variable, isSnapObject*/
|
||||
|
||||
modules.lists = '2018-March-08';
|
||||
modules.lists = '2019-January-07';
|
||||
|
||||
var List;
|
||||
var ListWatcherMorph;
|
||||
|
@ -80,26 +80,28 @@ var ListWatcherMorph;
|
|||
|
||||
setters (linked):
|
||||
-----------------
|
||||
cons - answer a new list with the given item in front
|
||||
cdr - answer all but the first element
|
||||
cons - answer a new list with the given item in front
|
||||
cdr - answer all but the first element
|
||||
|
||||
setters (arrayed):
|
||||
------------------
|
||||
add(element, index) - insert the element before the given slot,
|
||||
put(element, index) - overwrite the element at the given slot
|
||||
remove(index) - remove the given slot, shortening the list
|
||||
clear() - remove all elements
|
||||
add(element, index) - insert the element before the given slot,
|
||||
put(element, index) - overwrite the element at the given slot
|
||||
remove(index) - remove the given slot, shortening the list
|
||||
clear() - remove all elements
|
||||
|
||||
getters (all hybrid):
|
||||
---------------------
|
||||
length() - number of slots
|
||||
at(index) - element present in specified slot
|
||||
contains(element) - <bool>
|
||||
length() - number of slots
|
||||
at(index) - element present in specified slot
|
||||
contains(element) - <bool>
|
||||
|
||||
conversion:
|
||||
-----------
|
||||
asArray() - answer me as JavaScript array
|
||||
asText() - answer my elements (recursively) concatenated
|
||||
asArray() - answer me as JavaScript array, convert to arrayed
|
||||
itemsArray() - answer a JavaScript array shallow copy of myself
|
||||
asText() - answer my elements (recursively) concatenated
|
||||
asCSV() - answer a csv-formatted String of myself
|
||||
*/
|
||||
|
||||
// List instance creation:
|
||||
|
@ -399,6 +401,46 @@ List.prototype.becomeLinked = function () {
|
|||
}
|
||||
};
|
||||
|
||||
List.prototype.asCSV = function () {
|
||||
// RFC 4180
|
||||
// Caution, no error catching!
|
||||
// this method assumes that the list.canBeCSV()
|
||||
|
||||
var items = this.itemsArray(),
|
||||
rows = [];
|
||||
|
||||
function encodeCell(atomicValue) {
|
||||
var string = atomicValue.toString(),
|
||||
cell;
|
||||
if (string.indexOf('\"') === -1 && (string.indexOf('\n') === -1)) {
|
||||
return string;
|
||||
}
|
||||
cell = ['\"'];
|
||||
string.split('').forEach(function (letter) {
|
||||
cell.push(letter);
|
||||
if (letter === '\"') {
|
||||
cell.push(letter);
|
||||
}
|
||||
});
|
||||
cell.push('\"');
|
||||
return cell.join('');
|
||||
}
|
||||
|
||||
if (items.some(function (any) {return any instanceof List; })) {
|
||||
// 2-dimensional table
|
||||
items.forEach(function (item) {
|
||||
if (item instanceof List) {
|
||||
rows.push(item.itemsArray().map(encodeCell).join(','));
|
||||
} else {
|
||||
rows.push(encodeCell(item));
|
||||
}
|
||||
});
|
||||
return rows.join('\n');
|
||||
}
|
||||
// single row
|
||||
return items.map(encodeCell).join(',');
|
||||
};
|
||||
|
||||
// List testing
|
||||
|
||||
List.prototype.equalTo = function (other) {
|
||||
|
@ -447,6 +489,25 @@ List.prototype.equalTo = function (other) {
|
|||
return true;
|
||||
};
|
||||
|
||||
List.prototype.canBeCSV = function () {
|
||||
return this.itemsArray().every(function (value) {
|
||||
return !isNaN(+value) ||
|
||||
isString(value) ||
|
||||
value === true ||
|
||||
value === false ||
|
||||
(value instanceof List && value.hasOnlyAtomicData);
|
||||
});
|
||||
};
|
||||
|
||||
List.prototype.hasOnlyAtomicData = function () {
|
||||
return this.itemsArray().every(function (value) {
|
||||
return !isNaN(+value) ||
|
||||
isString(value) ||
|
||||
value === true ||
|
||||
value === false;
|
||||
});
|
||||
};
|
||||
|
||||
// ListWatcherMorph ////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -83,7 +83,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
|||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph,
|
||||
AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/
|
||||
|
||||
modules.objects = '2019-January-04';
|
||||
modules.objects = '2019-January-07';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -9567,16 +9567,30 @@ WatcherMorph.prototype.userMenu = function () {
|
|||
function readText(aFile) {
|
||||
var frd = new FileReader();
|
||||
frd.onloadend = function (e) {
|
||||
myself.target.setVar(
|
||||
myself.getter,
|
||||
e.target.result
|
||||
);
|
||||
// +++ needs to be refactored
|
||||
if (aFile.type.indexOf("csv") ||
|
||||
aFile.name.split('.').pop()
|
||||
.toLowerCase() === 'csv') {
|
||||
// catch parsing errors
|
||||
myself.target.setVar(
|
||||
myself.getter,
|
||||
Process.prototype.parseCSV(
|
||||
e.target.result
|
||||
)
|
||||
);
|
||||
} else {
|
||||
myself.target.setVar(
|
||||
myself.getter,
|
||||
e.target.result
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (aFile.type.indexOf("text") === -1) {
|
||||
// special cases for Windows
|
||||
// check the file extension for text-like-ness
|
||||
if (contains(
|
||||
// +++ avoid doubling
|
||||
['txt', 'csv', 'xml', 'json', 'tsv'],
|
||||
aFile.name.split('.').pop().toLowerCase()
|
||||
)) {
|
||||
|
@ -9620,6 +9634,19 @@ WatcherMorph.prototype.userMenu = function () {
|
|||
);
|
||||
}
|
||||
);
|
||||
} else if (this.currentValue instanceof List &&
|
||||
this.currentValue.canBeCSV()) { // +++
|
||||
menu.addItem(
|
||||
'export...',
|
||||
function () {
|
||||
var ide = myself.parentThatIsA(IDE_Morph);
|
||||
ide.saveFileAs(
|
||||
myself.currentValue.asCSV(),
|
||||
'text/csv;charset=utf-8', // RFC 4180
|
||||
myself.getter // variable name
|
||||
);
|
||||
}
|
||||
);
|
||||
} else if (this.currentValue instanceof Context) {
|
||||
vNames = this.currentValue.outerContext.variables.names();
|
||||
if (vNames.length) {
|
||||
|
|
Ładowanie…
Reference in New Issue