Skip to content

Commit

Permalink
towards v4.0.6
Browse files Browse the repository at this point in the history
* fixed #99 (saving linked lists)
* fixed #1163
* added web api / https reporter library
* new “transient variable” feature
* German translation update
  • Loading branch information
jmoenig committed Mar 16, 2016
1 parent 2cbee48 commit bbb5106
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 39 deletions.
36 changes: 34 additions & 2 deletions blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ BlockEditorMorph, localize, isNil*/

// Global stuff ////////////////////////////////////////////////////////

modules.blocks = '2016-February-24';
modules.blocks = '2016-March-16';

var SyntaxElementMorph;
var BlockMorph;
Expand Down Expand Up @@ -2216,6 +2216,16 @@ BlockMorph.prototype.userMenu = function () {
top,
blck;

function addOption(label, toggle, test, onHint, offHint) {
var on = '\u2611 ',
off = '\u2610 ';
menu.addItem(
(test ? on : off) + localize(label),
toggle,
test ? onHint : offHint
);
}

menu.addItem(
"help...",
'showHelp'
Expand All @@ -2236,7 +2246,15 @@ BlockMorph.prototype.userMenu = function () {
}
if (this.isTemplate) {
if (!(this.parent instanceof SyntaxElementMorph)) {
if (this.selector !== 'evaluateCustomBlock') {
if (this.selector === 'reportGetVar') {
addOption(
'transient',
'toggleTransientVariable',
myself.isTransientVariable(),
'uncheck to save contents\nin the project',
'check to prevent contents\nfrom being saved'
);
} else if (this.selector !== 'evaluateCustomBlock') {
menu.addItem(
"hide",
'hidePrimitive'
Expand Down Expand Up @@ -2430,6 +2448,20 @@ BlockMorph.prototype.hidePrimitive = function () {
ide.refreshPalette();
};

BlockMorph.prototype.isTransientVariable = function () {
// private - only for variable getter template inside the palette
var varFrame = this.receiver().variables.silentFind(this.blockSpec);
return varFrame ? varFrame.vars[this.blockSpec].isTransient : false;
};

BlockMorph.prototype.toggleTransientVariable = function () {
// private - only for variable getter template inside the palette
var varFrame = this.receiver().variables.silentFind(this.blockSpec);
if (!varFrame) {return; }
varFrame.vars[this.blockSpec].isTransient =
!(varFrame.vars[this.blockSpec].isTransient);
};

BlockMorph.prototype.deleteBlock = function () {
// delete just this one block, keep inputs and next block around
var scripts = this.parentThatIsA(ScriptsMorph),
Expand Down
18 changes: 16 additions & 2 deletions gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph*/

// Global stuff ////////////////////////////////////////////////////////

modules.gui = '2016-February-24';
modules.gui = '2016-March-16';

// Declarations

Expand Down Expand Up @@ -2524,6 +2524,17 @@ IDE_Morph.prototype.settingsMenu = function () {
'check for sprite\ninheritance features',
false
);
addPreference(
'Persist linked sublist IDs',
function () {
StageMorph.prototype.enableSublistIDs =
!StageMorph.prototype.enableSublistIDs;
},
StageMorph.prototype.enableSublistIDs,
'uncheck to disable\nsaving linked sublist identities',
'check to enable\nsaving linked sublist identities',
true
);
menu.popup(world, pos);
};

Expand Down Expand Up @@ -2796,7 +2807,7 @@ IDE_Morph.prototype.aboutSnap = function () {
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
world = this.world();

aboutTxt = 'Snap! 4.0.5\nBuild Your Own Blocks\n\n'
aboutTxt = 'Snap! 4.0.6\nBuild Your Own Blocks\n\n'
+ 'Copyright \u24B8 2016 Jens M\u00F6nig and '
+ 'Brian Harvey\n'
+ '[email protected], [email protected]\n\n'
Expand Down Expand Up @@ -3014,6 +3025,7 @@ IDE_Morph.prototype.newProject = function () {
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
SpriteMorph.prototype.useFlatLineEnds = false;
this.setProjectName('');
this.projectNotes = '';
Expand Down Expand Up @@ -3521,6 +3533,7 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) {
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
if (Process.prototype.isCatchingErrors) {
try {
this.serializer.openProject(
Expand Down Expand Up @@ -3564,6 +3577,7 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) {
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
if (Process.prototype.isCatchingErrors) {
try {
model = this.serializer.parse(str);
Expand Down
8 changes: 8 additions & 0 deletions history.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2874,3 +2874,11 @@ end - bulk of 151215
160306
------
* Objects: Reenable custom hat blocks when dropping a sprite

160316
------
* Store, Objects, GUI: fixed #99 (saving linked lists)
* Objects: fixed #1163
* added web api / https reporter library
* Blocks, Store: New “transient variable” feature
* German translation update
8 changes: 7 additions & 1 deletion lang-de.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'[email protected]', // optional
'last_changed':
'2016-02-24', // this, too, will appear in the Translators tab
'2016-03-16', // this, too, will appear in the Translators tab

// GUI
// control bar:
Expand Down Expand Up @@ -881,6 +881,12 @@ SnapTranslator.dict.de = {
'Umringen',
'unringify':
'Entringen',
'transient':
'nicht persistent',
'uncheck to save contents\nin the project':
'ausschalten, um den Inhalt\nim Projekt zu speichern',
'check to prevent contents\nfrom being saved':
'einschalten, um das Speichern des Inhalts\nim Projekt zu verhindern',

// custom blocks:
'delete block definition...':
Expand Down
1 change: 1 addition & 0 deletions libraries/LIBRARIES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ iteration-composition.xml Iteration, composition
list-utilities.xml List utilities
stream-tools.xml Streams (lazy lists)
variadic-reporters.xml Variadic reporters
httpBlocks.xml Web services access (https)

This comment has been minimized.

Copy link
@bromagosa

bromagosa Mar 16, 2016

Collaborator

Yay! We're getting there!

word-sentence.xml Words, sentences
cases.xml Multi-branched conditional (switch)
leap-library.xml LEAP Motion controller
Expand Down
4 changes: 4 additions & 0 deletions libraries/httpBlocks.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="%&apos;method&apos; url: %&apos;url&apos; send: %&apos;payload&apos; headers: %&apos;headers&apos;" type="reporter" category="sensing"><header></header><code></code><inputs><input type="%s" readonly="true">GET<options>GET
POST
PUT
DELETE</options></input><input type="%s">http://snap.berkeley.edu</input><input type="%s"></input><input type="%mult%l" readonly="true"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>method</l><l>url</l><l>data</l><l>headers</l><l>proc</l></list><l>var response, i, header;&#xD;if (!proc.httpRequest) {&#xD; proc.httpRequest = new XMLHttpRequest();&#xD; proc.httpRequest.open(method, url, true);&#xD; proc.assertType(headers, &apos;list&apos;);&#xD; for (i = 1; i &lt;= headers.length(); i += 1) {&#xD; header = headers.at(i);&#xD; proc.assertType(header, &apos;list&apos;);&#xD; proc.httpRequest.setRequestHeader(&#xD; header.at(1),&#xD; header.at(2)&#xD; );&#xD; }&#xD; proc.httpRequest.send(data || null);&#xD;} else if (proc.httpRequest.readyState === 4) {&#xD; response = proc.httpRequest.responseText;&#xD; proc.httpRequest = null;&#xD; return response;&#xD;}&#xD;proc.pushContext(&apos;doYield&apos;);&#xD;proc.pushContext();</l></block><list><block var="method"/><block var="url"/><block var="payload"/><block var="headers"/></list></block></block></script></block-definition><block-definition s="key: %&apos;key&apos; value: %&apos;value&apos;" type="reporter" category="operators"><header></header><code></code><inputs><input type="%s"></input><input type="%s"></input></inputs><script><block s="doReport"><block s="reportNewList"><list><block var="key"/><block var="value"/></list></block></block></script></block-definition></blocks>
4 changes: 2 additions & 2 deletions locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

/*global modules, contains*/

modules.locale = '2016-February-24';
modules.locale = '2016-March-16';

// Global stuff

Expand Down Expand Up @@ -161,7 +161,7 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'[email protected]',
'last_changed':
'2016-02-24'
'2016-03-16'
};

SnapTranslator.dict.it = {
Expand Down
5 changes: 3 additions & 2 deletions objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
TableMorph, TableFrameMorph*/

modules.objects = '2016-March-06';
modules.objects = '2016-March-16';

var SpriteMorph;
var StageMorph;
Expand Down Expand Up @@ -2423,7 +2423,7 @@ SpriteMorph.prototype.blocksMatching = function (

// variable getters
varNames.forEach(function (vName) {
var rel = relevance(labelOf(vName), search);
var rel = relevance(labelOf(vName.toLowerCase()), search);
if (rel !== -1) {
blocks.push([myself.variableBlock(vName), rel + '1']);
}
Expand Down Expand Up @@ -4726,6 +4726,7 @@ StageMorph.prototype.codeMappings = {};
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;

// StageMorph instance creation

Expand Down
90 changes: 64 additions & 26 deletions store.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ SyntaxElementMorph, Variable*/

// Global stuff ////////////////////////////////////////////////////////

modules.store = '2016-February-24';
modules.store = '2016-March-16';


// XML_Serializer ///////////////////////////////////////////////////////
Expand Down Expand Up @@ -414,6 +414,8 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
model.stage.attributes.codify === 'true';
StageMorph.prototype.enableInheritance =
model.stage.attributes.inheritance === 'true';
StageMorph.prototype.enableSublistIDs =
model.stage.attributes.sublistIDs === 'true';

model.hiddenPrimitives = model.project.childNamed('hidden');
if (model.hiddenPrimitives) {
Expand Down Expand Up @@ -773,13 +775,15 @@ SnapSerializer.prototype.loadVariables = function (varFrame, element) {
var myself = this;

element.children.forEach(function (child) {
var value;
var v, value;
if (child.tag !== 'variable') {
return;
}
value = child.children[0];
varFrame.vars[child.attributes.name] = new Variable(value ?
myself.loadValue(value) : 0);
v = new Variable();
v.isTransient = (child.attributes.transient === 'true');
v.value = (v.isTransient || !value ) ? 0 : myself.loadValue(value);
varFrame.vars[child.attributes.name] = v;
});
};

Expand Down Expand Up @@ -1121,7 +1125,7 @@ SnapSerializer.prototype.loadInput = function (model, input, block) {

SnapSerializer.prototype.loadValue = function (model) {
// private
var v, items, el, center, image, name, audio, option,
var v, lst, items, el, center, image, name, audio, option,
myself = this;

function record() {
Expand Down Expand Up @@ -1157,28 +1161,29 @@ SnapSerializer.prototype.loadValue = function (model) {
return model.contents === 'true';
case 'list':
if (model.attributes.hasOwnProperty('linked')) {
v = new List();
v.isLinked = true;
record();
lst = v;
items = model.childrenNamed('item');
if (items.length === 0) {
v = new List();
record();
return v;
}
items.forEach(function (item) {
var value = item.children[0];
if (v === undefined) {
v = new List();
record();
} else {
v = v.rest = new List();
}
v.isLinked = true;
if (!value) {
v.first = 0;
} else {
v.first = myself.loadValue(value);
}
var tail = model.childNamed('list') ||
model.childNamed('ref');
if (tail) {
v.rest = myself.loadValue(tail);
} else {
v.rest = new List();
v = v.rest;
v.isLinked = true;
}
});
return v;
return lst;
}
v = new List();
record();
Expand Down Expand Up @@ -1446,6 +1451,7 @@ StageMorph.prototype.toXML = function (serializer) {
'lines="@" ' +
'codify="@" ' +
'inheritance="@" ' +
'sublistIDs="@" ' +
'scheduled="@" ~>' +
'<pentrails>$</pentrails>' +
'<costumes>%</costumes>' +
Expand Down Expand Up @@ -1474,6 +1480,7 @@ StageMorph.prototype.toXML = function (serializer) {
SpriteMorph.prototype.useFlatLineEnds ? 'flat' : 'round',
this.enableCodeMapping,
this.enableInheritance,
this.enableSublistIDs,
StageMorph.prototype.frameRate !== 0,
this.trailsCanvas.toDataURL('image/png'),
serializer.store(this.costumes, this.name + '_cst'),
Expand Down Expand Up @@ -1587,7 +1594,12 @@ VariableFrame.prototype.toXML = function (serializer) {
return Object.keys(this.vars).reduce(function (vars, v) {
var val = myself.vars[v].value,
dta;
if (val === undefined || val === null) {
if (myself.vars[v].isTransient) {
dta = serializer.format(
'<variable name="@" transient="true"/>',
v)
;
} else if (val === undefined || val === null) {
dta = serializer.format('<variable name="@"/>', v);
} else {
dta = serializer.format(
Expand Down Expand Up @@ -1875,19 +1887,46 @@ ColorSlotMorph.prototype.toXML = function (serializer) {
List.prototype.toXML = function (serializer, mediaContext) {
// mediaContext is an optional name-stub
// when collecting media into a separate module
var xml, item;
var xml, value, item;
if (this.isLinked) {
xml = '<list linked="linked" ~>';
if (StageMorph.prototype.enableSublistIDs) {
// recursively nest tails:
value = this.first;
if (!isNil(value)) {
xml += serializer.format(
'<item>%</item>',
typeof value === 'object' ?
serializer.store(value, mediaContext)
: typeof value === 'boolean' ?
serializer.format('<bool>$</bool>', value)
: serializer.format('<l>$</l>', value)
);
}
if (!isNil(this.rest)) {
xml += serializer.store(this.rest, mediaContext);
}
return xml + '</list>';
}
// else sequentially serialize tails:
item = this;
do {
xml += serializer.format(
'<item>%</item>',
serializer.store(item.first)
);
value = item.first;
if (!isNil(value)) {
xml += serializer.format(
'<item>%</item>',
typeof value === 'object' ?
serializer.store(value, mediaContext)
: typeof value === 'boolean' ?
serializer.format('<bool>$</bool>', value)
: serializer.format('<l>$</l>', value)
);
}
item = item.rest;
} while (item !== undefined && (item !== null));
} while (!isNil(item));
return xml + '</list>';
}
// dynamic array:
return serializer.format(
'<list ~>%</list>',
this.contents.reduce(function (xml, item) {
Expand All @@ -1903,7 +1942,6 @@ List.prototype.toXML = function (serializer, mediaContext) {
);
};


Context.prototype.toXML = function (serializer) {
if (this.isContinuation) { // continuations are transient in Snap!
return '';
Expand Down
Loading

4 comments on commit bbb5106

@towerofnix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are transient variables?

@jmoenig
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hang on, documentation is coming in a minute!
(transient variables' values don't get serialized and saved in the project)

@towerofnix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm excited.

Cool!

@jmoenig
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to get excited really, this is just a minor release with a bunch of bug fixes and a kludge declared feature :-), but thanks anyway!

Please sign in to comment.