DOMite.st 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. Smalltalk createPackage: 'DOMite'!
  2. Object subclass: #Domite
  3. instanceVariableNames: 'element reference'
  4. package: 'DOMite'!
  5. !Domite commentStamp!
  6. I am (hopefully thin) wrapper around the notion of "cursor in a page".
  7. I represent a DOM node _and_ a point where
  8. to insert new content into it.
  9. So I play both the role of a container that inserts
  10. as well as the role of an element being inserted.
  11. Creation API:
  12. - `Domite new` creates an insertion point at the bottom of `<body>`.
  13. - `Domite open` is unique way to create pieces of content. It creates an instance "floating in thin air" (wrapper around DOM DocumentFragment) that can be filled with any contents and then inserted in a page.
  14. - `Domite fromElement: aDomElement` wraps an element and set the cursor to its end.
  15. Manipulation API:
  16. - `aDomite insertDomite:` and `aDomite insertString:` insert either a Domite or a text content at the insertion point.
  17. - `aDomite clearHere` deletes contents of the wrapped element.
  18. Cursor moving API:
  19. Take this sample HTML, where `[n]` are just markers, not real content:
  20. ```
  21. <body>
  22. <h1>header</h1>
  23. [4]<p>[2]Hello[1]world[3]</p>[5]
  24. <small>footer</small>
  25. </body>
  26. ```
  27. If `d` is a `Domite` representing `[1]`, then:
  28. - `d seekHereStart` would move `d` to be at `[2]`,
  29. - `d seekHereEnd` would move `d` to be at `[3]`,
  30. - `d seekBeforeHere` would move `d` to be at `[4]`, and
  31. - `d seekAfterHere` would move `d` to be at `[5]`.
  32. It is not presumed one would use `seekXxx`
  33. to actually move around in a single instance.
  34. It is envisioned this API will be used mostly
  35. in combination with `copy`, like
  36. `afterMe := self copy seekAfterHere`.!
  37. !Domite methodsFor: 'accessing'!
  38. element
  39. ^ element
  40. !
  41. element: anObject
  42. element := anObject
  43. !
  44. reference
  45. ^ reference
  46. !
  47. reference: anObject
  48. reference := anObject
  49. ! !
  50. !Domite methodsFor: 'deletion'!
  51. clearHere
  52. <
  53. var element = self['@element'], child;
  54. while (child = element.firstChild) element.removeChild(child);
  55. self['@reference'] = null;
  56. >
  57. ! !
  58. !Domite methodsFor: 'events'!
  59. off: aString unbind: aBlock
  60. self removeEventListener: aString block: aBlock useCapture: false
  61. !
  62. on: aString bind: aBlock
  63. self addEventListener: aString block: aBlock useCapture: false
  64. ! !
  65. !Domite methodsFor: 'initialization'!
  66. initialize
  67. super initialize.
  68. element := document body.
  69. reference := nil asJSON
  70. ! !
  71. !Domite methodsFor: 'insertion'!
  72. insertDomite: aDomite
  73. self insertElement: aDomite element
  74. !
  75. insertElement: aDomElement
  76. self element
  77. insertBefore: aDomElement
  78. reference: self reference
  79. !
  80. insertString: aString
  81. self insertElement: (
  82. document createTextNode: aString asString )
  83. ! !
  84. !Domite methodsFor: 'navigation'!
  85. seekAfterHere
  86. self
  87. reference: self element nextSibling;
  88. element: self element parentNode
  89. !
  90. seekBeforeHere
  91. self
  92. reference: self element;
  93. element: self element parentNode
  94. !
  95. seekHereEnd
  96. self reference: nil asJSON "null"
  97. !
  98. seekHereStart
  99. self reference: self element firstChild
  100. ! !
  101. !Domite methodsFor: 'testing'!
  102. canSeekOutOfHere
  103. ^ self element parentNode notNil
  104. !
  105. isInvalid
  106. ^ self element isNil
  107. ! !
  108. !Domite class methodsFor: 'instance creation'!
  109. fromElement: aDomElement
  110. ^ self new
  111. element: aDomElement;
  112. yourself
  113. !
  114. fromElement: aDomElement cursorBefore: anotherDomElement
  115. ^ self new
  116. element: aDomElement;
  117. referenceElement: anotherDomElement;
  118. yourself
  119. !
  120. fromSelector: aString
  121. ^ self fromElement: (document querySelector: aString)
  122. !
  123. newElement: aString
  124. ^ self fromElement: (document createElement: aString)
  125. !
  126. open
  127. ^ self fromElement: document createDocumentFragment
  128. ! !