浏览代码

Changed means of iteration.

Now, it is defined on HTMLCanvas.
You can insert iteration anywhere.
Is it delimited by two empty <script> tags internally.
Herbert Vojčík 11 年之前
父节点
当前提交
1b539e6d63

+ 7 - 5
lib/js/Trapped-Demo.deploy.js

@@ -173,19 +173,21 @@ return false;
 $2=_st($1)._with_("archive");
 $2;
 _st(html)._with_(" ]");
-_st(_st(html)._ul())._trapIter_tag_do_([smalltalk.symbolFor("todos")],smalltalk.symbolFor("li"),(function(each){
-return smalltalk.withContext(function($ctx5) {
_st(_st(html)._root())._empty();
+_st(_st(html)._ul())._with_((function(){
+return smalltalk.withContext(function($ctx5) {
return _st(html)._trapIter_tag_do_([smalltalk.symbolFor("todos")],smalltalk.symbolFor("li"),(function(each){
+return smalltalk.withContext(function($ctx6) {
_st(_st(html)._root())._empty();
 $3=_st(html)._input();
 _st($3)._type_("checkbox");
 $4=_st($3)._trap_(["done"]);
 $4;
 $5=_st(html)._span();
 _st($5)._trap_read_(["done"],(function(model){
-return smalltalk.withContext(function($ctx6) {
return _st(_st(html)._root())._class_(_st("done-").__comma(model));
-}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx1)})}));
+return smalltalk.withContext(function($ctx7) {
return _st(_st(html)._root())._class_(_st("done-").__comma(model));
+}, function($ctx7) {$ctx7.fillBlock({model:model},$ctx1)})}));
 $6=_st($5)._trap_(["text"]);
 return $6;
-}, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})}));
+}, function($ctx6) {$ctx6.fillBlock({each:each},$ctx1)})}));
+}, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 $7=_st(html)._form();
 _st($7)._onSubmit_((function(){
 return smalltalk.withContext(function($ctx5) {
_st(snap)._modify_((function(model){

+ 8 - 6
lib/js/Trapped-Demo.js

@@ -232,19 +232,21 @@ return false;
 $2=_st($1)._with_("archive");
 $2;
 _st(html)._with_(" ]");
-_st(_st(html)._ul())._trapIter_tag_do_([smalltalk.symbolFor("todos")],smalltalk.symbolFor("li"),(function(each){
-return smalltalk.withContext(function($ctx5) {
_st(_st(html)._root())._empty();
+_st(_st(html)._ul())._with_((function(){
+return smalltalk.withContext(function($ctx5) {
return _st(html)._trapIter_tag_do_([smalltalk.symbolFor("todos")],smalltalk.symbolFor("li"),(function(each){
+return smalltalk.withContext(function($ctx6) {
_st(_st(html)._root())._empty();
 $3=_st(html)._input();
 _st($3)._type_("checkbox");
 $4=_st($3)._trap_(["done"]);
 $4;
 $5=_st(html)._span();
 _st($5)._trap_read_(["done"],(function(model){
-return smalltalk.withContext(function($ctx6) {
return _st(_st(html)._root())._class_(_st("done-").__comma(model));
-}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx1)})}));
+return smalltalk.withContext(function($ctx7) {
return _st(_st(html)._root())._class_(_st("done-").__comma(model));
+}, function($ctx7) {$ctx7.fillBlock({model:model},$ctx1)})}));
 $6=_st($5)._trap_(["text"]);
 return $6;
-}, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})}));
+}, function($ctx6) {$ctx6.fillBlock({each:each},$ctx1)})}));
+}, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 $7=_st(html)._form();
 _st($7)._onSubmit_((function(){
 return smalltalk.withContext(function($ctx5) {
_st(snap)._modify_((function(model){
@@ -273,7 +275,7 @@ return smalltalk.withContext(function($ctx3) {
return _st(html)._with_("Loading
 }, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1)})}));
 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 trap: #(#todos) toggle: [ snap do: [\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 trapIter: #(#todos) tag: #li do: [ :each |\x0a            html root empty.\x0a            html input type: 'checkbox'; trap: #('done').\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); at: 'size' put: 30; placeholder: 'add new todo here'.\x0a            html input class: 'btn-primary'; type: 'submit'; value: 'add'.\x0a        ].\x0a    ]] ifNotPresent: [ html with: 'Loading ...' ]]",
+source: "renderOn: html\x0a    #() trapDescend: [ :snap |\x0a\x09html h2 trap: #(#title).\x0a    html div trap: #(#todos) toggle: [ snap do: [\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').\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); at: 'size' put: 30; placeholder: 'add new todo here'.\x0a            html input class: 'btn-primary'; type: 'submit'; value: 'add'.\x0a        ].\x0a    ]] ifNotPresent: [ html with: 'Loading ...' ]]",
 messageSends: ["trapDescend:", "trap:", "h2", "trap:toggle:ifNotPresent:", "do:", "span", "with:", "href:", "a", "onClick:", "modify:", "archive", "trapIter:tag:do:", "empty", "root", "type:", "input", "trap:read:", "class:", ",", "ul", "onSubmit:", "addTodo", "form", "at:put:", "placeholder:", "value:", "div"],
 referencedClasses: []
 }),

+ 59 - 25
lib/js/Trapped-Frontend.deploy.js

@@ -357,6 +357,45 @@ return self}, function($ctx1) {$ctx1.fill(self,"start:",{args:args}, smalltalk.T
 smalltalk.Trapped);
 
 
+smalltalk.addMethod(
+"_envelope_loop_before_tag_do_",
+smalltalk.method({
+selector: "envelope:loop:before:tag:do:",
+fn: function (envelope,model,endjq,aSymbol,aBlock){
+var self=this;
+var envjq;
+return smalltalk.withContext(function($ctx1) { 
envjq=_st(envelope)._asJQuery();
+_st(model)._withIndexDo_((function(item,i){
+return smalltalk.withContext(function($ctx2) {
_st(envelope)._with_((function(html){
+return smalltalk.withContext(function($ctx3) {
return _st(_st(html)._perform_(aSymbol))._trap_read_([i],aBlock);
+}, function($ctx3) {$ctx3.fillBlock({html:html},$ctx1)})}));
+return _st(_st(_st(envjq)._children())._detach())._insertBefore_(endjq);
+}, function($ctx2) {$ctx2.fillBlock({item:item,i:i},$ctx1)})}));
+_st(envjq)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"envelope:loop:before:tag:do:",{envelope:envelope,model:model,endjq:endjq,aSymbol:aSymbol,aBlock:aBlock,envjq:envjq}, smalltalk.Trapped.klass)})}
+}),
+smalltalk.Trapped.klass);
+
+smalltalk.addMethod(
+"_loop_between_and_tag_do_",
+smalltalk.method({
+selector: "loop:between:and:tag:do:",
+fn: function (model,start,end,aSymbol,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(_st(_st(start)._asJQuery())._nextUntil_(_st(end)._element()))._remove();
+_st(start)._with_((function(html){
+return smalltalk.withContext(function($ctx2) {
$1=model;
+if(($receiver = $1) == nil || $receiver == undefined){
+return $1;
+} else {
+return _st(self)._envelope_loop_before_tag_do_(_st(html)._div(),model,_st(end)._asJQuery(),aSymbol,aBlock);
+};
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"loop:between:and:tag:do:",{model:model,start:start,end:end,aSymbol:aSymbol,aBlock:aBlock}, smalltalk.Trapped.klass)})}
+}),
+smalltalk.Trapped.klass);
+
 smalltalk.addMethod(
 "_parse_",
 smalltalk.method({
@@ -524,6 +563,26 @@ return self}, function($ctx1) {$ctx1.fill(self,"trapDescend:",{aBlock:aBlock}, s
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+"_trapIter_tag_do_",
+smalltalk.method({
+selector: "trapIter:tag:do:",
+fn: function (path,aSymbol,aBlock){
+var self=this;
+var start,end;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._with_((function(html){
+return smalltalk.withContext(function($ctx2) {
start=_st(html)._script();
+start;
+end=_st(html)._script();
+return end;
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+_st(start)._trap_read_(path,(function(model){
+return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Trapped || Trapped))._loop_between_and_tag_do_(model,start,end,aSymbol,aBlock);
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"trapIter:tag:do:",{path:path,aSymbol:aSymbol,aBlock:aBlock,start:start,end:end}, smalltalk.HTMLCanvas)})}
+}),
+smalltalk.HTMLCanvas);
+
 smalltalk.addMethod(
 "_trap_",
 smalltalk.method({
@@ -612,28 +671,3 @@ return self}, function($ctx1) {$ctx1.fill(self,"trap:toggle:ifNotPresent:",{path
 }),
 smalltalk.TagBrush);
 
-smalltalk.addMethod(
-"_trapIter_tag_do_",
-smalltalk.method({
-selector: "trapIter:tag:do:",
-fn: function (path,aSymbol,aBlock){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
-$1=self;
-$2=path;
-$3=(function(model,html){
-return smalltalk.withContext(function($ctx2) {
_st(_st(html)._root())._empty();
-$4=model;
-if(($receiver = $4) == nil || $receiver == undefined){
-return $4;
-} else {
-return _st(model)._withIndexDo_((function(item,i){
-return smalltalk.withContext(function($ctx3) {
return _st(_st(html)._perform_(aSymbol))._trap_read_([i],aBlock);
-}, function($ctx3) {$ctx3.fillBlock({item:item,i:i},$ctx1)})}));
-};
-}, function($ctx2) {$ctx2.fillBlock({model:model,html:html},$ctx1)})});
-_st($1)._trap_read_($2,$3);
-return self}, function($ctx1) {$ctx1.fill(self,"trapIter:tag:do:",{path:path,aSymbol:aSymbol,aBlock:aBlock}, smalltalk.TagBrush)})}
-}),
-smalltalk.TagBrush);
-

+ 74 - 30
lib/js/Trapped-Frontend.js

@@ -453,6 +453,55 @@ referencedClasses: ["Trapped", "Smalltalk"]
 smalltalk.Trapped);
 
 
+smalltalk.addMethod(
+"_envelope_loop_before_tag_do_",
+smalltalk.method({
+selector: "envelope:loop:before:tag:do:",
+category: 'private',
+fn: function (envelope,model,endjq,aSymbol,aBlock){
+var self=this;
+var envjq;
+return smalltalk.withContext(function($ctx1) { 
envjq=_st(envelope)._asJQuery();
+_st(model)._withIndexDo_((function(item,i){
+return smalltalk.withContext(function($ctx2) {
_st(envelope)._with_((function(html){
+return smalltalk.withContext(function($ctx3) {
return _st(_st(html)._perform_(aSymbol))._trap_read_([i],aBlock);
+}, function($ctx3) {$ctx3.fillBlock({html:html},$ctx1)})}));
+return _st(_st(_st(envjq)._children())._detach())._insertBefore_(endjq);
+}, function($ctx2) {$ctx2.fillBlock({item:item,i:i},$ctx1)})}));
+_st(envjq)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"envelope:loop:before:tag:do:",{envelope:envelope,model:model,endjq:endjq,aSymbol:aSymbol,aBlock:aBlock,envjq:envjq}, smalltalk.Trapped.klass)})},
+args: ["envelope", "model", "endjq", "aSymbol", "aBlock"],
+source: "envelope: envelope loop: model before: endjq tag: aSymbol do: aBlock\x0a   \x09| envjq |\x0a    envjq := envelope asJQuery.\x0a    model withIndexDo: [ :item :i |\x0a        envelope with: [ :html | (html perform: aSymbol) trap: {i} read: aBlock ].\x0a        envjq children detach insertBefore: endjq.\x0a    ].\x0a    envjq remove\x0a",
+messageSends: ["asJQuery", "withIndexDo:", "with:", "trap:read:", "perform:", "insertBefore:", "detach", "children", "remove"],
+referencedClasses: []
+}),
+smalltalk.Trapped.klass);
+
+smalltalk.addMethod(
+"_loop_between_and_tag_do_",
+smalltalk.method({
+selector: "loop:between:and:tag:do:",
+category: 'private',
+fn: function (model,start,end,aSymbol,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(_st(_st(start)._asJQuery())._nextUntil_(_st(end)._element()))._remove();
+_st(start)._with_((function(html){
+return smalltalk.withContext(function($ctx2) {
$1=model;
+if(($receiver = $1) == nil || $receiver == undefined){
+return $1;
+} else {
+return _st(self)._envelope_loop_before_tag_do_(_st(html)._div(),model,_st(end)._asJQuery(),aSymbol,aBlock);
+};
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"loop:between:and:tag:do:",{model:model,start:start,end:end,aSymbol:aSymbol,aBlock:aBlock}, smalltalk.Trapped.klass)})},
+args: ["model", "start", "end", "aSymbol", "aBlock"],
+source: "loop: model between: start and: end tag: aSymbol do: aBlock\x0a    (start asJQuery nextUntil: end element) remove.\x0a    start with: [ :html | model ifNotNil: [\x0a    \x09self envelope: html div loop: model before: end asJQuery tag: aSymbol do: aBlock\x0a\x09]]\x0a",
+messageSends: ["remove", "nextUntil:", "element", "asJQuery", "with:", "ifNotNil:", "envelope:loop:before:tag:do:", "div"],
+referencedClasses: []
+}),
+smalltalk.Trapped.klass);
+
 smalltalk.addMethod(
 "_parse_",
 smalltalk.method({
@@ -675,6 +724,31 @@ referencedClasses: ["Trapped"]
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+"_trapIter_tag_do_",
+smalltalk.method({
+selector: "trapIter:tag:do:",
+category: '*Trapped-Frontend',
+fn: function (path,aSymbol,aBlock){
+var self=this;
+var start,end;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._with_((function(html){
+return smalltalk.withContext(function($ctx2) {
start=_st(html)._script();
+start;
+end=_st(html)._script();
+return end;
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+_st(start)._trap_read_(path,(function(model){
+return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Trapped || Trapped))._loop_between_and_tag_do_(model,start,end,aSymbol,aBlock);
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"trapIter:tag:do:",{path:path,aSymbol:aSymbol,aBlock:aBlock,start:start,end:end}, smalltalk.HTMLCanvas)})},
+args: ["path", "aSymbol", "aBlock"],
+source: "trapIter: path tag: aSymbol do: aBlock\x0a\x09| start end |\x0a    self with: [ :html | start := html script. end := html script ].\x0a    start trap: path read: [ :model |\x0a    \x09Trapped loop: model between: start and: end tag: aSymbol do: aBlock.\x0a    ]",
+messageSends: ["with:", "script", "trap:read:", "loop:between:and:tag:do:"],
+referencedClasses: ["Trapped"]
+}),
+smalltalk.HTMLCanvas);
+
 smalltalk.addMethod(
 "_trap_",
 smalltalk.method({
@@ -783,33 +857,3 @@ referencedClasses: []
 }),
 smalltalk.TagBrush);
 
-smalltalk.addMethod(
-"_trapIter_tag_do_",
-smalltalk.method({
-selector: "trapIter:tag:do:",
-category: '*Trapped-Frontend',
-fn: function (path,aSymbol,aBlock){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
-$1=self;
-$2=path;
-$3=(function(model,html){
-return smalltalk.withContext(function($ctx2) {
_st(_st(html)._root())._empty();
-$4=model;
-if(($receiver = $4) == nil || $receiver == undefined){
-return $4;
-} else {
-return _st(model)._withIndexDo_((function(item,i){
-return smalltalk.withContext(function($ctx3) {
return _st(_st(html)._perform_(aSymbol))._trap_read_([i],aBlock);
-}, function($ctx3) {$ctx3.fillBlock({item:item,i:i},$ctx1)})}));
-};
-}, function($ctx2) {$ctx2.fillBlock({model:model,html:html},$ctx1)})});
-_st($1)._trap_read_($2,$3);
-return self}, function($ctx1) {$ctx1.fill(self,"trapIter:tag:do:",{path:path,aSymbol:aSymbol,aBlock:aBlock}, smalltalk.TagBrush)})},
-args: ["path", "aSymbol", "aBlock"],
-source: "trapIter: path tag: aSymbol do: aBlock\x0a    self trap: path read: [ :model :html |\x0a        html root empty.\x0a        model ifNotNil: [ model withIndexDo: [ :item :i |\x0a            (html perform: aSymbol) trap: {i} read: aBlock\x0a        ]]\x0a    ]",
-messageSends: ["trap:read:", "empty", "root", "ifNotNil:", "withIndexDo:", "perform:"],
-referencedClasses: []
-}),
-smalltalk.TagBrush);
-

+ 2 - 2
lib/st/Trapped-Demo.st

@@ -159,11 +159,11 @@ renderOn: html
             false
         ]; with: 'archive'.
         html with: ' ]'.
-        html ul trapIter: #(#todos) tag: #li do: [ :each |
+        html ul with: [ html trapIter: #(#todos) tag: #li do: [ :each |
             html root empty.
             html input type: 'checkbox'; trap: #('done').
             html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').
-        ].
+        ]].
         html form onSubmit: [
             snap modify: [ :model | model addTodo ].
             false

+ 29 - 9
lib/st/Trapped-Frontend.st

@@ -179,6 +179,25 @@ parse: anArray
 			each first = '#' ifTrue: [ each allButFirst asSymbol ] ifFalse: [ each ]]]
 ! !
 
+!Trapped class methodsFor: 'private'!
+
+envelope: envelope loop: model before: endjq tag: aSymbol do: aBlock
+   	| envjq |
+    envjq := envelope asJQuery.
+    model withIndexDo: [ :item :i |
+        envelope with: [ :html | (html perform: aSymbol) trap: {i} read: aBlock ].
+        envjq children detach insertBefore: endjq.
+    ].
+    envjq remove
+!
+
+loop: model between: start and: end tag: aSymbol do: aBlock
+    (start asJQuery nextUntil: end element) remove.
+    start with: [ :html | model ifNotNil: [
+    	self envelope: html div loop: model before: end asJQuery tag: aSymbol do: aBlock
+	]]
+! !
+
 TrappedSingleton subclass: #TrappedPathStack
 	instanceVariableNames: 'elements'
 	package: 'Trapped-Frontend'!
@@ -244,6 +263,16 @@ trapDescend: aBlock
 	Trapped current descend: self snapshotDo: aBlock
 ! !
 
+!HTMLCanvas methodsFor: '*Trapped-Frontend'!
+
+trapIter: path tag: aSymbol do: aBlock
+	| start end |
+    self with: [ :html | start := html script. end := html script ].
+    start trap: path read: [ :model |
+    	Trapped loop: model between: start and: end tag: aSymbol do: aBlock.
+    ]
+! !
+
 !TagBrush methodsFor: '*Trapped-Frontend'!
 
 trap: path
@@ -273,14 +302,5 @@ trap: path toggle: aBlock ifNotPresent: anotherBlock
             (shown ifTrue: [aBlock] ifFalse: [anotherBlock]) value: data value: html.
         ]
     ]
-!
-
-trapIter: path tag: aSymbol do: aBlock
-    self trap: path read: [ :model :html |
-        html root empty.
-        model ifNotNil: [ model withIndexDo: [ :item :i |
-            (html perform: aSymbol) trap: {i} read: aBlock
-        ]]
-    ]
 ! !