-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from mattolson/preconnect
STRF-4605: Add resourceHints helper
- Loading branch information
Showing
6 changed files
with
258 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use strict'; | ||
|
||
const getFonts = require('../lib/fonts'); | ||
|
||
module.exports = function(paper) { | ||
const handlebars = paper.handlebars; | ||
|
||
handlebars.registerHelper('getFontLoaderConfig', function () { | ||
return new handlebars.SafeString(JSON.stringify(getFonts(paper, 'webFontLoaderConfig'))); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,11 @@ | ||
'use strict'; | ||
|
||
var _ = require('lodash'); | ||
const getFonts = require('../lib/fonts'); | ||
|
||
function helper(paper) { | ||
var handlebars = paper.handlebars; | ||
module.exports = function(paper) { | ||
const handlebars = paper.handlebars; | ||
|
||
handlebars.registerHelper('getFontsCollection', function () { | ||
var fontKeyFormat = new RegExp(/\w+(-\w*)*-font$/), | ||
googleFonts = [], | ||
linkElements = []; | ||
|
||
_.each(paper.themeSettings, function (value, key) { | ||
var split; | ||
|
||
if (fontKeyFormat.test(key)) { | ||
split = value.split('_'); | ||
|
||
switch (split[0]) { | ||
case 'Google': | ||
googleFonts.push(value); | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
} | ||
}); | ||
|
||
linkElements.push(googleParser(googleFonts)); | ||
|
||
return new handlebars.SafeString(linkElements.join('')); | ||
}); | ||
} | ||
|
||
/** | ||
* Parser for Google fonts | ||
* | ||
* @param fonts - Array of fonts that might look like | ||
* Google_Open+Sans | ||
* Google_Open+Sans_400 | ||
* Google_Open+Sans_400_sans | ||
* Google_Open+Sans_400,700_sans | ||
* Google_Open+Sans_400,700italic | ||
* Google_Open+Sans_400,700italic_sans | ||
* | ||
* @returns {string} | ||
*/ | ||
|
||
function googleParser(fonts) { | ||
var collection = [], | ||
familyHash = {}; | ||
|
||
_.each(fonts, function fontsIterator(font) { | ||
var split = font.split('_'), | ||
familyKey = split[1], // Eg: Open+Sans | ||
weights = split[2]; // Eg: 400,700italic | ||
|
||
if (_.isEmpty(familyKey)) { | ||
return; | ||
} | ||
|
||
if (_.isUndefined(weights)) { | ||
weights = ''; | ||
} | ||
|
||
if (!_.isArray(familyHash[familyKey])) { | ||
familyHash[familyKey] = []; | ||
} | ||
|
||
weights = weights.split(','); | ||
|
||
familyHash[familyKey].push(weights); | ||
familyHash[familyKey] = _.uniq(_.flatten(familyHash[familyKey])); | ||
return getFonts(paper, 'linkElements'); | ||
}); | ||
|
||
|
||
_.each(familyHash, function fontHashIterator(weights, family) { | ||
collection.push(family + ':' + weights.join(',')); | ||
}); | ||
|
||
return '<link href="//fonts.googleapis.com/css?family=' + collection.join('|') + '" rel="stylesheet">'; | ||
} | ||
|
||
module.exports = helper; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
'use strict'; | ||
|
||
const _ = require('lodash'); | ||
const getFonts = require('../lib/fonts'); | ||
|
||
const fontResources = { | ||
'Google': [ | ||
'//ajax.googleapis.com', | ||
'//fonts.googleapis.com', | ||
'//fonts.gstatic.com', | ||
], | ||
}; | ||
|
||
module.exports = function(paper) { | ||
paper.handlebars.registerHelper('resourceHints', function() { | ||
function format(host) { | ||
return `<link rel="dns-prefetch preconnect" href="${host}" crossorigin>`; | ||
} | ||
|
||
var hosts = []; | ||
|
||
// Add cdn | ||
const cdnUrl = paper.settings['cdn_url'] || ''; | ||
if (cdnUrl != '') { | ||
hosts.push(cdnUrl); | ||
} | ||
|
||
// Add font providers | ||
const fontProviders = _.keys(getFonts(paper, 'providerLists')); | ||
_.each(fontProviders, function(provider) { | ||
if (typeof fontResources[provider] !== 'undefined') { | ||
hosts = hosts.concat(fontResources[provider]); | ||
} | ||
}); | ||
|
||
return new paper.handlebars.SafeString(_.map(hosts, format).join('')); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
'use strict'; | ||
|
||
const _ = require('lodash'); | ||
const fontKeyFormat = new RegExp(/\w+(-\w*)*-font$/); | ||
const fontProviders = { | ||
'Google': { | ||
/** | ||
* Parser for Google fonts | ||
* | ||
* @param {Array} fonts - Array of fonts that might look like | ||
* Google_Open+Sans | ||
* Google_Open+Sans_400 | ||
* Google_Open+Sans_400_sans | ||
* Google_Open+Sans_400,700_sans | ||
* Google_Open+Sans_400,700italic | ||
* Google_Open+Sans_400,700italic_sans | ||
* | ||
* @returns {string} | ||
*/ | ||
parser: function(fonts) { | ||
var collection = [], | ||
familyHash = {}; | ||
|
||
_.each(fonts, function fontsIterator(font) { | ||
var split = font.split('_'), | ||
familyKey = split[1], // Eg: Open+Sans | ||
weights = split[2]; // Eg: 400,700italic | ||
|
||
if (_.isEmpty(familyKey)) { | ||
return; | ||
} | ||
|
||
if (_.isUndefined(weights)) { | ||
weights = ''; | ||
} | ||
|
||
if (!_.isArray(familyHash[familyKey])) { | ||
familyHash[familyKey] = []; | ||
} | ||
|
||
weights = weights.split(','); | ||
|
||
familyHash[familyKey].push(weights); | ||
familyHash[familyKey] = _.uniq(_.flatten(familyHash[familyKey])); | ||
}); | ||
|
||
_.each(familyHash, function fontHashIterator(weights, family) { | ||
collection.push(family + ':' + weights.join(',')); | ||
}); | ||
|
||
return collection; | ||
}, | ||
|
||
buildLink: function(fonts) { | ||
return '<link href="//fonts.googleapis.com/css?family=' + fonts.join('|') + '" rel="stylesheet">'; | ||
}, | ||
|
||
buildFontLoaderConfig: function(fonts) { | ||
function replaceSpaces(font) { | ||
return font.split('+').join(' '); | ||
} | ||
|
||
return { | ||
google: { | ||
families: _.map(fonts, replaceSpaces), | ||
} | ||
}; | ||
}, | ||
}, | ||
}; | ||
|
||
/** | ||
* Get collection of fonts used in theme settings. | ||
* | ||
* @param {Object} paper The paper instance | ||
* @param {string} format The desired return value. If format == 'providerLists', return an object with provider names for keys | ||
* and a list of fonts in the provider format as values, suitable for use with Web Font Loader. If format == 'linkElements', | ||
* return a string containing <link> elements to be directly inserted into the page. If format == 'webFontLoaderConfig', return an | ||
* object that can be used to configure Web Font Loader. | ||
* @returns {Object.<string, Array>|string} | ||
*/ | ||
module.exports = function(paper, format) { | ||
// Collect font strings from theme settings | ||
const collectedFonts = {}; | ||
_.each(paper.themeSettings, function(value, key) { | ||
if (!fontKeyFormat.test(key)) { | ||
return; | ||
} | ||
|
||
const splits = value.split('_'); | ||
const provider = splits[0]; | ||
|
||
if (typeof fontProviders[provider] === 'undefined') { | ||
return; | ||
} | ||
|
||
if (typeof collectedFonts[provider] === 'undefined') { | ||
collectedFonts[provider] = []; | ||
} | ||
|
||
collectedFonts[provider].push(value); | ||
}); | ||
|
||
// Parse font strings based on provider | ||
const parsedFonts = _.mapValues(collectedFonts, function(value, key) { | ||
return fontProviders[key].parser(value); | ||
}); | ||
|
||
// Format output based on requested format | ||
switch(format) { | ||
case 'linkElements': | ||
const formattedFonts = _.mapValues(parsedFonts, function(value, key) { | ||
return fontProviders[key].buildLink(value); | ||
}); | ||
return new paper.handlebars.SafeString(_.values(formattedFonts).join('')); | ||
|
||
case 'webFontLoaderConfig': | ||
// Build configs | ||
const configs = _.mapValues(parsedFonts, function(value, key) { | ||
return fontProviders[key].buildFontLoaderConfig(value); | ||
}); | ||
|
||
// Merge them | ||
const fontLoaderConfig = {}; | ||
_.each(configs, function(config) { | ||
return Object.assign(fontLoaderConfig, config); | ||
}); | ||
return fontLoaderConfig; | ||
|
||
case 'providerLists': | ||
default: | ||
return parsedFonts; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
var Code = require('code'), | ||
Lab = require('lab'), | ||
Paper = require('../../index'), | ||
lab = exports.lab = Lab.script(), | ||
describe = lab.experiment, | ||
expect = Code.expect, | ||
it = lab.it; | ||
|
||
function c(template, themeSettings) { | ||
return new Paper({}, themeSettings).loadTemplatesSync({template: template}).render('template', {}); | ||
} | ||
|
||
describe('getFontLoaderConfig helper', function () { | ||
it('should return the expected font url', function (done) { | ||
const themeSettings = { | ||
'test1-font': 'Google_Open+Sans', | ||
'test2-font': 'Google_Open+Sans_400italic', | ||
'test3-font': 'Google_Open+Sans_700', | ||
'test4-font': 'Google_Karla_700', | ||
'test5-font': 'Google_Lora_400_sans', | ||
'test6-font': 'Google_Volkron', | ||
'test7-font': 'Google_Droid_400,700', | ||
'test8-font': 'Google_Crimson+Text_400,700_sans', | ||
'random-property': 'not a font' | ||
}; | ||
|
||
const template = "{{getFontLoaderConfig}}"; | ||
const expectedConfig = { | ||
google: { | ||
families: ['Open Sans:,400italic,700', 'Karla:700', 'Lora:400', 'Volkron:', 'Droid:400,700', 'Crimson Text:400,700'] | ||
} | ||
}; | ||
|
||
expect(c(template, themeSettings)).to.be.equal(JSON.stringify(expectedConfig)); | ||
done(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
var Code = require('code'), | ||
Lab = require('lab'), | ||
Paper = require('../../index'), | ||
lab = exports.lab = Lab.script(), | ||
describe = lab.experiment, | ||
expect = Code.expect, | ||
it = lab.it; | ||
|
||
function c(template, themeSettings) { | ||
return new Paper({}, themeSettings).loadTemplatesSync({template: template}).render('template', {}); | ||
} | ||
|
||
describe('resourceHints helper', function () { | ||
it('should return the expected google resources', function (done) { | ||
var themeSettings = { | ||
'test1-font': 'Google_Open+Sans', | ||
'test2-font': 'Google_Open+Sans_400italic', | ||
'test3-font': 'Google_Open+Sans_700', | ||
'test4-font': 'Google_Karla_700', | ||
'test5-font': 'Google_Lora_400_sans', | ||
'test6-font': 'Google_Volkron', | ||
'test7-font': 'Google_Droid_400,700', | ||
'test8-font': 'Google_Crimson+Text_400,700_sans', | ||
'random-property': 'not a font' | ||
}; | ||
|
||
var template = "{{resourceHints}}"; | ||
|
||
expect(c(template, themeSettings)) | ||
.to.be.equal('<link rel="dns-prefetch preconnect" href="//ajax.googleapis.com" crossorigin><link rel="dns-prefetch preconnect" href="//fonts.googleapis.com" crossorigin><link rel="dns-prefetch preconnect" href="//fonts.gstatic.com" crossorigin>'); | ||
done(); | ||
}); | ||
}); |