angular4-testing/ng2-admin/config/html-elements-plugin/index.js

112 lines
3.3 KiB
JavaScript
Raw Normal View History

2017-02-24 22:54:59 +01:00
function HtmlElementsPlugin(locations) {
this.locations = locations;
}
HtmlElementsPlugin.prototype.apply = function (compiler) {
var self = this;
compiler.plugin('compilation', function (compilation) {
compilation.options.htmlElements = compilation.options.htmlElements || {};
compilation.plugin('html-webpack-plugin-before-html-generation', function (htmlPluginData, callback) {
const locations = self.locations;
if (locations) {
const publicPath = htmlPluginData.assets.publicPath;
Object.getOwnPropertyNames(locations).forEach(function (loc) {
compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
});
}
callback(null, htmlPluginData);
});
});
};
const RE_ENDS_WITH_BS = /\/$/;
/**
* Create an HTML tag with attributes from a map.
*
* Example:
* createTag('link', { rel: "manifest", href: "/assets/manifest.json" })
* // <link rel="manifest" href="/assets/manifest.json">
* @param tagName The name of the tag
* @param attrMap A Map of attribute names (keys) and their values.
* @param publicPath a path to add to eh start of static asset url
* @returns {string}
*/
function createTag(tagName, attrMap, publicPath) {
publicPath = publicPath || '';
// add trailing slash if we have a publicPath and it doesn't have one.
if (publicPath && !RE_ENDS_WITH_BS.test(publicPath)) {
publicPath += '/';
}
const attributes = Object.getOwnPropertyNames(attrMap)
.filter(function (name) {
return name[0] !== '=';
})
.map(function (name) {
var value = attrMap[name];
if (publicPath) {
// check if we have explicit instruction, use it if so (e.g: =herf: false)
// if no instruction, use public path if it's href attribute.
const usePublicPath = attrMap.hasOwnProperty('=' + name) ? !!attrMap['=' + name] : name === 'href';
if (usePublicPath) {
// remove a starting trailing slash if the value has one so we wont have //
value = publicPath + (value[0] === '/' ? value.substr(1) : value);
}
}
return `${name}="${value}"`;
});
const closingTag = tagName === 'script' ? '</script>' : '';
return `<${tagName} ${attributes.join(' ')}>${closingTag}`;
}
/**
* Returns a string representing all html elements defined in a data source.
*
* Example:
*
* const ds = {
* link: [
* { rel: "apple-touch-icon", sizes: "57x57", href: "/assets/icon/apple-icon-57x57.png" }
* ],
* meta: [
* { name: "msapplication-TileColor", content: "#00bcd4" }
* ]
* }
*
* getHeadTags(ds);
* // "<link rel="apple-touch-icon" sizes="57x57" href="/assets/icon/apple-icon-57x57.png">"
* "<meta name="msapplication-TileColor" content="#00bcd4">"
*
* @returns {string}
*/
function getHtmlElementString(dataSource, publicPath) {
return Object.getOwnPropertyNames(dataSource)
.map(function (name) {
if (Array.isArray(dataSource[name])) {
return dataSource[name].map(function (attrs) {
return createTag(name, attrs, publicPath);
});
} else {
return [createTag(name, dataSource[name], publicPath)];
}
})
.reduce(function (arr, curr) {
return arr.concat(curr);
}, [])
.join('\n\t');
}
module.exports = HtmlElementsPlugin;