1<!doctype html>
2<!--
3@license
4Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
5This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8Code distributed by Google as part of the polymer project is also
9subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10-->
11<html>
12<head>
13
14  <meta charset="utf-8">
15  <script src="./test-flags.js"></script>
16  <script src="../node_modules/wct-browser-legacy/browser.js"></script>
17  <script src="module/generated/css-parse.js"></script>
18
19  <title>css-parse</title>
20
21</head>
22<body>
23
24  <style id="test">
25    :host {
26      background: red;
27    }
28
29    .foo .bar .baz, zonk[happy]:focus {
30      font-family: sans-serif;
31      font-size: 15px;
32    }
33
34    @-webkit-keyframes fill-unfill-rotate {
35      12.5% { transform: rotate(135deg);  }
36      25%   { transform: rotate(270deg);  }
37      37.5% { transform: rotate(405deg);  }
38      50%   { transform: rotate(540deg);  }
39      62.5% { transform: rotate(675deg);  }
40      75%   { transform: rotate(810deg);  }
41      87.5% { transform: rotate(945deg);  }
42      to    { transform: rotate(1080deg); }
43    }
44
45    @media (max-width: 400px) {
46      div {
47        margin-left: 0 !important;
48      }
49    }
50  </style>
51
52  <style id="test-ignore">
53    @import '';
54
55    /* comment */
56    .stuff {
57      background: red;
58    }
59    /* comment */
60
61    /*
62      This is a multi-line comment
63    */
64
65    /*.aclassThatShouldBeIgnored {
66      someProperty: thatMustNotShowUp
67    }*/
68  </style>
69
70  <style id="short-escape-sequence">
71    .\33 d-model {
72      border-top: 3px solid red;
73    }
74    .\a33 d-model {
75      border-top: 3px solid red;
76    }
77    .\b333 d-model {
78      border-top: 3px solid red;
79    }
80    .\c3333 d-model {
81      border-top: 3px solid red;
82    }
83    .\d33333 d-model {
84      border-top: 3px solid red;
85    }
86    .\e33333d-model {
87      border-top: 3px solid red;
88    }
89  </style>
90
91  <style id="multiple-spaces">
92    .foo  .bar {}
93    .foo    .bar {}
94    .foo
95
96
97    .bar {}
98  </style>
99
100  <style id="empty"></style>
101<script>
102
103  function sanitizeCss(text) {
104    return text.replace(/[\s]+/g, ' ').trim();
105  }
106
107  suite('css-parse', function() {
108    var s, tree;
109
110    setup(function() {
111      s = document.querySelector('style#test');
112      tree = window.CssParse.parse(s.textContent);
113    });
114
115    test('window.CssParse rules parse', function() {
116      assert.equal(tree.rules.length, 4, 'unexpected number of rules');
117      assert.equal(tree.rules[2].rules.length, 8, 'unexpected number of rules in keyframes');
118      assert.equal(tree.rules[3].rules.length, 1, 'unexpected number of rules in @media');
119    });
120
121    test('rule selectors parse', function() {
122      assert.equal(tree.rules[0].selector, ':host', 'unexpected selector');
123      assert.equal(tree.rules[2].selector, '@-webkit-keyframes fill-unfill-rotate', 'unexpected selector in keyframes');
124      assert.equal(tree.rules[3].selector, '@media (max-width: 400px)', 'unexpected selector in @media');
125    });
126
127    test('rule cssText parse', function() {
128      assert.equal(tree.rules[0].cssText, 'background: red;', 'unexpected cssText');
129      assert.match(tree.rules[2].cssText, /^12.5%/, 'unexpected cssText in keyframes');
130      assert.equal(tree.rules[2].rules[2].cssText, 'transform: rotate(405deg);', 'unexpected cssText in keyframes');
131      assert.match(tree.rules[3].cssText, /^div/, 'unexpected cssText in @media');
132      assert.equal(tree.rules[3].rules[0].cssText, 'margin-left: 0 !important;', 'unexpected cssText in @media');
133    });
134
135    test('rule types', function() {
136      assert.equal(tree.rules[0].type, window.CssParse.types.STYLE_RULE);
137      assert.equal(tree.rules[1].type, window.CssParse.types.STYLE_RULE);
138      assert.equal(tree.rules[2].type, window.CssParse.types.KEYFRAMES_RULE);
139      assert.equal(tree.rules[3].type, window.CssParse.types.MEDIA_RULE);
140      assert.equal(tree.rules[3].rules[0].type, window.CssParse.types.STYLE_RULE);
141
142    });
143
144    test('rules stringify', function() {
145      var orig = sanitizeCss(s.textContent);
146      var result = sanitizeCss(window.CssParse.stringify(tree));
147      assert.equal(result, orig, 'unexpected stringified output');
148    });
149
150    test('parse correctly ignores @import and comments', function() {
151      var s2 = document.querySelector('#test-ignore');
152      var t = window.CssParse.parse(s2.textContent);
153      assert.equal(t.rules[0].selector, '.stuff', 'unexpected rule selector');
154      assert.equal(t.rules[0].cssText, 'background: red;', 'unexpected rule cssText');
155      var result = sanitizeCss(window.CssParse.stringify(t));
156      assert.equal(result, '.stuff { background: red; }', 'unexpected stringified output');
157    });
158
159    test('short escape sequences', function() {
160      var s3 = document.querySelector('#short-escape-sequence');
161      var t = window.CssParse.parse(s3.textContent);
162      assert.equal(t.rules[0].selector, '.\\000033d-model');
163      assert.equal(t.rules[1].selector, '.\\000a33d-model');
164      assert.equal(t.rules[2].selector, '.\\00b333d-model');
165      assert.equal(t.rules[3].selector, '.\\0c3333d-model');
166      assert.equal(t.rules[4].selector, '.\\d33333d-model');
167      assert.equal(t.rules[5].selector, '.\\e33333d-model');
168    });
169
170    test('multiple consequent spaces in CSS selector', function() {
171      var s4 = document.querySelector('#multiple-spaces');
172      var t = window.CssParse.parse(s4.textContent);
173      assert.equal(t.rules[0].selector, '.foo .bar');
174      assert.equal(t.rules[1].selector, '.foo .bar');
175      assert.equal(t.rules[2].selector, '.foo .bar');
176    });
177
178    test('empty styles are are handled', function() {
179      var s = document.querySelector('#empty');
180      var t = window.CssParse.parse(s.textContent);
181      window.CssParse.stringify(t);
182    });
183
184  });
185</script>
186
187</body>
188</html>
189