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

Less Public API Proposal - Next version #31

Closed
matthew-dean opened this issue Jul 15, 2018 · 10 comments
Closed

Less Public API Proposal - Next version #31

matthew-dean opened this issue Jul 15, 2018 · 10 comments

Comments

@matthew-dean
Copy link
Member

Per discussion in #15, I created some helpers within nodes in 3.0 to cast strings in various cases to Nodes, but I think that should be changed moving forward for a public API.

That is:

  • The internal nodes shouldn't have to do any "syntax checking" or casting in order to make them more "user-friendly"; as that can slow down evaluation, instead:
  • The public API should be an interface that creates nodes using whatever parsing / re-parsing is necessary

In addition, there are many cases where the Less tree nodes are just not relevant for a public API. So, what I'm hoping is we can:

  1. identify what is actually useful e.g. what types of Less nodes someone would realistically need/want to return from functions.
  2. limit the less object namespace to just what is "public" i.e. won't change (although existing properties/methods can exist in the prototype chain for back-compat)
  3. Deprecate demos showing tree.Declaration type returns from functions.

As an example of the Public API being different from the Less internal node structure, a less.tree implementation currently looks like:

return new tree.Ruleset([ new tree.Selector([ new tree.Element("", '&') ]) ],
               [new tree.Declaration("foo", new Value("bar"))])

A public API would be something like:

return less.ruleset({
  selectors: "&",
  rules: [
    { name: "foo", value: "bar" } // plain objects cast as declaration
  ]
})

One reason this is necessary: occasionally new features / parsing changes do require changes in the function arguments for less tree nodes. A Public API could however be more stable.

I would propose these are the main properties of a public API:

  • Subset of Less tree nodes (TBD)
  • parse
  • render
  • visitors

Any others? Thoughts? If you agree, what are the internal nodes that should be exposed as a public API?

@matthew-dean
Copy link
Member Author

Initial list of tree nodes to be be supported as function return values:

  • atrule
  • color
  • dimension
  • declaration
  • import ? - it would be great if a plugin could return an import call for a required .less file
  • ruleset

I don't think DetachedRulesets or variable calls should be on the Public API until those syntaxes are unified with mixins in the future.

Anything else seem necessary?

@rjgotten
Copy link

I'm wondering if rather than a 'public' and 'private' API a 'high-level' API and a 'low-level' API should be considered.

Might make it easier to work on plugin functions while the high-level API is not yet complete; is lagging behind in completeness of new features; or to cover cases where the high-level API simply cannot cope.

@matthew-dean
Copy link
Member Author

@rjgotten

I'm wondering if rather than a 'public' and 'private' API a 'high-level' API and a 'low-level' API should be considered.

Can you clarify with an example?

@rjgotten
Copy link

It's simple really:

Rather than making everything under tree private and inaccessible from the outside, promote it as a low-level API prone to breakage, but with more horsepower to implement truly complex behavior.

For instance: the tree namespace and the low level API would be something you'd have to fall back on as a plugin author when your plugin requires the creation of custom node types.

While there aren't very many reasons to have those, there are a few valid ones.
One example I have at the ready is a plugin function I once implemented which is capable of pulling a .json file from disk. it outputs a custom JSONObject node type that other functions can extract values from.

@matthew-dean
Copy link
Member Author

Rather than making everything under tree private and inaccessible from the outside, promote it as a low-level API prone to breakage, but with more horsepower to implement truly complex behavior.

Maybe what I said was confusing. Long and short: I wasn't suggesting making it private.

I guess I'm looking at this from the perspective of documentation. Right now we have no publicly documented API. When documented, the Less nodes can look pretty hairy. And yes, they're subject to change.

@matthew-dean
Copy link
Member Author

I guess the other thing I'd say is that the Less nodes have arguments that are really strictly for the parser "marking" them in a certain way for evaluation. They're just not designed to be public facing. Also, for legacy reasons, some nodes have parser index and fileInfo passed to them as the last 2 arguments, but some don't.

@rjgotten
Copy link

rjgotten commented Jul 16, 2018

I wasn't suggesting making it private.

Then don't name them like that either, I'd say.
Only thing that'll accomplish, is confusing authors.

Hence the suggestion to name them high-level / low-level.

Thinking some more about it; maybe something like public / semi-internal is better. It atleast gives off a strong signal that their should be some expectations of future breakages and that things are -- :: ahem :: -- "subject to change" ^_^

@matthew-dean
Copy link
Member Author

Then don't name them like that either, I'd say.

Ha, fair. I really just meant in terms of public visibility, not public / private in the programming sense. Which is why I said it would still be on the prototype chain.

public / internal is a better name, yes. It would just be good to have a way to mark those functions as internal where the primary consumer is essentially the parser & engine, not an end-user.

@kevinramharak
Copy link

I was reading in on less plugins at the official docs and found this note:

Note: A dimension is a number with or without a unit, like "10px", which would be less.Dimension(10, "px").
For a list of units, see the Less API.

Where Less API links to http://lesscss.org/features/TODO. I was wondering if this API still in active development and if there is any more 'official' documentation available.

@matthew-dean
Copy link
Member Author

@kevinramharak

I was wondering if this API still in active development and if there is any more 'official' documentation available.

I wouldn't call it active development as I haven't had time to iterate on it. In general, the "public" API has the same signature as the "internal" one. For the most part, any JavaScript function called from less should be returning one of these nodes: https://github.com/less/less.js/tree/master/lib/less/tree

Mostly, these will be basic value nodes, like anonymous, dimension, or color values, unless your plugin is doing something more complex.

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

No branches or pull requests

3 participants