2023-11-16 ============================================================================= [Problem] The following import command doesn't work after obfuscated. ----------------------------------------------------------------------------- @import url('https://fonts.googleapis.com/css2?family=Dela+Gothic+One&family=Noto+Serif+JP:wght@200&display=swap'); ----------------------------------------------------------------------------- It turned out that '@' is causing the problem. A solution is `urlencode()` '@' so the URL will be ----------------------------------------------------------------------------- @import url('https://fonts.googleapis.com/css2?family=Dela+Gothic+One&family=Noto+Serif+JP:wght%40200&display=swap'); ============================================================================= ----------------------------------------------------------------------------- Why does @ mark cause the problem? Maybe becuase it's used in URL to separate username:password from domain name. http://username:password@example.com/ - いずれにしても、この@問題はブラウザのJavaScriptで"import"コマンドを送るときにでる問題で Googleフォントのせいではない。Googleフォントのサイト以外でもこれはでるはずだ。 ----------------------------------------------------------------------------- A more generalized solution is to urlencode the entire URL. ==> Wrong because URL in CSS may be alredy urlecncoded. ----------------------------------------------------------------------------- Also, this problem occures only on obfuscated `import url("...")` and `import "..."` it doesn't happen on obfuscated `background:url()` ----------------------------------------------------------------------------- A solution should be change '@' to '%40' for `import ""` ============================================================================= !!!Twist!!! ----------------------------------------------------------------------------- Well, well, well, actually '@' in @import url() works. Check out ----------------------------------------------------------------------------- research/invalid-char-in-css-import ----------------------------------------------------------------------------- Maybe the problem is spliting rules in CCssRuleSpliter? ============================================================================= ============================================================================= In CCssRuleSpliter, '@', '{', and '}' cause the problem in `@import url(...)` Probably because '@' triggers At-rule and '{', and '}' triggers a css block. ============================================================================= CCssRuleSpliterのreCssRuleSplit()関数ないある次にRegExpパターンが原因のようだ。 ----------------------------------------------------------------------------- $at_rule="@[^@{};]+(?:;|({$css_block}))"; ----------------------------------------------------------------------------- これは at_rule が、';'かまたは’{...}'前までに、'@','{','}'がないことを前提にしている。 もし @import url("....") 内に、'@','{','}'があれば誤動作する。 ============================================================================= 解決策は、CCssRelUrlFixer内で、'@', '{', '}', ';' をURLencodeする。そうすれば、 CCssRuleSpliter内で、@[^@{};]+(?:;|({$css_block})) で誤動作することはない。 ============================================================================= ============================================================================= CChyJsComp内で、CCssRelUrlFixerを二回使いように変更する。 ----------------------------------------------------------------------------- //@@ 2023-11-18:modification:begin //@@ (3.A) urlencode '@','{','}',';' $px["keep-quotes"]=true; CCssRelUrlFixer::make($px); //@@ (4) Split into css rules CCssRuleSpliter::make($px); //@@ (3.B) Fix relative url issue $px["keep-quotes"]=false; CCssRelUrlFixer::make($px); //@@ 2023-11-18:modification:end ----------------------------------------------------------------------------- 1回目は、'@','{','}',';' にurlencodeを行う。 2回目は、相対パスに修正を行う。 ============================================================================= ============================================================================= 結局、変更したのは以下の2つのファイルである。 1. CCssRelUrlFixer 2. CChyJsComp 注: CCssRuleSpliterは変更していない。 ============================================================================= 余談になるが、ChromeとFireFoxで、複雑で長い@import文では、解釈可能かどうかで 違いがでることがわかった。 CCssRuleSpliter(import-fonts.css)より... 例えば、以下の@import文を考えてみる。 ----------------------------------------------------------------------------- @import url("gridy.css") supports(display: grid) screen and (max-width: 400px); ----------------------------------------------------------------------------- Chromeでは以下のように解釈されてしまうが、 ----------------------------------------------------------------------------- import url("gridy.css") not all; ----------------------------------------------------------------------------- FireFoxでは以下のように解釈される。 ----------------------------------------------------------------------------- @import url("gridy.css") supports(display: grid) screen and (max-width: 400px); ----------------------------------------------------------------------------- 以下の@import文では、 ----------------------------------------------------------------------------- @import url("whatever.css") supports((selector(h2 > p)) and (font-tech(color-COLRv1))); ----------------------------------------------------------------------------- Chrome、FireFoxのどちらでも、そのまま解釈される。 ----------------------------------------------------------------------------- @import url("whatever.css") supports((selector(h2 > p)) and (font-tech(color-COLRv1))); ----------------------------------------------------------------------------- =============================================================================