Skip to content

Add support for system-ui fallbacks #182

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

Merged
merged 3 commits into from
May 24, 2022
Merged

Add support for system-ui fallbacks #182

merged 3 commits into from
May 24, 2022

Conversation

onigoetz
Copy link
Contributor

The system-ui font family is a special font family that will be changed to the platform's default font family.

This feature will add fallback font families when unsupported

.foo {
  font-family: Helvetica, system-ui, sans-serif;
}

.bar {
  font: 100%/1.5 Helvetica, system-ui, sans-serif;
}

becomes

.foo {
  font-family: Helvetica, system-ui, AppleSystem, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
}

.bar {
  font: 100% / 1.5 Helvetica, system-ui, AppleSystem, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
}

The list of fonts comes from this postcss plugin: https://www.npmjs.com/package/postcss-font-family-system-ui

These are my very first lines of Rust, I'm open to feedback if something isn't idiomatic or could be made more efficiently or anything really :)

Comment on lines +319 to +324
/// safari: Some((13 << 16) | (2 << 8)),
/// ..Browsers::default()
/// };
/// \`\`\`
#[derive(Serialize, Debug, Deserialize, Clone, Copy, Default)]
#[allow(missing_docs)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed these lines to be the same as what the output already contains

Copy link
Member

@devongovett devongovett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! A few comments that might help make it a bit more idiomatic Rust, but what you did was by no means wrong.

Would you also mind adding a test? lib.rs has most of them. It's pretty long but you could add a test to the test_font function in there.

);

return Some(unwrapped_family);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could avoid the unwraps here, and the duplicate contains/position check with something like this:

if let Some(families) = &mut family {
  if let Some(position) = families.iter().position(|v| *v == system_ui) {
    families.splice(
      (position + 1)..(position + 1),
      DEFAULT_SYSTEM_FONTS
        .iter()
        .map(|name| FontFamily::FamilyName(CowArcStr::from(*name))),
    );
  }
}

You'll need to add mut to the definition of family in the function arguments for this to work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truly a fascinating language, thanks, I'll try that construct next time

fn compatible_font_family(family: Option<Vec<FontFamily>>, is_supported: bool) -> Option<Vec<FontFamily>> {
let system_ui = &FontFamily::Generic(GenericFontFamily::SystemUI);

let default_system_fonts: [FontFamily; 8] = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the suggestion below, this could be a const of strings instead:

const DEFAULT_SYSTEM_FONTS: &[&str] = &[
  // #1: Supported as the -apple-system value (only on Mac)
  "AppleSystem",
  // #2: Supported as the 'BlinkMacSystemFont' value (only on Mac)
  "BlinkMacSystemFont",
  "Segoe UI",  // Windows >= Vista
  "Roboto",    // Android >= 4
  "Noto Sans", // Plasma >= 5.5
  "Ubuntu",    // Ubuntu >= 10.10
  "Cantarell", // GNOME >= 3
  "Helvetica Neue",
];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. I tried to extract it before but by keeping the FontFamily and the compiler told me that CowArcStr could not be in a static context. looks better indeed

/// This list is an attempt at providing that support
#[inline]
fn compatible_font_family(family: Option<Vec<FontFamily>>, is_supported: bool) -> Option<Vec<FontFamily>> {
let system_ui = &FontFamily::Generic(GenericFontFamily::SystemUI);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a const

const SYSTEM_UI: FontFamily = FontFamily::Generic(GenericFontFamily::SystemUI);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/// It is platform dependent but if not supported by the target will simply be ignored
/// This list is an attempt at providing that support
#[inline]
fn compatible_font_family(family: Option<Vec<FontFamily>>, is_supported: bool) -> Option<Vec<FontFamily>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could either return early here if is_supported is true, or not even call this function in that case. Either way it would avoid some extra checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose the early return

@onigoetz
Copy link
Contributor Author

Thanks for the feedback, will do that tonight

Indeed I can add tests, forgot to ask you where to put them.

@onigoetz onigoetz requested a review from devongovett May 23, 2022 19:24
"#,
indoc! {r#"
.foo {
font-family: Helvetica, system-ui, AppleSystem, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess system-ui should be first?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it second on purpose, this makes sure that the fonts are added at the right place and don't remove the existing. Also, not everybody has Helvetica so it could make sense to want Helvetica but fallback to whatever system font the person has.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, I misread the input. Thanks!

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@devongovett devongovett merged commit b4d3733 into parcel-bundler:master May 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants