mod-build 3.7.1 → 3.7.2-7.beta-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/gulp-tasks/build.js +4 -4
  3. package/gulp-tasks/get-default-trade-questions.js +155 -0
  4. package/gulp-tasks/grab-cdn.js +26 -21
  5. package/gulp-tasks/grab-mhsadmin-data.js +418 -0
  6. package/gulp-tasks/grab-section-deals-components.js +47 -0
  7. package/gulp-tasks/grab-shared-scripts.js +21 -5
  8. package/gulp-tasks/serve.js +5 -5
  9. package/gulp-tasks/tasks.js +36 -3
  10. package/gulp-tasks/templates.js +95 -12
  11. package/package.json +1 -1
  12. package/src/scripts/vendor/heap-addeventproperties-identify.js +1 -1
  13. package/src/scripts/vendor/heap-tracking.js +1 -1
  14. package/src/scripts/vendor/heap-vwo.js +1 -1
  15. package/src/scripts/vendor/visual-website-optimizer.js +7 -8
  16. package/src/templates/_partials/scripts/vwo-redirect-callback.html +20 -0
  17. package/src/trade-questions/alerts_medical.js +111 -0
  18. package/src/trade-questions/bathroom_refacing.js +96 -0
  19. package/src/trade-questions/cabinet_refacing.js +251 -0
  20. package/src/trade-questions/cabinets.js +35 -0
  21. package/src/trade-questions/concrete_foundation.js +57 -0
  22. package/src/trade-questions/door.js +143 -0
  23. package/src/trade-questions/flooring.js +185 -0
  24. package/src/trade-questions/garage_door.js +89 -0
  25. package/src/trade-questions/gutters.js +45 -0
  26. package/src/trade-questions/home_security.js +130 -0
  27. package/src/trade-questions/home_warranty.js +57 -0
  28. package/src/trade-questions/hot_tubs.js +92 -0
  29. package/src/trade-questions/hvac.js +179 -0
  30. package/src/trade-questions/index.js +26 -0
  31. package/src/trade-questions/insulation.js +118 -0
  32. package/src/trade-questions/plumbing.js +260 -0
  33. package/src/trade-questions/roofing.js +118 -0
  34. package/src/trade-questions/siding.js +150 -0
  35. package/src/trade-questions/solar.js +69 -0
  36. package/src/trade-questions/stair_lifts.js +47 -0
  37. package/src/trade-questions/tree_services.js +169 -0
  38. package/src/trade-questions/walk_in_tubs.js +47 -0
  39. package/src/trade-questions/water_treatment.js +48 -0
  40. package/src/trade-questions/windows.js +132 -0
  41. package/src/trade-questions-config.js +139 -0
@@ -0,0 +1,418 @@
1
+ /* globals Promise */
2
+ /* eslint-disable space-before-function-paren */
3
+ const request = require('request');
4
+ const fs = require('fs');
5
+
6
+ module.exports = function(gulp, gulpPlugins, siteSettings, siteData) {
7
+ const lastModDateOptions = { year: 'numeric', month: '2-digit', day: '2-digit' };
8
+ const tradeLookUp = [];
9
+ const dateLocalString = 'en-US';
10
+ const showCostCalFor = ['windows', 'hvac'];
11
+ const perPageArticlesLimit = 100;
12
+ const articles = [];
13
+ let articleConfigsCount = 0, templatesCount = 0, cachedContractors = {};
14
+
15
+ const log = {
16
+ success: function(icon = '\u{23F3}', message = '') {
17
+ console.log(gulpPlugins.colors.bright, gulpPlugins.colors.fg.green, icon, ' ', message, gulpPlugins.colors.reset);
18
+ },
19
+ info: function(message = '') {
20
+ console.log(message);
21
+ },
22
+ error: function(message, throwError = true) {
23
+ console.log(gulpPlugins.colors.bg.red, gulpPlugins.colors.bright, message, gulpPlugins.colors.reset);
24
+ if (throwError) {
25
+ throw new Error(message);
26
+ }
27
+ }
28
+ };
29
+
30
+ function formatDate(date) {
31
+ const d = new Date(date);
32
+ const year = d.getFullYear();
33
+ const month = String(d.getMonth() + 1).padStart(2, '0');
34
+ const day = String(d.getDate()).padStart(2, '0');
35
+ return [year, month, day].join('-');
36
+ }
37
+
38
+ async function processAndSortContractorList(list, ratingPropertyName = 'reviewScore', minRating = null) {
39
+ list = list.sort(function(a, b) {
40
+ if (a[ratingPropertyName] === null && b[ratingPropertyName] === null) {
41
+ return a.displayName.localeCompare(b.displayName);
42
+ }
43
+ return b[ratingPropertyName] - a[ratingPropertyName];
44
+ });
45
+
46
+ if (minRating) {
47
+ list = await list.filter(data => !data[ratingPropertyName] || data[ratingPropertyName] >= minRating);
48
+ }
49
+
50
+ list = await list.map(function(data, i) {
51
+ if (data) {
52
+ data.index = i;
53
+ }
54
+ return data;
55
+ });
56
+
57
+ return list;
58
+ }
59
+
60
+ // helper function to create nested object dynamically
61
+ function assign(obj, keyPath, value) {
62
+ const lastKeyIndex = keyPath.length - 1;
63
+ for (var i = 0; i < lastKeyIndex; ++i) {
64
+ const key = keyPath[i];
65
+ if (!(key in obj)) {
66
+ obj[key] = {};
67
+ }
68
+ obj = obj[key];
69
+ }
70
+ obj[keyPath[lastKeyIndex]] = value;
71
+ }
72
+
73
+ const sortArticlesByDate = function(articlesList) {
74
+ if (articlesList.length) {
75
+ articlesList.sort(function(a, b) {
76
+ return new Date(b.data.published) - new Date(a.data.published);
77
+ });
78
+ }
79
+ };
80
+
81
+ // MARK: configureGlobalVariables
82
+ const configureGlobalVariables = function(siteData, siteSettings) {
83
+ return new Promise(resolve => {
84
+ const DOMAIN = `https://${siteSettings.nodeEnv === 'qa.modernize.com' ? 'qa' : ''}mhsadmin.wpenginepowered.com`;
85
+ const WP_ENDPOINT_BASE_URL = `${DOMAIN}/wp-json/wp/v2`;
86
+ siteSettings.endpoints = {};
87
+ siteSettings.endpoints.GET_DETAILED_ARTICLES = `${WP_ENDPOINT_BASE_URL}/article?_fields=data,meta,slug&per_page=${perPageArticlesLimit}&site=${siteData.siteName}`;
88
+ siteSettings.endpoints.GET_CONTRACTORS = `${WP_ENDPOINT_BASE_URL}/contractor`;
89
+ siteSettings.endpoints.GET_SITE_DETAILS = `${WP_ENDPOINT_BASE_URL}/site?_fields=data,slug,&site=${siteData.siteName}`;
90
+
91
+ siteData.sitemap = [];
92
+ siteData.page.articlesConfig = {
93
+ siteDetails: {},
94
+ articlesWithContractors: {},
95
+ tradeHubPagesArticlesList: {},
96
+ homePageArticlesList: {
97
+ featured: [],
98
+ top: [],
99
+ recent: []
100
+ },
101
+ defaultHomePage: 'home-services'
102
+ };
103
+ resolve();
104
+ });
105
+ };
106
+
107
+ // MARK: getArticlesList
108
+ const getSiteDetails = async (siteData, siteSettings) => {
109
+ return await new Promise((resolve) => {
110
+ if (!siteData.page) {
111
+ log.error('page is not defined in siteData!');
112
+ }
113
+ const { page, sitemap } = siteData;
114
+ const { articlesConfig } = page;
115
+ const { siteDetails, defaultHomePage } = articlesConfig;
116
+ return request(siteSettings.endpoints.GET_SITE_DETAILS, async function(_xhr, response, body) {
117
+ if (response.statusCode === 200) {
118
+ let result = await JSON.parse(body);
119
+ if (result.length) {
120
+ result = result.filter((data) => data.slug === siteData.siteName);
121
+ }
122
+ await Object.assign(siteDetails, result[0]);
123
+ siteDetails.vertical = await siteDetails?.data?.homepage?.hero?.heading;
124
+ siteDetails.costCalculatorTheme = siteData.costCalculatorTheme ? siteData.costCalculatorTheme : siteDetails?.slug;
125
+ siteDetails.domain = await siteDetails?.data?.domain?.replace(/\/*?$/, '');
126
+ siteDetails.homepage = await siteDetails?.data?.homepage?.slug ? siteDetails?.data?.homepage?.slug : defaultHomePage;
127
+ siteDetails.canonicalURL = await `${siteDetails?.domain}/${siteDetails?.homepage}/`;
128
+ if (siteDetails?.data?.favicon && Object.keys(siteDetails.data.favicon).length) {
129
+ page.headConfig.faviconPath = siteDetails.data.favicon.url ? siteDetails.data.favicon.url : page.headConfig.faviconPath;
130
+ }
131
+
132
+ sitemap.push(
133
+ {
134
+ link: `${siteDetails.domain}/${siteDetails.homepage}/`,
135
+ lastMod: formatDate(new Date().toLocaleDateString(dateLocalString, lastModDateOptions))
136
+ }
137
+ );
138
+ resolve();
139
+ } else {
140
+ log.error('GET_SITE_DETAILS - Something went wrong!');
141
+ }
142
+ });
143
+ });
144
+ };
145
+
146
+ // MARK: getDetailedArticles
147
+ const getDetailedArticles = async (siteSettings, page = 1) => {
148
+ return await new Promise((resolve) => {
149
+ log.info(`Fetching articles from page ${page?.toString()?.padStart(2, '0')}: ${siteSettings.endpoints.GET_DETAILED_ARTICLES}&page=${page}`);
150
+ return request(`${siteSettings.endpoints.GET_DETAILED_ARTICLES}&page=${page}`, async function(_xhr, response, body) {
151
+ if (response.statusCode === 200) {
152
+ const wpArticleTotalPages = await parseInt(response.headers['x-wp-totalpages']);
153
+ await articles.push(...JSON.parse(body));
154
+ if (page < wpArticleTotalPages) {
155
+ // recursive call to get the articles from next pages
156
+ await getDetailedArticles(siteSettings, page + 1);
157
+ } else {
158
+ log.success('\u{2705}', `Finished Fetching article(s) from ${wpArticleTotalPages} page(s)`);
159
+ }
160
+ } else {
161
+ log.error('GET_DETAILED_ARTICLES - Something went wrong!');
162
+ }
163
+ resolve();
164
+ });
165
+ });
166
+ };
167
+
168
+ // MARK: getContractors
169
+ const getContractors = async (trade, siteSettings) => {
170
+ if (!trade) {
171
+ return;
172
+ }
173
+ return await new Promise((resolve) => {
174
+ if (Object.keys(cachedContractors).length && cachedContractors[trade]) {
175
+ resolve(cachedContractors[trade]);
176
+ return;
177
+ } else {
178
+ return request(`${siteSettings.endpoints.GET_CONTRACTORS}?trade=${trade}`, async function(_xhr, response, body) {
179
+ if (response.statusCode === 200) {
180
+ const result = await JSON.parse(body);
181
+ cachedContractors = await { ...cachedContractors, [trade]: result };
182
+ resolve(result);
183
+ } else {
184
+ log.error('GET_CONTRACTORS - Something went wrong!', false);
185
+ resolve([]);
186
+ }
187
+ });
188
+ }
189
+ });
190
+ };
191
+
192
+ const getZipCardMarkup = async function(trade, gulpPlugins) {
193
+ let zipCard = null;
194
+
195
+ const _insertTrade = function(htmlString) {
196
+ const markup = gulpPlugins.htmlParser.parse(htmlString);
197
+ markup.querySelector('.btn--zip').setAttribute('data-service', trade.slug.toLowerCase().replaceAll(/[-|\s]/ig, '_'));
198
+ markup.querySelector('.trade').textContent = trade.displayName;
199
+ return markup;
200
+ };
201
+
202
+ return new Promise((resolve) => {
203
+ if (zipCard) {
204
+ zipCard = _insertTrade(zipCard);
205
+ return resolve(zipCard);
206
+ }
207
+ fs.readFile('./src/shared-components/section-deals/_partials/page-card-zip.html', 'utf-8', function(err, data) {
208
+ if (err) {
209
+ log.error('page-card-zip.html not found at "/src/shared-components/section-deals/_partials/page-card-zip.html" ');
210
+ }
211
+ zipCard = data;
212
+ zipCard = _insertTrade(zipCard);
213
+ resolve(zipCard);
214
+ });
215
+ });
216
+ };
217
+
218
+ // MARK: buildTemplates
219
+ async function buildTemplates(siteData, siteSettings, done) {
220
+ const { srcFolder, templatesSubfolder } = siteSettings;
221
+ const { page } = await siteData;
222
+ const { articlesConfig } = page;
223
+ const { articlesWithContractors, siteDetails } = articlesConfig;
224
+ const templatesPath = `${srcFolder}/${templatesSubfolder}/`;
225
+ return await new Promise(function(resolve) {
226
+ if (articlesWithContractors && Object.keys(articlesWithContractors).length) {
227
+ log.success('\u{23F3}', 'Building Article(s)...');
228
+ Object.entries(articlesWithContractors).forEach(async function([trade, articlesList]) {
229
+ Object.entries(articlesList).forEach(function([pageName, articleData]) {
230
+ let costCalculatorTrade = trade;
231
+ costCalculatorTrade = costCalculatorTrade.toLowerCase() === 'gutters' ? 'gutter' : costCalculatorTrade;
232
+ const tradeHubFileContent = `{{#page.articlesConfig.tradeHubPagesArticlesList.${trade}}}
233
+ {{fileInclude 'src/shared-components/section-deals/components/trade-hub-template.html'
234
+ tradeHubPageArticles = this
235
+ trade = '${articleData.data.trade.title}'
236
+ costCalculatorTrade = '${costCalculatorTrade}'
237
+ showCostCalculator = ${showCostCalFor.includes(trade)}
238
+ }}{{/page.articlesConfig.tradeHubPagesArticlesList.${trade}}}
239
+ <script>
240
+ window.siteData.trade='${trade}';
241
+ </script>`;
242
+
243
+ const fileName = articleData.slug;
244
+ const fileContent = `{{#page.articlesConfig.articlesWithContractors.${trade}.${pageName}}}
245
+ {{fileInclude 'src/shared-components/section-deals/components/article-template.html'
246
+ article = this
247
+ trade = '${trade}'
248
+ }}{{/page.articlesConfig.articlesWithContractors.${trade}.${pageName}}}`;
249
+ // make the directory by trade name
250
+ fs.mkdir(`${templatesPath}/${siteDetails.homepage}/${articleData.data.trade.slug}/`, { recursive: true }, async function(error) {
251
+ if (error) {
252
+ throw error;
253
+ }
254
+ fs.writeFile(`${templatesPath}/${siteDetails.homepage}/${articleData.data.trade.slug}/index.html`, tradeHubFileContent, function(err) {
255
+ if (err) {
256
+ throw err;
257
+ }
258
+ fs.writeFile(`${templatesPath}/${siteDetails.homepage}/${articleData.data.trade.slug}/${fileName}.html`, fileContent, function($err) {
259
+ if ($err) {
260
+ throw $err;
261
+ }
262
+ templatesCount++;
263
+ log.info(`Article template ${templatesCount?.toString()?.padStart(2, '0')}: ${templatesPath}${articleData.data.trade.slug}/${siteDetails.homepage}/${fileName}.html`);
264
+ if (articleConfigsCount === templatesCount) {
265
+ siteData.page.lastMod = formatDate(new Date().toLocaleDateString(dateLocalString, lastModDateOptions));
266
+ done();
267
+ log.success('\u{2705}', `Finished Building ${templatesCount} Article(s).`);
268
+ }
269
+ });
270
+ });
271
+ });
272
+ });
273
+ });
274
+ }
275
+ resolve();
276
+ });
277
+ }
278
+
279
+ // MARK: configureArticlesAndBuildTemplates
280
+ async function configureArticlesAndBuildTemplates(siteData, siteSettings, gulpPlugins) {
281
+ return await new Promise(function(done) {
282
+ if (!siteData.page) {
283
+ log.error('"page" is not defined in siteData!');
284
+ }
285
+
286
+ if (articles.length === 0) {
287
+ log.error('Articles not found!');
288
+ }
289
+
290
+ const { page } = siteData;
291
+ const { articlesConfig } = page;
292
+ const { homePageArticlesList, articlesWithContractors, tradeHubPagesArticlesList, siteDetails } = articlesConfig;
293
+
294
+ articles.forEach(async (article) => {
295
+ const templateData = article;
296
+ const articlesWithContractorsKey = article.slug.replaceAll(/[-|\s]/ig, '_');
297
+ const trade = article.data.trade.slug.toLowerCase().replaceAll(/[-|\s]/ig, '_');
298
+ const contractors = await getContractors(article.data.trade.slug, siteSettings);
299
+ const tradeDisplayName = article?.data?.trade?.title?.toLowerCase();
300
+ // Append contractors
301
+ if (contractors && contractors.length) {
302
+ templateData.contractors = await processAndSortContractorList(contractors, 'reviewScore');
303
+ }
304
+ const articleLink = await `${siteDetails?.homepage}/${article.data.trade.slug}/${article.slug}.html`;
305
+ const tradeHubLink = await `${siteDetails?.homepage}/${article.data.trade.slug}/`;
306
+ const categoryPageLink = await `${siteDetails?.homepage}/`;
307
+ templateData.data.redirectLink = await `/${articleLink}`;
308
+ templateData.data.tradeHubPageLink = await `/${tradeHubLink}`;
309
+ templateData.data.categoryPageLink = await `/${categoryPageLink}`;
310
+ templateData.meta.canonicalURL = await `${siteDetails?.domain}/${articleLink}`;
311
+ templateData.data.loc = await `${siteDetails?.domain}/${articleLink}`;
312
+ templateData.data.lastMod = await formatDate(new Date(article.data.published).toLocaleDateString(dateLocalString, lastModDateOptions));
313
+ templateData.data.vertical = siteDetails.vertical;
314
+ templateData.data.trade.displayName = tradeDisplayName === 'hvac' ? 'heating and cooling' : tradeDisplayName;
315
+
316
+ const lastMod = formatDate(new Date(templateData.data.published).toLocaleDateString(dateLocalString, lastModDateOptions));
317
+
318
+ if (!tradeLookUp.includes(article.data.trade.slug)) {
319
+ tradeLookUp.push(article.data.trade.slug);
320
+ siteData.sitemap.push(
321
+ {
322
+ link: `${siteDetails.domain}/${tradeHubLink}`,
323
+ lastMod
324
+ }
325
+ );
326
+ }
327
+
328
+ siteData.sitemap.push(
329
+ {
330
+ link: `${siteDetails.domain}/${articleLink}`,
331
+ lastMod
332
+ }
333
+ );
334
+
335
+ templateData.data.sponsoredContent = siteDetails.data.sponsoredContent.article;
336
+
337
+ const zipCard = await getZipCardMarkup(templateData.data.trade, gulpPlugins);
338
+ const htmlContent = gulpPlugins.htmlParser.parse(templateData.data.content);
339
+ const contentHeadings = htmlContent.querySelectorAll('h2[id]');
340
+ if (zipCard) {
341
+ // find the middle section index and add flag isMiddleSection
342
+ const middleSectionIndex = Math.floor((contentHeadings.length) / 2);
343
+ htmlContent.querySelectorAll('h2[id]')[middleSectionIndex].insertAdjacentHTML('beforebegin', zipCard);
344
+ }
345
+ templateData.data.content = htmlContent;
346
+
347
+ await assign(articlesWithContractors, [trade, articlesWithContractorsKey], templateData);
348
+
349
+ await articleConfigsCount++;
350
+
351
+ if (articleConfigsCount === articles.length) {
352
+ if (Object.keys(articlesWithContractors).length) {
353
+ Object.entries(articlesWithContractors).forEach(async function([tradeName, values]) {
354
+ await sortArticlesByDate(Object.values(values));
355
+ if (!tradeHubPagesArticlesList[tradeName]) {
356
+ tradeHubPagesArticlesList[tradeName] = {};
357
+ }
358
+
359
+ if (!tradeHubPagesArticlesList[tradeName].featured) {
360
+ tradeHubPagesArticlesList[tradeName].featured = [];
361
+ }
362
+
363
+ if (!tradeHubPagesArticlesList[tradeName].top) {
364
+ tradeHubPagesArticlesList[tradeName].top = [];
365
+ }
366
+
367
+ if (!tradeHubPagesArticlesList[tradeName].recent) {
368
+ tradeHubPagesArticlesList[tradeName].recent = [];
369
+ }
370
+
371
+ if (!tradeHubPagesArticlesList[tradeName].canonicalURL) {
372
+ tradeHubPagesArticlesList[tradeName].canonicalURL = `${siteDetails?.domain}/${tradeName}/`;
373
+ }
374
+
375
+ tradeHubPagesArticlesList[tradeName].page = await siteDetails?.data?.trades?.filter((data) => data.slug === tradeName)[0];
376
+
377
+ Object.entries(values).forEach(function([, data], i) {
378
+ if (i === 0) {
379
+ tradeHubPagesArticlesList[tradeName].featured.push(data.data);
380
+ }
381
+
382
+ if (showCostCalFor.includes(tradeName)) {
383
+ if (i >= 1) {
384
+ tradeHubPagesArticlesList[tradeName].recent.push(data.data);
385
+ tradeHubPagesArticlesList[tradeName].recentCount = tradeHubPagesArticlesList[tradeName].recent.length;
386
+ }
387
+ } else {
388
+ if (i > 0 && i < 3) {
389
+ tradeHubPagesArticlesList[tradeName].top.push(data.data);
390
+ tradeHubPagesArticlesList[tradeName].topCount = tradeHubPagesArticlesList[tradeName].top.length;
391
+ } else if (i >= 3) {
392
+ tradeHubPagesArticlesList[tradeName].recent.push(data.data);
393
+ tradeHubPagesArticlesList[tradeName].recentCount = tradeHubPagesArticlesList[tradeName].recent.length;
394
+ }
395
+ }
396
+
397
+ if (homePageArticlesList.featured.length === 0 && data.data.isFeatured) {
398
+ homePageArticlesList.featured.push(data.data);
399
+ } else if (homePageArticlesList.top.length < 2 && !data.data.isFeatured && data.data.isTopArticle) {
400
+ homePageArticlesList.top.push(data.data);
401
+ } else if (!data.data.isTopArticle && !data.data.isFeatured) {
402
+ homePageArticlesList.recent.push(data.data);
403
+ }
404
+ });
405
+ });
406
+ }
407
+ await buildTemplates(siteData, siteSettings, done);
408
+ }
409
+ });
410
+ });
411
+ }
412
+ return async function() {
413
+ await configureGlobalVariables(siteData, siteSettings);
414
+ await getSiteDetails(siteData, siteSettings);
415
+ await getDetailedArticles(siteSettings);
416
+ return await configureArticlesAndBuildTemplates(siteData, siteSettings, gulpPlugins);
417
+ };
418
+ };
@@ -0,0 +1,47 @@
1
+ /* globals Promise */
2
+ var request = require('request');
3
+ var source = require('vinyl-source-stream');
4
+
5
+ function streamSharedCompsToDestination(gulp, siteSettings, folder, fileName) {
6
+ return new Promise(resolve => {
7
+ request(`https://${siteSettings.nodeEnv}/quote/resources/mod-site/shared-components/${folder}/${fileName}`)
8
+ .on('response', resp => {
9
+ if (resp.statusCode !== 200) {
10
+ throw new Error(`${resp.statusCode} Error while fetching ${fileName}`);
11
+ }
12
+ })
13
+ .pipe(source(fileName))
14
+ .pipe(gulp.dest(`${siteSettings.srcFolder}/shared-components/${folder}/`))
15
+ .on('finish', resolve);
16
+ });
17
+ }
18
+
19
+ function getListOfSharedComponents(gulp, gulpPlugins, siteSettings, componentFolders) {
20
+ return componentFolders.map(folder => {
21
+ return new Promise(resolve => {
22
+ request(`https://${siteSettings.nodeEnv}/quote/resources/mod-site/shared-components/${folder}/all.json`, function(err, resp, body) {
23
+ if (resp.statusCode !== 200) {
24
+ throw new Error(`${resp.statusCode}: Error while fetching ${folder}/all.json`);
25
+ }
26
+ var listOfComponents = JSON.parse(body);
27
+ const componentPromises = listOfComponents.map(function(resource) {
28
+ return streamSharedCompsToDestination(gulp, siteSettings, folder, `${resource}`);
29
+ });
30
+ resolve(Promise.all(componentPromises));
31
+ });
32
+ });
33
+ });
34
+ }
35
+
36
+ module.exports = function(gulp, gulpPlugins, siteSettings) {
37
+ return function() {
38
+ const { nodeEnv } = siteSettings;
39
+ if (!nodeEnv) {
40
+ throw new Error('Missing environment variables. Did you start with gulp instead of npm run...?');
41
+ }
42
+
43
+ const componentFolders = ['section-deals'];
44
+
45
+ return getListOfSharedComponents(gulp, gulpPlugins, siteSettings, componentFolders);
46
+ };
47
+ };
@@ -7,6 +7,7 @@ var path = require('path');
7
7
  var buffer = require('gulp-buffer');
8
8
 
9
9
  const fileNames = {
10
+ geolocationFileName: '',
10
11
  modAlyticsFileName: '',
11
12
  modUtilsFileName: '',
12
13
  abandonmentJsFileName: '',
@@ -22,11 +23,16 @@ var resourceURL = '';
22
23
  var pathSubdirectory = '';
23
24
  var componentFolderPath = '';
24
25
 
25
- function replaceModalyticsSrc(gulp, gulpPlugins, siteSettings, siteData) {
26
- const doNotIncludeSrc = siteData.siteData && siteData.siteData.isPathSubdirectory || siteData && siteData.isPathSubdirectory;
27
- const resourcePath = isQuotePageOrUseRelativePath ? `${doNotIncludeSrc ? '' : '{{#if this.src}}{{this.src}}{{/if}}'}resources/scripts/mod-alytics/` : '/resources/scripts/mod-alytics/';
26
+ function replaceHeadScripts(gulp, gulpPlugins, siteSettings, siteData) {
27
+ const resourcePath = isQuotePageOrUseRelativePath ? '{{#if this.src}}{{this.src}}{{/if}}resources/scripts' : '/resources/scripts';
28
28
  return gulp.src(`${siteSettings.srcFolder}/${componentFolderPath}/head/head.html`)
29
- .pipe(replace(/".*(modalytics).*"/, `"${resourcePath}${fileNames.modAlyticsFileName}"`))
29
+ .pipe(replace(/"(?:(?!"|")[\s\S])+(modalytics.*?)js"|"(?:(?!"|")[\s\S])+(geolocation.*?)js"/g, function(match) {
30
+ if (match.includes('modalytics')) {
31
+ return `"${resourcePath}/mod-alytics/${fileNames.modAlyticsFileName}"`;
32
+ } else if (match.includes('geolocation')) {
33
+ return `"${resourcePath}/geolocation/${fileNames.geolocationFileName}"`;
34
+ }
35
+ }))
30
36
  .pipe(gulp.dest(`${siteSettings.srcFolder}/${componentFolderPath}/head`));
31
37
  }
32
38
  function replaceFootAssetScripts(gulp, gulpPlugins, siteSettings, siteData) {
@@ -187,6 +193,16 @@ const TASKS = {
187
193
  srcReplaceFn: replaceFootAssetScripts,
188
194
  additionalSrcReplaceFns: []
189
195
  },
196
+ copyGeolocation: {
197
+ url: 'shared-resources/scripts/geolocation/geolocation.min.js',
198
+ config: {
199
+ fileName: 'geolocationFileName',
200
+ dest: 'scripts/geolocation',
201
+ mapUrl: 'shared-resources/scripts/geolocation/geolocation.min.js.map',
202
+ },
203
+ srcReplaceFn: null,
204
+ additionalSrcReplaceFns: []
205
+ },
190
206
  copyModalytics: {
191
207
  url: 'mod-alytics/modalytics.min.js',
192
208
  config: {
@@ -194,7 +210,7 @@ const TASKS = {
194
210
  dest: 'scripts/mod-alytics',
195
211
  mapUrl: 'mod-alytics/modalytics.min.js.map',
196
212
  },
197
- srcReplaceFn: replaceModalyticsSrc,
213
+ srcReplaceFn: replaceHeadScripts,
198
214
  additionalSrcReplaceFns: []
199
215
  },
200
216
  copyAbandonmentComponentStyles: {
@@ -4,11 +4,11 @@ module.exports.src = function(gulp, gulpPlugins, siteSettings, siteData) {
4
4
  var runSequence = require('run-sequence');
5
5
  var sequenceOpts;
6
6
  if (siteData.useTypescript) {
7
- sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'grab-form-helpers', 'templates', 'styles', 'compile', 'grab-tooltips-json', 'combine-files', 'grab-images', 'js-lint'];
7
+ sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'get-default-trade-questions', 'grab-form-helpers', 'templates', 'styles', 'compile', 'grab-tooltips-json', 'combine-files', 'grab-images', 'js-lint'];
8
8
  } else if (siteData.isQSPage) {
9
- sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'grab-form-helpers', 'templates', 'styles', 'grab-theme-json', 'grab-tooltips-json', 'combine-files', 'grab-images', 'js-lint'];
9
+ sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'get-default-trade-questions', 'grab-form-helpers', 'templates', 'styles', 'grab-theme-json', 'grab-tooltips-json', 'combine-files', 'grab-images', 'js-lint'];
10
10
  } else {
11
- sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'grab-form-helpers', 'templates', 'styles', 'grab-tooltips-json', 'combine-files', 'grab-images','grab-global-images', 'js-lint'];
11
+ sequenceOpts = ['clean', 'add-editorconfig', 'grab-cdn', 'grab-shared-components', 'grab-shared-scripts', 'get-default-trade-questions', 'grab-form-helpers', 'templates', 'styles', 'grab-tooltips-json', 'combine-files', 'grab-images', 'grab-global-images', 'js-lint'];
12
12
  }
13
13
  runSequence(...sequenceOpts, () => {
14
14
  // Run a BrowserSync server
@@ -38,10 +38,10 @@ module.exports.src = function(gulp, gulpPlugins, siteSettings, siteData) {
38
38
  // If templates changed, rerun templates task
39
39
  if (!siteData.useTypescript && !siteData.isQSPage) {
40
40
  gulp.watch(siteSettings.srcFolder + '/' + siteSettings.templatesSubfolder + '/**/*.html', function() {
41
- runSequence('templates','grab-global-images')
41
+ runSequence('templates', 'grab-global-images');
42
42
  });
43
43
  } else {
44
- gulp.watch(siteSettings.srcFolder + '/' + siteSettings.templatesSubfolder + '/**/*.html', ['templates'])
44
+ gulp.watch(siteSettings.srcFolder + '/' + siteSettings.templatesSubfolder + '/**/*.html', ['templates']);
45
45
  }
46
46
 
47
47
  // If styles changed, rerun styles task
@@ -40,7 +40,7 @@ module.exports = function() {
40
40
  return require(opts.gulpTasksFolderPath + '/grab-cdn')(opts.gulp, opts.gulpPlugins, opts.gulpSettings, opts.siteData);
41
41
  }
42
42
  }
43
- },
43
+ },
44
44
 
45
45
  // Grab form helpers files from CDN
46
46
  'grab-form-helpers': {
@@ -356,7 +356,7 @@ module.exports = function() {
356
356
 
357
357
  return require(opts.gulpTasksFolderPath + '/grab-images')(opts.gulp, opts.gulpSettings, opts.siteData);
358
358
  }
359
- },
359
+ },
360
360
 
361
361
  // Get global images
362
362
  'grab-global-images': {
@@ -430,7 +430,7 @@ module.exports = function() {
430
430
 
431
431
  return require(opts.gulpTasksFolderPath + '/grab-tooltips-json')(opts.gulp, opts.gulpPlugins, opts.gulpSettings, opts.siteData);
432
432
  }
433
- },
433
+ },
434
434
 
435
435
  // copy resources directory into dist
436
436
  'copy-resources-to-dist': {
@@ -488,6 +488,39 @@ module.exports = function() {
488
488
 
489
489
  return require('./copy-xml-files-to-dist')(opts.gulp, opts.gulpSettings);
490
490
  }
491
+ },
492
+
493
+ 'grab-section-deals-components': {
494
+ subtasks: [],
495
+ func: function(opts) {
496
+ if ('undefined' === typeof opts.gulpTasksFolderPath) {
497
+ opts.gulpTasksFolderPath = '.';
498
+ }
499
+
500
+ return require('./grab-section-deals-components')(opts.gulp, opts.gulpPlugins, opts.gulpSettings, opts.siteData);
501
+ }
502
+ },
503
+
504
+ 'grab-mhsadmin-data': {
505
+ subtasks: [],
506
+ func: function(opts) {
507
+ if ('undefined' === typeof opts.gulpTasksFolderPath) {
508
+ opts.gulpTasksFolderPath = '.';
509
+ }
510
+
511
+ return require('./grab-mhsadmin-data')(opts.gulp, opts.gulpPlugins, opts.gulpSettings, opts.siteData);
512
+ }
513
+ },
514
+
515
+ 'get-default-trade-questions': {
516
+ subtasks: [],
517
+ func: function(opts) {
518
+ if ('undefined' === typeof opts.gulpTasksFolderPath) {
519
+ opts.gulpTasksFolderPath = '.';
520
+ }
521
+
522
+ return require('./get-default-trade-questions')(opts.gulp, opts.gulpPlugins, opts.gulpSettings, opts.siteData);
523
+ }
491
524
  }
492
525
  };
493
526