Browse Source

Rendering double-dispatch via renderOnSilk:

Herbert Vojčík 9 years ago
parent
commit
77efe31276
2 changed files with 112 additions and 1 deletions
  1. 83 1
      src/Silk.js
  2. 29 0
      src/Silk.st

+ 83 - 1
src/Silk.js

@@ -1,9 +1,91 @@
-define("silk/Silk", ["amber/boot", "domite/DOMite"], function($boot){
+define("silk/Silk", ["amber/boot", "domite/DOMite", "amber_core/Kernel-Objects", "amber_core/Kernel-Methods"], function($boot){
 var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;
 $core.addPackage('Silk');
 $core.packages["Silk"].innerEval = function (expr) { return eval(expr); };
 $core.packages["Silk"].transport = {"type":"amd","amdNamespace":"silk"};
 
 $core.addClass('Silk', $globals.Domite, [], 'Silk');
+//>>excludeStart("ide", pragmas.excludeIdeData);
+$globals.Silk.comment="I am adding convenience APIs to my subclass, `Domite`.\x0a\x0a##Rendering\x0a\x0a - `aSilk << anObject` uses double-dispatch via `renderOnSilk:`. This allows creating widgets (no formal superclass, anything with `renderOnSilk:` is a widget), as well as incorporating blocks: `aSilk << aBlock` runs the block, passing aSilk as a parameter.";
+//>>excludeEnd("ide");
+$core.addMethod(
+$core.method({
+selector: "nextPut:",
+protocol: 'writing',
+fn: function (anObject){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$receiver;
+$1=$recv(anObject)._renderOnSilk_(self);
+if(($receiver = $1) == null || $receiver.isNil){
+(
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = true, 
+//>>excludeEnd("ctx");
+$globals.Silk.superclass.fn.prototype._nextPut_.apply($recv(self), [anObject]));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = false;
+//>>excludeEnd("ctx");;
+} else {
+$1;
+};
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"nextPut:",{anObject:anObject},$globals.Silk)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "nextPut: anObject\x0a\x09\x22Double-dispatches anObject via renderOnSilk: message.\x0a\x09If a message returns nil, this fallbacks to superclass.\x0a\x09Otherwise, it is assumed renderOnSilk: did its job.\x22\x0a\x0a\x09(anObject renderOnSilk: self)\x0a\x09\x09ifNil: [ super nextPut: anObject ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["ifNil:", "renderOnSilk:", "nextPut:"]
+}),
+$globals.Silk);
+
+
+$core.addMethod(
+$core.method({
+selector: "renderOnSilk:",
+protocol: '*Silk',
+fn: function (aSilk){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+self._value_(aSilk);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"renderOnSilk:",{aSilk:aSilk},$globals.BlockClosure)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aSilk"],
+source: "renderOnSilk: aSilk\x0a\x09self value: aSilk",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["value:"]
+}),
+$globals.BlockClosure);
+
+$core.addMethod(
+$core.method({
+selector: "renderOnSilk:",
+protocol: '*Silk',
+fn: function (aSilk){
+var self=this;
+return nil;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aSilk"],
+source: "renderOnSilk: aSilk\x0a\x09^ nil",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Object);
 
 });

+ 29 - 0
src/Silk.st

@@ -2,4 +2,33 @@ Smalltalk createPackage: 'Silk'!
 Domite subclass: #Silk
 	instanceVariableNames: ''
 	package: 'Silk'!
+!Silk commentStamp!
+I am adding convenience APIs to my subclass, `Domite`.
+
+##Rendering
+
+ - `aSilk << anObject` uses double-dispatch via `renderOnSilk:`. This allows creating widgets (no formal superclass, anything with `renderOnSilk:` is a widget), as well as incorporating blocks: `aSilk << aBlock` runs the block, passing aSilk as a parameter.!
+
+!Silk methodsFor: 'writing'!
+
+nextPut: anObject
+	"Double-dispatches anObject via renderOnSilk: message.
+	If a message returns nil, this fallbacks to superclass.
+	Otherwise, it is assumed renderOnSilk: did its job."
+
+	(anObject renderOnSilk: self)
+		ifNil: [ super nextPut: anObject ]
+! !
+
+!BlockClosure methodsFor: '*Silk'!
+
+renderOnSilk: aSilk
+	self value: aSilk
+! !
+
+!Object methodsFor: '*Silk'!
+
+renderOnSilk: aSilk
+	^ nil
+! !