Skip to content

fix: fix support for function name strings for Sass < 3.5 #117

Merged
ncoden merged 7 commits intofoundation:developfrom
ncoden:fix/sass-3-get-function-compatibility
Jun 5, 2018
Merged

fix: fix support for function name strings for Sass < 3.5 #117
ncoden merged 7 commits intofoundation:developfrom
ncoden:fix/sass-3-get-function-compatibility

Conversation

@ncoden
Copy link
Contributor

@ncoden ncoden commented Jun 3, 2018

In order to improve modular namespacing, Sass 4 will only accepts first-class functions as argument for call() so functions will be called in their own context. As a first step, Sass 3.5 added get-function and throw a warning if a function name string is passed to call().

In #100, we started to use get-function() for all calls to call() to remove the warning and prepare support for Sass 4. This broke Motion UI for all Sass versions < 3.5 as they do not support get-function().

This PR fixes the support for Sass < 3.5 by introducing a set of helpers to safely manage both first-class functions and function name strings.

Note: In most case, get-function() must only be used by the user in its own context. End developer must be encouraged to use first-class functions.

Changes:

  • Add a set of helpers to test, validate and call function and function name stings in a safe way for all Sass versions.
  • Use -mui-is-function instead of a simple string type check as functions can now be first-hand functions with a function type
  • Use -mui-safe-call to handle both first-hand functions and function string names the same way. An error is thrown if the given argument is not callable, with informations about get-function() if relevant.

Added helpers:

  • -mui-is-function($value)
    Return if a given value is a function or a function name string.

  • -mui-is-callable($value)
    Return if a given value is callable.

  • -mui-assert-function($value)
    Check if a given value is callable and throw the appropriate error otherwise

  • -mui-safe-get-function($func)
    Return a reference to the given function or function name string compatible with the current Sass version. For Sass < 3.5, return the passed argument. For Sass >= 3.5, return a first-class function if a function name string was passed.

  • -mui-safe-call($func, $args...)
    Polyfill for the call function supporting both functions and strings.

References:

ncoden added 5 commits June 3, 2018 22:26
…ass 4

In order to improve modular namespacing, LibSass 4 only accepts first-class functions as argument so functions are called in their own context. In most case, `get-function()` must only be used by the user in its own context.  End developer must be encouraged to use first-class functions.

In this library, we need to use it to keep support of function name strings in Sass > 3.5.

Changes:
* Add `-mui-is-function` and `-mui-safe-call` to test and call function in a safe way for all Sass versions.
* Use `-mui-is-function` instead of a simple `string` type check as functions can now be first-hand functions with a `function` type
* Use `-mui-safe-call` to handle both first-hand functions and function string names the same way. A warning is thrown for function string names with Sass >= 3.5
`function-exists()` can only take strings and cannot be called for first-class functions.
…not found

Instead of warning about the usage of function name strings in Sass >= 3.5, check for function arguments and throw the appropriate error if invalid or not found.
@ncoden ncoden changed the title [WIP] fix: fix Sass 3 support for function string names fix: fix support for function name strings for Sass < 3.5 Jun 3, 2018
@ncoden ncoden requested a review from gakimball June 3, 2018 22:42
@ncoden
Copy link
Contributor Author

ncoden commented Jun 3, 2018

Poke @gakimball and @DanielRuf for review. 👋

/// @param {Duration} $duration [1s] - Length of the animation.
/// @param {Duration} $gap [0s] - Amount of time to pause before playing the animation after this one. Use a negative value to make the next effect overlap with the current one.
/// @param {Function} $keyframes... - One or more effect functions to build the keyframe with.
/// @param {Function|String} $keyframes... - One or more effect functions to build the keyframe with.
Copy link
Contributor

Choose a reason for hiding this comment

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

This parameter is technically an arglist given you use .... I believe the correct notation would be {Function[]|String[]}?

Copy link
Contributor Author

@ncoden ncoden Jun 4, 2018

Choose a reason for hiding this comment

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

SassDoc doesn't mention that notation or anything for .... But you built that tool so I'll believe you 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hugogiraudel hmmm... Shouldn't it be {Arglist} actually ? I don't find any reference or usage for the [] notation.

/// @return {*}
///
@function -mui-safe-call($func, $args...) {
$_: -mui-assert-function($func);
Copy link
Contributor

Choose a reason for hiding this comment

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

If you want to make this code a little less odd, you could write it like this:

@function -mui-safe-call($func, $args...) {
  @if (-mui-assert-function($func)) {
    @return call(-mui-safe-get-function($func), $args...);
  }
}

Copy link
Contributor Author

@ncoden ncoden Jun 4, 2018

Choose a reason for hiding this comment

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

This is an assert function. We expect it to throw an error if anything is wrong. I don't think this is odd, but I'll make the change if you think it is really needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand what it does. The fact is, you use an $_ because Sass doesn’t allow calling functions outside of a variable or an expression. That’s a hack. A necessary one, admittedly.

What I believe your code means is “if the function is callable, call it”. Hence why I would wrap it in an @if block. It produces the same result and appears to be slightly more clean to me.

I don’t feel strongly about it, it’s just a comment.

Copy link
Contributor Author

@ncoden ncoden Jun 4, 2018

Choose a reason for hiding this comment

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

Alright, it seems legit. I'll do that 👍

/// @return {Boolean}
///
@function -mui-assert-function($value) {
@if -mui-is-callable($value) == true {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could omit the == true here. :)

@ncoden
Copy link
Contributor Author

ncoden commented Jun 4, 2018

@hugogiraudel Thank you for the review 👍. Do you have an opinion about the approach itself ? Could it be used for SassyList ?

@KittyGiraudel
Copy link
Contributor

I suppose so? I’m not really invested into SassyLists anymore though. :)

@ncoden
Copy link
Contributor Author

ncoden commented Jun 4, 2018

@hugogiraudel I took care of the requested changes. I used Arglist for all argument lists as I found nothing about the [] notation.

@KittyGiraudel
Copy link
Contributor

@ncoden SassDoc does not maintain a list of types, so feel free to use the notation you want. Arglist is good because it is genuinely a valid Sass type, however it doesn’t give much information about the type of elements in the arglist. You could probably use the description for that.

@ncoden
Copy link
Contributor Author

ncoden commented Jun 5, 2018

You could probably use the description for that.

True, I checked for that. We already always precise the type in the description

@ncoden ncoden mentioned this pull request Jun 5, 2018
4 tasks
@ncoden ncoden merged commit 716be70 into foundation:develop Jun 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants