all files / postcss-scopify/ index.js

100% Statements 30/30
100% Branches 18/18
100% Functions 7/7
100% Lines 30/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                        29× 13×     16× 19×       14×     13×                         19× 19×                                       29× 16×     13×         13×        
'use strict';
var postcss = require('postcss');
 
var  conditionalGroupRules = ['media','supports','document'];
 
module.exports = postcss.plugin('postcss-scopify', scopify);
 
function scopify(scope, options) {
 
    options = options || {};
 
    return function(root) {
 
        // guard statment- allow only valid scopes
        if(!isValidScope(scope)){
            throw root.error('invalid scope', { plugin: 'postcss-scopify' });
        }
 
        root.walkRules(function (rule) {
 
            // skip scoping of special rules (certain At-rules, nested, etc')
            if(!isRuleScopable(rule)){
                return rule;
            }
 
            rule.selectors = rule.selectors.map(function(selector) {
                if (isScopeApplied(selector,scope)) {
                    return selector;
                }
 
                // special case for a top level '&' selector, resolves to scope
                if (selector === '&') {
                    return scope;
                }
 
                return scope + ' ' + selector;
 
            });
        });
    };
}
 
/**
 * Determine if selector is already scoped
 *
 * @param {string} selector
 * @param {string} scope
 */
function isScopeApplied(selector,scope) {
    var selectorTopScope = selector.split(" ",1)[0];
    return selectorTopScope === scope;
}
 
/**
 * Determine if scope is valid
 *
 * @param {string} scope
 */
function isValidScope(scope) {
    if (scope){
        return scope.indexOf(',') ===  -1;
    }
    else{
        return false;
    }
 
}
 
/**
 * Determine if rule should be scoped
 *
 * @param {rule} rule
 */
function isRuleScopable(rule){
 
    if(rule.parent.type !== 'root') {
        if (rule.parent.type === 'atrule' && conditionalGroupRules.indexOf(rule.parent.name) > -1){
            return true;
        }
        else {
            return false;
        }
    }
 
    else {
        return  true;
    }
 
}