Exemple #1
0
def csscombine(path=None, url=None, cssText=None, href=None,
               sourceencoding=None, targetencoding=None,
               minify=True, resolveVariables=True):
    """Combine sheets referred to by @import rules in given CSS proxy sheet
    into a single new sheet.

    :returns: combined cssText, normal or minified
    :Parameters:
        `path` or `url` or `cssText` + `href`
            path or URL to a CSSStyleSheet or a cssText of a sheet which imports
            other sheets which are then combined into one sheet.
            `cssText` normally needs `href` to be able to resolve relative
            imports.
        `sourceencoding` = 'utf-8'
            explicit encoding of the source proxysheet
        `targetencoding`
            encoding of the combined stylesheet
        `minify` = True
            defines if the combined sheet should be minified, in this case
            comments are not parsed at all!
        `resolveVariables` = True
            defines if variables in combined sheet should be resolved
    """
    css_parser.log.info('Combining files from %r' % url, neverraise=True)
    if sourceencoding is not None:
        css_parser.log.info('Using source encoding %r' % sourceencoding, neverraise=True)

    parser = css_parser.CSSParser(parseComments=not minify)

    if path and not cssText:
        src = parser.parseFile(path, encoding=sourceencoding)
    elif url:
        src = parser.parseUrl(url, encoding=sourceencoding)
    elif cssText:
        src = parser.parseString(cssText, href=href, encoding=sourceencoding)
    else:
        sys.exit('Path or URL must be given')

    result = css_parser.resolveImports(src)
    result.encoding = targetencoding
    css_parser.log.info('Using target encoding: %r' % targetencoding, neverraise=True)

    oldser = css_parser.ser
    css_parser.setSerializer(css_parser.serialize.CSSSerializer())
    if minify:
        css_parser.ser.prefs.useMinified()
    css_parser.ser.prefs.resolveVariables = resolveVariables
    cssText = result.cssText
    css_parser.setSerializer(oldser)

    return cssText
 def do():
     with self.patch_default_fetcher(fetcher):
         s = css_parser.parseString(a)
         r = css_parser.resolveImports(s)
     return s, r
    def test_resolveImports(self):
        "css_parser.resolveImports(sheet)"
        self._tempSer()
        css_parser.ser.prefs.useMinified()

        a = '@charset "iso-8859-1";@import"b.css";\xe4{color:green}'.encode(
            'iso-8859-1')
        b = '@charset "ascii";\\E4 {color:red}'.encode('ascii')

        # normal
        with self.patch_default_fetcher((None, b)):
            s = css_parser.parseString(a)

            # py3 TODO
            self.assertEqual(a, s.cssText)
            self.assertEqual(b, s.cssRules[1].styleSheet.cssText)

            c = css_parser.resolveImports(s)

            # py3 TODO
            self.assertEqual(
                '\xc3\xa4{color:red}\xc3\xa4{color:green}'.encode(
                    'iso-8859-1'), c.cssText)

            c.encoding = 'ascii'
            self.assertEqual(
                r'@charset "ascii";\E4 {color:red}\E4 {color:green}'.encode(),
                c.cssText)

        # b cannot be found
        with self.patch_default_fetcher((None, None)):
            s = css_parser.parseString(a)

            # py3 TODO
            self.assertEqual(a, s.cssText)
            self.assertEqual(css_parser.css.CSSStyleSheet,
                             type(s.cssRules[1].styleSheet))
            c = css_parser.resolveImports(s)
            # py3 TODO
            self.assertEqual(
                '@import"b.css";\xc3\xa4{color:green}'.encode('iso-8859-1'),
                c.cssText)

        # @import with media
        a = '@import"b.css";@import"b.css" print, tv ;@import"b.css" all;'
        b = 'a {color: red}'
        with self.patch_default_fetcher((None, b)):
            s = css_parser.parseString(a)

            c = css_parser.resolveImports(s)

            self.assertEqual(
                'a{color:red}@media print,tv{a{color:red}}a{color:red}'.encode(
                ), c.cssText)

        # cannot resolve with media => keep original
        a = '@import"b.css"print;'
        b = '@namespace "http://example.com";'
        with self.patch_default_fetcher((None, b)):
            s = css_parser.parseString(a)
            c = css_parser.resolveImports(s)
            self.assertEqual(a.encode(), c.cssText)

        # urls are adjusted too, layout:
        # a.css
        # c.css
        # img/img.gif
        # b/
        #     b.css
        #     subimg/subimg.gif
        a = '''
                @import"b/b.css";
                a {
                    x: url(/img/abs.gif);
                    y: url(img/img.gif);
                    z: url(b/subimg/subimg.gif);
                    }'''

        def fetcher(url):
            c = {
                'b.css':
                '''
                        @import"../c.css";
                        b {
                            x: url(/img/abs.gif);
                            y: url(../img/img.gif);
                            z: url(subimg/subimg.gif);
                            }''',
                'c.css':
                '''
                        c {
                            x: url(/img/abs.gif);
                            y: url(./img/img.gif);
                            z: url(./b/subimg/subimg.gif);
                            }'''
            }
            return 'utf-8', c[os.path.split(url)[1]]

        def do():
            with self.patch_default_fetcher(fetcher):
                s = css_parser.parseString(a)
                r = css_parser.resolveImports(s)
            return s, r

        s, r = do()

        css_parser.ser.prefs.useDefaults()
        css_parser.ser.prefs.keepComments = False
        self.assertEqual(
            '''c {
    x: url(/img/abs.gif);
    y: url(img/img.gif);
    z: url(b/subimg/subimg.gif)
    }
b {
    x: url(/img/abs.gif);
    y: url(img/img.gif);
    z: url(b/subimg/subimg.gif)
    }
a {
    x: url(/img/abs.gif);
    y: url(img/img.gif);
    z: url(b/subimg/subimg.gif)
    }'''.encode(), r.cssText)
Exemple #4
0
    def test_imports(self):
        "CSSVariables imports"

        def fetcher(url):
            url = url.replace('\\', '/')
            url = url[url.rfind('/') + 1:]
            return (None, {
                '3.css':
                '''
                    @variables {
                        over3-2-1-0: 3;
                        over3-2-1: 3;
                        over3-2: 3;
                        over3-2-0: 3;
                        over3-1: 3;
                        over3-1-0: 3;
                        over3-0: 3;
                        local3: 3;
                    }
                
                ''',
                '2.css':
                '''
                    @variables {
                        over3-2-1-0: 2;
                        over3-2-1: 2;
                        over3-2-0: 2;
                        over3-2: 2;
                        over2-1: 2;
                        over2-1-0: 2;
                        over2-0: 2;
                        local2: 2;
                    }
                
                ''',
                '1.css':
                '''
                    @import "3.css";
                    @import "2.css";
                    @variables {
                        over3-2-1-0: 1;
                        over3-2-1: 1;
                        over3-1: 1;
                        over3-1-0: 1;
                        over2-1: 1;
                        over2-1-0: 1;
                        over1-0: 1;
                        local1: 1;
                    }
                
                '''
            }[url])

        css = '''
            @import "1.css";
            @variables {
                over3-2-1-0: 0;
                over3-2-0: 0;
                over3-1-0: 0;
                over2-1-0: 0;
                over3-0: 0;
                over2-0: 0;
                over1-0: 0;
                local0: 0;
            }
            a {
                local0: var(local0);
                local1: var(local1);
                local2: var(local2);
                local3: var(local3);
                over1-0: var(over1-0);
                over2-0: var(over2-0);
                over3-0: var(over3-0);
                over2-1: var(over2-1);
                over3-1: var(over3-1);
                over3-2: var(over3-2);
                over2-1-0: var(over2-1-0);
                over3-2-0: var(over3-2-0);
                over3-2-1: var(over3-2-1);
                over3-2-1-0: var(over3-2-1-0);
            }
        '''
        p = css_parser.CSSParser(fetcher=fetcher)
        s = p.parseString(css)

        # only these in rule of this sheet
        self.assertEqual(s.cssRules[1].variables.length, 8)
        # but all vars in s available!
        self.assertEqual(s.variables.length, 15)
        self.assertEqual([
            'local0', 'local1', 'local2', 'local3', 'over1-0', 'over2-0',
            'over2-1', 'over2-1-0', 'over3-0', 'over3-1', 'over3-1-0',
            'over3-2', 'over3-2-0', 'over3-2-1', 'over3-2-1-0'
        ], sorted(s.variables.keys()))

        # test with variables rule
        css_parser.ser.prefs.resolveVariables = False
        self.assertEqual(
            s.cssText, '''@import "1.css";
@variables {
    over3-2-1-0: 0;
    over3-2-0: 0;
    over3-1-0: 0;
    over2-1-0: 0;
    over3-0: 0;
    over2-0: 0;
    over1-0: 0;
    local0: 0
    }
a {
    local0: var(local0);
    local1: var(local1);
    local2: var(local2);
    local3: var(local3);
    over1-0: var(over1-0);
    over2-0: var(over2-0);
    over3-0: var(over3-0);
    over2-1: var(over2-1);
    over3-1: var(over3-1);
    over3-2: var(over3-2);
    over2-1-0: var(over2-1-0);
    over3-2-0: var(over3-2-0);
    over3-2-1: var(over3-2-1);
    over3-2-1-0: var(over3-2-1-0)
    }'''.encode())

        # test with resolved vars
        css_parser.ser.prefs.resolveVariables = True
        self.assertEqual(
            s.cssText, '''@import "1.css";
a {
    local0: 0;
    local1: 1;
    local2: 2;
    local3: 3;
    over1-0: 0;
    over2-0: 0;
    over3-0: 0;
    over2-1: 1;
    over3-1: 1;
    over3-2: 2;
    over2-1-0: 0;
    over3-2-0: 0;
    over3-2-1: 1;
    over3-2-1-0: 0
    }'''.encode())

        s = css_parser.resolveImports(s)
        self.assertEqual(
            s.cssText, '''/* START @import "1.css" */
/* START @import "3.css" */
/* START @import "2.css" */
a {
    local0: 0;
    local1: 1;
    local2: 2;
    local3: 3;
    over1-0: 0;
    over2-0: 0;
    over3-0: 0;
    over2-1: 1;
    over3-1: 1;
    over3-2: 2;
    over2-1-0: 0;
    over3-2-0: 0;
    over3-2-1: 1;
    over3-2-1-0: 0
    }'''.encode())