forked from FINAKON/HelpProject
1. Initial Commit - a boiler plate code and POC to realize the concept of context sensitive help 2. Frontend code written in ReactJS 3. Backend code written in Java, Spring Boot Framework 4. Frontend Start: pre-requisites : node, npm npm run dev ==> to start the frontend vite server 5. Backend Start: pre-requisites : java, mvn mvn spring-boot:run ==> to start the backend server 6. Visit http://localhost:5173/ for basic demo of help, press F1 in textboxes 7. Visit http://localhost:5173/editor and enter "admin123" to add/modify texts. Happy Coding !!! Thank you, Bhargava.
262 lines
6.8 KiB
JavaScript
262 lines
6.8 KiB
JavaScript
const util = require('./util')
|
|
|
|
module.exports = function stringify (value, replacer, space) {
|
|
const stack = []
|
|
let indent = ''
|
|
let propertyList
|
|
let replacerFunc
|
|
let gap = ''
|
|
let quote
|
|
|
|
if (
|
|
replacer != null &&
|
|
typeof replacer === 'object' &&
|
|
!Array.isArray(replacer)
|
|
) {
|
|
space = replacer.space
|
|
quote = replacer.quote
|
|
replacer = replacer.replacer
|
|
}
|
|
|
|
if (typeof replacer === 'function') {
|
|
replacerFunc = replacer
|
|
} else if (Array.isArray(replacer)) {
|
|
propertyList = []
|
|
for (const v of replacer) {
|
|
let item
|
|
|
|
if (typeof v === 'string') {
|
|
item = v
|
|
} else if (
|
|
typeof v === 'number' ||
|
|
v instanceof String ||
|
|
v instanceof Number
|
|
) {
|
|
item = String(v)
|
|
}
|
|
|
|
if (item !== undefined && propertyList.indexOf(item) < 0) {
|
|
propertyList.push(item)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (space instanceof Number) {
|
|
space = Number(space)
|
|
} else if (space instanceof String) {
|
|
space = String(space)
|
|
}
|
|
|
|
if (typeof space === 'number') {
|
|
if (space > 0) {
|
|
space = Math.min(10, Math.floor(space))
|
|
gap = ' '.substr(0, space)
|
|
}
|
|
} else if (typeof space === 'string') {
|
|
gap = space.substr(0, 10)
|
|
}
|
|
|
|
return serializeProperty('', {'': value})
|
|
|
|
function serializeProperty (key, holder) {
|
|
let value = holder[key]
|
|
if (value != null) {
|
|
if (typeof value.toJSON5 === 'function') {
|
|
value = value.toJSON5(key)
|
|
} else if (typeof value.toJSON === 'function') {
|
|
value = value.toJSON(key)
|
|
}
|
|
}
|
|
|
|
if (replacerFunc) {
|
|
value = replacerFunc.call(holder, key, value)
|
|
}
|
|
|
|
if (value instanceof Number) {
|
|
value = Number(value)
|
|
} else if (value instanceof String) {
|
|
value = String(value)
|
|
} else if (value instanceof Boolean) {
|
|
value = value.valueOf()
|
|
}
|
|
|
|
switch (value) {
|
|
case null: return 'null'
|
|
case true: return 'true'
|
|
case false: return 'false'
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
return quoteString(value, false)
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
return String(value)
|
|
}
|
|
|
|
if (typeof value === 'object') {
|
|
return Array.isArray(value) ? serializeArray(value) : serializeObject(value)
|
|
}
|
|
|
|
return undefined
|
|
}
|
|
|
|
function quoteString (value) {
|
|
const quotes = {
|
|
"'": 0.1,
|
|
'"': 0.2,
|
|
}
|
|
|
|
const replacements = {
|
|
"'": "\\'",
|
|
'"': '\\"',
|
|
'\\': '\\\\',
|
|
'\b': '\\b',
|
|
'\f': '\\f',
|
|
'\n': '\\n',
|
|
'\r': '\\r',
|
|
'\t': '\\t',
|
|
'\v': '\\v',
|
|
'\0': '\\0',
|
|
'\u2028': '\\u2028',
|
|
'\u2029': '\\u2029',
|
|
}
|
|
|
|
let product = ''
|
|
|
|
for (let i = 0; i < value.length; i++) {
|
|
const c = value[i]
|
|
switch (c) {
|
|
case "'":
|
|
case '"':
|
|
quotes[c]++
|
|
product += c
|
|
continue
|
|
|
|
case '\0':
|
|
if (util.isDigit(value[i + 1])) {
|
|
product += '\\x00'
|
|
continue
|
|
}
|
|
}
|
|
|
|
if (replacements[c]) {
|
|
product += replacements[c]
|
|
continue
|
|
}
|
|
|
|
if (c < ' ') {
|
|
let hexString = c.charCodeAt(0).toString(16)
|
|
product += '\\x' + ('00' + hexString).substring(hexString.length)
|
|
continue
|
|
}
|
|
|
|
product += c
|
|
}
|
|
|
|
const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b)
|
|
|
|
product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar])
|
|
|
|
return quoteChar + product + quoteChar
|
|
}
|
|
|
|
function serializeObject (value) {
|
|
if (stack.indexOf(value) >= 0) {
|
|
throw TypeError('Converting circular structure to JSON5')
|
|
}
|
|
|
|
stack.push(value)
|
|
|
|
let stepback = indent
|
|
indent = indent + gap
|
|
|
|
let keys = propertyList || Object.keys(value)
|
|
let partial = []
|
|
for (const key of keys) {
|
|
const propertyString = serializeProperty(key, value)
|
|
if (propertyString !== undefined) {
|
|
let member = serializeKey(key) + ':'
|
|
if (gap !== '') {
|
|
member += ' '
|
|
}
|
|
member += propertyString
|
|
partial.push(member)
|
|
}
|
|
}
|
|
|
|
let final
|
|
if (partial.length === 0) {
|
|
final = '{}'
|
|
} else {
|
|
let properties
|
|
if (gap === '') {
|
|
properties = partial.join(',')
|
|
final = '{' + properties + '}'
|
|
} else {
|
|
let separator = ',\n' + indent
|
|
properties = partial.join(separator)
|
|
final = '{\n' + indent + properties + ',\n' + stepback + '}'
|
|
}
|
|
}
|
|
|
|
stack.pop()
|
|
indent = stepback
|
|
return final
|
|
}
|
|
|
|
function serializeKey (key) {
|
|
if (key.length === 0) {
|
|
return quoteString(key, true)
|
|
}
|
|
|
|
const firstChar = String.fromCodePoint(key.codePointAt(0))
|
|
if (!util.isIdStartChar(firstChar)) {
|
|
return quoteString(key, true)
|
|
}
|
|
|
|
for (let i = firstChar.length; i < key.length; i++) {
|
|
if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {
|
|
return quoteString(key, true)
|
|
}
|
|
}
|
|
|
|
return key
|
|
}
|
|
|
|
function serializeArray (value) {
|
|
if (stack.indexOf(value) >= 0) {
|
|
throw TypeError('Converting circular structure to JSON5')
|
|
}
|
|
|
|
stack.push(value)
|
|
|
|
let stepback = indent
|
|
indent = indent + gap
|
|
|
|
let partial = []
|
|
for (let i = 0; i < value.length; i++) {
|
|
const propertyString = serializeProperty(String(i), value)
|
|
partial.push((propertyString !== undefined) ? propertyString : 'null')
|
|
}
|
|
|
|
let final
|
|
if (partial.length === 0) {
|
|
final = '[]'
|
|
} else {
|
|
if (gap === '') {
|
|
let properties = partial.join(',')
|
|
final = '[' + properties + ']'
|
|
} else {
|
|
let separator = ',\n' + indent
|
|
let properties = partial.join(separator)
|
|
final = '[\n' + indent + properties + ',\n' + stepback + ']'
|
|
}
|
|
}
|
|
|
|
stack.pop()
|
|
indent = stepback
|
|
return final
|
|
}
|
|
}
|