These are chat archives for less/less.js

29th
Nov 2015
Joep van Liempd
@joepvl
Nov 29 2015 22:01

@matthew-dean Thanks for replying! I'm working on a tool that basically allows a user to make changes to a stylesheet through a UI (the stylesheet is abstracted away, so it's kind of like a visual editor) & see the updated styles applied to a bunch of markup, live, while they're making the changes. This is what I want to use modifyVars or something similar for.

In order to separate the styles of my UI from the styles of the markup the user is styling, I've put said markup in an iframe (would love to use shadow DOM for this but browser support is not good enough + spec is still in flux). To keep things from getting too complex, I'd like to be able to manage all of my logic from the page that contains the UI, and have no scripts running in the iframe (which could cause race conditions and/or other difficulties & what seems to me to be unnecessarily complex behaviour).

Ideally, I'd like to be able to do something like the following (this is browser code, but I'm using Webpack & npm so I can use CommonJS):

var less = require('less/browser');
var styles = '/* my stylesheet, assume there's valid Less code with some variables in here */';

var parser = new (less.Parser);
var tree = parser.parse(styles);
var css = tree.toCSS();

// let's imagine injectCss is a function that synchronously injects or replaces a stylesheet in the markup iframe
injectCss(css);

// when the user changes things, this function is called with the parse tree and
// an object representing the changed var(s), e.g.
// `{"mainFontSize": "15px"}` or `{"mainBackgroundColor": "#BADA55"}`)
function updateStyles(tree, changedVars) {
  tree.modifyVars(changedVars);
  return tree.toCSS();
  injectCss(newCss);
}

I know I need to provide more data to var parser = new (less.Parser)(/*...? */)and/or parser.parse(/* ...? */), but I don't know what and why. Also, I most likely want to avoid feeding the parser anything that contains imports; instead, I'd like to just use the parser for variables, mixins, and functions (and do any combining of files myself so I have complete control over network requests).
I might be missing something about how modifyVars works (I think it more or less just "tacks on" the variables to the end of the string (or even the parsed tree?) & then things will automagically work because Less is declarative rather than imperative).

Maybe I should post this to StackOverflow so other people can take advantage of it as well.
Damn, that return statement shouldn't be in the updateStyles function. Correction:
var less = require('less/browser');
var styles = '/* my stylesheet, assume there's valid Less code with some variables in here */';

var parser = new (less.Parser);
var tree = parser.parse(styles);
var css = tree.toCSS();

// let's imagine injectCss is a function that synchronously injects or replaces a stylesheet in the markup iframe
injectCss(css);

// when the user changes things, this function is called with the parse tree and
// an object representing the changed var(s), e.g.
// `{"mainFontSize": "15px"}` or `{"mainBackgroundColor": "#BADA55"}`)
function updateStyles(tree, changedVars) {
  tree.modifyVars(changedVars);
  tree.toCSS();
  injectCss(newCss);
}