Smalltalk createPackage: 'DOMite'! Object subclass: #Domite instanceVariableNames: 'element reference' package: 'DOMite'! !Domite commentStamp! I am (hopefully thin) wrapper around the notion of "cursor in a page". I represent a DOM node _and_ a point where to insert new content into it. So I play both the role of a container that inserts as well as the role of an element being inserted. Creation API: - `Domite new` creates an insertion point at the bottom of ``. - `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. - `Domite fromElement: aDomElement` wraps an element and set the cursor to its end. Manipulation API: - `aDomite insertDomite:` and `aDomite insertString:` insert either a Domite or a text content at the insertion point. - `aDomite clearHere` deletes contents of the wrapped element. Cursor moving API: Take this sample HTML, where `[n]` are just markers, not real content: ```

header

[4]

[2]Hello[1]world[3]

[5] footer ``` If `d` is a `Domite` representing `[1]`, then: - `d seekHereStart` would move `d` to be at `[2]`, - `d seekHereEnd` would move `d` to be at `[3]`, - `d seekBeforeHere` would move `d` to be at `[4]`, and - `d seekAfterHere` would move `d` to be at `[5]`. It is not presumed one would use `seekXxx` to actually move around in a single instance. It is envisioned this API will be used mostly in combination with `copy`, like `afterMe := self copy seekAfterHere`.! !Domite methodsFor: 'accessing'! element ^ element ! element: anObject element := anObject ! reference ^ reference ! reference: anObject reference := anObject ! ! !Domite methodsFor: 'deletion'! clearHere < var element = self['@element'], child; while (child = element.firstChild) element.removeChild(child); self['@reference'] = null; > ! ! !Domite methodsFor: 'initialization'! initialize super initialize. element := document body. reference := nil asJSON ! ! !Domite methodsFor: 'insertion'! insertDomite: aDomite self insertElement: aDomite element ! insertElement: aDomElement self element insertBefore: aDomElement reference: self reference ! insertString: aString self insertElement: ( document createTextNode: aString asString ) ! ! !Domite methodsFor: 'navigation'! seekAfterHere self reference: self element nextSibling; element: self element parentNode ! seekBeforeHere self reference: self element; element: self element parentNode ! seekHereEnd self reference: nil asJSON "null" ! seekHereStart self reference: self element firstChild ! ! !Domite methodsFor: 'testing'! canSeekOutOfHere ^ self element parentNode notNil ! ! !Domite class methodsFor: 'instance creation'! fromElement: aDomElement ^ self new element: aDomElement; yourself ! fromElement: aDomElement cursorBefore: anotherDomElement ^ self new element: aDomElement; referenceElement: anotherDomElement; yourself ! newElement: aString ^ self fromElement: (document createElement: aString) ! open ^ self fromElement: document createDocumentFragment ! !