ClassyKit / Classy

Expressive, flexible, and powerful stylesheets for UIView and friends.
http://classykit.github.io/Classy/
MIT License
740 stars 77 forks source link

Support custom functions in NSExpression / CASExpressionSolver #96

Closed keithnorm closed 9 years ago

keithnorm commented 9 years ago

Hey Jonas, I'm hoping to add some color utility functions to Classy, something like:

UIView.overlay {
  background-color: alpha($some-color, 0.5)
}

This can nearly be done with a UIColor extension that implements alpha:(NSNumber *val) and can be called via NSExpression like this (in Swift):

NSExpression(format: "function(%@, 'alpha:', %f)", someColor, 0.5)

I'd like to implement this in a way that it would get handled by CASExpressionSolver (as opposed to happening within the UIColor transformer the way rgb and related methods are handled) because then it would allow any extension to become callable from within a Classy property.

I spent some time tracing through CASExpressionSolver and I don't fully understand what it's doing, particularly inside of extractTuples. I can probably figure it out given a bit more time but I wanted to see if you could help at all to figure out how I might go about implementing this. Ultimately I think evaluateTokens given a function token just needs to be aware of if the function is built in or custom, and generate the custom function format string if it is custom, but the arguments I need are getting removed in extractTuples I think.

Anyway, if you have any insight or if you have a minute to help me think it through I would appreciate it. Thanks!

keithnorm commented 9 years ago

I got a basic version working but it's a little hacky I think, and it works for cases like

$color = #00ff00
background-color: alpha($color, 0.5);
// and
background-color: alpha(green, 0.5);
// but not
background-color: alpha(rgb(0, 255, 0), 0.5)

because I wasn't quite sure what the best approach was given tokens that have an inner and outer expression like that.

Anyway, check it out if you get a minute and let me know if you have any thoughts on a different approach or anything https://github.com/keithnorm/Classy/pull/2. Thanks!

cloudkite commented 9 years ago

@keithnorm to be honest its been quite a while since I've looked at this. From memory extractTuples is used to try support math expressions with round braces such as

(6 + 1) / (3 - (2 - 0)) // think it supports nesting round braces as well, not sure

its a bit gnarly and fragile, to be honest might be worth removing this to simplify the code base. Can't imagine many people know about or are using this

keithnorm commented 9 years ago

Cool yeah that's what I thought it was doing, though I'm surprised NSExpression doesn't handle that case the right way. I ended up not implementing this inside of the expression resolver though (for various other reasons) so I may not need to mess with it for the time being.

I'll try to get my implementation cleaned up and maybe submit a PR.

Thanks!