@@ -23,7 +23,7 @@ import JSZip from 'jszip';
2323
2424import  *  as  Blockly  from  'blockly/core' ; 
2525
26- import  { Block }  from  " ../toolbox/items" ; 
26+ import  { Block }  from  ' ../toolbox/items' ; 
2727import  startingOpModeBlocks  from  '../modules/opmode_start.json' ;  
2828import  startingMechanismBlocks  from  '../modules/mechanism_start.json' ; 
2929import  startingRobotBlocks  from  '../modules/robot_start.json' ; 
@@ -39,6 +39,7 @@ export type Module = {
3939  projectName : string , 
4040  moduleName : string , 
4141  dateModifiedMillis : number , 
42+   className : string , 
4243} ; 
4344
4445export  type  Mechanism  =  Module ; 
@@ -104,6 +105,84 @@ export function findModule(modules: Project[], modulePath: string): Module | nul
104105  return  null ; 
105106} 
106107
108+ /** 
109+  * Makes the given name a valid class name. 
110+  */ 
111+ export  function  onChangeClassName ( name : string ) : string  { 
112+   let  newName  =  '' ; 
113+ 
114+   // Force the first character to be an upper case letter 
115+   let  i  =  0 ; 
116+   for  ( ;  i  <  name . length ;  i ++ )  { 
117+     const  firstChar  =  name . charAt ( 0 ) ; 
118+     if  ( firstChar  >=  'A'  &&  firstChar  <=  'Z' )  { 
119+       newName  +=  firstChar ; 
120+       i ++ ; 
121+       break ; 
122+     }  else  if  ( firstChar  >=  'a'  &&  firstChar  <=  'z' )  { 
123+       newName  +=  firstChar . toUpperCase ( ) ; 
124+       i ++ ; 
125+       break ; 
126+     } 
127+   } 
128+ 
129+   for  ( ;  i  <  name . length ;  i ++ )  { 
130+     const  char  =  name . charAt ( i ) ; 
131+     if  ( ( char  >=  'A'  &&  char  <=  'Z' )  || 
132+         ( char  >=  'a'  &&  char  <=  'z' )  || 
133+         ( char  >=  '0'  &&  char  <=  '9' ) )  { 
134+       newName  +=  char ; 
135+     } 
136+   } 
137+ 
138+   return  newName ; 
139+ } 
140+ 
141+ /** 
142+  * Returns true if the given name is a valid class name. 
143+  */ 
144+ export  function  isValidClassName ( name : string ) : boolean  { 
145+   if  ( name )  { 
146+     return  / ^ [ A - Z ] [ A - Z a - z 0 - 9 ] * $ / . test ( name ) ; 
147+   } 
148+   return  false ; 
149+ } 
150+ 
151+ /** 
152+  * Returns the module name for the given class name. 
153+  */ 
154+ export  function  classNameToModuleName ( className : string ) : boolean  { 
155+   let  moduleName  =  '' ; 
156+   for  ( let  i  =  0 ;  i  <  className . length ;  i ++ )  { 
157+     const  char  =  className . charAt ( i ) ; 
158+     if  ( char  >=  'A'  &&  char  <=  'Z' )  { 
159+       if  ( i  >  0 )  { 
160+         moduleName  +=  '_' ; 
161+       } 
162+       moduleName  +=  char . toLowerCase ( ) ; 
163+     }  else  { 
164+       moduleName  +=  char ; 
165+     } 
166+   } 
167+   return  moduleName ; 
168+ } 
169+ 
170+ /** 
171+  * Returns the class name for the given module name. 
172+  */ 
173+ export  function  moduleNameToClassName ( moduleName : string ) : boolean  { 
174+   let  className  =  '' ; 
175+   let  nextCharUpper  =  true ; 
176+   for  ( let  i  =  0 ;  i  <  moduleName . length ;  i ++ )  { 
177+     const  char  =  moduleName . charAt ( i ) ; 
178+     if  ( char  !==  '_' )  { 
179+       className  +=  nextCharUpper  ? char . toUpperCase ( )  : char ; 
180+     } 
181+     nextCharUpper  =  ( char  ===  '_' ) ; 
182+   } 
183+   return  className ; 
184+ } 
185+ 
107186/** 
108187 * Returns true if the given name is a valid python module name. 
109188 */ 
@@ -180,6 +259,7 @@ export function newProjectContent(projectName: string): string {
180259    projectName : projectName , 
181260    moduleName : projectName , 
182261    dateModifiedMillis : 0 , 
262+     className : moduleNameToClassName ( projectName ) , 
183263  } ; 
184264
185265  return  startingBlocksToModuleContent ( module ,  startingRobotBlocks ) ; 
@@ -195,6 +275,7 @@ export function newMechanismContent(projectName: string, mechanismName: string):
195275    projectName : projectName , 
196276    moduleName : mechanismName , 
197277    dateModifiedMillis : 0 , 
278+     className : moduleNameToClassName ( mechanismName ) , 
198279  } ; 
199280
200281  return  startingBlocksToModuleContent ( module ,  startingMechanismBlocks ) ; 
@@ -210,6 +291,7 @@ export function newOpModeContent(projectName: string, opModeName: string): strin
210291    projectName : projectName , 
211292    moduleName : opModeName , 
212293    dateModifiedMillis : 0 , 
294+     className : moduleNameToClassName ( opModeName ) , 
213295  } ; 
214296
215297  return  startingBlocksToModuleContent ( module ,  startingOpModeBlocks ) ; 
@@ -356,6 +438,7 @@ function _processModuleContentForDownload(
356438    projectName : projectName , 
357439    moduleName : moduleName , 
358440    dateModifiedMillis : 0 , 
441+     className : moduleNameToClassName ( moduleName ) , 
359442  } ; 
360443
361444  // Clear out the python content and exported blocks. 
@@ -455,6 +538,7 @@ export function _processUploadedModule(
455538    projectName : projectName , 
456539    moduleName : moduleName , 
457540    dateModifiedMillis : 0 , 
541+     className : moduleNameToClassName ( moduleName ) , 
458542  } ; 
459543
460544  // Generate the python content and exported blocks. 
0 commit comments