Skip to content
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

Partially refactors HUGE/Fonts #81

Merged
merged 6 commits into from
Dec 2, 2022
Merged
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
8 changes: 4 additions & 4 deletions core/fonts/private/GetFormat.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
{{ $irregular := dict
"vnd.ms-fontobject" "embedded-opentype"
"font-woff" "woff"
"ttf" "truetype"
"font-sfnt" "truetype"
"otf" "opentype"
"font-sfnt" "opentype"
"ttf" "truetype"
"otf" "opentype"
"svgz" "svg"
}}
{{ with index $irregular $format }}
{{ $format = . }}
{{ end }}

{{ return $format }}
39 changes: 20 additions & 19 deletions core/fonts/private/GetLocals.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,32 @@

@return Slice of strings
*/}}
{{ $local := slice }}
{{ $local_output := slice }}

{{ $config := partialCached "huge/config/Get" "fonts" "fonts" }}

{{/* We add local */}}
{{/* 1. Font local setting is ommited */}}
{{ $add_local := not (isset . "local") }}
{{/* 2. OR font local setting is not `false` */}}
{{ $add_local = $add_local | or (ne .local false) }}
{{/* 2. AND fonts global setting `disable_local` is not true */}}
{{ $add_local = $add_local | and (not $config.disable_local) }}

{{ if $add_local }}
{{ with .local }}
{{/* This safely append the value of .local (a string or a slice) to the $local slice */}}
{{ $local = $local | append . }}
{{ else }}
{{/* If local is not set, we'll build it ourselves based on the font family name */}}
{{ with .family }}
{{ $local = $local | append . }}
{{/* Default is always true, meaning we built it ourselves */}}
{{ $local := true }}

{{ if isset $ "local" }}
{{ $local = $.local }}
{{ end }}
{{/* If local is neither true nor false, it means it is a string or a slice */}}
{{ if not (in (slice true false) $local) }}
{{/* This safely append the value of .local (a string or a slice) to the $local slice */}}
{{ $local_output = $local_output | append $local }}
{{ else }}
{{/* Only if it's true... */}}
{{ if $local }}
{{ with $.family }}
{{ $local_output = $local_output | append . }}
{{/* If a whitespace is in the family name, we can add a local with dash in place of ws */}}
{{ if in . " " }}
{{ $local = $local | append (replace . " " "-") }}
{{ $local_output = $local_output | append (replace . " " "-") }}
{{ end }}
{{ end }}
{{ end }}

{{ end }}
{{ return $local }}

{{ return $local_output }}
40 changes: 40 additions & 0 deletions core/fonts/private/GetMediaType.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{/*
GetFormat
Retrieves the font format of a given resource

@author @regisphilibert

@context Resource (.)

@access private

@returns String

*/}}
{{ $MainType := "font" }}
{{ $SubType := "woff2" }}
{{/* It appears CloudFlare produces an empty string when calling .MediaType.MainType or .MediaType.SubType on a woff2...
As this is by far the best font format these days in terms of support and optimization,
making it default to ensure it is not botched by cloudflare is "ok".
*/}}
{{ with .MediaType.SubType }}
{{ $SubType = . }}
{{ end }}
{{ with .MediaType.MainType }}
{{ $MainType = . }}
{{ end }}

{{ $format := printf "%s/%s" $MainType $SubType }}

{{/* Another weirdness for some files depending on hosting plaftorm.
Some woff file would return application/font-woff
But Chrome will print a `<link rel=preload> has an unsupported `type` value` warning on non-font "types".
*/}}
{{ $irregular := dict
"application/font-woff" "font/woff"
}}
{{ with index $irregular $format }}
{{ $format = . }}
{{ end }}

{{ return $format }}
40 changes: 22 additions & 18 deletions core/fonts/private/GetPreloadTags.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,30 @@
*/}}
{{ $tags := slice }}
{{/* We list all the fonts in order to produce the data for the "prefetch" tags on all its required files */}}
{{ range partialCached "huge/fonts/private/GetFonts" "GetFonts" }}
{{ if .preload }}
{{/* We want to print <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin> */}}
{{ range .resources }}
{{/* We want to print `<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin="anonymous">` */}}
{{ range $font := partialCached "huge/fonts/private/GetFonts" "GetFonts" }}
{{ with $preload := .preload }}
{{ range $font.resources }}
{{ $format := partialCached "huge/fonts/private/GetFormat" . .MediaType.SubType }}
{{/* For now it makes sens to restrict preload to the most supported file format.
Future release will allow other file formats to be preloaded.
*/}}
{{ if eq $format "woff2" }}
{{ $tag := dict
"name" "link"
"attr" (dict
"href" .RelPermalink
"as" "font"
"type" "font/woff2"
"rel" "preload"
"crossorigin" "anonymous"
)}}
{{ $tags = $tags | append $tag }}
{{/* If user resrticts preloading by format */}}
{{ if reflect.IsSlice $preload }}
{{/* If said font format not in the preload format list, we skip this resource */}}
{{ if not (in $preload $format) }}
{{ continue }}
{{ end }}
{{ end }}
{{/* Test above failed, we can proceeed */}}
{{ $tag := dict
"name" "link"
"attr" (dict
"href" .RelPermalink
"as" "font"
"type" (partialCached "huge/fonts/private/GetMediaType" . .)
"rel" "preload"
"crossorigin" "anonymous"
)
}}
{{ $tags = $tags | append $tag }}
{{ end }}
{{ end }}
{{ end }}
Expand Down
70 changes: 44 additions & 26 deletions core/fonts/private/ParseFont.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{/*
ParseFont
Parse data from Module's settings font declaration. For now it only adds a .resources containing the font files assets.
Parse data from Module's settings font declaration and base declarations

@author @regisphilibert

Expand All @@ -9,50 +9,68 @@
@access private

@return Map
String (.family)
String (.file)
Slice (.local)
Boolean (.preload)
Boolean | Slice of Strings (.preload)
String (.tech)
Resources (.resources)
String (.family)?
String (.weight)?
String (.style)?
String (.display)?
String (.variant)?
String (.feature-settings)?
String (.variation-settings)?
Map (.propertiers)
String (.family)
String (.weight)?
String (.style)?
String (.display)?
String (.variant)?
String (.feature-settings)?
String (.variation-settings)?


*/}}
{{ $font := . }}
{{ $s := newScratch }}
{{ $s.Set "data" dict }}

{{ $config := partialCached "huge/config/Get" "fonts" "fonts" }}

{{ with .file }}
{{ with resources.Match (print "/" . ".*") }}
{{/* This ensures woff2 and woff are declared first, it seems we can't realy rely on SubType (cloufflare as '' for woff2...) */}}
{{ with sort . "Name" "desc" }}
{{ $font = merge $font (dict "resources" (sort . "Name" "desc")) }}
{{ $s.SetInMap "data" "resources" (sort . "Name" "desc") }}
{{ end }}
{{ else }}
{{ partial "huge/console/warn" (printf "We did not find matching font files for basename `%s`.\nFont files should be added to the project's `assets` directory and match the relative path set in the font's settings." .) }}
{{ partial "huge/console/warn" (printf "We did not find matching font files for basename `/%s`.\nAs a result no @font-face CSS at-rule will be printed for this font. \nFont files should be added to the project's `assets` directory and match the relative path set in the font's settings." .) }}
{{ end }}
{{ end }}

{{ with partialCached "huge/fonts/private/GetLocals" . . }}
{{ $font = merge $font (dict "local" .) }}
{{ $font := . }}
{{ with $config.cascade }}
{{ $font = merge . $font }}
{{ end }}

{{/* We'll charge the parsed font with its `preload` preference. */}}
{{ $preload := false }}
{{/* First we check for the global setting */}}
{{ $preload_setting := $config.preload | default "always" }}
{{ if partialCached "huge/env/When" $preload_setting $preload_setting }}
{{ $preload = . }}
{{ with partialCached "huge/fonts/private/GetLocals" $font $font }}
{{ $s.SetInMap "data" "local" . }}
{{ end }}
{{/* if preload is set (can be `false`) on the declaration itself, it overwrites global's */}}
{{ if isset $ "preload" }}
{{ $preload = $.preload }}


{{ with partialCached "huge/fonts/private/SanitizeProperties" $font $font }}
{{ $s.SetInMap "data" "properties" . }}
{{ end }}

{{/* We preload by default */}}
{{ $preload := true }}
{{/* We use `isset` to ensure a falsy value is taken into account if set. */}}
{{ if isset $font "preload" }}
{{ $preload = $font.preload }}
{{ end }}


{{ with $font.tech }}
{{ $s.SetInMap "data" "tech" . }}
{{ end }}

{{ $s.SetInMap "data" "preload" $preload }}

{{ if not ($s.Get "data").resources }}
{{ $s.Set "data" dict }}
{{ end }}
{{ $font = merge $font (dict "preload" $preload) }}

{{ return $font }}
{{ return $s.Get "data" }}
39 changes: 9 additions & 30 deletions core/fonts/private/ParseFontface.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@access private

@use
- huge/fonts/privateParseFont
- huge/fonts/private/ParseFont

@return Map
String (.font-family)
Expand All @@ -35,43 +35,22 @@

{{ range . }}
{{ $format := partialCached "huge/fonts/private/GetFormat" . .MediaType.SubType }}
{{ $css_srcs = $css_srcs | append (printf `url("%s") format("%s")` .RelPermalink $format) }}
{{ $src := printf `url("%s") format("%s")` .RelPermalink $format }}
{{ with $font.tech }}
{{ $src = printf `%s tech("%s")` $src . }}
{{ end }}
{{ $css_srcs = $css_srcs | append $src }}
{{ end }}
{{ with $css_srcs }}
{{ $s.SetInMap "font" "src" (delimit . ",\n") }}
{{ end }}
{{ end }}
{{ end }}

{{ $properties := slice
"family"
"weight"
"style"
"display"
"variant"
"feature-settings"
"variation-settings"
"stretch"
}}
{{/* In order to tolerate if user uses `font-{property}: value` in the settings instead of `{property}: value`,
we add font-{property} to the valid properties */}}
{{ range $properties }}
{{ $properties = $properties | append (print "font-" .) }}
{{ end }}

{{ range $property := $properties }}
{{ with index $ . }}
{{ $key := $property }}
{{/* If missing font- we prepend the property */}}
{{ if not (in $key "font-") }}
{{ $key = print "font-" $property }}
{{ with .properties }}
{{ range $key, $v := . }}
{{ $s.SetInMap "font" (print "font-" $key) . }}
{{ end }}
{{ $s.SetInMap "font" $key . }}
{{ end }}
{{ end }}

{{ if not (index ($s.Get "font") "font-display") }}
{{ $s.SetInMap "font" "font-display" "swap" }}
{{ end }}

{{ return $s.Get "font" }}
38 changes: 38 additions & 0 deletions core/fonts/private/SanitizeProperties.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{/*
SanitizeProperties
Eliminate any property which is not a font property to be used in @font-face declaration.
Also clean the key (font-display > display)

@author @regisphilibert

@context Map (.)

@access private

@returns Map

*/}}
{{ $s := newScratch }}
{{ $s.Set "data" dict }}

{{ $property_keys := slice
"family"
"weight"
"style"
"display"
"variant"
"feature-settings"
"variation-settings"
"stretch"
}}
{{ range $key := $property_keys }}
{{ with index $ $key }}
{{ $s.SetInMap "data" $key . }}
{{ else }}
{{ with index $ (printf "font-" $key) }}
{{ $s.SetInMap "data" $key . }}
{{ end }}
{{ end }}
{{ end }}

{{ return $s.Get "data" }}