11var cheerio = require ( 'cheerio' ) ;
22var Promise = require ( 'bluebird' ) ;
3+ var srcset = require ( 'srcset' ) ;
34var utils = require ( '../utils' ) ;
45
56function loadHtml ( context , resource ) {
6- var sources = context . getHtmlSources ( ) ;
7- var handleResources = loadResources . bind ( null , context , resource ) ;
8-
7+ var rules = context . getHtmlSources ( ) ;
98 var p = beforeHandle ( resource ) ;
109
11- sources . forEach ( function ( src ) {
12- p = p . then ( function loadSource ( ) {
13- return handleResources ( src ) ;
10+ rules . forEach ( function ( rule ) {
11+ p = p . then ( function loadResources ( ) {
12+ return loadResourcesForRule ( context , resource , rule ) ;
1413 } ) ;
1514 } ) ;
1615 return p ;
@@ -37,31 +36,91 @@ function beforeHandle (resource) {
3736 return Promise . resolve ( resource ) ;
3837}
3938
40- function loadResources ( context , resource , source ) {
41- var url = resource . getUrl ( ) ;
42- var text = resource . getText ( ) ;
43- var filename = resource . getFilename ( ) ;
44- var $ = cheerio . load ( text ) ;
39+ /**
40+ * @param {HtmlData } htmlData
41+ * @returns {Function } - function which loads resources with given html data
42+ */
43+ function getResourceLoaderByHtmlData ( htmlData ) {
44+ if ( htmlData . tagName === 'img' && htmlData . attributeName === 'srcset' ) {
45+ return loadImgSrcsetResource ;
46+ }
47+ return loadGeneralResource ;
48+ }
4549
46- var promises = $ ( source . selector ) . map ( function loadForSelector ( ) {
47- var el = $ ( this ) ;
48- var attr = el . attr ( source . attr ) ;
50+ /**
51+ * @param {Object } el - cheerio element
52+ * @param {string } attrName - attribute name
53+ * @returns {HtmlData }
54+ */
55+ function createHtmlData ( el , attrName ) {
56+ return {
57+ tagName : el [ 0 ] . name ,
58+ attributeName : attrName ,
59+ attributeValue : el . attr ( attrName )
60+ }
61+ }
62+
63+ /**
64+ * Download resources from <img srcset="...">
65+ * @param context
66+ * @param {Resource } parentResource
67+ * @param {HtmlData } childResourceHtmlData
68+ * @returns {Promise }
69+ */
70+ function loadImgSrcsetResource ( context , parentResource , childResourceHtmlData ) {
71+ var imgScrsetParts = srcset . parse ( childResourceHtmlData . attributeValue ) ;
72+
73+ return Promise . mapSeries ( imgScrsetParts , function loadImgSrcsetPart ( imgScrsetPart ) {
74+ var childResourceUrl = utils . getUrl ( parentResource . getUrl ( ) , imgScrsetPart . url ) ;
75+ var childResource = parentResource . createChild ( childResourceUrl ) ;
76+ childResource . setHtmlData ( childResourceHtmlData ) ;
77+
78+ return context . loadResource ( childResource ) . then ( function updateSrcsetPart ( loadedResource ) {
79+ imgScrsetPart . url = loadedResource . getFilename ( ) ;
80+ } ) ;
81+ } ) . then ( function updateSrcset ( ) {
82+ return Promise . resolve ( srcset . stringify ( imgScrsetParts ) ) ;
83+ } ) ;
84+ }
85+
86+ /**
87+ * Download common resource
88+ * @param context
89+ * @param {Resource } parentResource
90+ * @param {HtmlData } childResourceHtmlData
91+ * @returns {Promise }
92+ */
93+ function loadGeneralResource ( context , parentResource , childResourceHtmlData ) {
94+ var attr = childResourceHtmlData . attributeValue ;
95+
96+ var resourceUrl = utils . getUrl ( parentResource . getUrl ( ) , attr ) ;
97+ var htmlResource = parentResource . createChild ( resourceUrl ) ;
98+ htmlResource . setHtmlData ( childResourceHtmlData ) ;
4999
50- if ( attr ) {
51- var resourceUrl = utils . getUrl ( url , attr ) ;
52- var htmlResource = resource . createChild ( resourceUrl ) ;
53- htmlResource . setHtmlData ( { tagName : el [ 0 ] . name , attributeName : source . attr } ) ;
100+ return context . loadResource ( htmlResource ) . then ( function handleLoadedSource ( loadedResource ) {
101+ var relativePath = utils . getRelativePath ( parentResource . getFilename ( ) , loadedResource . getFilename ( ) ) ;
102+ var hash = utils . getHashFromUrl ( attr ) ;
54103
55- return context . loadResource ( htmlResource ) . then ( function handleLoadedSource ( loadedResource ) {
56- var relativePath = utils . getRelativePath ( filename , loadedResource . getFilename ( ) ) ;
57- var hash = utils . getHashFromUrl ( attr ) ;
104+ if ( hash && loadedResource . isHtml ( ) ) {
105+ relativePath = relativePath . concat ( hash ) ;
106+ }
58107
59- if ( hash && loadedResource . isHtml ( ) ) {
60- relativePath = relativePath . concat ( hash ) ;
61- }
108+ return Promise . resolve ( relativePath ) ;
109+ } ) ;
110+ }
111+
112+ function loadResourcesForRule ( context , resource , rule ) {
113+ var text = resource . getText ( ) ;
114+ var $ = cheerio . load ( text ) ;
115+
116+ var promises = $ ( rule . selector ) . map ( function loadForElement ( ) {
117+ var el = $ ( this ) ;
118+ if ( el . attr ( rule . attr ) ) {
119+ var childResourceHtmlData = createHtmlData ( el , rule . attr ) ;
120+ var loadResourcesForElement = getResourceLoaderByHtmlData ( childResourceHtmlData ) ;
62121
63- el . attr ( source . attr , relativePath ) ;
64- return Promise . resolve ( ) ;
122+ return loadResourcesForElement ( context , resource , childResourceHtmlData ) . then ( function changeAttr ( updatedAttr ) {
123+ el . attr ( rule . attr , updatedAttr ) ;
65124 } ) ;
66125 }
67126 return Promise . reject ( ) ;
0 commit comments