@@ -2,6 +2,7 @@ const fs = require('fs');
22const chalk = require ( 'chalk' ) ;
33const pkgDir = require ( 'pkg-dir' ) ;
44const globby = require ( 'globby' ) ;
5+ const stringUtils = require ( 'ember-cli-string-utils' ) ;
56const j = require ( 'jscodeshift' ) . withParser ( 'ts' ) ;
67const debug = require ( 'debug' ) ( 'tagless-ember-components-codemod' ) ;
78
@@ -146,7 +147,47 @@ async function runForPath(path, options = {}) {
146147 }
147148 }
148149
149- // TODO analyze `tagName`, `attributeBindings`, `classNames`, ...
150+ // analyze `elementId`, `attributeBindings`, `classNames` and `classNameBindings`
151+ let elementId = findElementId ( properties ) ;
152+ if ( elementId !== null && elementId . constructor . name === 'NodePath' ) {
153+ console . log (
154+ chalk . yellow ( `${ dimPath } : Unexpected \`elementId\` value: ${ j ( elementId ) . toSource ( ) } ` )
155+ ) ;
156+ continue ;
157+ }
158+ debug ( `${ componentPath } : elementId: %o` , elementId ) ;
159+
160+ let attributeBindings = findAttributeBindings ( properties ) ;
161+ if ( attributeBindings . constructor . name === 'NodePath' ) {
162+ console . log (
163+ chalk . yellow (
164+ `${ dimPath } : Unexpected \`attributeBindings\` value: ${ j ( attributeBindings ) . toSource ( ) } `
165+ )
166+ ) ;
167+ continue ;
168+ }
169+ debug ( `${ componentPath } : attributeBindings: %o` , attributeBindings ) ;
170+
171+ let classNames = findClassNames ( properties ) ;
172+ if ( classNames . constructor . name === 'NodePath' ) {
173+ console . log (
174+ chalk . yellow ( `${ dimPath } : Unexpected \`classNames\` value: ${ j ( classNames ) . toSource ( ) } ` )
175+ ) ;
176+ continue ;
177+ }
178+ debug ( `${ componentPath } : classNames: %o` , classNames ) ;
179+
180+ let classNameBindings = findClassNameBindings ( properties ) ;
181+ if ( classNameBindings . constructor . name === 'NodePath' ) {
182+ console . log (
183+ chalk . yellow (
184+ `${ dimPath } : Unexpected \`classNameBindings\` value: ${ j ( classNameBindings ) . toSource ( ) } `
185+ )
186+ ) ;
187+ continue ;
188+ }
189+ debug ( `${ componentPath } : classNameBindings: %o` , classNameBindings ) ;
190+
150191 // TODO skip on error (warn incl. please report)
151192
152193 // TODO find corresponding template files
@@ -183,4 +224,106 @@ function findTagName(properties) {
183224 return tagNamePath ;
184225}
185226
227+ function findElementId ( properties ) {
228+ let elementIdProperty = properties . filter ( path => isProperty ( path , 'elementId' ) ) [ 0 ] ;
229+ if ( ! elementIdProperty ) {
230+ return null ;
231+ }
232+
233+ let elementIdPath = elementIdProperty . get ( 'value' ) ;
234+ if ( elementIdPath . value . type === 'StringLiteral' ) {
235+ return elementIdPath . value . value ;
236+ }
237+
238+ return elementIdPath ;
239+ }
240+
241+ function findAttributeBindings ( properties ) {
242+ let attrBindingsProperty = properties . filter ( path => isProperty ( path , 'attributeBindings' ) ) [ 0 ] ;
243+ if ( ! attrBindingsProperty ) {
244+ return new Map ( ) ;
245+ }
246+
247+ let arrayPath = attrBindingsProperty . get ( 'value' ) ;
248+ if ( arrayPath . value . type !== 'ArrayExpression' ) {
249+ return arrayPath ;
250+ }
251+
252+ let elements = arrayPath . get ( 'elements' ) . value ;
253+
254+ let attrBindings = new Map ( ) ;
255+ for ( let element of elements ) {
256+ if ( element . type !== 'StringLiteral' ) {
257+ return arrayPath ;
258+ }
259+
260+ let [ from , to ] = element . value . split ( ':' ) ;
261+ attrBindings . set ( from , to || from ) ;
262+ }
263+
264+ return attrBindings ;
265+ }
266+
267+ function findClassNames ( properties ) {
268+ let classNamesProperty = properties . filter ( path => isProperty ( path , 'classNames' ) ) [ 0 ] ;
269+ if ( ! classNamesProperty ) {
270+ return [ ] ;
271+ }
272+
273+ let arrayPath = classNamesProperty . get ( 'value' ) ;
274+ if ( arrayPath . value . type !== 'ArrayExpression' ) {
275+ return arrayPath ;
276+ }
277+
278+ let elements = arrayPath . get ( 'elements' ) . value ;
279+
280+ let classNames = [ ] ;
281+ for ( let element of elements ) {
282+ if ( element . type !== 'StringLiteral' ) {
283+ return arrayPath ;
284+ }
285+
286+ classNames . push ( element . value ) ;
287+ }
288+
289+ return classNames ;
290+ }
291+
292+ function findClassNameBindings ( properties ) {
293+ let classNameBindingsProperty = properties . filter ( path =>
294+ isProperty ( path , 'classNameBindings' )
295+ ) [ 0 ] ;
296+ if ( ! classNameBindingsProperty ) {
297+ return new Map ( ) ;
298+ }
299+
300+ let arrayPath = classNameBindingsProperty . get ( 'value' ) ;
301+ if ( arrayPath . value . type !== 'ArrayExpression' ) {
302+ return arrayPath ;
303+ }
304+
305+ let elements = arrayPath . get ( 'elements' ) . value ;
306+
307+ let classNameBindings = new Map ( ) ;
308+ for ( let element of elements ) {
309+ if ( element . type !== 'StringLiteral' ) {
310+ return arrayPath ;
311+ }
312+
313+ let parts = element . value . split ( ':' ) ;
314+
315+ if ( parts . length === 1 ) {
316+ classNameBindings . set ( parts [ 0 ] , [ stringUtils . dasherize ( parts [ 0 ] ) , null ] ) ;
317+ } else if ( parts . length === 2 ) {
318+ classNameBindings . set ( parts [ 0 ] , [ parts [ 1 ] , null ] ) ;
319+ } else if ( parts . length === 3 ) {
320+ classNameBindings . set ( parts [ 0 ] , [ parts [ 1 ] || null , parts [ 2 ] ] ) ;
321+ } else {
322+ return arrayPath ;
323+ }
324+ }
325+
326+ return classNameBindings ;
327+ }
328+
186329module . exports = { run } ;
0 commit comments