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

API for functions #178

Closed
ai opened this Issue Feb 6, 2015 · 25 comments

Comments

Projects
None yet
8 participants
@ai
Member

ai commented Feb 6, 2015

Many plugins use custom functions. I think Root#replaceValues is not enough.

Let’s coolect your ideas of syntax sugar API to process functions in decl values.

@ai ai added the enhancement label Feb 6, 2015

@MoOx

This comment has been minimized.

Show comment
Hide comment
@MoOx

MoOx Feb 6, 2015

Member

I'm using this in some plugin https://github.com/MoOx/reduce-function-call but it's probably not enough :)

Member

MoOx commented Feb 6, 2015

I'm using this in some plugin https://github.com/MoOx/reduce-function-call but it's probably not enough :)

@ai ai referenced this issue Feb 7, 2015

Closed

Gonzales error #15

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Feb 7, 2015

Member

We should parse arguments:

css.replaceFunctions('func', function (from, to) {
    from.value #=> 1
    from.unit  #=> 'px'
});
Member

ai commented Feb 7, 2015

We should parse arguments:

css.replaceFunctions('func', function (from, to) {
    from.value #=> 1
    from.unit  #=> 'px'
});
@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Feb 7, 2015

Member

@borodean also suggested to parsse color values and showed his proof-of-concept: https://github.com/borodean/postcss-custom-functions

Member

ai commented Feb 7, 2015

@borodean also suggested to parsse color values and showed his proof-of-concept: https://github.com/borodean/postcss-custom-functions

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Feb 7, 2015

Contributor

Redifinition of native functions (calc, element, expression, url) could lead to problems because of special parsing rules defined in CSS. Sass deprecated this feature since 3.4.10

Contributor

borodean commented Feb 7, 2015

Redifinition of native functions (calc, element, expression, url) could lead to problems because of special parsing rules defined in CSS. Sass deprecated this feature since 3.4.10

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Feb 7, 2015

Contributor

@ai the funny thing is that my proof of concept includes everything except for parsing colors.

Contributor

borodean commented Feb 7, 2015

@ai the funny thing is that my proof of concept includes everything except for parsing colors.

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Feb 7, 2015

Member

@borodean Sass can’t parse it because it is a programming language and it must parse there arguments very carefully. We can just return string for plugin developer and it will be his or her problem to parse it.

Member

ai commented Feb 7, 2015

@borodean Sass can’t parse it because it is a programming language and it must parse there arguments very carefully. We can just return string for plugin developer and it will be his or her problem to parse it.

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Feb 7, 2015

Contributor

Argument parser сould also be reused to parse property values. It would become simplier to implement custom properties like size: 10px 20px, position: absolute, 10px 20px auto auto.

Contributor

borodean commented Feb 7, 2015

Argument parser сould also be reused to parse property values. It would become simplier to implement custom properties like size: 10px 20px, position: absolute, 10px 20px auto auto.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Feb 7, 2015

Contributor

This discussion made remember reworkcss/css-value. Dunno if it is relevant.

Contributor

lydell commented Feb 7, 2015

This discussion made remember reworkcss/css-value. Dunno if it is relevant.

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Feb 7, 2015

Contributor

Also, custom functions could be made to be used outside property values.

To resolve path as in postcss-assets:

@import resolve('normalize.css');

In Sass I had function to escape CSS identifiers in selectors to easily write funky classnames:

a:hover,
a.#{ escape(':hover') } { // would become a.\3A hover {
  color: red;
}

To be used later to automate testing of hover styles:

<a class=":hover">I look like hovered!</a>
Contributor

borodean commented Feb 7, 2015

Also, custom functions could be made to be used outside property values.

To resolve path as in postcss-assets:

@import resolve('normalize.css');

In Sass I had function to escape CSS identifiers in selectors to easily write funky classnames:

a:hover,
a.#{ escape(':hover') } { // would become a.\3A hover {
  color: red;
}

To be used later to automate testing of hover styles:

<a class=":hover">I look like hovered!</a>
@TrySound

This comment has been minimized.

Show comment
Hide comment
@TrySound

TrySound Mar 2, 2015

Member

For functions reduce-function-call
Or low level balanced-match

Member

TrySound commented Mar 2, 2015

For functions reduce-function-call
Or low level balanced-match

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Apr 6, 2015

Contributor

Functions should be able to be async, like those accessing the filesystem.

Contributor

borodean commented Apr 6, 2015

Functions should be able to be async, like those accessing the filesystem.

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Apr 13, 2015

Member

Nice project from Rework community https://github.com/reworkcss/rework-plugin-function

Member

ai commented Apr 13, 2015

Nice project from Rework community https://github.com/reworkcss/rework-plugin-function

@1j01

This comment has been minimized.

Show comment
Hide comment
@1j01

1j01 Apr 13, 2015

It must be able to handle cases like a(b(a()), i.e nested functions, computed inside-to-out.
Ideally, this should work between different plugins.

In order to do that, what needs to be done?

I guess plugins need to be able to declare their functions, and then all the functions need to be resolved in one step.

Where would this step be?

You'd want it to come near the end, if not as the very last step.
We don't want every single plugins that use functions to have to tell you to make sure you don't forget include the built in function resolver, so it should default to coming in at the end.
If you need it to come before some step (Is this an actual use case?
Probably), how would you specify it? I'm thinking you could include rework.evaluateFunctions as a step.
Maybe having a built in step that has a default position is a little weird, and plugins would still want to mention that you can specify the time that functions are evaluated. Instead, you could create a different system, maybe where plugins depend on the function plugin, and use its non-plugin-API, and then the function plugin would be able to detect if it hasn't been included and throw a warning/error.
I don't know. But 👍 at any rate. Food for thought.
(Can it just come in at the end? That would make things simpler.)

1j01 commented Apr 13, 2015

It must be able to handle cases like a(b(a()), i.e nested functions, computed inside-to-out.
Ideally, this should work between different plugins.

In order to do that, what needs to be done?

I guess plugins need to be able to declare their functions, and then all the functions need to be resolved in one step.

Where would this step be?

You'd want it to come near the end, if not as the very last step.
We don't want every single plugins that use functions to have to tell you to make sure you don't forget include the built in function resolver, so it should default to coming in at the end.
If you need it to come before some step (Is this an actual use case?
Probably), how would you specify it? I'm thinking you could include rework.evaluateFunctions as a step.
Maybe having a built in step that has a default position is a little weird, and plugins would still want to mention that you can specify the time that functions are evaluated. Instead, you could create a different system, maybe where plugins depend on the function plugin, and use its non-plugin-API, and then the function plugin would be able to detect if it hasn't been included and throw a warning/error.
I don't know. But 👍 at any rate. Food for thought.
(Can it just come in at the end? That would make things simpler.)

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Apr 13, 2015

Member

@1j01 can you show a case, when a(b(a()) is needed?

I am worry, that adding some special case only for functions is not a PostCSS way, when plugins just transforms AST and PostCSS core doesn’t have privitives.

But practice is more important that theoretical purity. If there is some user case, we can think how to handle it.

Member

ai commented Apr 13, 2015

@1j01 can you show a case, when a(b(a()) is needed?

I am worry, that adding some special case only for functions is not a PostCSS way, when plugins just transforms AST and PostCSS core doesn’t have privitives.

But practice is more important that theoretical purity. If there is some user case, we can think how to handle it.

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean Apr 13, 2015

Contributor

@ai for instance, there could be custom functions nested inside default ones:

width: calc(sqrt(2px) + 10%);

And some other plugin could still postprocess calc() functions somehow.

Contributor

borodean commented Apr 13, 2015

@ai for instance, there could be custom functions nested inside default ones:

width: calc(sqrt(2px) + 10%);

And some other plugin could still postprocess calc() functions somehow.

@1j01

This comment has been minimized.

Show comment
Hide comment
@1j01

1j01 Apr 13, 2015

@1j01 Yeah, I don't like the idea of adding special cases either.
I'm sure though that we don't want confusing limitations to the implementation.
For instance, if I tried to use an alpha() plugin with a mix() plugin like alpha(mix(#fff, #f0f, 0.2), 0.8), it would work if the alpha plugin applied after the mix plugin, but not before. If it was before, you might be left with alpha(the result of mix), or the alpha() function might be called with mix(#fff, #f0f, 0.2) as an argument, and it wouldn't make any sense (to the user).
Functions shouldn't apply based on some order you specify outside of your code, they should apply based on the order they are in your code.
So I don't know exactly how this should be facilitated, but I hope it can be.

1j01 commented Apr 13, 2015

@1j01 Yeah, I don't like the idea of adding special cases either.
I'm sure though that we don't want confusing limitations to the implementation.
For instance, if I tried to use an alpha() plugin with a mix() plugin like alpha(mix(#fff, #f0f, 0.2), 0.8), it would work if the alpha plugin applied after the mix plugin, but not before. If it was before, you might be left with alpha(the result of mix), or the alpha() function might be called with mix(#fff, #f0f, 0.2) as an argument, and it wouldn't make any sense (to the user).
Functions shouldn't apply based on some order you specify outside of your code, they should apply based on the order they are in your code.
So I don't know exactly how this should be facilitated, but I hope it can be.

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Apr 13, 2015

Member

@1j01 alpha and mix are good examples.

BTW, functions are not a only example. There are same order problem with mixins and variables (putting postcss-simple-vars before postcss-mixins can broke mixins).

Maaybe we should split this big question to 2 separated small questionis? Functions API for current plugins API. And some flow API or strategy for plugin conflicts?

Member

ai commented Apr 13, 2015

@1j01 alpha and mix are good examples.

BTW, functions are not a only example. There are same order problem with mixins and variables (putting postcss-simple-vars before postcss-mixins can broke mixins).

Maaybe we should split this big question to 2 separated small questionis? Functions API for current plugins API. And some flow API or strategy for plugin conflicts?

@ai ai referenced this issue Apr 13, 2015

Open

Event based API #296

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai Apr 13, 2015

Member

@1j01 I created a seperated issue for loop/order problem #296

Member

ai commented Apr 13, 2015

@1j01 I created a seperated issue for loop/order problem #296

@borodean

This comment has been minimized.

Show comment
Hide comment
@borodean

borodean May 26, 2015

Contributor

@ai when do you expect this to be implemented? Because I'm thinking about extracting my function mapper from postcss-assets to a separate plugin.

Contributor

borodean commented May 26, 2015

@ai when do you expect this to be implemented? Because I'm thinking about extracting my function mapper from postcss-assets to a separate plugin.

@ai

This comment has been minimized.

Show comment
Hide comment
@ai

ai May 26, 2015

Member

@borodean I think separated library is good place to test a API :D

Member

ai commented May 26, 2015

@borodean I think separated library is good place to test a API :D

@TrySound

This comment has been minimized.

Show comment
Hide comment
@TrySound

TrySound May 26, 2015

Member

@borodean here I map functions with balanced-match and css-list
@ai I can extend css-list for mapping functions.

Member

TrySound commented May 26, 2015

@borodean here I map functions with balanced-match and css-list
@ai I can extend css-list for mapping functions.

@TrySound

This comment has been minimized.

Show comment
Hide comment
@TrySound

TrySound Sep 18, 2015

Member

Fast and simple: postcss-value-parser

Member

TrySound commented Sep 18, 2015

Fast and simple: postcss-value-parser

@jedmao

This comment has been minimized.

Show comment
Hide comment
@jedmao

jedmao Dec 8, 2015

Contributor

I also made some CSS value parsers that are completely decoupled from PostCSS:

Combined with postcss-resolve-prop, you can achieve some tight syntax, like postcss-font-helpers and postcss-margin-helpers.

Contributor

jedmao commented Dec 8, 2015

I also made some CSS value parsers that are completely decoupled from PostCSS:

Combined with postcss-resolve-prop, you can achieve some tight syntax, like postcss-font-helpers and postcss-margin-helpers.

@ai

This comment has been minimized.

Show comment
Hide comment
@ai
Member

ai commented Dec 8, 2015

@jedmao

This comment has been minimized.

Show comment
Hide comment
@jedmao

jedmao Dec 8, 2015

Contributor

Sure! I'm in flight right now, but when I get back home I'll do it when I have a moment.

Contributor

jedmao commented Dec 8, 2015

Sure! I'm in flight right now, but when I get back home I'll do it when I have a moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment