فهرست منبع

signal processor, on{Click,Submit} implemented by it

Herbert Vojčík 11 سال پیش
والد
کامیت
09327dd984
4فایلهای تغییر یافته به همراه191 افزوده شده و 63 حذف شده
  1. 35 51
      js/Trapped-Demo.js
  2. 110 0
      js/Trapped-Frontend.js
  3. 7 12
      st/Trapped-Demo.st
  4. 39 0
      st/Trapped-Frontend.st

+ 35 - 51
js/Trapped-Demo.js

@@ -241,80 +241,65 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$12,$13,$14,$15,$11;
-[]._trapDescend_((function(snap){
-return smalltalk.withContext(function($ctx2) {
 _st(_st(html)._h2())._trap_([["title"]]);
-$ctx2.sendIdx["trap:"]=1;
+$ctx1.sendIdx["trap:"]=1;
 _st(_st(html)._div())._trapGuard_contents_([["todos"], ["notNil"]],(function(){
-return smalltalk.withContext(function($ctx3) {
+return smalltalk.withContext(function($ctx2) {
 $1=_st(html)._span();
-$ctx3.sendIdx["span"]=1;
+$ctx2.sendIdx["span"]=1;
 _st($1)._trap_([["remaining"]]);
-$ctx3.sendIdx["trap:"]=2;
+$ctx2.sendIdx["trap:"]=2;
 _st(html)._with_(" of ");
-$ctx3.sendIdx["with:"]=1;
+$ctx2.sendIdx["with:"]=1;
 $2=_st(html)._span();
-$ctx3.sendIdx["span"]=2;
+$ctx2.sendIdx["span"]=2;
 _st($2)._trap_([["todos"], ["size"]]);
-$ctx3.sendIdx["trap:"]=3;
+$ctx2.sendIdx["trap:"]=3;
 _st(html)._with_(" remaining [ ");
-$ctx3.sendIdx["with:"]=2;
+$ctx2.sendIdx["with:"]=2;
 $3=_st(html)._a();
 _st($3)._href_("");
-_st($3)._onClick_((function(){
-return smalltalk.withContext(function($ctx4) {
-_st(snap)._modify_((function(model){
-return smalltalk.withContext(function($ctx5) {
-return _st(model)._archive();
-}, function($ctx5) {$ctx5.fillBlock({model:model},$ctx4,4)})}));
-$ctx4.sendIdx["modify:"]=1;
-return false;
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3,3)})}));
+_st($3)._trap_processors_([],[["signal", "archive"], "whenClicked"]);
+$ctx2.sendIdx["trap:processors:"]=1;
 $4=_st($3)._with_("archive");
-$ctx3.sendIdx["with:"]=3;
+$ctx2.sendIdx["with:"]=3;
 $4;
 _st(html)._with_(" ]");
-$ctx3.sendIdx["with:"]=4;
+$ctx2.sendIdx["with:"]=4;
 _st(_st(html)._ul())._with_((function(){
-return smalltalk.withContext(function($ctx4) {
+return smalltalk.withContext(function($ctx3) {
 return _st(html)._trapIter_tag_do_([["todos"]],"li",(function(each){
-return smalltalk.withContext(function($ctx5) {
+return smalltalk.withContext(function($ctx4) {
 $5=_st(html)._root();
-$ctx5.sendIdx["root"]=1;
+$ctx4.sendIdx["root"]=1;
 _st($5)._empty();
 $6=_st(html)._input();
-$ctx5.sendIdx["input"]=1;
+$ctx4.sendIdx["input"]=1;
 _st($6)._type_("checkbox");
-$ctx5.sendIdx["type:"]=1;
+$ctx4.sendIdx["type:"]=1;
 $7=_st($6)._trap_processors_(["done"],["inputChecked"]);
-$ctx5.sendIdx["trap:processors:"]=1;
+$ctx4.sendIdx["trap:processors:"]=2;
 $7;
 $8=_st(html)._span();
 _st($8)._trap_read_(["done"],(function(model){
-return smalltalk.withContext(function($ctx6) {
+return smalltalk.withContext(function($ctx5) {
 return _st(_st(html)._root())._class_("done-".__comma(model));
-$ctx6.sendIdx["class:"]=1;
-}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx5,7)})}));
+$ctx5.sendIdx["class:"]=1;
+}, function($ctx5) {$ctx5.fillBlock({model:model},$ctx4,4)})}));
 $9=_st($8)._trap_(["text"]);
 return $9;
-}, function($ctx5) {$ctx5.fillBlock({each:each},$ctx4,6)})}));
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3,5)})}));
-$ctx3.sendIdx["with:"]=5;
+}, function($ctx4) {$ctx4.fillBlock({each:each},$ctx3,3)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+$ctx2.sendIdx["with:"]=5;
 $10=_st(html)._form();
-_st($10)._onSubmit_((function(){
-return smalltalk.withContext(function($ctx4) {
-_st(snap)._modify_((function(model){
-return smalltalk.withContext(function($ctx5) {
-return _st(model)._addTodo();
-}, function($ctx5) {$ctx5.fillBlock({model:model},$ctx4,9)})}));
-return false;
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3,8)})}));
+_st($10)._trap_processors_([],[["signal", "addTodo"], "whenSubmitted"]);
+$ctx2.sendIdx["trap:processors:"]=3;
 $11=_st($10)._with_((function(){
-return smalltalk.withContext(function($ctx4) {
+return smalltalk.withContext(function($ctx3) {
 $12=_st(html)._input();
-$ctx4.sendIdx["input"]=2;
+$ctx3.sendIdx["input"]=2;
 _st($12)._type_("text");
-$ctx4.sendIdx["type:"]=2;
+$ctx3.sendIdx["type:"]=2;
 _st($12)._trap_processors_([["todoText"]],["inputValue"]);
 _st($12)._at_put_("size",(30));
 $13=_st($12)._placeholder_("add new todo here");
@@ -324,16 +309,15 @@ _st($14)._class_("btn-primary");
 _st($14)._type_("submit");
 $15=_st($14)._value_("add");
 return $15;
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3,10)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,5)})}));
 return $11;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
-$ctx2.sendIdx["trapGuard:contents:"]=1;
-return _st(_st(html)._p())._trapGuard_contents_([["todos"], ["isNil"]],"Loading ...");
-}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1,1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["trapGuard:contents:"]=1;
+_st(_st(html)._p())._trapGuard_contents_([["todos"], ["isNil"]],"Loading ...");
 return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.AppView)})},
 args: ["html"],
-source: "renderOn: html\x0a    #() trapDescend: [ :snap |\x0a\x09html h2 trap: #((title)).\x0a    html div trapGuard: #((todos) (notNil)) contents: [\x0a        html span trap:#((remaining)).\x0a        html with: ' of '.\x0a        html span trap: #((todos) (size)).\x0a        html with: ' remaining [ '.\x0a        html a href:''; onClick: [\x0a            snap modify: [ :model | model archive ].\x0a            false\x0a        ]; with: 'archive'.\x0a        html with: ' ]'.\x0a        html ul with: [ html trapIter: #((todos)) tag: #li do: [ :each |\x0a            html root empty.\x0a            html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).\x0a            html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').\x0a        ]].\x0a        html form onSubmit: [\x0a            snap modify: [ :model | model addTodo ].\x0a            false\x0a        ]; with: [\x0a            html input type: 'text'; trap: #((todoText)) processors: #(inputValue); at: 'size' put: 30; placeholder: 'add new todo here'.\x0a            html input class: 'btn-primary'; type: 'submit'; value: 'add'.\x0a        ].\x0a    ].\x0a\x09html p trapGuard: #((todos) (isNil)) contents: 'Loading ...'.\x0a\x09]",
-messageSends: ["trapDescend:", "trap:", "h2", "trapGuard:contents:", "div", "span", "with:", "href:", "a", "onClick:", "modify:", "archive", "ul", "trapIter:tag:do:", "empty", "root", "type:", "input", "trap:processors:", "trap:read:", "class:", ",", "onSubmit:", "form", "addTodo", "at:put:", "placeholder:", "value:", "p"],
+source: "renderOn: html\x0a\x09html h2 trap: #((title)).\x0a    html div trapGuard: #((todos) (notNil)) contents: [\x0a        html span trap:#((remaining)).\x0a        html with: ' of '.\x0a        html span trap: #((todos) (size)).\x0a        html with: ' remaining [ '.\x0a        html a\x0a\x09\x09\x09href:'';\x0a\x09\x09\x09trap: #() processors: #((signal archive) whenClicked);\x0a\x09\x09\x09with: 'archive'.\x0a        html with: ' ]'.\x0a        html ul with: [ html trapIter: #((todos)) tag: #li do: [ :each |\x0a            html root empty.\x0a            html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).\x0a            html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').\x0a        ]].\x0a        html form trap: #() processors: #((signal addTodo) whenSubmitted); with: [\x0a            html input type: 'text'; trap: #((todoText)) processors: #(inputValue); at: 'size' put: 30; placeholder: 'add new todo here'.\x0a            html input class: 'btn-primary'; type: 'submit'; value: 'add'.\x0a        ]\x0a    ].\x0a\x09html p trapGuard: #((todos) (isNil)) contents: 'Loading ...'",
+messageSends: ["trap:", "h2", "trapGuard:contents:", "div", "span", "with:", "href:", "a", "trap:processors:", "ul", "trapIter:tag:do:", "empty", "root", "type:", "input", "trap:read:", "class:", ",", "form", "at:put:", "placeholder:", "value:", "p"],
 referencedClasses: []
 }),
 smalltalk.AppView);

+ 110 - 0
js/Trapped-Frontend.js

@@ -38,6 +38,25 @@ referencedClasses: []
 }),
 smalltalk.TrappedDataCarrier);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "modifyTargetByPerforming:",
+category: 'action',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._target())._modify_((function(m){
+return smalltalk.withContext(function($ctx2) {
+return _st(m)._perform_(aString);
+}, function($ctx2) {$ctx2.fillBlock({m:m},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"modifyTargetByPerforming:",{aString:aString},smalltalk.TrappedDataCarrier)})},
+args: ["aString"],
+source: "modifyTargetByPerforming: aString\x0a\x09self target modify: [ :m | m perform: aString ]",
+messageSends: ["modify:", "target", "perform:"],
+referencedClasses: []
+}),
+smalltalk.TrappedDataCarrier);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "target",
@@ -564,6 +583,25 @@ referencedClasses: ["TrappedProcessorInputValue"]
 }),
 smalltalk.TrappedProcessor.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "signal:",
+category: 'factory',
+fn: function (aString){
+var self=this;
+function $TrappedProcessorSignal(){return smalltalk.TrappedProcessorSignal||(typeof TrappedProcessorSignal=="undefined"?nil:TrappedProcessorSignal)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($TrappedProcessorSignal())._new_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString},smalltalk.TrappedProcessor.klass)})},
+args: ["aString"],
+source: "signal: aString\x0a\x09^TrappedProcessorSignal new: aString",
+messageSends: ["new:"],
+referencedClasses: ["TrappedProcessorSignal"]
+}),
+smalltalk.TrappedProcessor.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "whenClicked",
@@ -786,6 +824,78 @@ smalltalk.TrappedProcessorInputValue);
 
 
 
+smalltalk.addClass('TrappedProcessorSignal', smalltalk.TrappedProcessor, ['selector'], 'Trapped-Frontend');
+smalltalk.TrappedProcessorSignal.comment="Instead of writing data directly to model,\x0aI instead modify it by sending a message specified when instantiating me.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@selector"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aString:aString},smalltalk.TrappedProcessorSignal)})},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorSignal);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toModel:",
+category: 'data transformation',
+fn: function (aDataCarrier){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aDataCarrier)._modifyTargetByPerforming_(self["@selector"]);
+return self}, function($ctx1) {$ctx1.fill(self,"toModel:",{aDataCarrier:aDataCarrier},smalltalk.TrappedProcessorSignal)})},
+args: ["aDataCarrier"],
+source: "toModel: aDataCarrier\x0a\x09aDataCarrier modifyTargetByPerforming: selector",
+messageSends: ["modifyTargetByPerforming:"],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorSignal);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toView:",
+category: 'data transformation',
+fn: function (aDataCarrier){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"toView:",{aDataCarrier:aDataCarrier},smalltalk.TrappedProcessorSignal)})},
+args: ["aDataCarrier"],
+source: "toView: aDataCarrier\x0a\x09\x22stop\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorSignal);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "new:",
+category: 'instance creation',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=self._new();
+_st($2)._selector_(aString);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"new:",{aString:aString},smalltalk.TrappedProcessorSignal.klass)})},
+args: ["aString"],
+source: "new: aString\x0a\x09^self new\x0a\x09\x09selector: aString;\x0a\x09\x09yourself",
+messageSends: ["selector:", "new", "yourself"],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorSignal.klass);
+
+
 smalltalk.addClass('TrappedProcessorWhenClicked', smalltalk.TrappedProcessor, [], 'Trapped-Frontend');
 smalltalk.TrappedProcessorWhenClicked.comment="I bind to an element and send true to blackboard when clicked.";
 smalltalk.addMethod(

+ 7 - 12
st/Trapped-Demo.st

@@ -148,32 +148,27 @@ Widget subclass: #AppView
 !AppView methodsFor: 'rendering'!
 
 renderOn: html
-    #() trapDescend: [ :snap |
 	html h2 trap: #((title)).
     html div trapGuard: #((todos) (notNil)) contents: [
         html span trap:#((remaining)).
         html with: ' of '.
         html span trap: #((todos) (size)).
         html with: ' remaining [ '.
-        html a href:''; onClick: [
-            snap modify: [ :model | model archive ].
-            false
-        ]; with: 'archive'.
+        html a
+			href:'';
+			trap: #() processors: #((signal archive) whenClicked);
+			with: 'archive'.
         html with: ' ]'.
         html ul with: [ html trapIter: #((todos)) tag: #li do: [ :each |
             html root empty.
             html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).
             html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').
         ]].
-        html form onSubmit: [
-            snap modify: [ :model | model addTodo ].
-            false
-        ]; with: [
+        html form trap: #() processors: #((signal addTodo) whenSubmitted); with: [
             html input type: 'text'; trap: #((todoText)) processors: #(inputValue); at: 'size' put: 30; placeholder: 'add new todo here'.
             html input class: 'btn-primary'; type: 'submit'; value: 'add'.
-        ].
+        ]
     ].
-	html p trapGuard: #((todos) (isNil)) contents: 'Loading ...'.
-	]
+	html p trapGuard: #((todos) (isNil)) contents: 'Loading ...'
 ! !
 

+ 39 - 0
st/Trapped-Frontend.st

@@ -31,6 +31,10 @@ modifyTarget
 	self target modify: [ self value ]
 !
 
+modifyTargetByPerforming: aString
+	self target modify: [ :m | m perform: aString ]
+!
+
 toTargetAttr: aString
 	self target asJQuery attr: aString put: (self value ifNotNil: [ :o | o value ] ifNil: [[]])
 !
@@ -197,6 +201,10 @@ inputValue
 	^TrappedProcessorInputValue new
 !
 
+signal: aString
+	^TrappedProcessorSignal new: aString
+!
+
 whenClicked
 	^TrappedProcessorWhenClicked new
 !
@@ -284,6 +292,37 @@ installToView: aDataCarrier toModel: anotherDataCarrier
 	brush onChange: [ anotherDataCarrier copy value: brush asJQuery val; proceed ]
 ! !
 
+TrappedProcessor subclass: #TrappedProcessorSignal
+	instanceVariableNames: 'selector'
+	package: 'Trapped-Frontend'!
+!TrappedProcessorSignal commentStamp!
+Instead of writing data directly to model,
+I instead modify it by sending a message specified when instantiating me.!
+
+!TrappedProcessorSignal methodsFor: 'accessing'!
+
+selector: aString
+	selector := aString
+! !
+
+!TrappedProcessorSignal methodsFor: 'data transformation'!
+
+toModel: aDataCarrier
+	aDataCarrier modifyTargetByPerforming: selector
+!
+
+toView: aDataCarrier
+	"stop"
+! !
+
+!TrappedProcessorSignal class methodsFor: 'instance creation'!
+
+new: aString
+	^self new
+		selector: aString;
+		yourself
+! !
+
 TrappedProcessor subclass: #TrappedProcessorWhenClicked
 	instanceVariableNames: ''
 	package: 'Trapped-Frontend'!