From 1b731e0af68bcbffa4b082fbafde29715b652813 Mon Sep 17 00:00:00 2001 From: Oleksandr Karpovich Date: Tue, 30 Nov 2021 14:47:30 +0100 Subject: [PATCH] web (breaking change): move top level functions for css selectors to new SelectorsScope (#1504) * web (breaking change): move top level functions for css selectors to new SelectorsScope These functions don't need to be on top level because their purpose is to be used within StyleSheet * web: update CSSSelector plus operator Co-authored-by: Oleksandr Karpovich --- .../jetbrains/compose/web/css/CSSBuilder.kt | 1 - .../jetbrains/compose/web/css/StyleSheet.kt | 5 +- .../compose/web/css/StyleSheetBuilder.kt | 57 ++++++++++++++++++- .../compose/web/css/selectors/CSSSelectors.kt | 50 ---------------- .../src/jsTest/kotlin/CSSStylesheetTests.kt | 2 - .../src/jsTest/kotlin/CssSelectorsTests.kt | 41 +++++++------ .../androidx/compose/web/sample/Sample.kt | 3 - 7 files changed, 83 insertions(+), 76 deletions(-) diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSBuilder.kt b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSBuilder.kt index af504f51e9..2c25442b79 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSBuilder.kt +++ b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSBuilder.kt @@ -1,7 +1,6 @@ package org.jetbrains.compose.web.css import org.jetbrains.compose.web.css.selectors.CSSSelector -import org.jetbrains.compose.web.css.selectors.desc interface CSSBuilder : CSSStyleRuleBuilder, GenericStyleSheetBuilder { val root: CSSSelector diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt index 5a2b94c180..7c698d11cd 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt +++ b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import org.jetbrains.compose.web.ExperimentalComposeWebStyleApi import org.jetbrains.compose.web.css.selectors.CSSSelector -import org.jetbrains.compose.web.css.selectors.className import org.jetbrains.compose.web.dom.Style import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -100,7 +99,7 @@ open class StyleSheet( return if (cssRule != null) { cssRule.selector.unsafeCast().className } else { - val classNameSelector = className("auto-${counter++}") + val classNameSelector = CSSSelector.CSSClass("auto-${counter++}") selfSelector.selector = classNameSelector add(classNameSelector, style) newCssRules.forEach { add(it) } @@ -115,7 +114,7 @@ open class StyleSheet( property: KProperty<*> ): ReadOnlyProperty { val sheetName = if (usePrefix) "${sheet::class.simpleName}-" else "" - val selector = className("$sheetName${property.name}") + val selector = CSSSelector.CSSClass("$sheetName${property.name}") val (properties, rules) = buildCSS(selector, selector, cssBuilder) sheet.add(selector, properties) rules.forEach { sheet.add(it) } diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheetBuilder.kt b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheetBuilder.kt index 5c20d03bec..5aaf5c9c66 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheetBuilder.kt +++ b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheetBuilder.kt @@ -10,7 +10,7 @@ interface CSSRulesHolder { } } -interface GenericStyleSheetBuilder : CSSRulesHolder { +interface GenericStyleSheetBuilder : CSSRulesHolder, SelectorsScope { fun buildRules( rulesBuild: GenericStyleSheetBuilder.() -> Unit ): CSSRuleDeclarationList @@ -34,6 +34,61 @@ interface GenericStyleSheetBuilder : CSSRulesHolder { } } +interface SelectorsScope { + fun selector(selector: String): CSSSelector = CSSSelector.Raw(selector) + fun combine(vararg selectors: CSSSelector): CSSSelector = CSSSelector.Combine(selectors.toMutableList()) + + operator fun CSSSelector.plus(selector: CSSSelector): CSSSelector { + if (this is CSSSelector.Combine) { + this.selectors.add(selector) + return this + } + return if (selector is CSSSelector.Combine) { + selector.selectors.add(0, this) + selector + } else { + combine(this, selector) + } + } + + operator fun CSSSelector.plus(selector: String): CSSSelector { + if (this is CSSSelector.Combine) { + this.selectors.add(selector(selector)) + return this + } + + return combine(this, selector(selector)) + } + + fun universal(): CSSSelector = CSSSelector.Universal + fun type(type: String): CSSSelector = CSSSelector.Type(type) + fun className(className: String): CSSSelector = CSSSelector.CSSClass(className) + fun id(id: String): CSSSelector = CSSSelector.Id(id) + fun attr( + name: String, + value: String? = null, + operator: CSSSelector.Attribute.Operator = CSSSelector.Attribute.Operator.Equals, + caseSensitive: Boolean = true + ): CSSSelector = CSSSelector.Attribute(name, value, operator, caseSensitive) + fun group(vararg selectors: CSSSelector): CSSSelector = CSSSelector.Group(selectors.toList()) + + @Deprecated("Replaced with `desc`", ReplaceWith("desc(parent, selected)")) + fun descendant(parent: CSSSelector, selected: CSSSelector): CSSSelector = desc(parent, selected) + fun desc(parent: CSSSelector, selected: CSSSelector): CSSSelector = CSSSelector.Descendant(parent, selected) + fun desc(parent: CSSSelector, selected: String): CSSSelector = desc(parent, selector(selected)) + fun desc(parent: String, selected: CSSSelector): CSSSelector = desc(selector(parent), selected) + fun desc(parent: String, selected: String): CSSSelector = desc(selector(parent), selector(selected)) + + fun child(parent: CSSSelector, selected: CSSSelector): CSSSelector = + CSSSelector.Child(parent, selected) + fun sibling(sibling: CSSSelector, selected: CSSSelector): CSSSelector = CSSSelector.Sibling(sibling, selected) + fun adjacent(sibling: CSSSelector, selected: CSSSelector): CSSSelector = CSSSelector.Adjacent(sibling, selected) + + fun not(selector: CSSSelector): CSSSelector = CSSSelector.PseudoClass.Not(selector) + fun hover(): CSSSelector = CSSSelector.PseudoClass.hover + fun hover(selector: CSSSelector): CSSSelector = selector + hover() +} + interface StyleSheetBuilder : CSSRulesHolder, GenericStyleSheetBuilder { override fun style(selector: CSSSelector, cssRule: CSSStyleRuleBuilder.() -> Unit) { add(selector, buildCSSStyleRule(cssRule)) diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/selectors/CSSSelectors.kt b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/selectors/CSSSelectors.kt index 075447b9fa..73b4a20ceb 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/selectors/CSSSelectors.kt +++ b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/selectors/CSSSelectors.kt @@ -254,56 +254,6 @@ abstract class CSSSelector { } } -fun selector(selector: String) = CSSSelector.Raw(selector) -fun combine(vararg selectors: CSSSelector) = CSSSelector.Combine(selectors.toMutableList()) -operator fun CSSSelector.plus(selector: CSSSelector) = combine(this, selector) -operator fun CSSSelector.plus(selector: String) = combine(this, selector(selector)) -operator fun CSSSelector.plus(selector: CSSSelector.Combine): CSSSelector.Combine { - selector.selectors.add(0, this) - return selector -} -operator fun CSSSelector.Combine.plus(selector: CSSSelector): CSSSelector.Combine { - this.selectors.add(selector) - return this -} -operator fun CSSSelector.Combine.plus(selector: String): CSSSelector.Combine { - this.selectors.add(selector(selector)) - return this -} - -fun universal() = CSSSelector.Universal -fun type(type: String) = CSSSelector.Type(type) -fun className(className: String) = CSSSelector.CSSClass(className) -fun id(id: String) = CSSSelector.Id(id) -fun attr( - name: String, - value: String? = null, - operator: CSSSelector.Attribute.Operator = CSSSelector.Attribute.Operator.Equals, - caseSensitive: Boolean = true -) = CSSSelector.Attribute(name, value, operator, caseSensitive) -fun group(vararg selectors: CSSSelector) = CSSSelector.Group(selectors.toList()) - -@Deprecated("Replaced with `desc`", ReplaceWith("desc(parent, selected)")) -fun descendant(parent: CSSSelector, selected: CSSSelector) = - desc(parent, selected) -fun desc(parent: CSSSelector, selected: CSSSelector) = - CSSSelector.Descendant(parent, selected) -fun desc(parent: CSSSelector, selected: String) = - desc(parent, selector(selected)) -fun desc(parent: String, selected: CSSSelector) = - desc(selector(parent), selected) -fun desc(parent: String, selected: String) = - desc(selector(parent), selector(selected)) - -fun child(parent: CSSSelector, selected: CSSSelector) = - CSSSelector.Child(parent, selected) -fun sibling(sibling: CSSSelector, selected: CSSSelector) = CSSSelector.Sibling(sibling, selected) -fun adjacent(sibling: CSSSelector, selected: CSSSelector) = CSSSelector.Adjacent(sibling, selected) - -fun not(selector: CSSSelector) = CSSSelector.PseudoClass.Not(selector) -fun hover() = CSSSelector.PseudoClass.hover -fun hover(selector: CSSSelector) = selector + hover() - @Suppress("SuspiciousEqualsCombination") private fun contains(that: CSSSelector, other: CSSSelector, children: List, strict: Boolean): Boolean { return that === other || // exactly same selector diff --git a/web/core/src/jsTest/kotlin/CSSStylesheetTests.kt b/web/core/src/jsTest/kotlin/CSSStylesheetTests.kt index 99aae72382..2418a1d7a5 100644 --- a/web/core/src/jsTest/kotlin/CSSStylesheetTests.kt +++ b/web/core/src/jsTest/kotlin/CSSStylesheetTests.kt @@ -7,8 +7,6 @@ package org.jetbrains.compose.web.core.tests import kotlinx.browser.window import org.jetbrains.compose.web.css.* -import org.jetbrains.compose.web.css.selectors.* -import org.jetbrains.compose.web.css.selectors.plus import org.jetbrains.compose.web.dom.Div import org.jetbrains.compose.web.dom.stringPresentation import org.w3c.dom.HTMLElement diff --git a/web/core/src/jsTest/kotlin/CssSelectorsTests.kt b/web/core/src/jsTest/kotlin/CssSelectorsTests.kt index 6ae98806c1..a1dfa00176 100644 --- a/web/core/src/jsTest/kotlin/CssSelectorsTests.kt +++ b/web/core/src/jsTest/kotlin/CssSelectorsTests.kt @@ -25,22 +25,31 @@ class CssSelectorsTests { @Test fun testPlusOperator() = runTest { - assertEquals("h1:hover", (selector("h1") + hover()).toString()) - - assertEquals( - "h1:hover:enabled", - ((selector("h1") + hover()) + CSSSelector.PseudoClass.enabled).toString() - ) - - assertEquals( - "h1:hover", - (selector("h1") + ":hover").toString() - ) - - assertEquals( - "h1:hover:enabled", - ((selector("h1") + hover()) + ":enabled").toString() - ) + val selectorScope = object : SelectorsScope {} + + with(selectorScope) { + assertEquals("h1:hover", (selector("h1") + hover()).toString()) + + assertEquals( + "h1:hover:enabled", + ((selector("h1") + hover()) + CSSSelector.PseudoClass.enabled).toString() + ) + + assertEquals( + "h1:hover", + (selector("h1") + ":hover").toString() + ) + + assertEquals( + "h1:hover:enabled", + ((selector("h1") + hover()) + ":enabled").toString() + ) + + assertEquals( + "h1:hover:enabled", + (selector("h1") + combine(hover(), selector(":enabled"))).toString() + ) + } } @Test diff --git a/web/integration-core/src/jsMain/kotlin/androidx/compose/web/sample/Sample.kt b/web/integration-core/src/jsMain/kotlin/androidx/compose/web/sample/Sample.kt index ec3d39f6c0..b2027c33e8 100644 --- a/web/integration-core/src/jsMain/kotlin/androidx/compose/web/sample/Sample.kt +++ b/web/integration-core/src/jsMain/kotlin/androidx/compose/web/sample/Sample.kt @@ -8,9 +8,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import org.jetbrains.compose.web.css.selectors.className -import org.jetbrains.compose.web.css.selectors.hover -import org.jetbrains.compose.web.css.selectors.plus import org.jetbrains.compose.web.renderComposableInBody import org.jetbrains.compose.web.sample.tests.launchTestCase import kotlinx.browser.window