amphora-html 6.0.0-3 → 6.0.0-6

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 (43) hide show
  1. package/.envrc +1 -1
  2. package/lib/media.js +6 -22
  3. package/package.json +1 -1
  4. package/.vscode/.history/amphora-html/lib/media.test_20210527151433.js +0 -797
  5. package/.vscode/.history/amphora-html/lib/media.test_20210607095503.js +0 -815
  6. package/.vscode/.history/amphora-html/lib/media.test_20210607095544.js +0 -815
  7. package/.vscode/.history/amphora-html/lib/media.test_20210607100025.js +0 -817
  8. package/.vscode/.history/amphora-html/lib/media.test_20210607100402.js +0 -817
  9. package/.vscode/.history/amphora-html/lib/media.test_20210607100635.js +0 -829
  10. package/.vscode/.history/amphora-html/lib/media.test_20210607105251.js +0 -852
  11. package/.vscode/.history/amphora-html/lib/media.test_20210607120734.js +0 -839
  12. package/.vscode/.history/amphora-html/lib/media.test_20210607121735.js +0 -873
  13. package/.vscode/.history/amphora-html/lib/media.test_20210608203514.js +0 -908
  14. package/.vscode/.history/amphora-html/lib/media_20210511135806.js +0 -434
  15. package/.vscode/.history/amphora-html/lib/media_20210512105948.js +0 -434
  16. package/.vscode/.history/amphora-html/lib/media_20210512110245.js +0 -434
  17. package/.vscode/.history/amphora-html/lib/media_20210512114913.js +0 -434
  18. package/.vscode/.history/amphora-html/lib/media_20210512114917.js +0 -434
  19. package/.vscode/.history/amphora-html/lib/media_20210512122725.js +0 -429
  20. package/.vscode/.history/amphora-html/lib/media_20210512123057.js +0 -429
  21. package/.vscode/.history/amphora-html/lib/media_20210512123102.js +0 -429
  22. package/.vscode/.history/amphora-html/lib/media_20210512123201.js +0 -429
  23. package/.vscode/.history/amphora-html/lib/media_20210512152244.js +0 -429
  24. package/.vscode/.history/amphora-html/lib/media_20210512152536.js +0 -433
  25. package/.vscode/.history/amphora-html/lib/media_20210512152541.js +0 -433
  26. package/.vscode/.history/amphora-html/lib/media_20210512152717.js +0 -433
  27. package/.vscode/.history/amphora-html/lib/media_20210512152931.js +0 -419
  28. package/.vscode/.history/amphora-html/lib/media_20210512152949.js +0 -420
  29. package/.vscode/.history/amphora-html/lib/media_20210512152958.js +0 -418
  30. package/.vscode/.history/amphora-html/lib/media_20210512155619.js +0 -418
  31. package/.vscode/.history/amphora-html/lib/media_20210512164028.js +0 -418
  32. package/.vscode/.history/amphora-html/lib/media_20210512170157.js +0 -418
  33. package/.vscode/.history/amphora-html/lib/media_20210512171030.js +0 -418
  34. package/.vscode/.history/amphora-html/lib/media_20210607085451.js +0 -454
  35. package/.vscode/.history/amphora-html/lib/media_20210607085550.js +0 -454
  36. package/.vscode/.history/amphora-html/lib/media_20210607095350.js +0 -454
  37. package/.vscode/.history/amphora-html/lib/media_20210607121609.js +0 -455
  38. package/.vscode/.history/amphora-html/lib/media_20210607121656.js +0 -455
  39. package/.vscode/.history/amphora-html/lib/media_20210607121742.js +0 -455
  40. package/.vscode/.history/amphora-html/lib/media_20210608203406.js +0 -454
  41. package/.vscode/.history/amphora-html/package_20210607131602.json +0 -62
  42. package/.vscode/.history/amphora-html/package_20210607131617.json +0 -62
  43. package/.vscode/.history/amphora-html/package_20210608210629.json +0 -62
@@ -1,454 +0,0 @@
1
- 'use strict';
2
-
3
- const _ = require('lodash'),
4
- path = require('path'),
5
- files = require('nymag-fs'),
6
- bluebird = require('bluebird'),
7
- setup = require('./setup'),
8
- styleguide = require('./styleguide'),
9
- STYLE_TAG = 'style',
10
- SCRIPT_TAG = 'scripts',
11
- ASYNC_SCRIPT_TAG = 'async',
12
- DEFER_SCRIPT_TAG = 'defer',
13
- ASYNC_DEFER_SCRIPT_TAG = 'async-defer',
14
- MEDIA_DIRECTORY = path.join(process.cwd(), 'public');
15
-
16
- /**
17
- * @param {string} str
18
- * @returns {number}
19
- */
20
- function findBottom(str) {
21
- var index = str.lastIndexOf('</body>');
22
-
23
- if (index === -1) {
24
- index = str.lastIndexOf('</');
25
- }
26
-
27
- return index;
28
- }
29
-
30
- /**
31
- * @param {string} str
32
- * @returns {number}
33
- */
34
- function findTop(str) {
35
- var index = str.indexOf('</head>');
36
-
37
- if (index === -1) {
38
- index = str.indexOf('>') + 1;
39
- }
40
- return index;
41
- }
42
-
43
- /**
44
- * Put items at index in the very large target string.
45
- *
46
- * @param {string} str
47
- * @param {number} index
48
- * @param {[string]} items
49
- * @returns {string}
50
- */
51
- function splice(str, index, items) {
52
- return str.substr(0, index) + items + str.substr(index);
53
- }
54
-
55
- /**
56
- * Get the contents of a string that come after specified characters.
57
- *
58
- * @param {string} str Any string to split
59
- * @param {string} dir The directory the file is in
60
- * @return {string}
61
- */
62
- function getFileName(str, dir) {
63
- return str.split(dir)[1];
64
- }
65
-
66
- /**
67
- * Retrieve the contents of a file
68
- *
69
- * @param {array} fileArray An array of file names
70
- * @param {string} targetDir The directory to retrieve files from
71
- * @param {string} filePrefix The string that comes right before the file name
72
- * @return {Promise}
73
- */
74
- function getContentsOfFiles(fileArray, targetDir, filePrefix) {
75
- var allPromises = [],
76
- currentDir = process.cwd();
77
-
78
- fileArray.forEach(file => {
79
- allPromises.push(files.readFilePromise(path.join(currentDir, targetDir, getFileName(file, filePrefix))));
80
- });
81
-
82
- return Promise.all(allPromises)
83
- .catch(err => {
84
- throw err;
85
- });
86
- }
87
-
88
- /**
89
- * Wraps a string with HTML tags
90
- * @param {string} string The string to wrap
91
- * @param {string} tag The HTML tag to use
92
- * @return {string}
93
- */
94
- function wrapWithTags(string, tag) {
95
- if (tag === SCRIPT_TAG) {
96
- return `<script type="text/javascript">
97
- // <![CDATA[
98
- ${string}
99
- // ]]
100
- </script>`;
101
- } else {
102
- return `<style>${string}</style>`;
103
- }
104
- }
105
-
106
- /**
107
- * Concatenates an array of files into one string.
108
- *
109
- * @param {array} fileArray An array of files
110
- * @param {string} directory The directory in which `fs` will look for the file
111
- * @param {string} filePrefix The directory path before the filename
112
- * @param {string|null} tag The type of tag to wrap the contents in.
113
- * @return {string}
114
- */
115
- function combineFileContents(fileArray, directory, filePrefix, tag) {
116
- if (!fileArray || !fileArray.length) {
117
- return false;
118
- }
119
-
120
- // If there are files, retrieve contents
121
- return getContentsOfFiles(fileArray, directory, filePrefix)
122
- .then(function (fileContents) {
123
- return wrapWithTags(fileContents.join(''), tag);
124
- });
125
- }
126
-
127
- /**
128
- * Append at the bottom of the head tag, or if no head tag, then the top of root tag.
129
- *
130
- * @param {array} styles
131
- * @param {string} html
132
- * @returns {string}
133
- */
134
- function appendMediaToTop(styles, html) {
135
- var index = findTop(html);
136
-
137
- return splice(html, index, styles);
138
- }
139
-
140
- /**
141
- * Append at the bottom of the body tag, or if no body tag, then the bottom of the root tag.
142
- * @param {Array} scripts
143
- * @param {string} html
144
- * @returns {string}
145
- */
146
- function appendMediaToBottom(scripts, html) {
147
- var index = findBottom(html);
148
-
149
- return splice(html, index, scripts);
150
- }
151
-
152
- function injectTags(fileArray, site, tag) {
153
- var buster = module.exports.cacheBuster ? `?version=${module.exports.cacheBuster}` : '';
154
-
155
- return bluebird.resolve(_.map(fileArray, function (file) {
156
- if (tag === STYLE_TAG) {
157
- return `<link rel="stylesheet" type="text/css" href="${file}${buster}">`;
158
- } else if (tag === ASYNC_SCRIPT_TAG) {
159
- return `<script async src="${file}" type="text/javascript"></script>`;
160
- } else if (tag === DEFER_SCRIPT_TAG) {
161
- return `<script defer src="${file}" type="text/javascript"></script>`;
162
- } else if (tag === ASYNC_DEFER_SCRIPT_TAG) {
163
- return `<script async defer src="${file}" type="text/javascript"></script>`;
164
- } else {
165
- return `<script type="text/javascript" src="${file}${buster}"></script>`;
166
- }
167
- }).join('\n'));
168
- }
169
-
170
- /**
171
- * Filter the components rendered in this request, removing Webpack-managed
172
- * assets so that we can fall back on Browserify.
173
- *
174
- * @param {Object} state - Amphora render state.
175
- * @returns {string[]} - A list of components not available through Webpack.
176
- */
177
- function filterManifestComponents(state) {
178
- const site = state.locals.site,
179
- assetDir = site && site.assetDir || MEDIA_DIRECTORY,
180
- manifestName = site && site.manifestName || 'assets-manifest.json',
181
- manifestFile = path.resolve(path.join(assetDir, manifestName));
182
- let manifest;
183
-
184
- try {
185
- manifest = files.tryRequire(manifestFile);
186
- } catch (err) {
187
- return state._components;
188
- }
189
-
190
-
191
- return state._components
192
- .filter(componentName => !manifest.hasOwnProperty(`${ componentName }.js`));
193
- }
194
-
195
- /**
196
- * Gets a list of all css and js needed for the components listed.
197
- * @param {Object} state
198
- * @returns {{styles: Array, scripts: Array}}
199
- */
200
- function getMediaMap(state) {
201
- return {
202
- styles: module.exports.getStyleFiles(state),
203
- scripts: module.exports.getScriptFiles(state),
204
- manifestAssets: module.exports.getManifestAssets(state)
205
- };
206
- }
207
-
208
- /* eslint-disable complexity */
209
- /**
210
- * Get the proper styles for the component. If a styleguide is configured, use
211
- * that css. Defaults to the site slug
212
- *
213
- * @param {Object} state
214
- * @returns {array}
215
- */
216
- function getStyleFiles(state) {
217
- const { site } = state.locals,
218
- assetDir = site && site.assetDir || MEDIA_DIRECTORY,
219
- assetPath = site && site.assetPath || '',
220
- assetHost = site && site.assetHost || '',
221
- siteStyleguide = site && site.styleguide,
222
- layoutName = _.get(state, '_layoutData.name');
223
- let cssFilePaths = [], layoutBasePath;
224
-
225
- // legacy behavior: load <component>.css and <component>.<site>.css
226
- if (!site.styleguide) {
227
- const siteSlug = site && site.slug;
228
-
229
- cssFilePaths = state._components
230
- .reduce((acc, curr) => {
231
- acc.push(
232
- path.join(assetDir, 'css', `${curr}.css`),
233
- path.join(assetDir, 'css', `${curr}.${siteSlug}.css`)
234
- );
235
- return acc;
236
- }, []);
237
- // in edit mode, grab all variations
238
- } else if (state.locals.edit) {
239
- const availableVariations = styleguide.getVariations(siteStyleguide);
240
-
241
- cssFilePaths = state._components
242
- .reduce((acc, cmptName) => {
243
- acc.push(cmptName, ...availableVariations[cmptName] || []);
244
- return acc;
245
- }, [])
246
- .map(baseName => {
247
- const basePath = path.join(assetDir, 'css', `${baseName}.${siteStyleguide}.css`);
248
-
249
- return files.fileExists(basePath) ?
250
- basePath :
251
- path.join(assetDir, 'css', `${baseName}._default.css`);
252
- });
253
- // in view mode, grab only used variations
254
- } else if (state._usedVariations) {
255
- cssFilePaths = state._usedVariations
256
- .map(variation => {
257
- const styleguideVariationPath = path.join(assetDir, 'css', `${variation}.${siteStyleguide}.css`);
258
-
259
- return files.fileExists(styleguideVariationPath) ?
260
- styleguideVariationPath :
261
- path.join(assetDir, 'css', `${variation}._default.css`);
262
- });
263
- }
264
-
265
- // add the layout css
266
- if (layoutName) {
267
- layoutBasePath = path.join(assetDir, 'css', `${layoutName}.${siteStyleguide}.css`);
268
-
269
- if (files.fileExists(layoutBasePath)) {
270
- cssFilePaths.push(layoutBasePath);
271
- } else {
272
- cssFilePaths.push(path.join(assetDir, 'css', `${layoutName}._default.css`));
273
- }
274
- }
275
-
276
- return cssFilePaths
277
- .filter(files.fileExists)
278
- .map(pathJoin(assetHost, assetPath, assetDir));
279
- }
280
- /* eslint-enable complexity */
281
-
282
- /**
283
- * Get the proper scripts for the component
284
- *
285
- * @param {string} name
286
- * @param {object} site
287
- * @returns {array}
288
- */
289
-
290
- function getScriptFiles(state) {
291
- const site = state.locals.site,
292
- slug = site.slug,
293
- assetDir = site && site.assetDir || MEDIA_DIRECTORY,
294
- assetPath = site && site.assetPath || '',
295
- assetHost = site && site.assetHost || '';
296
-
297
- return filterManifestComponents(state)
298
- .reduce((prev, name) => {
299
- prev.push(
300
- path.join(assetDir, 'js', `${name}.js`),
301
- path.join(assetDir, 'js', `${name}.${slug}.js`),
302
- path.join(assetDir, 'js', `${name}.client.js`)
303
- );
304
- return prev;
305
- }, [])
306
- .filter(files.fileExists)
307
- .map(pathJoin(assetHost, assetPath, assetDir));
308
- }
309
-
310
- /**
311
- * Read the asset manifest generated by the `clay pack` bundling command and
312
- * check for scripts which match the rendered component names. The manifest for
313
- * each asset lists its complete set of dependencies, so we dedupe them.
314
- * Webpack's runtime is added to the beginning of the list, downstream legacy
315
- * globals and Clay CLI's init script to the end.
316
- *
317
- * @param {Object} state - Amphora's render state.
318
- * @return {string[]} A list of component assets.
319
- */
320
- function getManifestAssets(state) {
321
- const site = state.locals.site,
322
- assetDir = site && site.assetDir || MEDIA_DIRECTORY,
323
- assetHost = site && site.assetHost || '',
324
- assetPath = site && site.assetPath || '',
325
- manifestName = site && site.manifestName || 'assets-manifest.json',
326
- manifestFile = path.resolve(path.join(assetDir, manifestName));
327
- let manifest;
328
-
329
- try {
330
- manifest = files.tryRequire(manifestFile);
331
- } catch (err) {
332
- return [];
333
- }
334
-
335
- const runtime = _.get(manifest, 'runtime.js', '');
336
-
337
- const scriptFiles = [...state._components, '__clay_globals', '__clay_client_init'].reduce((components, component) => {
338
- const assets = _.get(manifest, ['entrypoints', component, 'assets', 'js'], []);
339
-
340
- return components.concat(assets);
341
- }, []);
342
-
343
- return _.union(runtime, scriptFiles).map(pathJoin(assetHost, assetPath, assetDir));
344
- }
345
-
346
- /**
347
- * Trim the path on the file system bythe link of the
348
- * asset directory and then join it with either the assetHost
349
- * value of the site or the assetPath value (found in the
350
- * site's config file)
351
- *
352
- * @param {String} assetHost
353
- * @param {String} assetPath
354
- * @param {String} assetDir
355
- * @return {Function}
356
- */
357
- function pathJoin(assetHost, assetPath, assetDir) {
358
- var assetDirLen = assetDir.length;
359
-
360
- return function (filePath) {
361
- var pathToFile = filePath.substr(assetDirLen);
362
-
363
- if (assetHost) return `${assetHost}${pathToFile}`;
364
- return path.join(assetPath, pathToFile);
365
- };
366
- }
367
-
368
- /**
369
- * Set the values for inlining vs tagging edit mode styles/scripts
370
- *
371
- * @param {object|boolean} options
372
- * @param {string} [cacheBuster]
373
- */
374
- function configure(options, cacheBuster = '') {
375
- if (options && _.isObject(options)) {
376
- module.exports.editStylesTags = options.styles || false;
377
- module.exports.editScriptsTags = options.scripts || false;
378
- } else {
379
- module.exports.editStylesTags = options;
380
- module.exports.editScriptsTags = options;
381
- }
382
- // Assign cacheBuster
383
- module.exports.cacheBuster = cacheBuster;
384
- }
385
-
386
- /**
387
- * Given the state and html string...
388
- *
389
- * 1. Find all associated scripts/styles
390
- * 2. Run `resolveMedia`
391
- * 3. Stitch in the assets' contents
392
- * 4. Return the HTML string
393
- *
394
- * @param {Object} state
395
- * @return {Function}
396
- */
397
- function injectScriptsAndStyles(state) {
398
- const { locals } = state;
399
-
400
- return function (html) {
401
- var mediaMap = {};
402
-
403
- // Check that HTML is string
404
- if (typeof html !== 'string') {
405
- throw new Error('Missing html parameter');
406
- }
407
-
408
- // We've got a string so let's actually get the map of styles
409
- mediaMap = module.exports.getMediaMap(state);
410
-
411
- // allow site to change the media map before applying it
412
- if (setup.resolveMedia) mediaMap = setup.resolveMedia(mediaMap, locals) || mediaMap;
413
-
414
- if (!locals.edit) {
415
- mediaMap.styles = combineFileContents(mediaMap.styles, 'public/css', '/css/', STYLE_TAG);
416
- mediaMap.scripts = combineFileContents(mediaMap.scripts, 'public/js', '/js/', SCRIPT_TAG);
417
-
418
- // TODO: Ideally, we'd load these scripts asynchronously or after the DOM
419
- // is ready, setting the `async` attribute, the `defer` attribute, or
420
- // both. Because the order in which they're parsed and executed currently
421
- // matters, we can't do that safely.
422
- mediaMap.manifestAssets = injectTags(mediaMap.manifestAssets, locals.site, SCRIPT_TAG);
423
- } else {
424
- mediaMap.styles = module.exports.editStylesTags ? injectTags(mediaMap.styles, locals.site, STYLE_TAG) : combineFileContents(mediaMap.styles, 'public/css', '/css/', STYLE_TAG);
425
- mediaMap.scripts = module.exports.editScriptsTags ? injectTags(mediaMap.scripts, locals.site, SCRIPT_TAG) : combineFileContents(mediaMap.scripts, 'public/js', '/js/', SCRIPT_TAG);
426
-
427
- // FIXME: Some of the logic which excludes client-side scripts from edit
428
- // mode sits with nymag/sites, in the `resolve-media` module, and some
429
- // lives here. Since we're currently not using Webpack for Kiln and model
430
- // assets, this feels like the best place to null out client scripts.
431
- mediaMap.manifestAssets = null;
432
- }
433
-
434
- return bluebird.props(mediaMap)
435
- .then(combinedFiles => {
436
- html = combinedFiles.styles ? appendMediaToTop(combinedFiles.styles, html) : html; // If there are styles, append them
437
- html = combinedFiles.manifestAssets ? appendMediaToBottom(combinedFiles.manifestAssets, html) : html; // If there are assets registered with the manifest, append them
438
- html = combinedFiles.scripts ? appendMediaToBottom(combinedFiles.scripts, html) : html; // If there are scripts, append them
439
- return html; // Return the compiled HTML
440
- });
441
- };
442
- }
443
-
444
- module.exports.injectScriptsAndStyles = injectScriptsAndStyles;
445
- module.exports.getMediaMap = getMediaMap;
446
- module.exports.cacheBuster = '';
447
- module.exports.configure = configure;
448
- module.exports.editStylesTags = false;
449
- module.exports.editScriptsTags = false;
450
-
451
- // For testing
452
- module.exports.getManifestAssets = getManifestAssets;
453
- module.exports.getScriptFiles = getScriptFiles;
454
- module.exports.getStyleFiles = getStyleFiles;