]
119 | ```
120 |
121 | ## Options
122 |
123 |
124 | - [rootElement](#optionsrootelement)
125 | - [include](#optionsinclude)
126 | - [exclude](#optionsexclude)
127 | - [filter](#optionsfilter)
128 | - [skipDisabled](#optionsskipdisabled)
129 | - [useCSSOM](#optionsusecssom)
130 | - [onBeforeSend](#optionsonbeforesend)
131 | - [onSuccess](#optionsonsuccess)
132 | - [onError](#optionsonerror)
133 | - [onComplete](#optionsoncomplete)
134 |
135 | **Example**
136 |
137 | ```javascript
138 | // Default values shown
139 | getCssData({
140 | rootElement : document,
141 | include : 'link[rel=stylesheet],style',
142 | exclude : '',
143 | filter : '',
144 | skipDisabled: true,
145 | useCSSOM : false,
146 | onBeforeSend: function(xhr, node, url) {
147 | // ...
148 | },
149 | onSuccess: function(cssText, node, url) {
150 | // ...
151 | },
152 | onError: function(xhr, node, url) {
153 | // ...
154 | },
155 | onComplete: function(cssText, cssArray, nodeArray) {
156 | // ...
157 | }
158 | });
159 | ```
160 |
161 | ### options.rootElement
162 |
163 | - Type: `object`
164 | - Default: `document`
165 |
166 | Root element to traverse for `` and ``);
56 |
57 | getCss({
58 | include: '[data-test]',
59 | onComplete(cssText, cssArray, nodeArray) {
60 | expect(cssText).to.equal(styleCss);
61 | done();
62 | }
63 | });
64 | });
65 |
66 |
67 | // Tests: `);
74 |
75 | getCss({
76 | include: '[data-test]',
77 | onComplete(cssText, cssArray, nodeArray) {
78 | expect(cssText).to.equal(styleCss);
79 | done();
80 | }
81 | });
82 | });
83 |
84 | it('returns CSS from single SVG
90 |
91 |
92 | `);
93 |
94 | getCss({
95 | include: 'svg style',
96 | onComplete(cssText, cssArray, nodeArray) {
97 | expect(cssText).to.equal(styleCss);
98 | done();
99 | }
100 | });
101 | });
102 |
103 | it('returns CSS from multiple `.repeat(2));
106 | const expected = styleCss.repeat(styleElms.length);
107 |
108 | getCss({
109 | include: '[data-test]',
110 | onComplete(cssText, cssArray, nodeArray) {
111 | expect(cssText).to.equal(expected);
112 | done();
113 | }
114 | });
115 | });
116 |
117 | it('returns CSS from multiple `.repeat(2));
120 | const expected = fixtures['style2.out.css'].repeat(styleElms.length);
121 |
122 | getCss({
123 | include: '[data-test]',
124 | onComplete(cssText, cssArray, nodeArray) {
125 | expect(cssText).to.equal(expected);
126 | done();
127 | }
128 | });
129 | });
130 |
131 | it('returns CSS from multiple `.repeat(2));
134 | const expected = fixtures['style3.out.css'].repeat(styleElms.length);
135 |
136 | getCss({
137 | include: '[data-test]',
138 | onComplete(cssText, cssArray, nodeArray) {
139 | expect(cssText).to.equal(expected);
140 | done();
141 | }
142 | });
143 | });
144 |
145 | it('returns CSS from multiple `.repeat(2));
150 |
151 | getCss({
152 | include: '[data-test]',
153 | onComplete(cssText, cssArray, nodeArray) {
154 | cssText = cssText.replace(/\n/g, '');
155 |
156 | expect(cssText).to.equal(expected);
157 | done();
158 | }
159 | });
160 | });
161 | });
162 |
163 |
164 | // Tests: CSS
165 | // -------------------------------------------------------------------------
166 | describe(' nodes', function() {
167 | it('returns CSS from single node', function(done) {
168 | const linkUrl = '/base/tests/fixtures/style1.css';
169 | const expected = fixtures['style1.css'];
170 |
171 | createTestElms(``);
172 |
173 | getCss({
174 | include: '[data-test]',
175 | onComplete(cssText, cssArray, nodeArray) {
176 | expect(cssText).to.equal(expected);
177 | done();
178 | }
179 | });
180 | });
181 |
182 | it('returns CSS from single node with data URI scheme', function(done) {
183 | const encodedCSS = encodeURIComponent(fixtures['style1.css']);
184 | const URIScheme = `data:text/css;charset=UTF-8,${encodedCSS}`;
185 | const expected = fixtures['style1.css'];
186 |
187 | createTestElms(``);
188 |
189 | getCss({
190 | include: '[data-test]',
191 | onComplete(cssText, cssArray, nodeArray) {
192 | expect(cssText).to.equal(expected);
193 | done();
194 | }
195 | });
196 | });
197 |
198 | it('returns CSS from single node via CORS', function(done) {
199 | const linkProtocol = 'https:';
200 | const linkUrl = `${linkProtocol}//cdn.jsdelivr.net/npm/get-css-data@1.0.0/tests/fixtures/style1.css`;
201 |
202 | createTestElms(``);
203 |
204 | // IE9 does not support CORS requests with different protocol
205 | if (isIElte9 & location.protocol !== linkProtocol) {
206 | getCss({
207 | include: '[data-test]',
208 | onError(xhr, node, url) {
209 | done();
210 | }
211 | });
212 | }
213 | else {
214 | axios.get(linkUrl)
215 | .then(response => response.data)
216 | .then(expected => {
217 | getCss({
218 | include: '[data-test]',
219 | onComplete(cssText, cssArray, nodeArray) {
220 | expect(cssText).to.equal(expected);
221 | done();
222 | }
223 | });
224 | });
225 | }
226 | });
227 |
228 | it('returns CSS from multiple nodes', function(done) {
229 | const linkUrl = '/base/tests/fixtures/style1.css';
230 | const linkElms = createTestElms(``.repeat(2));
231 | const expected = fixtures['style1.css'].repeat(linkElms.length);
232 |
233 | getCss({
234 | include: '[data-test]',
235 | onComplete(cssText, cssArray, nodeArray) {
236 | expect(cssText).to.equal(expected);
237 | done();
238 | }
239 | });
240 | });
241 |
242 | it('returns CSS from multiple nodes with data URI scheme', function(done) {
243 | const encodedCSS = encodeURIComponent(fixtures['style1.css']);
244 | const URIScheme = `data:text/css;charset=UTF-8,${encodedCSS}`;
245 | const linkElms = createTestElms(``.repeat(2));
246 | const expected = fixtures['style1.css'].repeat(linkElms.length);
247 |
248 | getCss({
249 | include: '[data-test]',
250 | onComplete(cssText, cssArray, nodeArray) {
251 | expect(cssText).to.equal(expected);
252 | done();
253 | }
254 | });
255 | });
256 |
257 | it('returns empty string from single node w/ empty stylesheet', function(done) {
258 | const linkUrl = '/base/tests/fixtures/style-empty.css';
259 | const expected = fixtures['style-empty.css'];
260 |
261 | createTestElms(``);
262 |
263 | getCss({
264 | include: '[data-test]',
265 | onError(xhr, node, url) {
266 | console.log('Error', node, url);
267 | },
268 | onComplete(cssText, cssArray, nodeArray) {
269 | expect(cssText).to.equal(expected);
270 | done();
271 | }
272 | });
273 | });
274 |
275 | it('returns CSS from multiple nodes with flat @import', function(done) {
276 | const linkUrl = '/base/tests/fixtures/style2.css';
277 | const linkElms = createTestElms(``.repeat(2));
278 | const expected = fixtures['style2.out.css'].repeat(linkElms.length);
279 |
280 | getCss({
281 | include: '[data-test]',
282 | onComplete(cssText, cssArray, nodeArray) {
283 | expect(cssText).to.equal(expected);
284 | done();
285 | }
286 | });
287 | });
288 |
289 | it('returns CSS from multiple nodes with nested @import', function(done) {
290 | const linkUrl = '/base/tests/fixtures/style3.css';
291 | const linkElms = createTestElms(``.repeat(2));
292 | const expected = fixtures['style3.out.css'].repeat(linkElms.length);
293 |
294 | getCss({
295 | include: '[data-test]',
296 | onComplete(cssText, cssArray, nodeArray) {
297 | expect(cssText).to.equal(expected);
298 | done();
299 | }
300 | });
301 | });
302 | });
303 |
304 |
305 | // Tests: & `);
353 |
354 | getCss({
355 | include: '[data-test]',
356 | exclude: 'link',
357 | onComplete(cssText, cssArray, nodeArray) {
358 | expect(cssText).to.equal(styleCss);
359 | done();
360 | }
361 | });
362 | });
363 |
364 | it('options.filter', function(done) {
365 | const linkUrl = '/base/tests/fixtures/style1.css';
366 | const styleCss = '.keepme { color: red; }';
367 |
368 | createTestElms(``);
369 | createTestElms(``);
370 |
371 | getCss({
372 | include: '[data-test]',
373 | filter : /keepme/,
374 | onComplete(cssText, cssArray, nodeArray) {
375 | expect(cssText).to.equal(styleCss);
376 | done();
377 | }
378 | });
379 | });
380 |
381 | it('options.skipDisabled', function(done) {
382 | const linkUrl = '/base/tests/fixtures/style1.css';
383 | const styleCss = fixtures['style1.css'];
384 |
385 | const testElms = createTestElms([
386 | ``,
387 | ``
388 | ]);
389 |
390 | for (const sheet of document.styleSheets) {
391 | sheet.disabled = true;
392 | }
393 |
394 | function step1() {
395 | getCss({
396 | include : '[data-test]',
397 | skipDisabled: true,
398 | onComplete(cssText, cssArray, nodeArray) {
399 | expect(nodeArray.length, '1:nodeArray').to.equal(0);
400 | expect(cssArray.length, '1:cssArray').to.equal(0);
401 | expect(cssText, '1:cssText').to.equal('');
402 |
403 | // Enable `.repeat(2));
536 |
537 | let onSuccessCount = 0;
538 |
539 | getCss({
540 | include: '[data-test]',
541 | onSuccess(cssText, node, url) {
542 | onSuccessCount++;
543 |
544 | return '!';
545 | },
546 | onComplete(cssText, cssArray, nodeArray) {
547 | expect(cssText, 'return value').to.equal('!'.repeat(styleElms.length));
548 | expect(onSuccessCount, 'onSuccess count').to.equal(styleElms.length);
549 | done();
550 | }
551 | });
552 | });
553 |
554 | it('triggers onSuccess callback for each node', function(done) {
555 | const linkUrl = '/base/tests/fixtures/style1.css';
556 | const linkElms = createTestElms(``.repeat(2));
557 |
558 | let onSuccessCount = 0;
559 |
560 | getCss({
561 | include: '[data-test]',
562 | onSuccess(cssText, node, url) {
563 | onSuccessCount++;
564 |
565 | return '!';
566 | },
567 | onComplete(cssText, cssArray, nodeArray) {
568 | expect(cssText, 'return value').to.equal('!'.repeat(linkElms.length));
569 | expect(onSuccessCount, 'onSuccess count').to.equal(linkElms.length);
570 | done();
571 | }
572 | });
573 | });
574 |
575 | it('filters CSS and nodes based on onSuccess() return value', function(done) {
576 | const testElms = createTestElms([
577 | '',
578 | '',
579 | '',
580 | ''
581 | ]);
582 |
583 | getCss({
584 | include: '[data-test]',
585 | onSuccess(cssText, node, url) {
586 | const returnVals = [false, null, 0, ''];
587 | const nodeIndex = testElms.indexOf(node);
588 |
589 | if (nodeIndex > -1) {
590 | return returnVals[nodeIndex];
591 | }
592 | },
593 | onComplete(cssText, cssArray, nodeArray) {
594 | expect(cssText).to.equal('');
595 | expect(cssArray.length).to.equal(0);
596 | expect(nodeArray.length).to.equal(0);
597 | done();
598 | }
599 | });
600 | });
601 |
602 | it('modifies CSS text based on onSuccess() value', function(done) {
603 | const linkUrl = '/base/tests/fixtures/style1.css';
604 | const styleCss = fixtures['style1.css'];
605 | const modifiedCss = '.modified { color: red; }';
606 |
607 | createTestElms(``);
608 | createTestElms(``);
609 |
610 | getCss({
611 | include: '[data-test]',
612 | onSuccess(cssText, node, url) {
613 | return modifiedCss;
614 | },
615 | onComplete(cssText, cssArray, nodeArray) {
616 | expect(cssText).to.equal(modifiedCss.repeat(2));
617 | done();
618 | }
619 | });
620 | });
621 |
622 | it('triggers onError callback for each @import 404 error', function(done) {
623 | const styleCss = '@import "fail.css";';
624 | const styleElms = createTestElms(``.repeat(3));
625 |
626 | let onErrorCount = 0;
627 |
628 | getCss({
629 | include: '[data-test]',
630 | onError(xhr, node, url) {
631 | onErrorCount++;
632 | },
633 | onComplete(cssText, cssArray, nodeArray) {
634 | expect(onErrorCount).to.equal(styleElms.length);
635 | done();
636 | }
637 | });
638 | });
639 |
640 | it('triggers onError callback for each 404 error', function(done) {
641 | const linkUrl = 'fail.css';
642 | const linkElms = createTestElms(``.repeat(2));
643 |
644 | let onErrorCount = 0;
645 |
646 | getCss({
647 | include: '[data-test]',
648 | onError(xhr, node, url) {
649 | onErrorCount++;
650 | },
651 | onComplete(cssText, cssArray, nodeArray) {
652 | expect(onErrorCount).to.equal(linkElms.length);
653 | done();
654 | }
655 | });
656 | });
657 |
658 | it('triggers onError callback for each invalid XMLHttpRequest.responseText', function(done) {
659 | const linkUrl = '/base/tests/fixtures/404.html';
660 | const linkElms = createTestElms(``.repeat(2));
661 |
662 | let onErrorCount = 0;
663 |
664 | getCss({
665 | include: '[data-test]',
666 | onError(xhr, node, url) {
667 | onErrorCount++;
668 | },
669 | onComplete(cssText, cssArray, nodeArray) {
670 | expect(onErrorCount).to.equal(linkElms.length);
671 | done();
672 | }
673 | });
674 | });
675 |
676 | it('triggers onComplete callback with no matching
19 |
20 | ${this.getAttribute('data-text')}
21 | `;
22 | }
23 | }
24 |
25 | window.customElements.define('test-component', TestComponent);
26 |
27 | // createElms({ tag: 'style', text: ':root { --test-component-background: green; }', appendTo: 'head' });
28 | // createElms([
29 | // { tag: 'test-component', attr: { 'data-text': 'Custom element' }},
30 | // { tag: 'p', text: 'Standard element' }
31 | // ], { appendTo: 'body' });
32 | };
33 |
--------------------------------------------------------------------------------