Skip to content

Commit

Permalink
feat(gsoc'24): Utils.js file migrated to Typescript + Vue's reactive (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
niladrix719 authored Aug 12, 2024
1 parent 966edae commit 129048f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 80 deletions.
16 changes: 5 additions & 11 deletions src/components/Extra.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@

<!-- --------------------------------------------------------------------------------------------- -->
<!-- Message Display -->
<div id="MessageDiv"></div>
<div id="MessageDiv">
<div v-for="mes in useState().successMessages" class='alert alert-success' role='alert'> {{ mes }}</div>
<div v-for="error in useState().errorMessages" class='alert alert-danger' role='alert'> {{ error }}</div>
</div>
<!-- --------------------------------------------------------------------------------------------- -->

<!-- --------------------------------------------------------------------------------------------- -->
Expand Down Expand Up @@ -173,14 +176,5 @@ import ReportIssue from './ReportIssue/ReportIssue.vue'
import TestBenchPanel from './Panels/TestBenchPanel/TestBenchPanel.vue'
import TestBenchCreator from './Panels/TestBenchPanel/TestBenchCreator.vue'
import TestBenchValidator from './Panels/TestBenchPanel/TestBenchValidator.vue'
import { useLayoutStore } from '#/store/layoutStore'
import { onMounted, ref } from 'vue'
const layoutStore = useLayoutStore()
const layoutElementPanelRef = ref<HTMLElement | null>(null);
onMounted(() => {
layoutStore.layoutElementPanelRef = layoutElementPanelRef.value
})
import { useState } from '#/store/SimulatorStore/state'
</script>
129 changes: 60 additions & 69 deletions src/simulator/src/utils.js → src/simulator/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ import {
import { layoutModeGet } from './layoutMode'
import plotArea from './plotArea'
import { SimulatorStore } from '#/store/SimulatorStore/SimulatorStore'
import { useActions } from '#/store/SimulatorStore/actions'

window.globalScope = undefined
window.lightMode = false // To be deprecated
window.projectId = undefined
window.id = undefined
window.loading = false // Flag - all assets are loaded

var prevErrorMessage // Global variable for error messages
var prevShowMessage // Global variable for error messages
let prevErrorMessage: string | undefined // Global variable for error messages
let prevShowMessage: string | undefined // Global variable for error messages
export function generateId() {
var id = ''
var possible =
let id = ''
const possible =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

for (var i = 0; i < 20; i++) {
for (let i = 0; i < 20; i++) {
id += possible.charAt(Math.floor(Math.random() * possible.length))
}

Expand All @@ -48,39 +49,25 @@ export function clockTick() {

/**
* Helper function to show error
* @param {string} error -The error to be shown
* @category utils
*/
export function showError(error) {
export function showError(error: string) {
errorDetectedSet(true)
// if error ha been shown return
if (error === prevErrorMessage) return
prevErrorMessage = error
var id = Math.floor(Math.random() * 10000)
$('#MessageDiv').append(
`<div class='alert alert-danger' role='alert' id='${id}'> ${error}</div>`
)
setTimeout(() => {
prevErrorMessage = undefined
$(`#${id}`).fadeOut()
}, 1500)

useActions().showMessage(error, 'error')
}

// Helper function to show message
export function showMessage(mes) {
export function showMessage(mes: string) {
if (mes === prevShowMessage) return
prevShowMessage = mes
var id = Math.floor(Math.random() * 10000)
$('#MessageDiv').append(
`<div class='alert alert-success' role='alert' id='${id}'> ${mes}</div>`
)
setTimeout(() => {
prevShowMessage = undefined
$(`#${id}`).fadeOut()
}, 2500)

useActions().showMessage(mes, 'success')
}

export function distance(x1, y1, x2, y2) {
export function distance(x1: number, y1: number, x2: number, y2: number) {
return Math.sqrt((x2 - x1) ** 2) + (y2 - y1) ** 2
}

Expand All @@ -89,22 +76,22 @@ export function distance(x1, y1, x2, y2) {
* @param {Array} a - any array
* @category utils
*/
export function uniq(a) {
var seen = {}
export function uniq(a: any[]) {
const seen: { [key: string]: boolean } = {};
const tmp = a.filter((item) =>
seen.hasOwnProperty(item) ? false : (seen[item] = true)
)
return tmp
);
return tmp;
}

// Generates final verilog code for each element
// Gate = &/|/^
// Invert is true for xNor, Nor, Nand
export function gateGenerateVerilog(gate, invert = false) {
var inputs = []
var outputs = []
let inputs = []
let outputs = []

for (var i = 0; i < this.nodeList.length; i++) {
for (let i = 0; i < this.nodeList.length; i++) {
if (this.nodeList[i].type == NODE_INPUT) {
inputs.push(this.nodeList[i])
} else {
Expand All @@ -114,13 +101,13 @@ export function gateGenerateVerilog(gate, invert = false) {
}
}

var res = 'assign '
let res = 'assign '
if (outputs.length == 1) res += outputs[0].verilogLabel
else res += `{${outputs.map((x) => x.verilogLabel).join(', ')}}`

res += ' = '

var inputParams = inputs.map((x) => x.verilogLabel).join(` ${gate} `)
const inputParams = inputs.map((x) => x.verilogLabel).join(` ${gate} `)
if (invert) {
res += `~(${inputParams});`
} else {
Expand All @@ -130,16 +117,16 @@ export function gateGenerateVerilog(gate, invert = false) {
}

// Helper function to download text
export function download(filename, text) {
var pom = document.createElement('a')
export function download(filename: string, text: string | number | boolean) {
const pom = document.createElement('a')
pom.setAttribute(
'href',
'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
)
pom.setAttribute('download', filename)

if (document.createEvent) {
var event = document.createEvent('MouseEvents')
const event = document.createEvent('MouseEvents')
event.initEvent('click', true, true)
pom.dispatchEvent(event)
} else {
Expand All @@ -148,40 +135,40 @@ export function download(filename, text) {
}

// Helper function to open a new tab
export function openInNewTab(url) {
var win = window.open(url, '_blank')
win.focus()
export function openInNewTab(url: string | URL | undefined) {
const win = window.open(url, '_blank')
win?.focus()
}

export function copyToClipboard(text) {
export function copyToClipboard(text: string) {
const textarea = document.createElement('textarea')

// Move it off-screen.
textarea.style.cssText = 'position: absolute; left: -99999em'

// Set to readonly to prevent mobile devices opening a keyboard when
// text is .select()'ed.
textarea.setAttribute('readonly', true)
textarea.setAttribute('readonly', 'true')

document.body.appendChild(textarea)
textarea.value = text

// Check if there is any content selected previously.
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
document.getSelection()?.rangeCount ?? 0 > 0
? document.getSelection()?.getRangeAt(0)
: false

// iOS Safari blocks programmatic execCommand copying normally, without this hack.
// https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
const editable = textarea.contentEditable
textarea.contentEditable = true
textarea.contentEditable = 'true'
const range = document.createRange()
range.selectNodeContents(textarea)
const sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(range)
sel?.removeAllRanges()
sel?.addRange(range)
textarea.setSelectionRange(0, 999999)
textarea.contentEditable = editable
} else {
Expand All @@ -193,8 +180,8 @@ export function copyToClipboard(text) {

// Restore previous selection.
if (selected) {
document.getSelection().removeAllRanges()
document.getSelection().addRange(selected)
document.getSelection()?.removeAllRanges()
document.getSelection()?.addRange(selected)
}
textarea.remove()
return result
Expand All @@ -205,7 +192,7 @@ export function copyToClipboard(text) {
}
}

export function truncateString(str, num) {
export function truncateString(str: string, num: number) {
// If the length of str is less than or equal to num
// just return str--don't truncate it.
if (str.length <= num) {
Expand All @@ -220,9 +207,9 @@ export function bitConverterDialog() {
simulatorStore.dialogBox.hex_bin_dec_converter_dialog = true
}

export function getImageDimensions(file) {
export function getImageDimensions(file: string) {
return new Promise(function (resolved, rejected) {
var i = new Image()
const i = new Image()
i.onload = function () {
resolved({ w: i.width, h: i.height })
}
Expand All @@ -231,15 +218,15 @@ export function getImageDimensions(file) {
}

// convertors
export var convertors = {
dec2bin: (x) => '0b' + x.toString(2),
dec2hex: (x) => '0x' + x.toString(16),
dec2octal: (x) => '0' + x.toString(8),
dec2bcd: (x) => parseInt(x.toString(10), 16).toString(2),
export const convertors = {
dec2bin: (x: number) => '0b' + x.toString(2),
dec2hex: (x: number) => '0x' + x.toString(16),
dec2octal: (x: number) => '0' + x.toString(8),
dec2bcd: (x: number) => parseInt(x.toString(10), 16).toString(2),
}

export function parseNumber(num) {
if (num instanceof Number) return num
export function parseNumber(num: string | number) {
if(typeof num === 'number') return num;
if (num.slice(0, 2).toLocaleLowerCase() == '0b')
return parseInt(num.slice(2), 2)
if (num.slice(0, 2).toLocaleLowerCase() == '0x')
Expand All @@ -248,26 +235,30 @@ export function parseNumber(num) {
return parseInt(num)
}

export function promptFile(contentType, multiple) {
var input = document.createElement('input')
export function promptFile(contentType: string, multiple: boolean) {
const input = document.createElement('input')
input.type = 'file'
input.multiple = multiple
input.accept = contentType
return new Promise(function (resolve) {
document.activeElement.onfocus = function () {
document.activeElement.onfocus = null
setTimeout(resolve, 500)
if (document.activeElement instanceof HTMLInputElement) {
(document.activeElement as HTMLInputElement).onfocus = function () {
(document.activeElement as HTMLInputElement).onfocus = null;
setTimeout(resolve, 500);
};
}
input.onchange = function () {
var files = Array.from(input.files)
if (multiple) return resolve(files)
resolve(files[0])
const files = input.files
if (files === null) return resolve([])
const fileArray = Array.from(files)
if (multiple) return resolve(fileArray)
resolve(fileArray[0])
}
input.click()
})
}

export function escapeHtml(unsafe) {
export function escapeHtml(unsafe: string) {
return unsafe
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
Expand Down
17 changes: 17 additions & 0 deletions src/store/SimulatorStore/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,26 @@ export const useActions = defineStore('simulatorStore.actions', () => {
function showTitle(): void {
}

function showMessage(message: string, type: 'error' | 'success') {
if (type === 'error') {
state.errorMessages.push(message)
} else {
state.successMessages.push(message)
}

setTimeout(() => {
if (type === 'error') {
state.errorMessages.shift()
} else {
state.successMessages.shift()
}
}, type === 'error' ? 1500 : 2500)
}

// Note you are free to define as many internal functions as you want.
// You only expose the functions that are returned.
return {
showTitle,
showMessage,
}
})
4 changes: 4 additions & 0 deletions src/store/SimulatorStore/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface State {
isVerilog?: boolean
focussed?: boolean
}[];
errorMessages: string[]
successMessages: string[]
circuit_name_clickable: boolean;
dialogBox: {
// create_circuit: boolean
Expand Down Expand Up @@ -41,6 +43,8 @@ export const useState = defineStore({
title: 'Welcome to CircuitVerse Simulator',
activeCircuit: undefined,
circuit_list: [],
errorMessages: [],
successMessages: [],
circuit_name_clickable: false,
dialogBox: {
// create_circuit: false,
Expand Down

0 comments on commit 129048f

Please sign in to comment.