grunt-processhtml
Advanced tools
+4
-1
| { | ||
| "name": "grunt-processhtml", | ||
| "description": "Process html files at build time to modify them depending on the release environment", | ||
| "version": "0.3.2", | ||
| "version": "0.3.3", | ||
| "homepage": "https://github.com/dciccale/grunt-processhtml", | ||
@@ -31,2 +31,5 @@ "author": { | ||
| }, | ||
| "dependencies": { | ||
| "htmlprocessor": "~0.1.0" | ||
| }, | ||
| "devDependencies": { | ||
@@ -33,0 +36,0 @@ "grunt": "0.4.1", |
+13
-8
@@ -214,21 +214,25 @@ # grunt-processhtml [](https://travis-ci.org/dciccale/grunt-processhtml) [](http://badge.fury.io/js/grunt-processhtml) | ||
| #### options.environment | ||
| Type: `Object` | ||
| Default value: `target` | ||
| The environemnt variable will be available to use in the comments, it defaults to the task target. | ||
| #### options.data | ||
| Type: `Object` | ||
| Default value: `{environment: target}` | ||
| Default value: `{}` | ||
| An object `data` that is passed to the `html` file used to compile all template blocks and the entire file if `process` | ||
| is true. | ||
| If a custom object is passed as `data`, this will be merged with the default to keep the `environment` key intact. | ||
| #### options.templateSettings | ||
| Type: `Object` | ||
| Default value: `null` (Will use default grunt template delimiters `<%` and `%>`) | ||
| Default value: `null` (Will use default lodash template delimiters `<%` and `%>`) | ||
| Define the `templateSettings` option with a custom `opener` and `closer` delimiters to customize the | ||
| template syntax delimiters. | ||
| Define the `templateSettings` option with lodash (templateSettings)[http://lodash.com/docs#templateSettings] options to customize the | ||
| template syntax. | ||
| ```javascript | ||
| templateSettings: { | ||
| opener: '{{', | ||
| closer: '}}' | ||
| interpolate: /{{([\s\S]+?)}}/g // mustache | ||
| } | ||
@@ -415,3 +419,3 @@ ``` | ||
| options: { | ||
| process: true | ||
| process: true, | ||
| data: { | ||
@@ -499,2 +503,3 @@ title: 'My app', | ||
| ## Release History | ||
| - 0.3.3 Add [node-htmlprocessor](https://github.com/dciccale/node-htmlprocessor) as a dependency | ||
| - 0.3.2 Fix/feature #39 | ||
@@ -501,0 +506,0 @@ - 0.3.1 Fix #35 |
+2
-21
@@ -14,4 +14,3 @@ /* | ||
| var utils = require('../lib/utils'); | ||
| var HTMLProcessor = require('../lib/htmlprocessor'); | ||
| var HTMLProcessor = require('htmlprocessor'); | ||
| var path = require('path'); | ||
@@ -29,24 +28,6 @@ | ||
| customBlockTypes: [], | ||
| }); | ||
| // Extend template data with the current target | ||
| grunt.util._.extend(options.data, { | ||
| environment: this.target | ||
| }); | ||
| // Set custom delimiters | ||
| var templateSettings = options.templateSettings; | ||
| if (templateSettings && templateSettings.opener && templateSettings.closer) { | ||
| grunt.template.addDelimiters('lodash', templateSettings.opener, templateSettings.closer); | ||
| options.delimiters = 'lodash'; | ||
| } | ||
| // Allow registering custom block types | ||
| var customBlockTypes = options.customBlockTypes; | ||
| if (customBlockTypes && customBlockTypes.length) { | ||
| options.customBlockTypes = customBlockTypes.map(function (processor) { | ||
| return path.resolve(processor); | ||
| }); | ||
| } | ||
| var html = new HTMLProcessor(options); | ||
@@ -66,3 +47,3 @@ | ||
| if (options.process) { | ||
| content = utils.template(content, options); | ||
| content = html.template(content, html.data, options.templateSettings); | ||
| } | ||
@@ -69,0 +50,0 @@ |
| var fs = require('fs'); | ||
| var path = require('path'); | ||
| var utils = require('./utils'); | ||
| // Define default block types | ||
| module.exports = { | ||
| css: function (content, block, blockLine, blockContent) { | ||
| return content.replace(blockLine, block.indent + '<link rel="stylesheet" href="' + block.asset + '">'); | ||
| }, | ||
| js: function (content, block, blockLine, blockContent) { | ||
| return content.replace(blockLine, block.indent + '<script src="' + block.asset + '"><\/script>'); | ||
| }, | ||
| attr: function (content, block, blockLine, blockContent) { | ||
| var re = new RegExp('(\\s*(?:' + block.attr + ')=[\'"])(.*)?(".*)', 'gi'); | ||
| var replaced = false; | ||
| // Only run attr replacer for the block content | ||
| var replacedBlock = blockContent.replace(re, function (wholeMatch, start, asset, end) { | ||
| // Check if only the path was provided to leave the original asset name intact | ||
| asset = (!path.extname(block.asset) && /\//.test(block.asset))? block.asset + path.basename(asset) : block.asset; | ||
| replaced = true; | ||
| return start + asset + end; | ||
| }); | ||
| // If the attribute doesn't exist, add it. | ||
| if (!replaced) { | ||
| replacedBlock = blockContent.replace(/>/, ' ' + block.attr + '="' + block.asset + '">'); | ||
| } | ||
| return content.replace(blockLine, replacedBlock); | ||
| }, | ||
| remove: function (content, block, blockLine, blockContent) { | ||
| var blockRegExp = utils.blockToRegExp(blockLine); | ||
| return content.replace(blockRegExp, ''); | ||
| }, | ||
| template: function (content, block, blockLine, blockContent) { | ||
| var compiledTmpl = utils.template(blockContent, this.options); | ||
| // Clean template output and fix indent | ||
| compiledTmpl = block.indent + utils._.trim(compiledTmpl).replace(/([\r\n])\s*/g, '$1' + block.indent); | ||
| return content.replace(blockLine, compiledTmpl); | ||
| }, | ||
| include: function (content, block, blockLine, blockContent, filepath) { | ||
| var base = this.options.includeBase || path.dirname(filepath); | ||
| var filepath = path.join(base, block.asset); | ||
| var l = blockLine.length; | ||
| var fileContent, i; | ||
| if (fs.existsSync(filepath)) { | ||
| // Recursively process included files | ||
| if (this.options.recursive) { | ||
| fileContent = this.process(filepath); | ||
| } else { | ||
| fileContent = fs.readFileSync(filepath).toString(); | ||
| } | ||
| // Add indentation and remove any last new line | ||
| fileContent = block.indent + fileContent.replace(/\n$/, ''); | ||
| while ((i = content.indexOf(blockLine)) !== -1) { | ||
| content = content.substring(0, i) + fileContent + content.substring(i + l); | ||
| } | ||
| } | ||
| return content; | ||
| } | ||
| }; |
| /* | ||
| * grunt-processhtml | ||
| * https://github.com/dciccale/grunt-processhtml | ||
| * | ||
| * Copyright (c) 2013-2014 Denis Ciccale (@tdecs) | ||
| * Licensed under the MIT license. | ||
| * https://github.com/dciccale/grunt-processhtml/blob/master/LICENSE-MIT | ||
| */ | ||
| 'use strict'; | ||
| var fs = require('fs'); | ||
| var path = require('path'); | ||
| var utils = require('./utils'); | ||
| var blockTypes = require('./blocktypes'); | ||
| var getBlocks = function (content, marker) { | ||
| /* | ||
| * <!-- build:<type>[:target] [value] --> | ||
| * - type (required) js, css, href, remove, template | ||
| * - target|attribute i.e. dev, release or [href] [src] | ||
| * - value (optional) i.e. script.min.js | ||
| */ | ||
| var regStart = new RegExp('<!--\\s*' + marker + ':(\\[?[\\w-]+\\]?)(?::([\\w,]+))?(?:\\s*([^\\s]+)\\s*-->)*'); | ||
| // <!-- /build --> | ||
| var regEnd = new RegExp('(?:<!--\\s*)*\\/' + marker + '\\s*-->'); | ||
| // Normalize line endings and split in lines | ||
| var lines = content.replace(/\r\n/g, '\n').split(/\n/); | ||
| var inside = false; | ||
| var sections = []; | ||
| var block; | ||
| lines.forEach(function (line) { | ||
| var build = line.match(regStart); | ||
| var endbuild = regEnd.test(line); | ||
| var attr; | ||
| if (build) { | ||
| inside = true; | ||
| attr = build[1].match(/(?:\[([\w\-]+)\])*/)[1]; | ||
| block = { | ||
| type: attr ? 'attr': build[1], | ||
| attr: attr, | ||
| targets: !!build[2] ? build[2].split(',') : null, | ||
| asset: build[3], | ||
| indent: /^\s*/.exec(line)[0], | ||
| raw: [] | ||
| }; | ||
| } | ||
| if (inside && block) { | ||
| block.raw.push(line); | ||
| } | ||
| if (inside && endbuild) { | ||
| inside = false; | ||
| sections.push(block); | ||
| } | ||
| }); | ||
| return sections; | ||
| }; | ||
| // The processor | ||
| var HTMLProcessor = function (options) { | ||
| this.options = options; | ||
| this.target = options.data.environment; | ||
| // Register custom block types | ||
| if (this.options.customBlockTypes.length) { | ||
| utils._.each(this.options.customBlockTypes, function (processor) { | ||
| require(processor).call(this, this); | ||
| }, this); | ||
| } | ||
| }; | ||
| HTMLProcessor.prototype._blockTypes = blockTypes; | ||
| HTMLProcessor.prototype.registerBlockType = function (name, fn) { | ||
| this._blockTypes[name] = fn; | ||
| }; | ||
| // Returns a single line of the current block comment | ||
| HTMLProcessor.prototype._getBlockLine = function (block) { | ||
| return block.raw.join(this.linefeed); | ||
| }; | ||
| // Returns the block content (not including the build comments) | ||
| HTMLProcessor.prototype._getBlockContent = function (block) { | ||
| return block.raw.slice(1, -1).join(this.linefeed); | ||
| }; | ||
| // Replace passed block with the processed content | ||
| HTMLProcessor.prototype._replace = function (block, content, filepath) { | ||
| var blockLine = this._getBlockLine(block); | ||
| var blockContent = this._getBlockContent(block); | ||
| var result = this._blockTypes[block.type].call(this, content, block, blockLine, blockContent, filepath); | ||
| return result; | ||
| }; | ||
| // Strips blocks not matched for the current target | ||
| HTMLProcessor.prototype._strip = function (block, content) { | ||
| var blockLine = this._getBlockLine(block); | ||
| var blockContent = this._getBlockContent(block); | ||
| var blockRegExp = utils.blockToRegExp(blockLine); | ||
| var result = content.replace(blockRegExp, '\n\n' + blockContent); | ||
| return result; | ||
| }; | ||
| HTMLProcessor.prototype._replaceBlocks = function (blocks, filepath) { | ||
| var result = this.content; | ||
| // Replace found blocks | ||
| utils._.each(blocks, function (block) { | ||
| // Parse through correct block type checking the build target | ||
| if (this._blockTypes[block.type] && (!block.targets || utils._.indexOf(block.targets, this.target) >= 0)) { | ||
| result = this._replace(block, result, filepath); | ||
| } else if (this.options.strip) { | ||
| result = this._strip(block, result, filepath); | ||
| } | ||
| }, this); | ||
| return result; | ||
| }; | ||
| // Process the file content | ||
| HTMLProcessor.prototype.process = function (filepath) { | ||
| this.content = fs.readFileSync(filepath).toString(); | ||
| this.linefeed = /\r\n/g.test(this.content) ? '\r\n' : '\n'; | ||
| // Parse the file content to look for build comment blocks | ||
| var blocks = getBlocks(this.content, this.options.commentMarker); | ||
| // Replace found blocks | ||
| var content = this._replaceBlocks(blocks, filepath); | ||
| return content; | ||
| }; | ||
| // Export the processor | ||
| module.exports = HTMLProcessor; |
-29
| /* | ||
| * grunt-processhtml | ||
| * https://github.com/dciccale/grunt-processhtml | ||
| * | ||
| * Copyright (c) 2013-2014 Denis Ciccale (@tdecs) | ||
| * Licensed under the MIT license. | ||
| * https://github.com/dciccale/grunt-processhtml/blob/master/LICENSE-MIT | ||
| */ | ||
| 'use strict'; | ||
| var grunt = require('grunt'); | ||
| var utils = module.exports = {}; | ||
| var escapeRegExp = function (str) { | ||
| return str.replace(/([.?*+\^=!:$\[\]\\(){}|\-])/g, '\\$1'); | ||
| }; | ||
| utils.blockToRegExp = function (blockLine) { | ||
| var escaped = escapeRegExp(blockLine); | ||
| return new RegExp(escaped.replace(/^\s*|[\r\n]+\s*/g, '\\s*').replace(/\n{1}$/g, '\\n')); | ||
| }; | ||
| utils.template = function (tmpl, options) { | ||
| return grunt.template.process(tmpl, options); | ||
| }; | ||
| utils._ = grunt.util._; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
516
0.98%0
-100%16951
-32.05%2
100%5
-37.5%45
-82.63%1
Infinity%+ Added
+ Added