shithub: mycel

Download patch

ref: d61b126cf6eb12fa51c0ccb4d12114d524c7a9f8
parent: d09f37f9a1ae9736abe320071764ffdfa3a61957
author: Philip Silva <philip.silva@protonmail.com>
date: Sun Jan 16 10:04:23 EST 2022

Parse out @imports

--- a/style/css.go
+++ b/style/css.go
@@ -33,7 +33,7 @@
 	Val       string
 }
 
-func Preprocess(s string) (bs []byte, ct opossum.ContentType, err error) {
+func Preprocess(s string) (bs []byte, ct opossum.ContentType, imports []string, err error) {
 	buf := bytes.NewBufferString("")
 	l := css.NewLexer(parse.NewInputString(s))
 	ct.MediaType = "text/css"
@@ -57,24 +57,35 @@
 			if tt == css.StringToken {
 				ct.Params["charset"] = string(data)
 			}
-			continue
 		case "@import":
-			continue
+			if tt == css.StringToken || tt == css.URLToken {
+				imports = append(imports, parseUrl(string(data)))
+			}
+		default:
+			buf.Write(data)
 		}
-		if _, err := buf.Write(data); err != nil {
-			return nil, ct, err
-		}
 	}
-	return buf.Bytes(), ct, nil
+	return buf.Bytes(), ct, imports, nil
 }
 
+func parseUrl(u string) string {
+	u = strings.TrimPrefix(u, "url(")
+	u = strings.TrimSuffix(u, ")")
+	u = strings.ReplaceAll(u, `'`, ``)
+	u = strings.ReplaceAll(u, `"`, ``)
+	return u
+}
+
 func Parse(str string, inline bool) (s Sheet, err error) {
 	s.Rules = make([]Rule, 0, 1000)
 	stack := make([]Rule, 0, 2)
 	selectors := make([]Selector, 0, 1)
-	bs, ct, err := Preprocess(str)
+	bs, ct, imports, err := Preprocess(str)
 	if err != nil {
 		return s, fmt.Errorf("preprocess: %v", err)
+	}
+	for _, imp := range imports {
+		log.Infof("skipping import %v", imp)
 	}
 	p := css.NewParser(parse.NewInputString(ct.Utf8(bs)), inline)
 	if inline {
--- a/style/css_test.go
+++ b/style/css_test.go
@@ -234,3 +234,31 @@
 		t.Fatalf("%+v", d)
 	}
 }
+
+func TestPreprocessAtImport(t *testing.T) {
+	// Examples from https://developer.mozilla.org/en-US/docs/Web/CSS/@import
+	imports := map[string]string{
+		`@import url("fineprint.css") print;`:                              `fineprint.css`,
+		`@import url("bluish.css") projection, tv;`:                        `bluish.css`,
+		`@import 'custom.css';`:                                            `custom.css`,
+		`@import url("example://path/folder/");`:                           `example://path/folder/`,
+		`@import "common.css" screen, projection;`:                         `common.css`,
+		`@import url('landscape.css') screen and (orientation:landscape);`: `landscape.css`,
+	}
+	main := `
+		@media only screen and (max-width: 600px) {
+		  body {
+		    background-color: lightblue;
+		  }
+		}
+	`
+	for imp, exp := range imports {
+		_, _, is, err := Preprocess(imp + main)
+		if err != nil {
+			t.Fatalf("%v", err)
+		}
+		if len(is) != 1 || is[0] != exp {
+			t.Fatalf("%+v", is)
+		}
+	}
+}