GithubHelp home page GithubHelp logo

cycle-snabbdom's Introduction

cycle-snabbdom Build Status

Deprecation

It's been great, and thank you for using this library :) @cycle/dom is likely reached it's last release candidate, and will be released soon! This library is at 100% parity with it, and is actually a slight step ahead as it has updated to the latest snabbdom 0.5.0 in the process. However, this will be the very last update this library will see. I strongly urge you to start updating your application to Cycle.js Diversity as soon as you can, and to stop using Rx ;)

Alternative DOM driver utilizing the snabbdom library

Install

$ npm install cycle-snabbdom

API

makeDOMDriver(container: string|Element, {modules?: Array})
import {makeDOMDriver} from 'cycle-snabbdom'
makeHTMLDriver()
import {makeHTMLDriver} from 'cycle-snabbdom'
h - thunk - hyperscript-helpers

Shorcuts to snabbdom/h, snabbdom/thunk and hyperscript-helpers

import {h, thunk, div, span, h4} from 'cycle-snabbdom'
modules : Array

Shortcut to snabbdom modules.

import Cycle from '@cycle/core'
import {modules, makeDOMDriver} from 'cycle-snabbdom'
const {
  StyleModule, PropsModule,
  AttrsModule, ClassModule,
  HeroModule, EventsModule,
} = modules
...

Cycle.run(main, {
  DOM: makeDOMDriver('#app', {modules: [
    StyleModule, PropsModule,
    AttrsModule, ClassModule,
    HeroModule, EventsModule
  ]})
})
mockDOMSource()

A testing utility which aids in creating a queryable collection of Observables. Call mockDOMSource giving it an object specifying selectors, eventTypes and their Observables, and get as output an object following the same format as the DOM Driver's source.

Example:

const userEvents = mockDOMSource({
 '.foo': {
   'click': Rx.Observable.just({target: {}}),
   'mouseover': Rx.Observable.just({target: {}})
 },
 '.bar': {
   'scroll': Rx.Observable.just({target: {}})
 }
});

// Usage
const click$ = userEvents.select('.foo').events('click');

Arguments:

mockedSelectors :: Object an object where keys are selector strings and values are objects. Those nested objects have eventType strings as keys and values are Observables you created. Return:

(Object) fake DOM source object, containing a function select() which can be used just like the DOM Driver's source. Call select(selector).events(eventType) on the source object to get the Observable you defined in the input of mockDOMSource.

cycle-snabbdom's People

Contributors

arlair avatar skaterdad avatar tylors avatar widdershin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cycle-snabbdom's Issues

Isolate bug?

I haven't got to the bottom of this, but I'm not sure isolate is working correctly in cycle-snabbdom.

On this demo page that is using cycle-snabbdom:
http://eldarlabs.github.io/cycle-ui-typescript-webpack/

Most of the components default to isolated, but when I view source I only get 3 cycle-scopes.

cycle-scope-cycle16, 17 and 18

It should create cycle-scope classes for anything that has been created with isolate, right?

I also tried passing in the isolate method via sources from the main file to make sure it was aways using the same instance of isolate, but that didn't seem to make any difference.

Silent failures with v1.1

I'm not sure how the commits from 1.0.3 to 1.1.0 have accomplished this, but I discovered my DOM events weren't firing anymore after updating.

Most concerning is that I didn't receive any error messages.

I downgraded to 1.0.3 and everything worked normally again.

These are the observables watching for the events. Could the commit about sorting namespaces have any effect on this?

  const changeDistance$ = DOM.select('input.dist').events('input')
    .debounce(500)
    .map(ev => ev.target.value)
    .map(val => {
      return function updateDist(query) {
        *insert proprietary stuff here
      }
    })

  const changeCountry$ = DOM.select('select.country').events('change')
    .map(ev => ev.target.value)
    .map(val => {
      return function updateCountry(query) {
        *insert proprietary stuff here
      }
    })

not receiving blur or focus events

blur and focus events don't fire. In this simple example the focus event will never cause the dom to update, however the click event will:

import {Observable} from 'rx';
import {div, a, form, textarea} from 'cycle-snabbdom';

const main = sources => {
  const focus$ = Observable.merge(
    sources.DOM.select('.text').events('focus').map(true),
    sources.DOM.select('.text').events('focus').map(false)
  ).startWith(false);

  const click$ = sources.DOM.select('.text').events('click').map(true).startWith(false);

  const vtree$ = Observable.combineLatest(focus$, click$, (focus, clicked) =>
    div('.container', [
      div('.focus', [focus ? 'yes' : 'no']),
      div('.clicked', [clicked ? 'yes' : 'no']),
      form([
        textarea('.text')
      ])
    ])
  );

  return {
    DOM: vtree$
  }
};

export default main

Cannot find module 'snabbdom-to-html' when installing from NPM

Hello ! I am getting the following error when trying to install cycle-snabbdom from NPM :
Cannot find module 'snabbdom-to-html' from '/xxxx/cycle-snabbdom/lib
I am guessing this is the same as #15 reported a while back, but was perhaps not published to npm ? (version numbers match though, so its odd)

Empty hyperscript helpers return undefined

I was converting over to cycle-snabbdom and I think I found a bug.

When going through my existing code bit by bit, I was testing pieces as it exploded and had an empty div that was returning undefined. You could also test with something like a br.

The issue is vTree.data.ns ends up with undefined for data. I modified that one, but then there were multiple style calls with similar issues, eg vnode.data.style, oldVnode.data.style, vnode.data.style giving:

TypeError: Cannot read property 'style' of undefined

I started trying to fix it, but got distracted (and feeling kind of deprived when I found CoffeeScript's existential operator that is not available in JavaScript). I'll try check it out again later.

Access snabbdom-to-html modules when using makeHTMLDriver

Overview

Add modules option for makeHTMLDriver

import Rx from 'rx'
-import toHTML from 'snabbdom-to-html'
+import init from from 'snabbdom-to-html/init'
+import AttrsModule from 'snabbdom-to-html/modules/attributes'
+import StyeModule from 'snabbdom-to-html/modules/style'
import {transposeVTree} from './transposition'

function makeBogusSelect() {
  return function select() {
    return {
      observable: Rx.Observable.empty(),
      events() {
        return Rx.Observable.empty()
      },
    }
  }
}

+const defaultModules = [
+  AttrsModules, StyleModule,
+]

-function makeHTMLDriver() {
+function makeHTMLDriver({modules = defaultModules} = {modules: defaultModules})
+  const toHTML = init(modules)
  return function htmlDriver(vtree$) {
    let output$ = vtree$.flatMapLatest(transposeVTree).last().map(toHTML)
    output$.select = makeBogusSelect()
    return output$
  }
}

export {makeHTMLDriver}

Root element is replaced

It seems that root (container) element is being replaced while DOM update. I belive driver should leave it alone (as @cycle/dom does)

parseTree not handling null vTree

Description

When a null value is passed into parseTree, javascript thinks its typeof = 'object', so it passes this null object along to combineVTreeStreams. That function gives us a runtime error since it can't check for keys on null.

I came across this while making my github search example fancier. Some searches would work perfectly, but others would give this error (funny enough, searches for "cycle" would work, but searches for "react" or "angular" would break). In the end, it turned out Github's API returns "description": null for some repositories. I was just putting the description value as a child of an a tag, without any other wrapping or null checks.

Possible updates to library code

To make debugging easier, the parseTree function could use a null check to throw a new error.

const parseTree =
  vTree => {
    // NEW CODE HERE
    if (vTree === null) {
      throw new Error(`Null tree value`)
    }
    if (vTree.observe) {
      return vTree.flatMap(parseTree)
    } else if (`object` === typeof vTree) {
      const vtree$ = Rx.Observable.just(vTree)
      if (vTree.children && vTree.children.length > 0) {
        return Rx.Observable.combineLatest(
          vtree$,
          ...map(vTree.children, parseTree),
          combineVTreeStreams
        )
      }
      return vtree$
    } else {
      throw new Error(`Unhandled tree value`)
    }
  }

Or it could swallow the error and convert null to an empty string vNode. This is probably not ideal for a library, but for my use cases, this would work fine. Could also post a console warning when this happens.

const parseTree =
  vTree => {
    // NEW CODE HERE
    if (vTree === null) {
      vTree = { text: '' }
    }
    if (vTree.observe) {
      return vTree.flatMap(parseTree)
    } else if (`object` === typeof vTree) {
      const vtree$ = Rx.Observable.just(vTree)
      if (vTree.children && vTree.children.length > 0) {
        return Rx.Observable.combineLatest(
          vtree$,
          ...map(vTree.children, parseTree),
          combineVTreeStreams
        )
      }
      return vtree$
    } else {
      throw new Error(`Unhandled tree value`)
    }
  }

I'll gladly submit a PR if you like either of these options.

v1.0.1 throwing errors with empty children arrays?

I tried updating to 1.0.1 in my examples app, and my examples which bring in data via HTTP requests are throwing errors.

TypeError: Cannot read property 'data' of null

It seems that the updated driver isn't handling null or [] children as well? Not sure if you changed any of that safety code, but both of my routes which start with an empty array are having problems.

In the snippet below, results begins life = []:

  const vtree$ = state$
    .map(({results, loading}) =>
      h('div.page-wrapper', {key: `ghpage`, style: fadeInOutStyle}, [
        h('div.page.github-search-container', {}, [
          h('label.label', {}, 'Search Github Repos:'),
          h('input.field', {props: {type: 'text'}}),
          h('hr'),
          h('section.search-results', {}, results.map(resultView).concat(loading ? loadingSpinner() : null)),
        ]),
      ])
    )

Thanks for the new quick reference to the snabbdom modules, btw ๐Ÿ‘

Hoping to try out the HTML driver soon.

can not make cycle-snabbdom runable with xstream

it seems that cycle-snabbdom stick strictly with rxjs.

When I try to swap to xstream, It failed with error:

Uncaught TypeError: observables[_name2].doOnError is not a function

import Cycle from '@cycle/core'
import {modules, makeDOMDriver, h} from 'cycle-snabbdom'
import xs from 'xstream';
const {
  StyleModule, PropsModule,
  AttrsModule, ClassModule,
  HeroModule, EventsModule,
} = modules

const main = () => ({DOM: xs.of(h('div', 'yoyo'))});
Cycle.run(main, {
  DOM: makeDOMDriver('#application', {modules: [
    StyleModule, PropsModule,
    AttrsModule, ClassModule,
    HeroModule, EventsModule
  ]})
})

Any progress on the 'dirty hack' in Index.js?

Hello! I was very happy to stumble across this repo today. I've been learning Cycle recently, but animations have been a stumbling block. Snabbdom seems to address those nicely, so this driver is just what I was after.

In 'src/index.js', you wrote a comment about something being a hack to workaround a snabbdom bug. Has there been any progress on fixing that? I noticed you're using snabbdom in your Motorcycle-DOM library as well, which doesn't mention any hacks. Is that due to using MOST instead of RxJS?

    const rootElem$ = view$
      .flatMapLatest(parseTree)
      .flatMap(view => {
        // dirty dirty hack to workaround snabbdom bug
        // TODO: FIX!!!!
        rootElem.innerHTML = ''
        let renderContainer = document.createElement(`div`)
        rootElem.appendChild(renderContainer)
        patch(renderContainer, view)
        return Observable.just(rootElem)
      }).replay(null, 1)

Even with the hack in place, would you consider this library stable and usable?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.