Remove properties from rendered Less CSS

1.2k views Asked by At

There seem to be some patterns in LessCSS (1.7.x) that allow (pre/post)-processing of a CSS render tree. I was wondering if it was possible to use the Visitor (I tried that, but couldn't make it work - or anything else) to remove properties from the CSS output upon rendering. E.g. if the output was

a {
 font-size: 12px;
 -some-aribitrary-property: value;
}

I would like to remove -some-arbitrary-property from the CSS output when calling .toCSS. I can't seem to find any documentation about this, only references to the upcoming version 2.0 - does anyone know if this is even possible and if yes how to do so, or point me to some example?

2

There are 2 answers

0
Joscha On BEST ANSWER

I tried to make this an edit to @bass-jobsen's post, but it got rejected with the reason it should be an answer. So for Less 1.7.x, you create a visitor class:

RemoveProperty = function() {
    this._visitor = new less.tree.visitor(this);
};
RemoveProperty.prototype = {
    isReplacing: true,
    run: function (root) {
        return this._visitor.visit(root);
    },
    visitRule: function (ruleNode, visitArgs) {
        if(ruleNode.name != '-some-aribitrary-property') {        
            return ruleNode;
        } else {
            return [];
        }
    }
};

then in your parsing code, use it like this:

var parser = new(less.Parser)();
parser.parse(yourLessData, function(err, tree) { 
    var css = tree.toCSS({
        plugins: [new RemoveProperty()]
    });
});

patching of less itself (like in @bass-jobsen's answer) is not needed.

5
Bass Jobsen On

Since Less v2, you can use plugins. You can also use a visitor in your plugin. A example of using a visitor can be found at: https://github.com/less/less-plugin-inline-urls.

Inside your visitor plugin you can use something like that show below:

   visitRule: function (ruleNode, visitArgs) {
        if(ruleNode.name[0].value != '-some-aribitrary-property')
        {        
            return ruleNode;
        }
        else
        {
            return [];
        }   
    }

Notice that the above currently does not remove but produces : ;. I will update my answer later on, see also: Howto remove a entry from the tree in a Less visitor plugin.

it does not seem to work for Visitors in v1.7 - do you have an example for that?

for less < v2

update

as suggested by @Joscha himself use:

var parser = new(less.Parser)();
parser.parse(yourLessData, function(err, tree) { 
    var css = tree.toCSS({
        plugins: [new RemoveProperty()]
    });
});

with:

RemoveProperty = function() {
    this._visitor = new tree.visitor(this);
};
RemoveProperty.prototype = {
    isReplacing: true,
    run: function (root) {
    return this._visitor.visit(root);
    },
    visitRule: function (ruleNode, visitArgs) {
        if(ruleNode.name != '-some-aribitrary-property')
        {        
            return ruleNode;
        }
        else {
            return [];
        }
    }
};

end update

create a file in lib/less called custom-visitor.js which contains the following content:

(function (tree) {

    tree.RemoveProperty = function() {
        this._visitor = new tree.visitor(this);
    };
    tree.RemoveProperty.prototype = {
        isReplacing: true,
        run: function (root) {
        return this._visitor.visit(root);
        },
        visitRule: function (ruleNode, visitArgs) {
            if(ruleNode.name != '-some-aribitrary-property')
            {        
                return ruleNode;
            }
            else {
                return [];
            }
        }
    };
})(require('./tree'));

than in less/lib/index.js add require('./custom-visitor.js');, the end of this file will now look like that shown below:

require('./env');
require('./functions');
require('./colors');
require('./visitor.js');
require('./import-visitor.js');
require('./extend-visitor.js');
require('./join-selector-visitor.js');
require('./custom-visitor.js');
require('./to-css-visitor.js');
require('./source-map-output.js');

for (var k in less) { if (less.hasOwnProperty(k)) { exports[k] = less[k]; }}

and finally new(tree.RemoveProperty)(), into less/lib/parser.js, around line 554, so that the code looks like that shown beneath:

visitors = [
    new(tree.joinSelectorVisitor)(),
    new(tree.processExtendsVisitor)(),
    new(tree.RemoveProperty)(),
    new(tree.toCSSVisitor)({compress: Boolean(options.compress)})
    ],