Skip to content

Instantly share code, notes, and snippets.

@milankinen

milankinen/render-dom.diff

Last active Feb 26, 2016
Embed
What would you like to do?
cyclejs-dom isolation mods
@@ -4,6 +4,7 @@ let VDOM = {
h: require(`./virtual-hyperscript`),
diff: require(`virtual-dom/diff`),
patch: require(`virtual-dom/patch`),
+ createElement: require(`virtual-dom/create-element`),
parse: typeof window !== `undefined` ? require(`vdom-parser`) : () => {},
}
let {transposeVTree} = require(`./transposition`)
@@ -60,26 +61,66 @@ function renderRawRootElem$(vtree$, domContainer) {
.flatMap(diffAndPatchToElement$)
}
-function isolateSource(source, scope) {
- return source.select(`.cycle-scope-${scope}`)
+// we could get rid of this mutable varibale if cycle's "isolate"
+// used isolatedSource[key].isolateSink instead of
+// source[key].isolateSink
+const IsolatedRoots$ = {}
+
+function IsolatedVNode(vtree, subject) {
+ this.vtree = vtree
+ this.subject = subject
+}
+
+Object.assign(IsolatedVNode.prototype, {
+ type: `Widget`,
+ init() {
+ let rootNode = VDOM.createElement(this.vtree)
+ this.domNode = rootNode
+ this.subject.onNext(rootNode)
+ return rootNode
+ },
+ update() {
+ let patches = VDOM.diff(prev.vtree, this.vtree)
+ return VDOM.patch(domNode, patches)
+ },
+ destroy() {
+ delete this.domNode
+ this.subject.onCompleted()
+ }
+})
+
+
+function isolateSource(_, scope) {
+ let isolatedRoot$ = IsolatedRoots$[scope] = new Rx.ReplaySubject(1)
+ return {
+ observable: isolatedRoot$,
+ namespace: [],
+ select: makeElementSelector(isolatedRoot$),
+ events: makeEventsSelector(isolatedRoot$, []),
+ dispose: () => isolatedRoot$.onCompleted(),
+ isolateSource,
+ isolateSink
+ }
}
function isolateSink(sink, scope) {
- return sink.map(vtree => {
- const {className: vtreeClass = ``} = vtree.properties
- if (vtreeClass.indexOf(`cycle-scope-${scope}`) === -1) {
- const c = `${vtreeClass} cycle-scope-${scope}`.trim()
- vtree.properties.className = c
- }
- if (vtree.properties.attributes) { // for svg root elements
- const vtreeAttrClass = vtree.properties.attributes[`class`] || ``
- if (vtreeAttrClass.indexOf(`cycle-scope-${scope}`) === -1) {
- const cattr = `${vtreeAttrClass} cycle-scope-${scope}`.trim()
- vtree.properties.attributes[`class`] = cattr
+ return sink
+ .share()
+ .startWith(null)
+ .scan((widget, vtree) => {
+ if (!widget) {
+ widget = new IsolatedVNode(vtree, IsolatedRoots$[scope])
+ } else {
+ // well.. actually we are performing side-effects here but in every
+ // proper library there smells oil inside the engine room ;-)
+ let patches = VDOM.diff(widget.vtree, vtree)
+ widget.vtree = vtree
+ VDOM.patch(widget.domNode, patches)
}
- }
- return vtree
- })
+ return widget
+ })
+ .filter(root => root !== null)
+ .distinctUntilChanged()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.