Skip to content

Unique class names #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ pom.xml.asc
/.idea
.hgignore
.hg/
/.lsp/
/.clj-kondo/
2 changes: 1 addition & 1 deletion src/main/shadow/css.clj
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
;; but may end up emitting invalid references in code
;; which again is fine in JS since it'll just be undefined
css-id
(s/generate-id ns-str line column)
(s/generate-id (vec body))

passthrough
(->> body
Expand Down
27 changes: 19 additions & 8 deletions src/main/shadow/css/build.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,18 @@
(emitln w " " (name prop) ": " (get group-rules prop) ";"))
(emitln w "}")))

(defn emit-def [w {:keys [sel rules at-rules ns line column rules] :as def}]
;; (emitln w (str "/* " ns " " line ":" column " */"))
(defn emit-meta-comments
"Within a single comment, output a list of namespaces, line and column numbers
for a given set of rules."
[w rules]
(emitln w (str "/*\n"
(str/join "\n"
(for [{:keys [ns line column]} rules]
(str ns " " line ":" column )))
"\n*/")))

(defn emit-def [w {:keys [sel rules at-rules ns line column rules] :as def}]
(emit-rule w sel rules)

(doseq [[media-query rules] at-rules]
(emitln w media-query "{")
(emit-rule w sel rules)
Expand All @@ -114,8 +121,12 @@
[(doseq [inc classpath-includes]
(emitln sw (slurp (io/resource inc))))])

(doseq [def rules]
(emit-def sw def))
(doseq [[_ def-rules] (group-by :css-id rules)]
;; emit comments for all of the rules
(emit-meta-comments sw def-rules)
;; but we only need to emit the first actual def
(emit-def sw (first def-rules)))

(.toString sw))))))

(defn collect-namespaces-for-chunk
Expand Down Expand Up @@ -187,8 +198,8 @@
(let [all-rules
(->> (for [ns (:chunk-namespaces chunk)
:let [{:keys [ns css] :as ns-info} (get namespaces ns)]
{:keys [line column] :as form-info} css
:let [css-id (s/generate-id ns line column)]]
{:keys [form] :as form-info} css
:let [css-id (s/generate-id form)]]
(-> (ana/process-form build-state form-info)
(assoc
:ns ns
Expand Down Expand Up @@ -499,4 +510,4 @@
(load-colors-from-classpath)
(load-indexes-from-classpath)
(generate-color-aliases)
(generate-spacing-aliases))))))
(generate-spacing-aliases))))))
29 changes: 20 additions & 9 deletions src/main/shadow/css/specs.cljc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns shadow.css.specs
(:require [clojure.spec.alpha :as s]
[clojure.string :as str]))
[clojure.string :as str]
[clojure.walk :refer [postwalk]]))

(s/def ::alias keyword?)

Expand Down Expand Up @@ -94,11 +95,21 @@
{:parts [] :invalid true :body body :spec (s/explain-data ::class-def body)}
conformed)))

(defn generate-id [ns line column]
(str (-> (str ns)
(str/replace #"\." "_")
(munge))
"__"
"L" line
"_"
"C" column))
(defn generate-id
"Generates a class name which is unique given the contents. Will account for
different ordering within the subqueries."
[rules]
(str "sc-" (postwalk
(fn [rule]
(cond
;; postwalk will give you a vector pair for a map before it
;; gives you the actual map
(map-entry? rule)
rule

(vector? rule)
(hash (sort rule))

:else
(hash rule)))
rules)))
33 changes: 33 additions & 0 deletions src/test/shadow/css/specs_test.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(ns shadow.css.specs-test
(:require
[clojure.test :refer [deftest is testing]]
[shadow.css.specs :as specs]))

(deftest generate-id-test
(testing "Complex ID"
(is (= "sc--1789522625"
(specs/generate-id [:px-4 :my-2
"pass"
:c-text-1
[:&hover :py-10]
[:md+ :px-6
["@media print" :px-2]]
[:lg+ :px-8
[:&hover :py-12]]]))))

(testing "Order of rules"
(testing "doesn't matter within selectors/main list"
(is (= (specs/generate-id [:px-4 :my-2
[:&hover :m-4 :py-10 :px-4]
[:lg+ :px-8
[:&hover :p-4 :py-12]]])
(specs/generate-id [:px-4 :my-2
[:&hover :py-10 :m-4 :px-4]
[:lg+ :px-8
[:&hover :py-12 :p-4]]]))))

(testing "does matter for the whole structure"
(is (not= (specs/generate-id [:m-4
[:&hover :px-4]])
(specs/generate-id [:px-4
[:&hover :m-4]]))))))