@@ -12,21 +12,37 @@ import { layoutModeGet, toggleLayoutMode } from '../layoutMode'
1212import { verilogModeGet } from '../Verilog2CV'
1313import domtoimage from 'dom-to-image'
1414import canvasToSvg from "canvas-to-svg"
15- import { useProjectStore } from '# /store/projectStore'
16- import { provideProjectName } from '# /components/helpers/promptComponent/PromptComponent.vue'
17- import { UpdateProjectDetail } from '# /components/helpers/createNewProject/UpdateProjectDetail.vue'
18- import { confirmOption } from '# /components/helpers/confirmComponent/ConfirmComponent.vue'
19- import { getToken } from '# /pages/simulatorHandler.vue'
15+ import { useProjectStore } from '../../.. /store/projectStore'
16+ import { provideProjectName } from '../../.. /components/helpers/promptComponent/PromptComponent.vue'
17+ import { UpdateProjectDetail } from '../../.. /components/helpers/createNewProject/UpdateProjectDetail.vue'
18+ import { confirmOption } from '../../.. /components/helpers/confirmComponent/ConfirmComponent.vue'
19+ import { getToken } from '../../.. /pages/simulatorHandler.vue'
2020import { renderOrder } from '../metadata'
2121
22- // var projectName = undefined
22+ // Extend Window interface to include global variables
23+ declare global {
24+ interface Window {
25+ globalScope : any
26+ width : number
27+ height : number
28+ projectId : string | number | undefined
29+ isUserLoggedIn : boolean
30+ logixProjectId : string | number | undefined
31+ }
32+ }
33+
34+ // Get global variables from window
35+ const globalScope = window . globalScope
36+ let width = window . width
37+ let height = window . height
38+ const projectId = window . projectId
2339
2440/**
2541 * Function to set the name of project.
2642 * @param {string } name - name for project
2743 * @category data
2844 */
29- export function setProjectName ( name ) {
45+ export function setProjectName ( name : string | undefined ) : void {
3046 const projectStore = useProjectStore ( )
3147 if ( name == undefined ) {
3248 // $('#projectName').html('Untitled')
@@ -43,19 +59,20 @@ export function setProjectName(name) {
4359 * @param {string } name - name for project
4460 * @category data
4561 */
46- export function getProjectName ( ) {
62+ export function getProjectName ( ) : string | undefined {
4763 const projectStore = useProjectStore ( )
4864 if ( projectStore . getProjectNameDefined )
4965 return projectStore . getProjectName . trim ( )
5066 else return undefined
5167}
68+
5269/**
5370 * Helper function to save canvas as image based on image type
5471 * @param {string } name -name of the circuit
5572 * @param {string } imgType - image type ex: png,jpg etc.
5673 * @category data
5774 */
58- function downloadAsImg ( name , imgType ) {
75+ function downloadAsImg ( name : string , imgType : string ) : void {
5976 const gh = simulationArea . canvas . toDataURL ( `image/${ imgType } ` )
6077 const anchor = document . createElement ( 'a' )
6178 anchor . href = gh
@@ -66,31 +83,51 @@ function downloadAsImg(name, imgType) {
6683/**
6784 * Returns the order of tabs in the project
6885 */
69- export function getTabsOrder ( ) {
70- var tabs = document . getElementById ( 'tabsBar' ) . firstChild . children
71- var order = [ ]
72- for ( let i = 0 ; i < tabs ?. length ; i ++ ) {
73- order . push ( tabs [ i ] . id )
86+ export function getTabsOrder ( ) : string [ ] {
87+ const tabs = ( document . getElementById ( 'tabsBar' ) ? .firstChild as HTMLElement ) ? .children
88+ const order : string [ ] = [ ]
89+ for ( let i = 0 ; i < ( tabs ?. length || 0 ) ; i ++ ) {
90+ order . push ( ( tabs as HTMLCollection ) [ i ] . id )
7491 }
7592 return order
7693}
7794
95+ interface SaveData {
96+ name : string
97+ timePeriod : number
98+ clockEnabled : boolean
99+ projectId : string | number | undefined
100+ focussedCircuit : string | number
101+ orderedTabs : string [ ]
102+ scopes : any [ ]
103+ }
104+
78105/**
79106 * Generates JSON of the entire project
80107 * @param {string } name - the name of project
81108 * @return {JSON }
82109 * @category data
83110 */
84- export async function generateSaveData ( name , setName = true ) {
85- let data = { }
111+ export async function generateSaveData ( name ?: string , setName : boolean = true ) : Promise < string | Error > {
112+ let data : SaveData = {
113+ name : '' ,
114+ timePeriod : 0 ,
115+ clockEnabled : false ,
116+ projectId : undefined ,
117+ focussedCircuit : '' ,
118+ orderedTabs : [ ] ,
119+ scopes : [ ]
120+ }
86121
87122 // Prompts for name, defaults to Untitled
88- name = getProjectName ( ) || name || ( await provideProjectName ( ) )
89- if ( name instanceof Error ) {
123+ const projectName = getProjectName ( ) || name || ( await provideProjectName ( ) )
124+ if ( projectName instanceof Error ) {
90125 return new Error ( 'cancel' )
91126 // throw 'save has been canceled'
92- } else if ( name == '' ) {
127+ } else if ( projectName == '' ) {
93128 name = 'Untitled'
129+ } else {
130+ name = projectName
94131 }
95132 data . name = stripTags ( name )
96133 if ( setName ) setProjectName ( data . name )
@@ -104,16 +141,16 @@ export async function generateSaveData(name, setName = true) {
104141
105142 // Project Circuits, each scope is one circuit
106143 data . scopes = [ ]
107- const dependencyList = { }
108- const completed = { }
144+ const dependencyList : { [ key : string ] : string [ ] } = { }
145+ const completed : { [ key : string ] : boolean } = { }
109146 // Getting list of dependencies for each circuit
110- for ( id in scopeList ) {
147+ for ( const id in scopeList ) {
111148 dependencyList [ id ] = scopeList [ id ] . getDependencies ( )
112149 }
113150
114151 // Helper function to save Scope
115152 // Recursively saves inner subcircuits first, before saving parent circuits
116- function saveScope ( id ) {
153+ function saveScope ( id : string ) : void {
117154 if ( completed [ id ] ) return
118155
119156 for ( let i = 0 ; i < dependencyList [ id ] . length ; i ++ ) {
@@ -139,21 +176,21 @@ export async function generateSaveData(name, setName = true) {
139176 }
140177
141178 // convert to text
142- data = JSON . stringify ( data )
143- return data
179+ const dataString = JSON . stringify ( data )
180+ return dataString
144181}
145182
146183// Helper function to download text
147- function download ( filename , text ) {
148- var pom = document . createElement ( 'a' )
184+ function download ( filename : string , text : string ) : void {
185+ const pom = document . createElement ( 'a' )
149186 pom . setAttribute (
150187 'href' ,
151188 'data:text/plain;charset=utf-8,' + encodeURIComponent ( text )
152189 )
153190 pom . setAttribute ( 'download' , filename )
154191
155192 if ( document . createEvent ) {
156- var event = document . createEvent ( 'MouseEvents' )
193+ const event = document . createEvent ( 'MouseEvents' )
157194 event . initEvent ( 'click' , true , true )
158195 pom . dispatchEvent ( event )
159196 } else {
@@ -171,12 +208,12 @@ function download(filename, text) {
171208 * @category data
172209 */
173210export function generateImage (
174- imgType ,
175- view ,
176- transparent ,
177- resolution ,
178- down = true
179- ) {
211+ imgType : string ,
212+ view : string ,
213+ transparent : boolean ,
214+ resolution : number ,
215+ down : boolean = true
216+ ) : string | undefined {
180217 // Backup all data
181218 const backUpOx = globalScope . ox
182219 const backUpOy = globalScope . oy
@@ -204,7 +241,7 @@ export function generateImage(
204241 const scope = globalScope
205242
206243 // Focus circuit
207- var flag = 1
244+ const flag = 1
208245 if ( flag ) {
209246 if ( view === 'full' ) {
210247 findDimensions ( )
@@ -230,18 +267,18 @@ export function generateImage(
230267
231268 simulationArea . canvas . width = width
232269 simulationArea . canvas . height = height
233- backgroundArea . canvas . width = width
234- backgroundArea . canvas . height = height
270+ backgroundArea . canvas ! . width = width
271+ backgroundArea . canvas ! . height = height
235272
236273 backgroundArea . context = simulationArea . context
237274
238275 simulationArea . clear ( )
239276
240277 // Background
241278 if ( ! transparent ) {
242- simulationArea . context . fillStyle = colors [ 'canvas_fill' ]
243- simulationArea . context . rect ( 0 , 0 , width , height )
244- simulationArea . context . fill ( )
279+ simulationArea . context ! . fillStyle = colors [ 'canvas_fill' ]
280+ simulationArea . context ! . rect ( 0 , 0 , width , height )
281+ simulationArea . context ! . fill ( )
245282 }
246283
247284 // Draw circuits
@@ -251,11 +288,11 @@ export function generateImage(
251288 }
252289 }
253290
254- let returnData
291+ let returnData : string | undefined
255292 // If circuit is to be downloaded, download, other wise return dataURL
256293 if ( down ) {
257294 if ( imgType === 'svg' ) {
258- const mySerializedSVG = simulationArea . context . getSerializedSvg ( ) // true here, if you need to convert named to numbered entities.
295+ const mySerializedSVG = ( simulationArea . context as any ) . getSerializedSvg ( ) // true here, if you need to convert named to numbered entities.
259296 download ( `${ globalScope . name } .svg` , mySerializedSVG )
260297 } else {
261298 downloadAsImg ( globalScope . name , imgType )
@@ -269,8 +306,8 @@ export function generateImage(
269306 height = backUpHeight
270307 simulationArea . canvas . width = width
271308 simulationArea . canvas . height = height
272- backgroundArea . canvas . width = width
273- backgroundArea . canvas . height = height
309+ backgroundArea . canvas ! . width = width
310+ backgroundArea . canvas ! . height = height
274311 globalScope . scale = backUpScale
275312 backgroundArea . context = backUpContextBackground
276313 simulationArea . context = backUpContextSimulation
@@ -282,22 +319,21 @@ export function generateImage(
282319 if ( ! down ) return returnData
283320}
284321
285- async function crop ( dataURL , w , h ) {
322+ async function crop ( dataURL : string , w : number , h : number ) : Promise < string > {
286323 //get empty second canvas
287- var myCanvas = document . createElement ( 'CANVAS' )
324+ const myCanvas = document . createElement ( 'CANVAS' ) as HTMLCanvasElement
288325 myCanvas . width = w
289326 myCanvas . height = h
290- var myContext = myCanvas . getContext ( '2d' )
291- var myImage
292- var img = new Image ( )
327+ const myContext = myCanvas . getContext ( '2d' )
328+ const img = new Image ( )
293329 return new Promise ( function ( resolved , rejected ) {
294330 img . src = dataURL
295331 img . onload = ( ) => {
296- myContext . drawImage ( img , 0 , 0 , w , h , 0 , 0 , w , h )
297- myContext . save ( )
332+ myContext ? .drawImage ( img , 0 , 0 , w , h , 0 , 0 , w , h )
333+ myContext ? .save ( )
298334
299335 //create a new data URL
300- myImage = myCanvas . toDataURL ( 'image/jpeg' )
336+ const myImage = myCanvas . toDataURL ( 'image/jpeg' )
301337 resolved ( myImage )
302338 }
303339 } )
@@ -308,22 +344,22 @@ async function crop(dataURL, w, h) {
308344 * @return {JSON }
309345 * @category data
310346 */
311- async function generateImageForOnline ( ) {
347+ async function generateImageForOnline ( ) : Promise < string > {
312348 // Verilog Mode -> Different logic
313349 // Fix aspect ratio to 1.6
314350 // Ensure image is approximately 700 x 440
315- var ratio = 1.6
351+ const ratio = 1.6
316352 if ( verilogModeGet ( ) ) {
317- var node = document . getElementsByClassName ( 'CodeMirror' ) [ 0 ]
353+ const node = document . getElementsByClassName ( 'CodeMirror' ) [ 0 ] as HTMLElement
318354 // var node = document.getElementsByClassName('CodeMirror')[0];
319- var prevHeight = window . getComputedStyle ( node ) . height
320- var prevWidth = window . getComputedStyle ( node ) . width
321- var baseWidth = 500
322- var baseHeight = Math . round ( baseWidth / ratio )
355+ const prevHeight = window . getComputedStyle ( node ) . height
356+ const prevWidth = window . getComputedStyle ( node ) . width
357+ const baseWidth = 500
358+ const baseHeight = Math . round ( baseWidth / ratio )
323359 node . style . height = baseHeight + 'px'
324360 node . style . width = baseWidth + 'px'
325361
326- var data = await domtoimage . toJpeg ( node )
362+ let data = await domtoimage . toJpeg ( node )
327363 node . style . width = prevWidth
328364 node . style . height = prevHeight
329365 data = await crop ( data , baseWidth , baseHeight )
@@ -348,34 +384,35 @@ async function generateImageForOnline() {
348384 440 / ( simulationArea . maxHeight - simulationArea . minHeight )
349385 )
350386
351- data = generateImage ( 'jpeg' , 'current' , false , resolution , false )
387+ const data = generateImage ( 'jpeg' , 'current' , false , resolution , false )
352388
353389 // Restores Focus
354390 globalScope . centerFocus ( false )
355- return data
391+ return data as string
356392}
393+
357394/**
358395 * Function called when you save acircuit online
359396 * @category data
360397 * @exports save
361398 */
362- export default async function save ( ) {
399+ export default async function save ( ) : Promise < void > {
363400 if ( layoutModeGet ( ) ) toggleLayoutMode ( )
364401
365402 projectSavedSet ( true )
366403
367404 const data = await generateSaveData ( )
368405 if ( data instanceof Error ) return
369- let loadingIcon = document . querySelector ( '.loadingIcon' ) ;
406+ let loadingIcon = document . querySelector ( '.loadingIcon' ) as HTMLElement ;
370407 loadingIcon . style . transition = 'opacity 0.5s linear' ;
371408 loadingIcon . style . opacity = '1' ;
372409
373410 const projectName = getProjectName ( )
374- var imageData = await generateImageForOnline ( )
411+ const imageData = await generateImageForOnline ( )
375412
376- const headers = {
413+ const headers : HeadersInit = {
377414 'Content-Type' : 'application/json' ,
378- 'X-CSRF-Token' : document . querySelector ( 'meta[name="csrf-token"]' ) ?. getAttribute ( 'content' ) ,
415+ 'X-CSRF-Token' : document . querySelector ( 'meta[name="csrf-token"]' ) ?. getAttribute ( 'content' ) || '' ,
379416 Authorization : `Token ${ getToken ( 'cvt' ) } ` ,
380417 }
381418
@@ -390,12 +427,12 @@ export default async function save() {
390427 )
391428 window . location . href = '/users/sign_in'
392429 else {
393- let loadingIcon = document . querySelector ( '.loadingIcon' )
430+ let loadingIcon = document . querySelector ( '.loadingIcon' ) as HTMLElement
394431 loadingIcon . style . transition = 'opacity 0.2s' ;
395432 loadingIcon . style . opacity = '0' ;
396433 }
397434 // eslint-disable-next-line camelcase
398- } else if ( [ 0 , undefined , null , '' , '0' ] . includes ( window . logixProjectId ) ) {
435+ } else if ( [ 0 , undefined , null , '' , '0' ] . includes ( window . logixProjectId as any ) ) {
399436 // Create new project - this part needs to be improved and optimised
400437 // const form = $('<form/>', {
401438 // action: '/api/v1/simulator/create',
@@ -447,7 +484,7 @@ export default async function save() {
447484 `We have Created a new project: ${ projectName } in our servers.`
448485 )
449486
450- let loadingIcon = document . querySelector ( '.loadingIcon' )
487+ let loadingIcon = document . querySelector ( '.loadingIcon' ) as HTMLElement
451488 loadingIcon . style . transition = 'opacity 0.2s' ;
452489 loadingIcon . style . opacity = '0' ;
453490
@@ -520,7 +557,7 @@ export default async function save() {
520557 "There was an error, we couldn't save to our servers"
521558 )
522559 }
523- let loadingIcon = document . querySelector ( '.loadingIcon' )
560+ let loadingIcon = document . querySelector ( '.loadingIcon' ) as HTMLElement
524561 loadingIcon . style . transition = 'opacity 0.2s' ;
525562 loadingIcon . style . opacity = '0' ;
526563 } )
0 commit comments