summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-05-25 18:20:56 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-05-25 18:20:56 +0200
commitd02a59ad4984144125b98a4b1900138d8363eb3e (patch)
tree207f71dab22aaefe600c9a6faddb2695578972e2
parented0a0286a6bc1772c0bace457e900bf7123cb39e (diff)
Adds a way to do some additive CSS.
As baffling as it may appear, Cascading Style Sheets cannot actually do cascading property values through multiple classes (you can only override the previous value, not see it). You'd think there would be a "current()" function which returns the not-yet-evaluated, about-to-be-overridden current value of the attribute, but no, there is not. There is no way to have any equivalent either, and since it's been nearly a decade they've seen propositions to address this deficiency without actually adding any, I wouldn't expect things to change within the next decade either. Doesn't help that they seem to consider the issue to be intertwined with the animation attributes, whereas it ought to be a generic thing.
-rw-r--r--src/css/src/shared/additive-css.scss185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/css/src/shared/additive-css.scss b/src/css/src/shared/additive-css.scss
new file mode 100644
index 0000000..da077e9
--- /dev/null
+++ b/src/css/src/shared/additive-css.scss
@@ -0,0 +1,185 @@
+@use "sass:list";
+@use "sass:map";
+
+$collections: ();
+$properties: ();
+$var-prefix: additive;
+
+@function variable-name ($collection, $property, $instance)
+{
+ @return --#{$var-prefix}-#{$collection}-#{$property}-#{$instance};
+}
+
+@mixin new-collection ($collection)
+{
+ @if (map-has-key($collections, $collection))
+ {
+ @warn "Additive collection #{$collection} is declared multiple times."
+ }
+ @else
+ {
+ $new_collection:
+ (
+ "instances": 0,
+ "has_been_used": false,
+ "properties": ()
+ );
+
+ $collections:
+ map-merge($collections, ($collection: $new_collection))
+ !global;
+ }
+}
+
+@mixin new-property ($property, $neutral-value)
+{
+ @if (map-has-key($properties, $property))
+ {
+ @if (not (map-get($properties, $property) == $neutral-value))
+ {
+ @warn "Additive property #{$property} has multiple default values.";
+ }
+ }
+ @else
+ {
+ $properties:
+ map-merge($properties, ($property: $neutral-value))
+ !global;
+ }
+}
+
+@mixin add-property-to-collection ($collection, $property)
+{
+ @if (not map-has-key($properties, $property))
+ {
+ @warn "Adding property to a collection prior to defining default value.";
+ }
+ @if (not map-has-key($collections, $collection))
+ {
+ @error "Adding property to undefined collection.";
+ }
+ $collection-state: map-get($collections, $collection);
+ $collection-state:
+ map-merge(
+ $collection-state,
+ (
+ "properties":
+ append(
+ map-get($collection-state, "properties"),
+ $property
+ )
+ )
+ );
+ $collections:
+ map-merge($collections, ($collection: $collection-state))
+ !global;
+}
+
+@mixin set-property ($collection, $property, $value)
+{
+ @if (not map-has-key($properties, $property))
+ {
+ @error "Using undefined property #{$property}.";
+ }
+ @if (not map-has-key($collections, $collection))
+ {
+ @error "Using undefined collection #{$collection}.";
+ }
+
+ $collection-state: map-get($collections, $collection);
+
+ @if (map-get($collection-state, "has_been_used"))
+ {
+ @error "Adding to a property after it already has been used.";
+ }
+
+ $instances: map-get($collection-state, "instances");
+ $collection-state:
+ map-merge(
+ $collection-state,
+ (
+ "instances":($instances + 1)
+ )
+ );
+ $collections:
+ map-merge($collections, ($collection: $collection-state))
+ !global;
+
+ #{variable-name($collection, $property, $instances)}: $value;
+}
+
+@mixin use-property ($collection, $property, $separator)
+{
+ @if (not map-has-key($properties, $property))
+ {
+ @error "Using undefined property #{$property}.";
+ }
+ @if (not map-has-key($collections, $collection))
+ {
+ @error "Using undefined collection #{$collection}.";
+ }
+ $collection-state: map-get($collections, $collection);
+ $instances: map-get($collection-state, "instances");
+ $collection-state:
+ map-merge(
+ $collection-state,
+ (
+ "has_been_used": true
+ )
+ );
+ $collections:
+ map-merge($collections, ($collection: $collection-state))
+ !global;
+
+ @if (index(map-get($collection-state, "properties"), $property) == null)
+ {
+ @warn "Attempting to get value for unused additive property."
+ }
+ @else
+ {
+ $value: ();
+ @for $i from 0 to $instances
+ {
+ $value:
+ append(
+ $value,
+ var(#{variable_name($collection, $property, $i)}),
+ $separator
+ );
+ }
+
+ #{$property}: #{$value};
+ }
+}
+
+@mixin define-all-neutral-values ()
+{
+ :root
+ {
+ @each $collection, $env in $collections
+ {
+ $collections:
+ map-merge(
+ $collections,
+ (
+ $collection:
+ map-merge(
+ $env,
+ (
+ "has_been_used": true
+ )
+ )
+ )
+ )
+ !global;
+ @each $property in map-get($env, "properties")
+ {
+ $default-value: map-get($properties, $property);
+ @for $i from 0 to map-get($env, "instances")
+ {
+ #{variable_name($collection, $property, $i)}: $default-value;
+ }
+ }
+ }
+ }
+}