Smalltalk createPackage: 'Trapped-Processors'! (Smalltalk packageAt: 'Trapped-Processors' ifAbsent: [ self error: 'Package not created: Trapped-Processors' ]) imports: {'amber/jquery/Wrappers-JQuery'. 'jquery.xontent'}! TrappedDataExpectingProcessor subclass: #TrappedProcessorAttribute instanceVariableNames: 'attrName' package: 'Trapped-Processors'! !TrappedProcessorAttribute commentStamp! I set the data into an attribute speciried when creating me. No observing and sending back, atm.! !TrappedProcessorAttribute methodsFor: 'accessing'! attrName: aString attrName := aString ! ! !TrappedProcessorAttribute methodsFor: 'data transformation'! toView: aDataCarrier aDataCarrier toTargetAttr: attrName ! ! !TrappedProcessorAttribute class methodsFor: 'instance creation'! new: aString ^self new attrName: aString; yourself ! ! TrappedDataExpectingProcessor subclass: #TrappedProcessorDataAdhoc instanceVariableNames: 'toViewBlock' package: 'Trapped-Processors'! !TrappedProcessorDataAdhoc commentStamp! I put data into target via contents: in toView:! !TrappedProcessorDataAdhoc methodsFor: 'accessing'! toViewBlock: aBlock toViewBlock := aBlock ! ! !TrappedProcessorDataAdhoc methodsFor: 'data transformation'! toView: aDataCarrier toViewBlock value: aDataCarrier ! ! !TrappedProcessorDataAdhoc class methodsFor: 'instance creation'! newToView: aBlock ^self new toViewBlock: aBlock; yourself ! ! TrappedProcessor subclass: #TrappedProcessorDescend instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorDescend commentStamp! I intepret data-trap in descendants of my brush.! !TrappedProcessorDescend methodsFor: 'data transformation'! toView: aDataCarrier Trapped current injectToChildren: aDataCarrier target element ! ! TrappedProcessor subclass: #TrappedProcessorGuardBase instanceVariableNames: 'guardPath' package: 'Trapped-Processors'! !TrappedProcessorGuardBase commentStamp! I serve as base class for brush-guarding processors. I cover instantiation and subclasses have to provide implementation of toVIew: that react appropriately to guard releasing.! !TrappedProcessorGuardBase methodsFor: 'accessing'! guardPath: anArray guardPath := anArray ! ! !TrappedProcessorGuardBase methodsFor: 'data transformation'! toModel: aDataCarrier "stop" ! toView: aDataCarrier self subclassResponsibility ! ! !TrappedProcessorGuardBase class methodsFor: 'instance creation'! new: anArray ^ self new guardPath: anArray; yourself ! ! TrappedProcessorGuardBase subclass: #TrappedProcessorGuard instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorGuard commentStamp! I am used to guard contents filling process of the brush I am installed on. I observe guard expression in the model, and when it changes to nil or false, I delete the brush contents; on the other hand, when it changes to non-nil and non-false, I run the rest on the chain, which should be one-time that sets up the contents,! !TrappedProcessorGuard methodsFor: 'data transformation'! toView: aDataCarrier | frozen xon | frozen := aDataCarrier copy. xon := frozen xontent. frozen target trapGuard: guardPath contents: [ :html | frozen copy target: html root; xontent: xon; proceed ] ! ! TrappedDataExpectingProcessor subclass: #TrappedProcessorInputChecked instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorInputChecked commentStamp! I bind to checkbox checked state.! !TrappedProcessorInputChecked methodsFor: 'data transformation'! toView: aDataCarrier aDataCarrier toTargetProp: 'checked' ! ! !TrappedProcessorInputChecked methodsFor: 'installation'! installToView: aDataCarrier toModel: anotherDataCarrier | brush | brush := aDataCarrier target. brush onChange: [ anotherDataCarrier copy value: (brush asJQuery prop: 'checked'); proceed ] ! ! TrappedDataExpectingProcessor subclass: #TrappedProcessorInputValue instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorInputValue commentStamp! I bind to input value.! !TrappedProcessorInputValue methodsFor: 'data transformation'! toView: aDataCarrier aDataCarrier toTargetValue ! ! !TrappedProcessorInputValue methodsFor: 'installation'! installToView: aDataCarrier toModel: anotherDataCarrier | brush | brush := aDataCarrier target. brush onChange: [ anotherDataCarrier copy value: brush asJQuery val; 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: #TrappedProcessorLoopZ instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorLoopZ 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 script type=application/x-beacon, noscript, ins or del).! !TrappedProcessorLoopZ methodsFor: 'data transformation'! toView: aDataCarrier | frozen xon | frozen := aDataCarrier copy. xon := frozen xontent. frozen target trapIter: #() after: [ :html | frozen copy target: html root; xontent: xon; proceed ] ! ! TrappedDataExpectingProcessor subclass: #TrappedProcessorOptionValue instanceVariableNames: '' package: 'Trapped-Processors'! !TrappedProcessorOptionValue commentStamp! I set the option value. Additionally, when changed (by toView:), I ping closest