1
0

Silk.st 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. Smalltalk createPackage: 'Silk'!
  2. Domite subclass: #Silk
  3. instanceVariableNames: ''
  4. package: 'Silk'!
  5. !Silk commentStamp!
  6. I am adding convenience APIs to my subclass, `Domite`.
  7. ##Rendering
  8. - `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.
  9. ##Convenience
  10. - `aCssSelectorString asSilk` returns Silk wrapping an element at a selector.
  11. - `anObject inSilk` returns anObject rendered in a document fragment.
  12. ##Element creation
  13. These messages use DNU to dynamically create
  14. elements with any (letters-and-numbers) tag name,
  15. Next samples show this on an example of `<div>`.
  16. - `Silk DIV` is shortcut for `Silk newElement: 'div'`.
  17. - `aSilk DIV` is shortcut for `[ |tmp| tmp := Silk DIV. aSilk << tmp. tmp] value`. IOW, it not just creates the element and returns it, but also puts in on aSilk.
  18. - `aSilk DIV: anObject` is shortcut for `aSilk DIV << anObject; yourself`. IOW, it not just creates and insert the element, but puts a content into it.!
  19. !Silk methodsFor: 'writing'!
  20. doesNotUnderstand: aMessage
  21. "`aSilk DIV` creates a div element and inserts it.
  22. `aSilk DIV: anObject` creates a div element, inserts it
  23. and puts contents in it"
  24. | selector newElement useArg |
  25. selector := aMessage selector.
  26. selector asUppercase = selector
  27. ifFalse: [ ^ super doesNotUnderstand: aMessage ].
  28. selector last = ':'
  29. ifTrue: [ useArg := true. selector := selector allButLast ]
  30. ifFalse: [ useArg := false ].
  31. (selector includes: ':')
  32. ifTrue: [ ^ super doesNotUnderstand: aMessage ].
  33. newElement := self class newElement: selector asLowercase.
  34. self << newElement.
  35. useArg ifTrue: [ newElement << aMessage arguments first ].
  36. ^ newElement
  37. !
  38. nextPut: anObject
  39. "Double-dispatches anObject via renderOnSilk: message.
  40. If a message returns nil, this fallbacks to superclass.
  41. Otherwise, it is assumed renderOnSilk: did its job."
  42. (anObject renderOnSilk: self)
  43. ifNil: [ super nextPut: anObject ]
  44. ! !
  45. !Silk class methodsFor: 'message handling'!
  46. doesNotUnderstand: aMessage
  47. "`Silk DIV` creates a div element"
  48. | selector |
  49. selector := aMessage selector.
  50. selector asUppercase = selector
  51. ifFalse: [ ^ super doesNotUnderstand: aMessage ].
  52. (selector includes: ':')
  53. ifTrue: [ ^ super doesNotUnderstand: aMessage ].
  54. ^ self newElement: selector asLowercase
  55. ! !
  56. !BlockClosure methodsFor: '*Silk'!
  57. renderOnSilk: aSilk
  58. self value: aSilk
  59. ! !
  60. !CharacterArray methodsFor: '*Silk'!
  61. asSilk
  62. ^ Silk at: self asString
  63. ! !
  64. !JSObjectProxy methodsFor: '*Silk'!
  65. inSilk
  66. ^ Silk newStream << self; yourself
  67. ! !
  68. !Object methodsFor: '*Silk'!
  69. inSilk
  70. ^ Silk newStream << self; yourself
  71. !
  72. renderOnSilk: aSilk
  73. ^ nil
  74. ! !