grunt-data-separator

Split up your Data-URI (or anything else) into a separate CSS file.

grunt-data-separator

Split up your Data-URI (or anything else) into a separate CSS file.

This plugin requires Grunt.

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-data-separator --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-data-separator');

In version 0.1.* the whole rule with a matched value will be duplicated.

In your project's Gruntfile, add a section named dataSeparator to the data object passed into grunt.initConfig().

grunt.initConfig({
    dataSeparator: {
        icons: {
            options: {
                pattern: {
                    matchValue: /data/, // The RegExp to match values with 
                    matchProp: false, // The RegExp to match properties with 
                    matchRule: false, // The RegExp to match values with 
                    matchParent: true // Rules (eg. in @media blocks) include their parent node. 
                },
                output: 'tmp/styles.icons.css'
            },
            files: {
                'tmp/styles.css': ['test/fixtures/source.css']
            }
        }
    }
})

Type: RegExp Default value: /data:/

A string value that is used to set the value your are searching for in your css.

Type: RegExp Default value: /background-image/

A string value that is used to set the property your are searching for in your css.

Type: RegExp Default value: false

A string value that is used to set the rule your are searching for in your css.

Type: RegExp Default value: false

A value that is used to set the media query your are searching for in your css.

Type: Boolean Default value: true

A boolean value that is used to include/exclude the rules parent node (eg. in @media blocks).

Type: String Default value: ''

A string value which needs a path and filename (eg. in tmp/styles.icons.css).

In this example, the default options are used to get two files which are generated to the specific folder. So if the source.css file has the content

a.top {
background-repeat: no-repeat;
}
a.top {
background-image: url("data:image/svg+xml;charset=US-ASCII,%3C%3Fx.....");
}

the generated result would be that there are now two files. One which has the standard styles, the second with your data-uris:

styles.css

a.top {
background-repeat: no-repeat;
}

styles.icons.css

a.top {
background-image: url("data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20v.......");
}

In this example, custom options are used to get two files which are generated to the specific folder:

grunt.initConfig({
    dataSeparator: {
        ie8: {
            options: {
                pattern: {
                    matchValue: false, // The RegExp to match values with 
                    matchRule: /lt-ie9/, // The RegExp to match values with 
                    matchParent: true // Rules (eg. in @media blocks) include their parent node. 
                },
                output: 'tmp/styles.ie8.css'
            },
            files: {
                'tmp/styles.css': ['test/fixtures/source.css']
            }
        }
    }
})

So if the source.css file has the content

a.top {
background-repeat: no-repeat;
}
.lt-ie9 a.top {
background-image: url("data:image/svg+xml;charset=US-ASCII,%3C%3Fx.....");
}

the generated result would be that there are now two files. One which has the standard styles, the second with your data-uris:

styles.css

a.top {
background-repeat: no-repeat;
}

styles.ie8.css

.lt-ie9 a.top {
background-image: url("data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20v.......");
}

In this example, custom options are used to get two files which are generated to the specific folder:

grunt.initConfig({
    dataSeparator: {
        image2x: {
            options: {
                pattern: {
                    matchValue: false, // The RegExp to match values with 
                    matchRule: false, // The RegExp to match values with 
                    matchMedia: /((min|max)-)?resolution\:\s*(\d+)?\.?(\d+)?dppx/, // The RegExp to match media queries with 
                    matchParent: true // Rules (eg. in @media blocks) include their parent node. 
                },
                output: 'tmp/styles.media.css'
            },
            files: {
                'tmp/styles.css': ['test/fixtures/source.css']
            }
        }
    }
})

So if the source.css file has the content

captionthtd {
    text-align: left;
    font-weight: normal;
    vertical-align: middle;
}
 
qblockquote {
    quotes: none;
}
 
q:beforeq:afterblockquote:beforeblockquote:after {
    content: "";
    content: none;
}
 
a img {
    border: none;
}
 
@media only screen and (max-width: 568px) {
 
    a.media {
        background-repeat: no-repeat;
    }
 
}
 
@media print {
}
 
@media (width: 100px) {
    .w-100 {
        width: 100px;
    }
}
 
@media (resolution: 2dppx) {
    .r-2dppx {
        width: 45px;
    }
}
 
@media (min-resolution: 1dppx) {
    .r-1dppx-min {
        width: 45px;
    }
}
 
@media (max-resolution: 1dppx) {
    .r-1dppx-max {
        width: 45px;
    }
}
 
@media (resolution: 1.5dppx) {
    .r-15dppx {
        width: 45px;
    }
}
 
@media (resolution: 10.786dppx) {
    .r-10dppx {
        width: 45px;
    }
}
 
@media (resolution: .5dppx) {
    .r-0-5dppx {
        width: 45px;
    }
}
 
@media (-webkit-min-device-pixel-ratio: 1.3), 
(-o-min-device-pixel-ratio: 2.6/2), 
(min--moz-device-pixel-ratio: 1.3), 
(min-device-pixel-ratio: 1.3), 
(resolution: 1.3dppx) {
    .dpr {
        width: 45px;
    }
}

the generated result would be that there are now two files. One which has the standard styles, the second with your media queries:

styles.css

captionthtd {
    text-align: left;
    font-weight: normal;
    vertical-align: middle;
}
 
qblockquote {
    quotes: none;
}
 
q:beforeq:afterblockquote:beforeblockquote:after {
    content: "";
    content: none;
}
 
a img {
    border: none;
}
 
@media only screen and (max-width: 568px) {
 
    a.media {
        background-repeat: no-repeat;
    }
 
}
 
@media print {
}
 
@media (width: 100px) {
    .w-100 {
        width: 100px;
    }
}

styles.media.css

@media (resolution: 2dppx) {
    .r-2dppx {
        width: 45px;
    }
}
 
@media (min-resolution: 1dppx) {
    .r-1dppx-min {
        width: 45px;
    }
}
 
@media (max-resolution: 1dppx) {
    .r-1dppx-max {
        width: 45px;
    }
}
 
@media (resolution: 1.5dppx) {
    .r-15dppx {
        width: 45px;
    }
}
 
@media (resolution: 10.786dppx) {
    .r-10dppx {
        width: 45px;
    }
}
 
@media (resolution: .5dppx) {
    .r-0-5dppx {
        width: 45px;
    }
}
 
@media (-webkit-min-device-pixel-ratio: 1.3), 
(-o-min-device-pixel-ratio: 2.6/2), 
(min--moz-device-pixel-ratio: 1.3), 
(min-device-pixel-ratio: 1.3), 
(resolution: 1.3dppx) {
    .dpr {
        width: 45px;
    }
}

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

(Nothing yet)

Copyright (c) 2014 Sebastian Fitzner. Licensed under the MIT license.