jsMain.styled.CssAccess.kt Maven / Gradle / Ivy
package styled
import js.core.asList
import js.core.jso
import web.buffer.Blob
import web.buffer.BlobPart
import web.cssom.CSSStyleSheet
import web.dom.Element
import web.dom.document
import web.html.HTMLAnchorElement
import web.location.location
import web.storage.localStorage
import web.uievents.CLICK
import web.uievents.MouseEvent
import web.url.URL
import web.window.window
external interface StyledNext {
fun useDevSheet(isDev: Boolean)
fun getStylesheets(): Array
/**
* @param [block] is executed on every CSS text rule in DOM
* @return resulting array of [block] returned values if they are not null
*/
fun mapNotNullRules(block: (String) -> T?): Array
/** @return array of all CSS rules that contain partialCss */
fun getCss(partialCss: String?): Array
/** download a file with CSS rules that contain partialCss */
fun downloadCss(partialCss: String?, filename: String?)
}
internal object GlobalCssAccess {
private enum class SheetType {
Dev,
CSSOM
}
private const val sheetTypeKey: String = "sheetType"
private fun downloadFile(blob: BlobPart, name: String) {
val binaryData = arrayOf(blob)
val blobUrl = URL.createObjectURL(Blob(binaryData, jso { type = "application/text" }))
val link = document.createElement("a") as HTMLAnchorElement
link.href = blobUrl
link.download = name
document.body.appendChild(link)
link.dispatchEvent(MouseEvent(MouseEvent.CLICK, jso { bubbles = true; cancelable = true; view = window }))
document.body.removeChild(link)
}
fun useDevSheet(isDev: Boolean = true) {
localStorage.setItem(sheetTypeKey, if (isDev) SheetType.Dev.name else SheetType.CSSOM.name)
location.reload()
}
fun isDevSheet(): Boolean {
return localStorage.getItem(sheetTypeKey) == SheetType.Dev.name
}
internal fun setupCssHelperFunctions() {
window.asDynamic().StyledNext = object : StyledNext {
override fun useDevSheet(isDev: Boolean) {
[email protected](isDev)
}
override fun getStylesheets(): Array {
return buildList {
for (i in 0 until document.styleSheets.length) {
val node = document.styleSheets.item(i) ?: continue
if ((node.ownerNode as Element).id.startsWith("ksc-global-style")) add(node)
}
}.toTypedArray()
}
override fun mapNotNullRules(block: (String) -> T?): Array {
return getStylesheets().flatMap { sheet ->
sheet.cssRules.asList().mapNotNull { rule ->
block(rule.cssText)
}
}.toTypedArray()
}
override fun getCss(partialCss: String?) = mapNotNullRules { if (it.contains(partialCss ?: "")) it else null }
override fun downloadCss(partialCss: String?, filename: String?) {
downloadFile(getCss(partialCss).joinToString("\n"), filename ?: "index.css")
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy