mod-build 3.6.75-beta.2 → 4.0.0-alpha.2
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.
- package/.eslintignore +3 -0
- package/.eslintrc +18 -0
- package/CHANGELOG.md +2 -252
- package/README.md +16 -263
- package/gulp-tasks/grab-cdn.js +0 -10
- package/package.json +18 -68
- package/siteconfig.js +38 -0
- package/src/data/footer.js +117 -0
- package/src/data/seasons.js +5 -7
- package/src/index.html +18 -0
- package/src/main.js +45 -0
- package/src/scripts/has-qs-params.js +6 -5
- package/src/scripts/url-cleaner.js +3 -3
- package/src/scripts/utils.js +178 -0
- package/src/styles/home.scss +1 -0
- package/src/templates/_partials/scripts/deferred-styles.html +16 -16
- package/src/templates/_partials/scripts/vwo-redirect-callback.html +43 -45
- package/src/templates/components/head.html +70 -0
- package/tasks/clean.js +13 -0
- package/tasks/grab-cdn.js +107 -0
- package/tasks/grab-form-helpers.js +94 -0
- package/tasks/grab-shared-components.js +81 -0
- package/tasks/grab-shared-scripts.js +267 -0
- package/tasks/serve.js +15 -0
- package/tasks/templates.js +168 -0
- package/template.js +801 -0
- package/vite.config.js +56 -0
- package/.eslintrc.yml +0 -59
- package/src/data/common.js +0 -704
- package/src/data/components/qs-footer.js +0 -55
- package/src/data/components/quote-footer.js +0 -73
- package/src/scripts/apt-block.js +0 -919
- package/src/scripts/components/custom-selects.js +0 -48
- package/src/scripts/components/radio-panels.js +0 -45
- package/src/scripts/es6-1.js +0 -6
- package/src/scripts/es6-2.js +0 -2
- package/src/scripts/qs-form.js +0 -839
- package/src/scripts/vendor/maxmind-geoip2.js +0 -2
- package/src/scripts/vendor/swiper.min.js +0 -13
- package/src/styles/apt-block.scss +0 -888
- package/src/templates/_partials/apt-block.html +0 -30
- package/src/templates/_partials/scripts/analytics.html +0 -4
- package/src/templates/_partials/scripts/go-page-hiding-snippet.html +0 -8
- package/src/templates/_partials/scripts/google-maps.html +0 -1
- package/src/templates/_partials/scripts/google-optimize.html +0 -12
- package/src/templates/_partials/scripts/gtm-editorials/body/google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-editorials/head/google-tag-manager-head.html +0 -10
- package/src/templates/_partials/scripts/gtm-hil/body/google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-hil/head/google-tag-manager-head.html +0 -10
- package/src/templates/_partials/scripts/gtm-pro/body/google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-pro/head/google-tag-manager-head.html +0 -10
- package/src/templates/_partials/scripts/gtm-quote/body/google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-quote/head/google-tag-manager-head.html +0 -9
- package/src/templates/_partials/scripts/gtm-whitelabel/body/mod-google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-whitelabel/body/non-mod-google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-whitelabel/head/mod-google-tag-manager-head.html +0 -10
- package/src/templates/_partials/scripts/gtm-whitelabel/head/non-mod-google-tag-manager-head.html +0 -9
- package/src/templates/_partials/scripts/gtm-wordpress/body/google-tag-manager-body.html +0 -5
- package/src/templates/_partials/scripts/gtm-wordpress/head/google-tag-manager-head.html +0 -9
- package/src/templates/_partials/scripts/visual-website-optimizer.html +0 -5
- package/src/templates/index.html +0 -46
- /package/{src → public}/favicon.ico +0 -0
package/package.json
CHANGED
|
@@ -1,79 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mod-build",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.2",
|
|
4
4
|
"description": "Share components for S3 sites.",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"scripts": {
|
|
6
|
-
"
|
|
7
|
-
"
|
|
7
|
+
"dev": "export NODE_ENV=qa.modernize.com IS_LOCAL=true && vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
8
10
|
},
|
|
9
|
-
"author": "",
|
|
10
|
-
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"del": "^3.0.0",
|
|
18
|
-
"gulp": "^3.9.1",
|
|
19
|
-
"gulp-autoprefixer": "^3.1.1",
|
|
20
|
-
"gulp-babel": "^8.0.0",
|
|
21
|
-
"gulp-buffer": "0.0.2",
|
|
22
|
-
"gulp-clean-css": "^3.0.4",
|
|
23
|
-
"gulp-concat": "^2.6.1",
|
|
24
|
-
"gulp-cssmin": "^0.1.7",
|
|
25
|
-
"gulp-csso": "^3.0.0",
|
|
26
|
-
"gulp-eslint": "^5.0.0",
|
|
27
|
-
"gulp-eslint-threshold": "^0.1.1",
|
|
28
|
-
"gulp-filter": "^5.0.0",
|
|
12
|
+
"@rollup/plugin-inject": "^5.0.5",
|
|
13
|
+
"axios": "^1.6.2",
|
|
14
|
+
"del": "^7.1.0",
|
|
15
|
+
"eslint": "^8.55.0",
|
|
16
|
+
"gulp": "^4.0.2",
|
|
29
17
|
"gulp-handlebars-file-include": "^1.0.0",
|
|
30
18
|
"gulp-hash": "^4.2.2",
|
|
31
|
-
"gulp-
|
|
32
|
-
"gulp-if": "^2.0.2",
|
|
33
|
-
"gulp-imagemin": "^3.2.0",
|
|
34
|
-
"gulp-insert": "^0.5.0",
|
|
35
|
-
"gulp-load-plugins": "^0.10.0",
|
|
36
|
-
"gulp-minify": "0.0.14",
|
|
37
|
-
"gulp-mocha-phantomjs": "^0.12.1",
|
|
38
|
-
"gulp-plumber": "^1.1.0",
|
|
39
|
-
"gulp-rename": "^1.2.2",
|
|
40
|
-
"gulp-replace": "^0.5.4",
|
|
41
|
-
"gulp-rev": "^7.1.2",
|
|
42
|
-
"gulp-rev-all": "^0.9.7",
|
|
43
|
-
"gulp-rev-delete-original": "^0.2.3",
|
|
44
|
-
"gulp-rev-replace": "^0.4.3",
|
|
45
|
-
"gulp-sass": "^5.1.0",
|
|
46
|
-
"gulp-sass-lint": "^1.3.2",
|
|
47
|
-
"gulp-sass-variables": "^1.2.0",
|
|
48
|
-
"gulp-size": "^2.1.0",
|
|
49
|
-
"gulp-sourcemaps": "^2.6.0",
|
|
19
|
+
"gulp-replace": "^1.1.4",
|
|
50
20
|
"gulp-tap": "^2.0.0",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"lodash.merge": "^4.6.2",
|
|
59
|
-
"nouislider": "^10.1.0",
|
|
60
|
-
"path": "^0.12.7",
|
|
61
|
-
"request": "^2.88.0",
|
|
62
|
-
"run-sequence": "^2.2.1",
|
|
63
|
-
"sass": "^1.49.9",
|
|
64
|
-
"should": "^11.2.1",
|
|
65
|
-
"vinyl-source-stream": "^2.0.0",
|
|
66
|
-
"webpack-stream": "^5.2.1"
|
|
67
|
-
},
|
|
68
|
-
"resolutions": {
|
|
69
|
-
"graceful-fs": "4.2.3"
|
|
70
|
-
},
|
|
71
|
-
"husky": {
|
|
72
|
-
"hooks": {
|
|
73
|
-
"pre-push": "gulp sass-lint && gulp js-lint-husky"
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"overrides": {
|
|
77
|
-
"graceful-fs": "^4.2.9"
|
|
21
|
+
"husky": "^8.0.3",
|
|
22
|
+
"jquery": "^3.7.1",
|
|
23
|
+
"sass": "^1.69.5",
|
|
24
|
+
"vite": "^5.0.0",
|
|
25
|
+
"vite-plugin-eslint": "^1.8.1",
|
|
26
|
+
"vite-plugin-handlebars": "^1.6.0",
|
|
27
|
+
"vite-plugin-static-copy": "^1.0.0"
|
|
78
28
|
}
|
|
79
29
|
}
|
package/siteconfig.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export let siteData = {
|
|
2
|
+
primary_trade: 'Medical Alerts',
|
|
3
|
+
service: 'alerts_medical', // required to fetch the correct tcpa blurb
|
|
4
|
+
gtm_container_ID: 'GTM-TBJV3H', // e.g. GTM-N23VMDW
|
|
5
|
+
qs_gtm_container_ID: 'GTM-TBJV3H',
|
|
6
|
+
email: 'support@emedicalalerts.com', // e.g. // e.g. support@homesolarsurvey.com
|
|
7
|
+
email_unsub: 'unsubscribe@emedicalalerts.com', // e.g. unsubscribe@homesolarsurvey.com
|
|
8
|
+
domain: 'emedicalalerts.com', // e.g. homesolarsurvey.com
|
|
9
|
+
company_name: 'eMedicalAlerts', // e.g. Home Solar Survey
|
|
10
|
+
website_name: 'eMedicalAlerts.com', // e.g. HomeSolarSurvey.com
|
|
11
|
+
useCDN: true,
|
|
12
|
+
isWhiteLabel: true,
|
|
13
|
+
isQSPage: true,
|
|
14
|
+
useAccessibleConfig: true
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function setSiteData(newSiteData) {
|
|
18
|
+
siteData = newSiteData;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const defaultSettings = {
|
|
22
|
+
tmpFolder: '.tmp',
|
|
23
|
+
srcFolder: 'src',
|
|
24
|
+
browserSyncServeFolders: ['.tmp', 'src', 'node_modules/mod-style-bootstrap/src', 'node_modules/mod-base/src'],
|
|
25
|
+
distFolder: 'dist',
|
|
26
|
+
fontsSubfolder: 'fonts',
|
|
27
|
+
imagesSubfolder: 'images',
|
|
28
|
+
stylesSubfolder: 'styles',
|
|
29
|
+
scriptsSubfolder: 'scripts',
|
|
30
|
+
scriptsCompiledFolder: 'scripts/compiled',
|
|
31
|
+
templatesSubfolder: 'templates',
|
|
32
|
+
dataSubfolder: 'data',
|
|
33
|
+
modBuild: '',
|
|
34
|
+
resourceDomain: process.env.IS_LOCAL ? 'qa.modernize.com' : 'modernize.com',
|
|
35
|
+
nodeEnv: process.env.NODE_ENV,
|
|
36
|
+
isLocal: process.env.IS_LOCAL || import.meta?.env?.DEV,
|
|
37
|
+
buildPath: process.env.BUILD_PATH
|
|
38
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/* contains data for qs-footer and quote-footer */
|
|
2
|
+
export default function(siteData) {
|
|
3
|
+
let trade = '';
|
|
4
|
+
if (siteData?.contractor_trade) {
|
|
5
|
+
trade = `&trade=${siteData.contractor_trade}`;
|
|
6
|
+
} else if (siteData?.primary_trade) {
|
|
7
|
+
trade = `&trade=${siteData.primary_trade.replace(/[\s]+|_/g, '-').toLowerCase()}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const footerKey = siteData.isQSPage ? 'qsFooterData' : 'quoteFooterData';
|
|
11
|
+
|
|
12
|
+
const qsLinks = [
|
|
13
|
+
{
|
|
14
|
+
name: 'About',
|
|
15
|
+
url: '/about/',
|
|
16
|
+
modal: true,
|
|
17
|
+
company: true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Privacy Notice',
|
|
21
|
+
url: '/privacy/',
|
|
22
|
+
modal: true
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'Affiliates',
|
|
26
|
+
url: 'https://modernize.com/contact?publisher',
|
|
27
|
+
modal: false
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Terms of Use',
|
|
31
|
+
url: '/terms/',
|
|
32
|
+
modal: true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'Contact Us',
|
|
36
|
+
url: '/contact-us/',
|
|
37
|
+
modal: true
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'California - Do not sell my info',
|
|
41
|
+
url: 'https://privacy-central.securiti.ai/#/dsr/983cfd4b-c36a-4601-89e9-b651e5a05708',
|
|
42
|
+
modal: false
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
const quoteLinks = [
|
|
47
|
+
{
|
|
48
|
+
url: 'about',
|
|
49
|
+
text: 'About Us',
|
|
50
|
+
modal: true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
url: 'terms',
|
|
54
|
+
text: 'Terms of Use',
|
|
55
|
+
modal: true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
url: 'privacy',
|
|
59
|
+
text: 'Privacy Policy',
|
|
60
|
+
modal: true
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
url: 'https://modernize.com/contact?publisher',
|
|
64
|
+
text: 'I\'m a publisher',
|
|
65
|
+
modal: false,
|
|
66
|
+
target: '_blank'
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
const quoteSpecific = {
|
|
71
|
+
capchaDisclosure: {
|
|
72
|
+
text: 'This site is protected by reCAPTCHA and the Google',
|
|
73
|
+
privacy: {
|
|
74
|
+
text: 'Privacy Policy',
|
|
75
|
+
url: 'https://policies.google.com/privacy'
|
|
76
|
+
},
|
|
77
|
+
terms: {
|
|
78
|
+
text: 'Terms of Service',
|
|
79
|
+
url: 'https://policies.google.com/terms'
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
privacyLinks: [
|
|
83
|
+
{
|
|
84
|
+
text: 'California Privacy',
|
|
85
|
+
anchor: 'ccpa',
|
|
86
|
+
modal: true
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
text: 'New York Privacy',
|
|
90
|
+
anchor: 'nyna',
|
|
91
|
+
modal: true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
text: 'Do Not Sell My Personal Information',
|
|
95
|
+
anchor: 'uspi',
|
|
96
|
+
modal: true
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const data = {
|
|
102
|
+
[footerKey]: {
|
|
103
|
+
links: [
|
|
104
|
+
...siteData.isQSPage ? qsLinks : quoteLinks,
|
|
105
|
+
],
|
|
106
|
+
copyright: `${siteData.isQSPage ? 'QuinStreet, Inc.' : ''} All Rights Reserved.`,
|
|
107
|
+
contractor: {
|
|
108
|
+
text: 'Are you a contractor?',
|
|
109
|
+
linkText: 'Join Our Contractor Network',
|
|
110
|
+
link: 'https://modernize.com/pro/register/leads/?utm_campaign=quinstreet-referral' + trade
|
|
111
|
+
},
|
|
112
|
+
...siteData.isQSPage ? null : quoteSpecific,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return data;
|
|
117
|
+
}
|
package/src/data/seasons.js
CHANGED
package/src/index.html
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
{{ fileInclude 'src/templates/components/head.html'
|
|
5
|
+
page = this
|
|
6
|
+
path = 'home'
|
|
7
|
+
}}
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
{{#header}}
|
|
11
|
+
{{ fileInclude 'src/accessible-components/header/header.html'
|
|
12
|
+
header = this
|
|
13
|
+
}}
|
|
14
|
+
{{/header}}
|
|
15
|
+
<h1>Hello</h1>
|
|
16
|
+
<script type="module" src="/main.js"></script>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
package/src/main.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import './styles/home.scss';
|
|
2
|
+
import { templateData } from '../template.js';
|
|
3
|
+
import { defaultSettings, siteData } from '../siteconfig.js';
|
|
4
|
+
|
|
5
|
+
const { page } = templateData();
|
|
6
|
+
|
|
7
|
+
if (page.headConfig.useDynamicGtm || typeof window.isQSPage === 'undefined') {
|
|
8
|
+
import('./scripts/has-qs-params.js').then((qs) => {
|
|
9
|
+
qs.default();
|
|
10
|
+
window.gtm_container_ID = window.isQSPage ? siteData.qs_gtm_container_ID : siteData.gtm_container_ID;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { additionalAssets } = page.headConfig;
|
|
15
|
+
if (additionalAssets) {
|
|
16
|
+
const { afterBegin, beforeEnd } = additionalAssets;
|
|
17
|
+
|
|
18
|
+
if (afterBegin || beforeEnd) {
|
|
19
|
+
let additionalHeadAssets = [];
|
|
20
|
+
if (afterBegin) {
|
|
21
|
+
additionalHeadAssets.push(...afterBegin);
|
|
22
|
+
}
|
|
23
|
+
if (beforeEnd) {
|
|
24
|
+
additionalHeadAssets.push(...beforeEnd);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
additionalHeadAssets.forEach((asset) => {
|
|
28
|
+
const { type, src, isLocal, localSrc, useModCdn, defer, async } = asset;
|
|
29
|
+
if (type === 'script') {
|
|
30
|
+
const script = document.createElement(type);
|
|
31
|
+
script.src = (isLocal ? localSrc : (useModCdn ? `https://${defaultSettings.resourceDomain}/${src}` : src));
|
|
32
|
+
script.async = async;
|
|
33
|
+
script.defer = defer;
|
|
34
|
+
document.head.appendChild(script);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (type === 'style') {
|
|
38
|
+
const link = document.createElement('link');
|
|
39
|
+
link.rel = 'stylesheet';
|
|
40
|
+
link.href = (isLocal ? localSrc : (useModCdn ? `https://${defaultSettings.resourceDomain}/${src}` : src));
|
|
41
|
+
document.head.appendChild(link);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Load GTM tag dynamically MOD vs QS by checking the quad parameters on URL **/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
)
|
|
2
|
+
export const searchParams = new URLSearchParams(window.location.search);
|
|
3
|
+
export const qsParams = ['CLK', 'CCID', 'QTR', 'quadlink'];
|
|
4
|
+
|
|
5
|
+
export default function() {
|
|
6
|
+
return window.isQSPage = qsParams.some(param => searchParams.has(param))
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// On page load if hash has an
|
|
2
|
-
|
|
1
|
+
// On page load if hash has an ampersand all text after is removed, if there's a hash with only 'q + number' format we replace history without hash
|
|
2
|
+
let hash = window.location.hash;
|
|
3
3
|
if (hash.indexOf('&') > -1) {
|
|
4
|
-
|
|
4
|
+
window.location.hash = hash = hash.split('&')[0];
|
|
5
5
|
}
|
|
6
6
|
if (/^#q\d$/.test(hash)) {
|
|
7
7
|
history.replaceState(null, '', window.location.href.split('#')[0]);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { seasons } from "../data/seasons.js";
|
|
2
|
+
import { defaultSettings } from "../../siteconfig.js";
|
|
3
|
+
import gulpHandlebarsFileInclude from "gulp-handlebars-file-include";
|
|
4
|
+
|
|
5
|
+
export function getFileFromURL(url) {
|
|
6
|
+
return url.split('/').pop();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getActiveSeasons() {
|
|
10
|
+
const today = new Date();
|
|
11
|
+
const year = today.getFullYear();
|
|
12
|
+
const activeSeason = [];
|
|
13
|
+
|
|
14
|
+
for (const key in seasons) {
|
|
15
|
+
if (Object.prototype.hasOwnProperty.call(seasons, key)) {
|
|
16
|
+
const seasonName = key;
|
|
17
|
+
const dateRanges = seasons[key];
|
|
18
|
+
const startDate = new Date(`${Object.values(dateRanges)[0]}-${year}`);
|
|
19
|
+
const endDate = new Date(`${Object.values(dateRanges)[1]}-${year}`);
|
|
20
|
+
|
|
21
|
+
if (startDate < today && today < endDate) {
|
|
22
|
+
activeSeason.push(seasonName);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return activeSeason;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function handlebarsX(expression, context) {
|
|
31
|
+
const result = (function() {
|
|
32
|
+
try {
|
|
33
|
+
return new Function(expression);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
console.warn(
|
|
37
|
+
'• Expression: {{x \'' + expression + '\'}}\n'
|
|
38
|
+
+ '• JS-Error: ', e, '\n'
|
|
39
|
+
+ '• Context: ',
|
|
40
|
+
context
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}).call(context);
|
|
44
|
+
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const handlebarsHelpers = [
|
|
49
|
+
// Run any js line
|
|
50
|
+
{
|
|
51
|
+
name: 'x',
|
|
52
|
+
fn: function(expression, options) {
|
|
53
|
+
return handlebarsX(expression, this, options);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
// Run any js line and check if it is true
|
|
57
|
+
{
|
|
58
|
+
name: 'xif',
|
|
59
|
+
fn: function(expression, options) {
|
|
60
|
+
return handlebarsX(expression, this, options) ? options.fn(this) : options.inverse(this);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
// Reverse array
|
|
64
|
+
{
|
|
65
|
+
name: 'reverseArray',
|
|
66
|
+
fn: function(expression) {
|
|
67
|
+
expression.reverse();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
// Check if one var equals to another
|
|
71
|
+
{
|
|
72
|
+
name: 'equals',
|
|
73
|
+
fn: function(v1, v2, block) {
|
|
74
|
+
if (v1 === v2) {
|
|
75
|
+
return block.fn(this);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
// Convert string to uppercase
|
|
80
|
+
{
|
|
81
|
+
name: 'uppercase',
|
|
82
|
+
fn: function(expression) {
|
|
83
|
+
return 'string' === typeof expression ? expression.toUpperCase() : '';
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
// Convert deferred styles string to links
|
|
87
|
+
{
|
|
88
|
+
name: 'deferredStyles',
|
|
89
|
+
fn: function(str) {
|
|
90
|
+
var urls = str.split(';'),
|
|
91
|
+
links = [];
|
|
92
|
+
|
|
93
|
+
urls.forEach(function(url) {
|
|
94
|
+
links.push('<link href="' + url + '" rel="stylesheet" type="text/css" />');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return links.join('');
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
// Format Phone number like type1 : xxx-xxx-xxxx OR type2 : (xxx) xxx-xxxx
|
|
101
|
+
{
|
|
102
|
+
name: 'formatPhoneNo',
|
|
103
|
+
fn: function(expression, type) {
|
|
104
|
+
var mask = /(\d{3})(\d{3})(\d{,4})?/;
|
|
105
|
+
var newValues;
|
|
106
|
+
if (type === 'type1') {
|
|
107
|
+
newValues = '$1-$2-$3';
|
|
108
|
+
} else {
|
|
109
|
+
newValues = '($1) $2-$3';
|
|
110
|
+
}
|
|
111
|
+
return expression.replace(mask, newValues);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
// It will take the json object & variable name to assign the object & return it in the script tag
|
|
115
|
+
{
|
|
116
|
+
name: 'jsonVarScriptTag',
|
|
117
|
+
fn: function(json, variable) {
|
|
118
|
+
var check = (typeof json === 'object') && (typeof variable === 'string' && variable);
|
|
119
|
+
return check ? '<script>' + 'var ' + variable + '=' + JSON.stringify(json) + '</script>' : '';
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
// It will take & return json object
|
|
123
|
+
{
|
|
124
|
+
name: 'json',
|
|
125
|
+
fn: function(json) {
|
|
126
|
+
return JSON.stringify(json);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
// Adding increment of 1 to value
|
|
130
|
+
{
|
|
131
|
+
name: 'inc',
|
|
132
|
+
fn: function(index) {
|
|
133
|
+
index++;
|
|
134
|
+
return index;
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
// Loop to go through and add each attribute defined in the attributes: {} object
|
|
138
|
+
{
|
|
139
|
+
name: 'addAttributes',
|
|
140
|
+
fn: function(obj) {
|
|
141
|
+
var output = '';
|
|
142
|
+
var ignoreKeys = Array.prototype.slice.call(arguments, 1, -1);
|
|
143
|
+
|
|
144
|
+
for (var key in obj.attributes) {
|
|
145
|
+
if (ignoreKeys.indexOf(key) === -1) {
|
|
146
|
+
if (typeof obj.attributes[key] !== 'object') {
|
|
147
|
+
output += key + '="' + obj.attributes[key] + '" ';
|
|
148
|
+
} else if (key === 'data') {
|
|
149
|
+
for (var dataKey in obj.attributes[key]) {
|
|
150
|
+
output += 'data-' + dataKey + '="' + obj.attributes[key][dataKey] + '" ';
|
|
151
|
+
}
|
|
152
|
+
} else if (key === 'aria') {
|
|
153
|
+
for (var ariaKey in obj.attributes[key]) {
|
|
154
|
+
output += 'aria-' + ariaKey + '="' + obj.attributes[key][ariaKey] + '" ';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return output.trim();
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'resolveAlias',
|
|
164
|
+
fn: function(input) {
|
|
165
|
+
if (input.includes('@')) {
|
|
166
|
+
const resolvedValue = defaultSettings.modBuild || '';
|
|
167
|
+
return input.replace('@', resolvedValue);
|
|
168
|
+
}
|
|
169
|
+
return input;
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'fileInclude',
|
|
174
|
+
fn: function(input) {
|
|
175
|
+
return gulpHandlebarsFileInclude(input);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// an example SCSS file to import
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
<noscript id="deferred-styles">
|
|
2
|
+
{{{deferredStyles deferredStyleUrls}}}
|
|
3
|
+
</noscript>
|
|
4
|
+
<script>
|
|
5
|
+
const loadDeferredStyles = function() {
|
|
6
|
+
let addStylesNode = document.getElementById("deferred-styles");
|
|
7
|
+
let replacement = document.createElement("div");
|
|
8
|
+
replacement.innerHTML = addStylesNode.textContent;
|
|
9
|
+
document.body.appendChild(replacement)
|
|
10
|
+
addStylesNode.parentElement.removeChild(addStylesNode);
|
|
11
|
+
};
|
|
12
|
+
const raf = requestAnimationFrame || mozRequestAnimationFrame ||
|
|
13
|
+
webkitRequestAnimationFrame || msRequestAnimationFrame;
|
|
14
|
+
if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
|
|
15
|
+
else window.addEventListener('load', loadDeferredStyles);
|
|
16
|
+
</script>
|
|
@@ -1,49 +1,47 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
{{ fileInclude 'node_modules/mod-build/src/scripts/
|
|
3
|
-
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
break;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
var _vwoOldPush = window._vwo_evq.push;
|
|
16
|
-
window._vwo_evq.push = function() {
|
|
17
|
-
var eventData = arguments[0],
|
|
18
|
-
willRedirectionOccur;
|
|
19
|
-
if (eventData[0] === 'rD') {
|
|
20
|
-
willRedirectionOccur = eventData[1];
|
|
21
|
-
// It will be set to true if a redirection is going to be done by VWO.
|
|
22
|
-
window.willRedirectionOccurByVWO = willRedirectionOccur;
|
|
2
|
+
{{ fileInclude 'node_modules/mod-build/src/scripts/vendor/visual-website-optimizer.js' }}
|
|
3
|
+
|
|
4
|
+
(function(VWO_HARD_TIMEOUT) {
|
|
5
|
+
window._vwo_evq = window._vwo_evq || [];
|
|
6
|
+
var queue = window._vwo_evq;
|
|
7
|
+
for (var i = 0; i < queue.length; i++) {
|
|
8
|
+
if (queue[i][0] === 'rD') {
|
|
9
|
+
window.willRedirectionOccur = true;
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
23
12
|
}
|
|
24
|
-
_vwoOldPush
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
13
|
+
var _vwoOldPush = window._vwo_evq.push;
|
|
14
|
+
window._vwo_evq.push = function() {
|
|
15
|
+
var eventData = arguments[0],
|
|
16
|
+
willRedirectionOccur;
|
|
17
|
+
if (eventData[0] === 'rD') {
|
|
18
|
+
willRedirectionOccur = eventData[1];
|
|
19
|
+
// It will be set to true if a redirection is going to be done by VWO.
|
|
20
|
+
window.willRedirectionOccurByVWO = willRedirectionOccur;
|
|
21
|
+
}
|
|
22
|
+
_vwoOldPush.apply(window._vwo_evq, [].slice.call(arguments));
|
|
23
|
+
};
|
|
24
|
+
var hardLimitTimedout = false;
|
|
25
|
+
|
|
26
|
+
function tryNonVWOTracking() {
|
|
27
|
+
if ((window._vwo_code && (window._vwo_code.finished() || window._vwo_code.libExecuted)) || hardLimitTimedout) {
|
|
28
|
+
if (!window.willRedirectionOccurByVWO) {
|
|
29
|
+
clearTimeout(hardLimitTimer);
|
|
30
|
+
try {
|
|
31
|
+
// flag to call Modalytics.initHeapVwo() method in site level js
|
|
32
|
+
window.initHeapVwo = true;
|
|
33
|
+
} catch (e) {}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
37
36
|
}
|
|
37
|
+
setTimeout(function() {
|
|
38
|
+
tryNonVWOTracking()
|
|
39
|
+
}, 500)
|
|
38
40
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}, VWO_HARD_TIMEOUT);
|
|
47
|
-
tryNonVWOTracking();
|
|
48
|
-
})(5000 /*MAXIMUM TIME IN SECONDS IN WHICH CODE WILL EXECUTE ANYWAY*/ );
|
|
49
|
-
</script>
|
|
41
|
+
|
|
42
|
+
var hardLimitTimer = setTimeout(function() {
|
|
43
|
+
hardLimitTimedout = true;
|
|
44
|
+
}, VWO_HARD_TIMEOUT);
|
|
45
|
+
tryNonVWOTracking();
|
|
46
|
+
})(5000 /*MAXIMUM TIME IN SECONDS IN WHICH CODE WILL EXECUTE ANYWAY*/ );
|
|
47
|
+
</script>
|