Skip to content

Commit

Permalink
[fixed] properly allow iterable children
Browse files Browse the repository at this point in the history
fixes #13
  • Loading branch information
jquense committed Dec 19, 2015
1 parent 40a6df8 commit cbad23f
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ export function create(options = {}) {

if (rule.classNames)
fns.push(
failText(({ props: { className }}) => {
failText(({ props }) => {
let className = props && props.className
return rule.classNames.every(clsName =>
className && className.indexOf(clsName) !== -1)
})
Expand Down
17 changes: 10 additions & 7 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import isPlainObject from 'lodash/lang/isPlainObject';
import { create as createCompiler, parse } from './compiler';
import {
anyParent, directParent
, isDomElement, isCompositeElement
, isDomElement, isCompositeElement, isTextElement
, isReactInstance, isDOMComponent, isCompositeComponent } from './utils';

export function eachChild(subject, fn) {
Expand All @@ -22,15 +22,18 @@ export function eachChild(subject, fn) {
publicInst = inst.getPublicInstance()

if (isDOMComponent(publicInst)) {
let renderedChildren = inst._renderedChildren || {}
let renderedChildren = inst._renderedChildren
, child = element && element.props.children;

if (child != null && !isPlainObject(child) && !Array.isArray(child) && !isReactInstance(child))
// in cases where there is a single child
// renderedChildren will be null if that child is a non-element
// renderable thing, like a string or number.
if (renderedChildren != null)
Object.keys(renderedChildren || {}).forEach(
key => fn(renderedChildren[key])
);
else if (child != null && isTextElement(child))
fn(child)

Object.keys(renderedChildren).forEach(
key => fn(renderedChildren[key])
);
}
else if (isCompositeComponent(publicInst) && inst._renderedComponent != null) {
fn(inst._renderedComponent);
Expand Down
5 changes: 3 additions & 2 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import has from 'lodash/object/has';
import React from 'react';

let isValidPlainElement = element => typeof element === 'object' && element != null;
export let isValidPlainElement =
element => typeof element === 'object' && element != null && has(element, 'type');

export let isTextElement =
element => !isValidPlainElement(element) && element !== false
element => !isValidPlainElement(element) && element !== false && element != null

export let isDomElement =
element => !isTextElement(element) && typeof element.type === 'string' && element.type.toLowerCase() === element.type
Expand Down
24 changes: 23 additions & 1 deletion test/compiler.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import React from 'react';
import { create } from '../src/compiler';
import { isTextElement } from '../src/utils';

let { compile, selector: s } = create()

chai.use(require('sinon-chai'))

describe('create compiler', ()=> {
let compile, s, registerPseudo;

beforeEach(() => {
({ compile, registerPseudo, selector: s } = create())
})

it('should return a function', ()=>{
let result = compile('a.foo')
Expand Down Expand Up @@ -35,10 +40,26 @@ describe('create compiler', ()=> {
}).should.equal(false)
})

it('should handle non element values', ()=> {
registerPseudo('text', ()=> element => isTextElement(element))
let result = compile(':text')

result({}).should.equal(true)
result('hello').should.equal(true)
result(500).should.equal(true)
result(/regex/).should.equal(true)
result([1, 2, 3]).should.equal(true)
result(new Date()).should.equal(true)
result(true).should.equal(true)
result(false).should.equal(false)
result(null).should.equal(false)
})

it('should match props', ()=>{
let result = compile('[foo="5"]')

result({
type: 'p',
props: {
foo: 5
}
Expand All @@ -49,6 +70,7 @@ describe('create compiler', ()=> {
let result = compile('[foo]')

result({
type: 'p',
props: {
foo: true
}
Expand Down
2 changes: 1 addition & 1 deletion test/traversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let renderIntoDocument = (elements) =>

let c = fn => React.createClass({ render(){ return fn(this.props, this.context) } })

describe.only('instance tree traversal', () => {
describe('instance tree traversal', () => {
it('should find all text nodes', ()=> {
let Example = c(()=> <div className="foo"><span className="bar">textme!</span></div>)
let inst = renderIntoDocument(<Example />);
Expand Down

0 comments on commit cbad23f

Please sign in to comment.