Procházet zdrojové kódy

loopProc processor

Herbert Vojčík před 10 roky
rodič
revize
2b9651788c

+ 8 - 9
js/Trapped-Demo.js

@@ -231,8 +231,8 @@ smalltalk.AppModel);
 
 
 
-smalltalk.addClass('TodoItemsWidget', smalltalk.Widget, [], 'Trapped-Demo');
-smalltalk.TodoItemsWidget.comment="<!-- Code from AngularJS Todo example, http://angularjs.org/#todo-html -->\x0a  <body>\x0a    <h2>Todo</h2>\x0a    <div ng-controller=\x22TodoCtrl\x22>\x0a      <span>{{remaining()}} of {{todos.length}} remaining</span>\x0a      [ <a href=\x22\x22 ng-click=\x22archive()\x22>archive</a> ]\x0a      <ul class=\x22unstyled\x22>\x0a        <li ng-repeat=\x22todo in todos\x22>\x0a          <input type=\x22checkbox\x22 ng-model=\x22todo.done\x22>\x0a          <span class=\x22done-{{todo.done}}\x22>{{todo.text}}</span>\x0a        </li>\x0a      </ul>\x0a      <form ng-submit=\x22addTodo()\x22>\x0a        <input type=\x22text\x22 ng-model=\x22todoText\x22  size=\x2230\x22\x0a               placeholder=\x22add new todo here\x22>\x0a        <input class=\x22btn-primary\x22 type=\x22submit\x22 value=\x22add\x22>\x0a      </form>\x0a    </div>\x0a  </body>";
+smalltalk.addClass('TodoItemWidget', smalltalk.Widget, [], 'Trapped-Demo');
+smalltalk.TodoItemWidget.comment="<!-- Code from AngularJS Todo example, http://angularjs.org/#todo-html -->\x0a  <body>\x0a    <h2>Todo</h2>\x0a    <div ng-controller=\x22TodoCtrl\x22>\x0a      <span>{{remaining()}} of {{todos.length}} remaining</span>\x0a      [ <a href=\x22\x22 ng-click=\x22archive()\x22>archive</a> ]\x0a      <ul class=\x22unstyled\x22>\x0a        <li ng-repeat=\x22todo in todos\x22>\x0a          <input type=\x22checkbox\x22 ng-model=\x22todo.done\x22>\x0a          <span class=\x22done-{{todo.done}}\x22>{{todo.text}}</span>\x0a        </li>\x0a      </ul>\x0a      <form ng-submit=\x22addTodo()\x22>\x0a        <input type=\x22text\x22 ng-model=\x22todoText\x22  size=\x2230\x22\x0a               placeholder=\x22add new todo here\x22>\x0a        <input class=\x22btn-primary\x22 type=\x22submit\x22 value=\x22add\x22>\x0a      </form>\x0a    </div>\x0a  </body>";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderOn:",
@@ -241,9 +241,8 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4;
-_st(html)._trapIter_tag_do_([],"li",(function(each){
+_st(_st(html)._li())._with_((function(){
 return smalltalk.withContext(function($ctx2) {
-_st(_st(html)._root())._empty();
 $1=_st(html)._input();
 _st($1)._type_("checkbox");
 $2=_st($1)._trap_processors_(["done"],["inputChecked"]);
@@ -253,14 +252,14 @@ $3=_st(html)._span();
 _st($3)._trap_processors_(["done"],["classDoneXxx"]);
 $4=_st($3)._trap_(["text"]);
 return $4;
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.TodoItemsWidget)})},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.TodoItemWidget)})},
 args: ["html"],
-source: "renderOn: html\x0a\x09html trapIter: #() tag: #li do: [ :each |\x0a\x09\x09html root empty.\x0a\x09\x09html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).\x0a\x09\x09html span\x0a\x09\x09\x09trap: #('done') processors: #(classDoneXxx);\x0a\x09\x09\x09trap: #('text')\x0a\x09]",
-messageSends: ["trapIter:tag:do:", "empty", "root", "type:", "input", "trap:processors:", "span", "trap:"],
+source: "renderOn: html\x0a\x09html li with: [\x0a\x09\x09html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).\x0a\x09\x09html span\x0a\x09\x09\x09trap: #('done') processors: #(classDoneXxx);\x0a\x09\x09\x09trap: #('text') ]",
+messageSends: ["with:", "li", "type:", "input", "trap:processors:", "span", "trap:"],
 referencedClasses: []
 }),
-smalltalk.TodoItemsWidget);
+smalltalk.TodoItemWidget);
 
 
 smalltalk.addMethod(

+ 19 - 0
js/Trapped-Frontend.js

@@ -577,6 +577,25 @@ referencedClasses: ["TrappedProcessorInputValue"]
 }),
 smalltalk.TrappedProcessor.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "loopProc",
+category: 'factory',
+fn: function (){
+var self=this;
+function $TrappedProcessorLoopProc(){return smalltalk.TrappedProcessorLoopProc||(typeof TrappedProcessorLoopProc=="undefined"?nil:TrappedProcessorLoopProc)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($TrappedProcessorLoopProc())._new();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"loopProc",{},smalltalk.TrappedProcessor.klass)})},
+args: [],
+source: "loopProc\x0a\x09^TrappedProcessorLoopProc new",
+messageSends: ["new"],
+referencedClasses: ["TrappedProcessorLoopProc"]
+}),
+smalltalk.TrappedProcessor.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "path",

+ 65 - 0
js/Trapped-Processors.js

@@ -402,6 +402,71 @@ smalltalk.TrappedProcessorGuardProc);
 
 
 
+smalltalk.addClass('TrappedProcessorLoopBase', smalltalk.TrappedProcessor, [], 'Trapped-Processors');
+smalltalk.TrappedProcessorLoopBase.comment="I serve as base class for looping processors.\x0a\x0aI cover instantiation and subclasses have to provide\x0aimplementation of toVIew: that loops appropriately.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toModel:",
+category: 'data transformation',
+fn: function (aDataCarrier){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"toModel:",{aDataCarrier:aDataCarrier},smalltalk.TrappedProcessorLoopBase)})},
+args: ["aDataCarrier"],
+source: "toModel: aDataCarrier\x0a\x09\x22stop\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorLoopBase);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toView:",
+category: 'data transformation',
+fn: function (aDataCarrier){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"toView:",{aDataCarrier:aDataCarrier},smalltalk.TrappedProcessorLoopBase)})},
+args: ["aDataCarrier"],
+source: "toView: aDataCarrier\x0a\x09self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorLoopBase);
+
+
+
+smalltalk.addClass('TrappedProcessorLoopProc', smalltalk.TrappedProcessorLoopBase, [], 'Trapped-Processors');
+smalltalk.TrappedProcessorLoopProc.comment="I am used to loop over data and repeat the contents filling process\x0aof the brush I am installed on.\x0a\x0aI observe the data in the model,\x0aand when it changes, I loop over it\x0aand run the rest of the processing chain\x0afor each element, putting the result _after_ my brush.\x0a\x0aMy brush itself should be as least visible as possible,\x0aas it only serve as a position flag (use for example\x0anoscript, ins or del).";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toView:",
+category: 'data transformation',
+fn: function (aDataCarrier){
+var self=this;
+var frozen;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+frozen=_st(aDataCarrier)._copy();
+$ctx1.sendIdx["copy"]=1;
+_st(_st(frozen)._target())._trapIter_after_([],(function(html){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(frozen)._copy();
+_st($1)._target_(_st(html)._root());
+$2=_st($1)._proceed();
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"toView:",{aDataCarrier:aDataCarrier,frozen:frozen},smalltalk.TrappedProcessorLoopProc)})},
+args: ["aDataCarrier"],
+source: "toView: aDataCarrier\x0a\x09| frozen |\x0a\x09frozen := aDataCarrier copy.\x0a\x09frozen target trapIter: #() after: [ :html | frozen copy target: html root; proceed ]",
+messageSends: ["copy", "trapIter:after:", "target", "target:", "root", "proceed"],
+referencedClasses: []
+}),
+smalltalk.TrappedProcessorLoopProc);
+
+
+
 smalltalk.addClass('TrappedProcessorSignal', smalltalk.TrappedProcessor, ['selector'], 'Trapped-Processors');
 smalltalk.TrappedProcessorSignal.comment="Instead of writing data directly to model,\x0aI instead modify it by sending a message specified when instantiating me.";
 smalltalk.addMethod(

+ 2 - 1
meta/demo.html

@@ -1,3 +1,4 @@
+<!doctype html>
 <html data-trap="App: path">
 <head>
     <title data-trap="#title"></title>
@@ -39,7 +40,7 @@
 <div data-trap=": (guardContents (#todos #notNil))">
     <span data-trap="#remaining"></span> of <span data-trap="#todos #size"></span> remaning
     [ <a href="" data-trap=": (signal archive) whenClicked">archive</a> ]
-    <ul data-trap="#todos: (widget TodoItemsWidget)"></ul>
+    <ul><noscript data-trap="#todos: loopProc (widget TodoItemWidget)"></noscript></ul>
     <form data-trap=": (signal addTodo) whenSubmitted">
         <input type="text" data-trap="#todoText: inputValue" size="30" placeholder="add new todo here"/>
         <input type="submit" class="btn-primary" value="add"/>

+ 5 - 7
st/Trapped-Demo.st

@@ -121,10 +121,10 @@ archive
     self todos: self todosNotDone
 ! !
 
-Widget subclass: #TodoItemsWidget
+Widget subclass: #TodoItemWidget
 	instanceVariableNames: ''
 	package: 'Trapped-Demo'!
-!TodoItemsWidget commentStamp!
+!TodoItemWidget commentStamp!
 <!!-- Code from AngularJS Todo example, http://angularjs.org/#todo-html -->
   <body>
     <h2>Todo</h2>
@@ -145,16 +145,14 @@ Widget subclass: #TodoItemsWidget
     </div>
   </body>!
 
-!TodoItemsWidget methodsFor: 'rendering'!
+!TodoItemWidget methodsFor: 'rendering'!
 
 renderOn: html
-	html trapIter: #() tag: #li do: [ :each |
-		html root empty.
+	html li with: [
 		html input type: 'checkbox'; trap: #('done') processors: #(inputChecked).
 		html span
 			trap: #('done') processors: #(classDoneXxx);
-			trap: #('text')
-	]
+			trap: #('text') ]
 ! !
 
 !TrappedProcessor class methodsFor: '*Trapped-Demo'!

+ 4 - 0
st/Trapped-Frontend.st

@@ -200,6 +200,10 @@ inputValue
 	^TrappedProcessorInputValue new
 !
 
+loopProc
+	^TrappedProcessorLoopProc new
+!
+
 path
 	^TrappedProcessorDescend new
 !

+ 43 - 0
st/Trapped-Processors.st

@@ -211,6 +211,49 @@ toView: aDataCarrier
 	frozen target trapGuard: guardPath contents: [ frozen copy proceed ]
 ! !
 
+TrappedProcessor subclass: #TrappedProcessorLoopBase
+	instanceVariableNames: ''
+	package: 'Trapped-Processors'!
+!TrappedProcessorLoopBase commentStamp!
+I serve as base class for looping processors.
+
+I cover instantiation and subclasses have to provide
+implementation of toVIew: that loops appropriately.!
+
+!TrappedProcessorLoopBase methodsFor: 'data transformation'!
+
+toModel: aDataCarrier
+	"stop"
+!
+
+toView: aDataCarrier
+	self subclassResponsibility
+! !
+
+TrappedProcessorLoopBase subclass: #TrappedProcessorLoopProc
+	instanceVariableNames: ''
+	package: 'Trapped-Processors'!
+!TrappedProcessorLoopProc commentStamp!
+I am used to loop over data and repeat the contents filling process
+of the brush I am installed on.
+
+I observe the data in the model,
+and when it changes, I loop over it
+and run the rest of the processing chain
+for each element, putting the result _after_ my brush.
+
+My brush itself should be as least visible as possible,
+as it only serve as a position flag (use for example
+noscript, ins or del).!
+
+!TrappedProcessorLoopProc methodsFor: 'data transformation'!
+
+toView: aDataCarrier
+	| frozen |
+	frozen := aDataCarrier copy.
+	frozen target trapIter: #() after: [ :html | frozen copy target: html root; proceed ]
+! !
+
 TrappedProcessor subclass: #TrappedProcessorSignal
 	instanceVariableNames: 'selector'
 	package: 'Trapped-Processors'!