From 822708999e06f362b5c59866efb21b77c8dd82b3 Mon Sep 17 00:00:00 2001 From: jquense Date: Sun, 11 Oct 2015 13:14:13 -0400 Subject: [PATCH] [added] support Component displayName and inferred functionName --- lib/element-selector.js | 7 +------ lib/package.json | 2 +- package.json | 1 + src/compiler.js | 11 +++++++++-- src/utils.js | 17 +++++++++++++++++ test/compiler.js | 30 ++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/lib/element-selector.js b/lib/element-selector.js index d8724ce..4db522e 100644 --- a/lib/element-selector.js +++ b/lib/element-selector.js @@ -73,12 +73,7 @@ function findAll(root, test, includeSelf) { var parent = function parent() { return { parent: root, getParent: getParent }; }; - - if (_react2['default'].isValidElement(child)) { - if (test(child, parent)) found.push(child); - - found = found.concat(findAll(child, test, false, parent)); - } + found = found.concat(findAll(child, test, true, parent)); }); return found; diff --git a/lib/package.json b/lib/package.json index d2d64c9..daddcc9 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,6 +1,6 @@ { "name": "bill", - "version": "1.3.1", + "version": "1.3.2", "description": "css selectors for React Elements", "main": "index.js", "repository": { diff --git a/package.json b/package.json index 5d7c641..edc5a78 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ }, "dependencies": { "css-selector-parser": "^1.1.0", + "fn-name": "^2.0.1", "lodash": "^3.10.1" }, "release-script": { diff --git a/src/compiler.js b/src/compiler.js index 2ba7738..5cc1fde 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -2,10 +2,12 @@ import React from 'react'; import transform from 'lodash/object/transform'; import has from 'lodash/object/has'; import uid from 'lodash/utility/uniqueId'; -import { isTextElement } from './utils'; +import { isTextElement, legacySelector } from './utils'; import { CssSelectorParser } from 'css-selector-parser'; +import fnName from 'fn-name'; let parser = new CssSelectorParser(); +let name = type => type.displayName || fnName(type) || '' let prim = value => { let typ = typeof value; @@ -134,6 +136,9 @@ export function create(options = {}) { } function selector(strings, ...values){ + if (!Array.isArray(strings)) + [ strings, values ] = legacySelector.apply(null, [strings].concat(values)); + let valueMap = Object.create(null); let selector = strings.reduce((rslt, string, idx) => { @@ -163,7 +168,9 @@ function getTagComparer(rule, values) { if (isStr(tagName)){ tagName = tagName.toUpperCase(); - return root => isStr(root.type) && root.type.toUpperCase() === tagName; + return root => isStr(root.type) + ? root.type.toUpperCase() === tagName + : name(root.type).toUpperCase() === tagName; } return root => root.type === tagName diff --git a/src/utils.js b/src/utils.js index 6449e5c..369573a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -22,3 +22,20 @@ export function directParent(test, element, parentNode) { element = parentNode().parent return !!(element && test(element, parentNode().getParent)) } + +export function legacySelector(...args){ + let strings = [] + , values = []; + + args.forEach((arg, idx) => { + let isString = typeof arg === 'string'; + + if (isString) strings.push(arg) + else { + if (idx === 0) strings.push('') + values.push(arg) + } + }) + + return [strings, values] +} diff --git a/test/compiler.js b/test/compiler.js index 695e530..36a5044 100644 --- a/test/compiler.js +++ b/test/compiler.js @@ -101,6 +101,15 @@ describe('create compiler', ()=> { selector.match(/^sub_____\d\.foo$/).should.be.ok }) + it('should create valid selector as a normal function call', ()=>{ + let List = ()=>{}; + let { selector, valueMap } = s(List, '.foo'); + + ;(() => compile(selector)).should.not.throw() + + selector.match(/^sub_____\d\.foo$/).should.be.ok + }) + it('should use == on non interpolated values', ()=>{ let result = compile(s`a[foo=false]`) @@ -120,6 +129,27 @@ describe('create compiler', ()=> { result({ type: 'a', props: { foo: false } }).should.equal(true) }) + it.only('should match inferred name', ()=>{ + let Klass = ()=>{} + let result = compile('Klass.foo') + + result({ + type: Klass, + props: { className: 'foo' } + }).should.equal(true) + }) + + it('should match displayName', ()=>{ + let Klass = ()=>{} + Klass.displayName = 'MyComponent' + let result = compile('MyComponent.foo') + + result({ + type: Klass, + props: { className: 'foo' } + }).should.equal(true) + }) + it('should match interpolated tagName', ()=>{ let Klass = ()=>{} let result = compile(s`${Klass}.foo`)