UNPKG

2.95 kBJavaScriptView Raw
1'use strict';
2
3var q = require('q');
4var request = require('request');
5var cheerio = require('cheerio');
6
7var resolveCssImportUrls = require('resolve-css-import-urls');
8var getLinkContents = require('./utils/get-link-contents');
9var createLink = require('./utils/create-link');
10
11module.exports = function(url, options){
12
13 var deferred = q.defer();
14
15 var options = options || {};
16
17 var status = {
18 parsed: 0,
19 total: 0
20 }
21
22 var result = {
23 links: [],
24 styles: [],
25 css: ''
26 };
27
28 if (options.ignoreCerts) {
29 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
30 }
31
32 options.timeout = options.timeout || 5000;
33
34 function handleResolve() {
35 if (status.parsed >= status.total) {
36 deferred.resolve(result);
37 }
38 }
39
40 function parseHtml(html) {
41 var $ = cheerio.load(html);
42 result.pageTitle = $('title').text();
43
44 $('[rel=stylesheet]').each(function() {
45 var link = $(this).attr('href');
46 result.links.push(createLink(link, url));
47 });
48
49 $('style').each(function() {
50 result.styles.push( $(this).text() );
51 });
52
53 status.total = result.links.length + result.styles.length;
54 if (!status.total) {
55 deferred.resolve(false);
56 }
57
58 result.links.forEach(function(link) {
59 getLinkContents(link.url, options)
60 .then(function(css) {
61 handleCssFromLink(link, css);
62 })
63 .catch(function(error) {
64 link.error = error;
65 status.parsed++;
66 handleResolve();
67 });
68 });
69
70 result.styles.forEach(function(css) {
71 result.css += css;
72 status.parsed++;
73 handleResolve();
74 });
75 }
76
77 function handleCssFromLink(link, css) {
78 link.css += css;
79
80 parseCssForImports(link, css);
81
82 status.parsed++;
83 handleResolve();
84 }
85
86 // Handle potential @import url(foo.css) statements in the CSS.
87 function parseCssForImports(link, css) {
88 link.imports = resolveCssImportUrls(link.url, css);
89 status.total += link.imports.length;
90 result.css += css;
91
92 link.imports.forEach(function(importUrl) {
93 var importLink = createLink(importUrl, importUrl);
94 result.links.push(importLink);
95
96 getLinkContents(importLink.url, options)
97 .then(function(css) {
98 handleCssFromLink(importLink, css);
99 })
100 .catch(function(error) {
101 link.error = error;
102 status.parsed++;
103 handleResolve();
104 });
105 });
106 }
107
108 request({ url: url, timeout: options.timeout, gzip: true }, function(error, response, body) {
109 if (error) {
110 if (options.verbose) console.log('Error from ' + url + ' ' + error);
111 deferred.reject(error);
112 return;
113 }
114
115 if (response && response.statusCode != 200) {
116 if (options.verbose) console.log('Received a ' + response.statusCode + ' from: ' + url);
117 deferred.reject({ url: url, statusCode: response.code });
118 return;
119 }
120
121 parseHtml(body);
122 });
123
124 return deferred.promise;
125};