123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- var util = require('util');
- var fs = require('fs');
- var path = require('path');
- var cheerio = require('cheerio');
- var wiring = module.exports;
- /**
- * Update a file containing HTML markup with new content, either
- * appending, prepending or replacing content matching a particular
- * selector.
- *
- * The following modes are available:
- *
- * - `a` Append
- * - `p` Prepend
- * - `r` Replace
- * - `d` Delete
- *
- * @param {String} html
- * @param {String} tagName
- * @param {String} content
- * @param {String} mode
- */
- wiring.domUpdate = function domUpdate(html, tagName, content, mode) {
- var $ = cheerio.load(html);
- if (content !== undefined) {
- if (mode === 'a') {
- $(tagName).append(content);
- } else if (mode === 'p') {
- $(tagName).prepend(content);
- } else if (mode === 'r') {
- $(tagName).html(content);
- } else if (mode === 'd') {
- $(tagName).remove();
- }
- return $.html();
- } else {
- console.error('Please supply valid content to be updated.');
- }
- };
- /**
- * Insert specific content as the last child of each element matched
- * by the `tagName` selector.
- *
- * @param {String} html
- * @param {String} tagName
- * @param {String} content
- */
- wiring.append = function append(html, tagName, content) {
- return this.domUpdate(html, tagName, content, 'a');
- };
- /**
- * Insert specific content as the first child of each element matched
- * by the `tagName` selector.
- *
- * @param {String} html
- * @param {String} tagName
- * @param {String} content
- */
- wiring.prepend = function prepend(html, tagName, content) {
- return this.domUpdate(html, tagName, content, 'p');
- };
- /**
- * Insert specific content as the last child of each element matched
- * by the `tagName` selector. Writes to file.
- *
- * @param {String} path
- * @param {String} tagName
- * @param {String} content
- */
- wiring.appendToFile = function appendToFile(path, tagName, content) {
- var html = this.readFileAsString(path);
- var updatedContent = this.append(html, tagName, content);
- this.writeFileFromString(path, updatedContent);
- };
- /**
- * Insert specific content as the first child of each element matched
- * by the `tagName` selector. Writes to file.
- *
- * @param {String} path
- * @param {String} tagName
- * @param {String} content
- */
- wiring.prependToFile = function prependToFile(path, tagName, content) {
- var html = this.readFileAsString(path);
- var updatedContent = this.prepend(html, tagName, content);
- this.writeFileFromString(path, updatedContent);
- };
- /**
- * Generate a usemin-handler block.
- *
- * @param {String} blockType
- * @param {String} optimizedPath
- * @param {String} filesBlock
- * @param {String|Array} searchPath
- */
- wiring.generateBlock = function generateBlock(blockType, optimizedPath, filesBlock, searchPath) {
- var blockStart, blockEnd;
- var blockSearchPath = '';
- if (searchPath !== undefined) {
- if (util.isArray(searchPath)) {
- searchPath = '{' + searchPath.join(',') + '}';
- }
- blockSearchPath = '(' + searchPath + ')';
- }
- blockStart = '\n <!-- build:' + blockType + blockSearchPath + ' ' + optimizedPath + ' -->\n';
- blockEnd = ' <!-- endbuild -->\n';
- return blockStart + filesBlock + blockEnd;
- };
- /**
- * Append files, specifying the optimized path and generating the necessary
- * usemin blocks to be used for the build process. In the case of scripts and
- * styles, boilerplate script/stylesheet tags are written for you.
- *
- * @param {String|Object} htmlOrOptions
- * @param {String} fileType
- * @param {String} optimizedPath
- * @param {Array} sourceFileList
- * @param {Object} attrs
- * @param {String} searchPath
- */
- wiring.appendFiles = function appendFiles(htmlOrOptions, fileType, optimizedPath, sourceFileList, attrs, searchPath) {
- var blocks, updatedContent;
- var html = htmlOrOptions;
- var files = '';
- if (typeof htmlOrOptions === 'object') {
- html = htmlOrOptions.html;
- fileType = htmlOrOptions.fileType;
- optimizedPath = htmlOrOptions.optimizedPath;
- sourceFileList = htmlOrOptions.sourceFileList;
- attrs = htmlOrOptions.attrs;
- searchPath = htmlOrOptions.searchPath;
- }
- attrs = this.attributes(attrs);
- if (fileType === 'js') {
- sourceFileList.forEach(function (el) {
- files += ' <script ' + attrs + ' src="' + el + '"></script>\n';
- });
- blocks = this.generateBlock('js', optimizedPath, files, searchPath);
- updatedContent = this.append(html, 'body', blocks);
- } else if (fileType === 'css') {
- sourceFileList.forEach(function (el) {
- files += ' <link ' + attrs + ' rel="stylesheet" href="' + el + '">\n';
- });
- blocks = this.generateBlock('css', optimizedPath, files, searchPath);
- updatedContent = this.append(html, 'head', blocks);
- }
- // cleanup trailing whitespace
- return updatedContent.replace(/[\t ]+$/gm, '');
- };
- /**
- * Computes a given Hash object of attributes into its HTML representation.
- *
- * @param {Object} attrs
- */
- wiring.attributes = function attributes(attrs) {
- return Object.keys(attrs || {}).map(function (key) {
- return key + '="' + attrs[key] + '"';
- }).join(' ');
- };
- /**
- * Scripts alias to `appendFiles`.
- *
- * @param {String} html
- * @param {String} optimizedPath
- * @param {Array} sourceFileList
- * @param {Object} attrs
- */
- wiring.appendScripts = function appendScripts(html, optimizedPath, sourceFileList, attrs) {
- return this.appendFiles(html, 'js', optimizedPath, sourceFileList, attrs);
- };
- /**
- * Simple script removal.
- *
- * @param {String} html
- * @param {String} scriptPath
- */
- wiring.removeScript = function removeScript(html, scriptPath) {
- return this.domUpdate(html, 'script[src$="' + scriptPath + '"]', '', 'd');
- };
- /**
- * Style alias to `appendFiles`.
- *
- * @param {String} html
- * @param {String} optimizedPath
- * @param {Array} sourceFileList
- * @param {Object} attrs
- */
- wiring.appendStyles = function appendStyles(html, optimizedPath, sourceFileList, attrs) {
- return this.appendFiles(html, 'css', optimizedPath, sourceFileList, attrs);
- };
- /**
- * Simple style removal.
- *
- * @param {String} html
- * @param {String} path
- */
- wiring.removeStyle = function removeStyle(html, path) {
- return this.domUpdate(html, 'link[href$="' + path + '"]', '', 'd');
- };
- /**
- * Append a directory of scripts.
- *
- * @param {String} html
- * @param {String} optimizedPath
- * @param {String} sourceScriptDir
- * @param {Object} attrs
- */
- wiring.appendScriptsDir = function appendScriptsDir(html, optimizedPath, sourceScriptDir, attrs) {
- var sourceScriptList = fs.readdirSync(path.resolve(sourceScriptDir));
- return this.appendFiles(html, 'js', optimizedPath, sourceScriptList, attrs);
- };
- /**
- * Append a directory of stylesheets.
- *
- * @param {String} html
- * @param {String} optimizedPath
- * @param {String} sourceStyleDir
- * @param {Object} attrs
- */
- wiring.appendStylesDir = function appendStylesDir(html, optimizedPath, sourceStyleDir, attrs) {
- var sourceStyleList = fs.readdirSync(path.resolve(sourceStyleDir));
- return this.appendFiles(html, 'css', optimizedPath, sourceStyleList, attrs);
- };
- /**
- * Read in the contents of a resolved file path as a string.
- *
- * @param {String} filePath
- */
- wiring.readFileAsString = function readFileAsString(filePath) {
- return fs.readFileSync(path.resolve(filePath), 'utf8');
- };
- /**
- * Write the content of a string to a resolved file path.
- *
- * @param {String} html
- * @param {String} filePath
- */
- wiring.writeFileFromString = function writeFileFromString(html, filePath) {
- fs.writeFileSync(path.resolve(filePath), html, 'utf8');
- };
|