hedgedoc/html-to-react/src/utils/convertInlineStyleToMap.ts
jason lim 620b7d9fa8 fix: use more complex parsing for css statement splitting
Signed-off-by: Lim Jia Sheng <50891910+sxxov@users.noreply.github.com>
2024-11-01 15:26:33 +01:00

76 lines
2.1 KiB
TypeScript

/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
/**
* Converts an inline style string into an object of React style properties
*
* @param {String} inlineStyle='' The inline style to convert
* @returns {Object} The converted style
*/
export function convertInlineStyleToMap(
inlineStyle = ''
): Record<string, string> {
if (inlineStyle === '') {
return {}
}
const statements: string[] = []
let i = -1
let offset = 0
do {
i++
let curr = inlineStyle[i]
let prev = inlineStyle[i - 1]
if ((curr === "'" || curr === '"') && prev !== '\\') {
const quote = curr
do {
i++
curr = inlineStyle[i]
prev = inlineStyle[i - 1]
} while (!(curr === quote && prev !== '\\') && i < inlineStyle.length)
continue
}
if (curr === ';' && prev !== '\\') {
statements.push(inlineStyle.slice(offset, i))
offset = i + 1
continue
}
} while (i < inlineStyle.length)
statements.push(inlineStyle.slice(offset, inlineStyle.length))
return statements.reduce<Record<string, string>>(
(styleObject, stylePropertyValue) => {
// extract the style property name and value
const [property, value] = stylePropertyValue
.split(/^([^:]+):/)
.filter((val, i) => i > 0)
.map((item) => item.trim())
// if there is no value (i.e. no : in the style) then ignore it
if (value === undefined) {
return styleObject
}
// convert the property name into the correct React format
// remove all hyphens and convert the letter immediately after each hyphen to upper case
// additionally don't uppercase any -ms- prefix
// e.g. -ms-style-property = msStyleProperty
// -webkit-style-property = WebkitStyleProperty
const replacedProperty = property
.toLowerCase()
.replace(/^-ms-/, 'ms-')
.replace(/-(.)/g, (_, character: string) => character.toUpperCase())
// add the new style property and value to the style object
styleObject[replacedProperty] = value
return styleObject
},
{}
)
}