123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- Smalltalk current createPackage: 'Trapped-Processors'!
- 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 injectToJQuery: aDataCarrier target asJQuery children
- ! !
- 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: #TrappedProcessorGuardContents
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorGuardContents commentStamp!
- I am used to guard contents of the brush I am installed on.
- I save the brush contents, then 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 restore it from remembered state and interpret all contained
- data-trap attributes inside.!
- !TrappedProcessorGuardContents methodsFor: 'data transformation'!
- toView: aDataCarrier
- | frozen contents |
- frozen := aDataCarrier copy.
- contents := frozen contents.
- frozen target trapGuard: guardPath contents: [ :html |
- Trapped current cloneAndInject: contents inPlaceOf: html del ]
- ! !
- TrappedProcessorGuardBase subclass: #TrappedProcessorGuardProc
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorGuardProc 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,!
- !TrappedProcessorGuardProc methodsFor: 'data transformation'!
- toView: aDataCarrier
- | frozen |
- frozen := aDataCarrier copy.
- frozen target trapGuard: guardPath contents: [ frozen copy proceed ]
- ! !
- TrappedDataExpectingProcessor subclass: #TrappedProcessorInputChecked
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorInputChecked commentStamp!
- I bind to checkbox checked attribute.!
- !TrappedProcessorInputChecked methodsFor: 'data transformation'!
- toView: aDataCarrier
- aDataCarrier toTargetAttr: 'checked'
- ! !
- !TrappedProcessorInputChecked methodsFor: 'installation'!
- installToView: aDataCarrier toModel: anotherDataCarrier
- | brush |
- brush := aDataCarrier target.
- brush onChange: [ anotherDataCarrier copy value: (brush asJQuery attr: 'checked') notNil; 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: #TrappedProcessorLoopContents
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorLoopContents commentStamp!
- I am used to loop over data and repeat the contents
- of the brush I am installed on.
- I save the brush contents, then I observe the data in the model,
- and when it changes, I loop over it
- and restore the contents from remembered state
- and interpret all contained data-trap attributes inside
- 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).!
- !TrappedProcessorLoopContents methodsFor: 'data transformation'!
- toView: aDataCarrier
- | frozen contents |
- frozen := aDataCarrier copy.
- contents := frozen contents.
- frozen target trapIter: #() after: [ :html |
- Trapped current cloneAndInject: contents inPlaceOf: html del ]
- ! !
- 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: #TrappedProcessorReplace
- instanceVariableNames: 'left right'
- package: 'Trapped-Processors'!
- !TrappedProcessorReplace commentStamp!
- I convert data to string representation and do a regex replace.
- I get two parameters, in toView:, first is replaced with second,
- and in toModel:, the second is replaced with first.
- I remove leading '^' and ending '$' from the string used as replacement,
- so it safe to replace ^to with ^To, for example.!
- !TrappedProcessorReplace methodsFor: 'accessing'!
- left: aString
- left := aString
- !
- right: aString
- right := aString
- ! !
- !TrappedProcessorReplace methodsFor: 'data transformation'!
- toModel: aDataCarrier
- | replacement old |
- replacement := (left replace: '^\^' with: '') replace: '\$$' with: ''.
- old := aDataCarrier value asString.
- aDataCarrier
- value: (old replace: right with: replacement) whenDifferentFrom: old;
- proceed
- !
- toView: aDataCarrier
- | replacement old |
- replacement := (right replace: '^\^' with: '') replace: '\$$' with: ''.
- old := aDataCarrier value asString.
- aDataCarrier
- value: (old replace: left with: replacement) whenDifferentFrom: old;
- proceed
- ! !
- !TrappedProcessorReplace class methodsFor: 'instance creation'!
- new: aString with: anotherString
- ^ self new
- left: aString asString;
- right: anotherString asString;
- yourself
- ! !
- TrappedProcessor subclass: #TrappedProcessorSignal
- instanceVariableNames: 'selector'
- package: 'Trapped-Processors'!
- !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
- ! !
- TrappedDataExpectingProcessor subclass: #TrappedProcessorToBlackboard
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorToBlackboard commentStamp!
- I save the data to blackboard in toModel:, to position specified by path.!
- !TrappedProcessorToBlackboard methodsFor: 'data transformation'!
- toModel: aDataCarrier
- aDataCarrier target modify: [ aDataCarrier value ]
- ! !
- TrappedProcessor subclass: #TrappedProcessorUriComponentDecode
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorUriComponentDecode commentStamp!
- I uriComponentDecode in toView:
- and encode in toModel:!
- !TrappedProcessorUriComponentDecode methodsFor: 'data transformation'!
- toModel: aDataCarrier
- aDataCarrier
- value: aDataCarrier value uriComponentEncoded;
- proceed
- !
- toView: aDataCarrier
- aDataCarrier
- value: aDataCarrier value uriComponentDecoded;
- proceed
- ! !
- TrappedProcessor subclass: #TrappedProcessorUriComponentEncode
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorUriComponentEncode commentStamp!
- I uriComponentEncode in toView:
- and decode in toModel:!
- !TrappedProcessorUriComponentEncode methodsFor: 'data transformation'!
- toModel: aDataCarrier
- aDataCarrier
- value: aDataCarrier value uriComponentDecoded;
- proceed
- !
- toView: aDataCarrier
- aDataCarrier
- value: aDataCarrier value uriComponentEncoded;
- proceed
- ! !
- TrappedProcessor subclass: #TrappedProcessorWhenClicked
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorWhenClicked commentStamp!
- I bind to an element and send true to blackboard when clicked.!
- !TrappedProcessorWhenClicked methodsFor: 'installation'!
- installToView: aDataCarrier toModel: anotherDataCarrier
- aDataCarrier target onClick: [ anotherDataCarrier copy proceed. false ]
- ! !
- TrappedProcessor subclass: #TrappedProcessorWhenSubmitted
- instanceVariableNames: ''
- package: 'Trapped-Processors'!
- !TrappedProcessorWhenSubmitted commentStamp!
- I bind to a form and send true to blackboard when submitted.!
- !TrappedProcessorWhenSubmitted methodsFor: 'installation'!
- installToView: aDataCarrier toModel: anotherDataCarrier
- aDataCarrier target onSubmit: [ anotherDataCarrier copy proceed. false ]
- ! !
- TrappedProcessor subclass: #TrappedProcessorWidget
- instanceVariableNames: 'viewName'
- package: 'Trapped-Processors'!
- !TrappedProcessorWidget commentStamp!
- I insert a widget instance of the class specified when creating me.!
- !TrappedProcessorWidget methodsFor: 'accessing'!
- viewName: aString
- viewName := aString
- ! !
- !TrappedProcessorWidget methodsFor: 'data transformation'!
- toView: aDataCarrier
- aDataCarrier target with: (Smalltalk current at: viewName) new
- ! !
- !TrappedProcessorWidget class methodsFor: 'instance creation'!
- new: aString
- ^self new
- viewName: aString;
- yourself
- ! !
- !TrappedDataCarrier methodsFor: '*Trapped-Processors'!
- contents
- | contents tag holder |
- contents := nil.
- holder := self target asJQuery.
- tag := (holder prop: 'tagName') asLowercase.
- tag = 'script' ifTrue: [
- holder := ((holder attr: 'data-content') ifNil: [ ^self error: '<script> need data-content' ]) asJQuery.
- tag := (holder prop: 'tagName') asLowercase ].
- tag = 'template' ifTrue: [
- contents := (holder prop: 'content') ifNotNil: [ :content | content asJQuery ] ].
- contents ifNil: [ contents := holder contents detach ].
- ^contents
- !
- modifyTarget
- self target modify: [ self value ]
- !
- modifyTargetByPerforming: aString
- self target modify: [ :m | m perform: aString ]
- !
- toTargetAttr: aString
- self falseAsNilValue
- ifNil: [ self target removeAt: aString ]
- ifNotNil: [ :value | self target at: aString put: (value = true ifTrue: [ aString ] ifFalse: [ value ]) ]
- !
- toTargetContents
- self target contents: self value
- !
- toTargetValue
- self target asJQuery val: (self value ifNotNil: [ :o | o value ] ifNil: [[]])
- ! !
- !TrappedProcessor class methodsFor: '*Trapped-Processors'!
- attr: aString
- ^TrappedProcessorAttribute new: aString
- !
- dataToView: aBlock
- ^TrappedProcessorDataAdhoc newToView: aBlock
- !
- deuric
- ^TrappedProcessorUriComponentDecoded new
- !
- guardContents: anArray
- ^TrappedProcessorGuardContents new: anArray
- !
- guardProc: anArray
- ^TrappedProcessorGuardProc new: anArray
- !
- inputChecked
- ^TrappedProcessorInputChecked new
- !
- inputValue
- ^TrappedProcessorInputValue new
- !
- loopContents
- ^TrappedProcessorLoopContents new
- !
- loopProc
- ^TrappedProcessorLoopProc new
- !
- path
- ^TrappedProcessorDescend new
- !
- replace: aString with: anotherString
- ^TrappedProcessorReplace new: aString with: anotherString
- !
- signal: aString
- ^TrappedProcessorSignal new: aString
- !
- toBlackboard
- ^TrappedProcessorToBlackboard new
- !
- uric
- ^TrappedProcessorUriComponentEncoded new
- !
- whenClicked
- ^TrappedProcessorWhenClicked new
- !
- whenSubmitted
- ^TrappedProcessorWhenSubmitted new
- !
- widget: aString
- ^TrappedProcessorWidget new: aString
- ! !
|