'f'
mh-two-thousand-and-two
2024-04-12 26f2711ef9461961fb953e2b497bd314ef95e345
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
'use strict';
 
var helpers = require( 'postcss-helpers' );
var util    = require( 'util' );
 
/**
 * Checks validity of config object.
 * @private
 * @param   {Object} config Configuration object
 */
var validateConfig = function( config ) {
    if ( !config || !config.rules ) {
        throw new Error( 'You must configure at least one replace rule.' );
    }
 
    if ( !util.isArray( config.rules ) && typeof config.rules !== 'function' ) {
        throw new Error( 'Rules must be an Array or Function.' );
    }
 
    if ( util.isArray( config.rules ) ) {
        config.rules.forEach( function ( rule ) {
            if ( !rule.from && !rule.to ) {
                throw new Error( 'Rules must be in { from: "from", to: "to" } format.' );
            }
            else if ( typeof rule.from !== 'string' && !util.isRegExp( rule.from ) ) {
                throw new Error( 'Rule.from must be a String or RegExp.' );
            }
            else if ( [ 'string', 'function' ].indexOf( typeof rule.to ) === -1 ) {
                throw new Error( 'Rule.to must be a String or Function.' );
            }
        } );
    }
 
    if ( config.properties && !Array.isArray( config.properties ) && !( typeof config.properties === 'boolean' ) ) {
        throw new Error( 'Properties must be an Array of Strings or Boolean.' );
    }
 
    if ( Array.isArray( config.properties ) ) {
        config.properties.forEach( function( prop ) {
            if ( typeof prop !== 'string' ) {
                throw new Error( 'Items in "properties" array must be Strings.' );
            }
        } );
    }
};
 
/**
 * Returns callback function for URI replacement based on config params.
 * @private
 * @param   {Array}    rules Array of objects with "from" and "to" keys to use
 *                            as arguments to String.replace.
 * @returns {Function} Callback function.
 */
var useRulesCallback = function( rules ) {
    rules = rules;
    return function( uri ) {
        var modified = false;
        var original = uri.href();
 
        rules.forEach( function( rule ) {
            if ( modified ) { return; }
 
            var tmp = original.replace( rule.from, rule.to );
 
            if ( tmp !== original ) {
                modified = true;
                uri.href( tmp );
            }
        } );
    };
};
 
/**
 * Plugin body.
 * @param   {Boolean}        config.imports    If set to true, will also replace @import values.
 * @param   {Array|Boolean}  config.properties List of css properties to update or false.
 * @param   {Array|Function} config.rules      Array of replace params or
 *                                              callback function.
 * @returns {Function} PostCSS plugin.
 */
var urlrewrite = function( config ) {
    validateConfig( config );
 
    // Choosing which callback to use: One received from user or autogenerated
    // from params.
    var callback = ( Array.isArray( config.rules ) ) ? useRulesCallback( config.rules ) : config.rules;
 
    // Function to update @import URIs
    var updateImport = function( atRule ) {
        if( atRule.name !== 'import' ) { return; }
 
        var helper = helpers.createImportHelper( atRule.params );
 
        callback( helper.URI );
        atRule.params = helper.getModifiedRule();
    };
 
    // Function to update declarations URIs
    var updateDecl = function( decl ) {
        if ( config.properties === false ) { return; }
        if ( Array.isArray( config.properties ) && config.properties.indexOf( decl.prop ) === -1 ) { return; }
        if ( !decl.value.match( helpers.regexp.URLS ) ) { return; }
 
        var helper = helpers.createUrlsHelper( decl.value );
 
        helper.URIS.forEach( callback );
        decl.value = helper.getModifiedRule();
    };
 
    return function( style ) {
        if ( config.imports    ) { style.walkAtRules( updateImport ); }
        if ( config.properties !== false ) { style.walkDecls( updateDecl ); }
    };
};
 
module.exports = urlrewrite;