├── .coveralls.yml ├── .gitignore ├── .jscsrc ├── .jshintignore ├── .jshintrc ├── .npmignore ├── .nvmrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE-MIT ├── README.md ├── index.js ├── package.json └── test ├── data ├── data_one.json └── data_two.json ├── html ├── page_one.html ├── page_three.html ├── page_three_result.html ├── page_two.html └── page_two_result.html └── test.js /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: mePGP3F1sWX3RTtxs4jjc0YzZYLgmQO3D -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | npm-debug.log 4 | tmp 5 | .idea 6 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowSpacesInNamedFunctionExpression": { 3 | "beforeOpeningRoundBrace": true 4 | }, 5 | "disallowSpacesInFunctionExpression": { 6 | "beforeOpeningRoundBrace": true 7 | }, 8 | "disallowSpacesInAnonymousFunctionExpression": { 9 | "beforeOpeningRoundBrace": true 10 | }, 11 | "disallowSpacesInFunctionDeclaration": { 12 | "beforeOpeningRoundBrace": true 13 | }, 14 | "disallowEmptyBlocks": true, 15 | "disallowSpacesInsideArrayBrackets": true, 16 | "disallowSpacesInsideParentheses": true, 17 | "disallowQuotedKeysInObjects": null, 18 | "disallowSpaceAfterObjectKeys": true, 19 | "disallowSpaceAfterPrefixUnaryOperators": true, 20 | "disallowSpaceBeforePostfixUnaryOperators": true, 21 | "disallowSpaceBeforeBinaryOperators": [ 22 | "," 23 | ], 24 | "disallowMixedSpacesAndTabs": true, 25 | "disallowTrailingWhitespace": true, 26 | "disallowTrailingComma": true, 27 | "disallowYodaConditions": true, 28 | "disallowKeywords": [ "with" ], 29 | "disallowMultipleLineBreaks": true, 30 | "disallowMultipleVarDecl": true, 31 | "requireSpaceBeforeBlockStatements": true, 32 | "requireParenthesesAroundIIFE": true, 33 | "requireSpacesInConditionalExpression": true, 34 | "requireBlocksOnNewline": 0, 35 | "requireCommaBeforeLineBreak": true, 36 | "requireSpaceBeforeBinaryOperators": true, 37 | "requireSpaceAfterBinaryOperators": true, 38 | "requireCamelCaseOrUpperCaseIdentifiers": false, 39 | "requireLineFeedAtFileEnd": null, 40 | "requireCapitalizedConstructors": null, 41 | "requireDotNotation": null, 42 | "requireSpacesInForStatement": true, 43 | "requireSpaceBetweenArguments": true, 44 | "requireCurlyBraces": [ 45 | "do" 46 | ], 47 | "requireSpaceAfterKeywords": [ 48 | "if", 49 | "else", 50 | "for", 51 | "while", 52 | "do", 53 | "switch", 54 | "case", 55 | "return", 56 | "try", 57 | "catch", 58 | "typeof" 59 | ], 60 | "requirePaddingNewLinesBeforeLineComments": null, 61 | "requirePaddingNewLinesAfterBlocks": null, 62 | "safeContextKeyword": "_this", 63 | "validateLineBreaks": "LF", 64 | "validateQuoteMarks": "'", 65 | "validateIndentation": 2, 66 | "excludeFiles": ["node_modules/**", "tmp/**"] 67 | } -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tmp -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "maxparams": 5, 3 | "maxdepth": 5, 4 | "maxstatements": 6, 5 | "maxerr": 10, 6 | "passfail": false, 7 | "smarttabs": true, 8 | "node": true, 9 | "browser": true, 10 | "globals": { 11 | "require": true, 12 | "module": true, 13 | "sinon": true, 14 | "S": true, 15 | "steal": true, 16 | "test": true, 17 | "equal": true, 18 | "ok": true, 19 | "console": true, 20 | "process": true, 21 | "angular": false, 22 | "describe": false, 23 | "beforeEach": false, 24 | "it": false, 25 | "expect": true, 26 | "inject": false, 27 | "afterEach": false, 28 | "_": false, 29 | "browserTrigger": false, 30 | "alert": false, 31 | "getSlug": false, 32 | "spyOn": false, 33 | "iit": false, 34 | "moment": false, 35 | "Prism": false, 36 | "CodePenEmbed": false, 37 | "onmessage": false, 38 | "postMessage": false, 39 | "self": false 40 | }, 41 | 42 | "debug": false, 43 | "devel": false, 44 | "esnext": true, 45 | "strict": true, 46 | "asi": false, 47 | "laxbreak": false, 48 | "laxcomma": false, 49 | "bitwise": true, 50 | "boss": false, 51 | "curly": true, 52 | "eqeqeq": true, 53 | "eqnull": false, 54 | "evil": false, 55 | "expr": true, 56 | "forin": false, 57 | "immed": true, 58 | "latedef": true, 59 | "loopfunc": false, 60 | "multistr": false, 61 | "noarg": true, 62 | "shadow": false, 63 | "supernew": false, 64 | "undef": true, 65 | "unused": true, 66 | "quotmark": "single", 67 | "camelcase": true, 68 | "indent": 2, 69 | "newcap": true, 70 | "noempty": false, 71 | "nonew": true, 72 | "nomen": false, 73 | "onevar": false, 74 | "plusplus": false, 75 | "sub": true, 76 | "trailing": true, 77 | "white": false 78 | 79 | } 80 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | test/ 3 | .idea 4 | npm-debug.log 5 | .jscsrc 6 | .jshintignore 7 | .jshintrc 8 | .coveralls.yml 9 | .travis.yml 10 | CHANGELOG.md -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 6.8.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "11" 5 | - "6" 6 | 7 | after_script: 8 | - './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls' -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3 "Code review" 2 | * Code review by PostHTML maintainer voischev. Published to npm repository 3 | 4 | ## 0.2 "Initial release" 5 | * First release -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Andy Walpole 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # posthtml-head-elements 2 | 3 | [![Build Status][ci-img]][ci] 4 | [![devDependency Status](https://david-dm.org/tcotton/portfolio/dev-status.svg?style=flat-square)](https://david-dm.org/tcotton/posthtml-head-elements#info=devDependencies) 5 | [![npm version](https://badge.fury.io/js/posthtml-head-elements.svg)](http://badge.fury.io/js/posthtml-head-elements) 6 | [![Coverage Status](https://coveralls.io/repos/posthtml/posthtml-head-elements/badge.svg?branch=master&service=github)](https://coveralls.io/github/posthtml/posthtml-head-elements?branch=master) 7 | 8 | [ci-img]: https://travis-ci.org/posthtml/posthtml-head-elements.svg 9 | [ci]: https://travis-ci.org/posthtml/posthtml-head-elements 10 | 11 | This plugin is intended to work with [PostHTML](https://github.com/posthtml/posthtml). It will allow you to keep HTML head elements - title, script, link, base and meta - in a separate JSON file: 12 | 13 | ```json 14 | { 15 | "meta": [ 16 | { 17 | "charset": "utf-8" 18 | }, 19 | { 20 | "http-equiv": "X-UA-Compatible", 21 | "content": "IE=edge" 22 | }, 23 | { 24 | "name": "description", 25 | "content": "A front-end template that helps you build fast, modern mobile web apps." 26 | }, 27 | { 28 | "name": "viewport", 29 | "content": "width=device-width, initial-scale=1" 30 | } 31 | ], 32 | "title": "Web Starter Kit", 33 | "link": [ 34 | { 35 | "rel": "manifest", 36 | "href": "manifest.json" 37 | }, 38 | { 39 | "rel": "icon", 40 | "sizes": "192x192", 41 | "href": "images/touch/chrome-touch-icon-192x192.png" 42 | } 43 | ], 44 | "script": [ 45 | { 46 | "src": "//cdn.polyfill.io/v1/polyfill.min.js" 47 | } 48 | ], 49 | "base": [ 50 | { 51 | "href": "/" 52 | } 53 | ] 54 | } 55 | ``` 56 | 57 | A custom tag, which signifies where the HTML head elements should be inserted during the build process, needs to be placed in the document head: 58 | 59 | ```html 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ``` 72 | 73 | This is then configured like below if you are using [gulp-posthtml](https://www.npmjs.com/package/gulp-posthtml). 74 | Please read the [PostHTML GitHub page](https://github.com/posthtml/posthtml) for plugin configuration guidelines. 75 | 76 | ```javascript 77 | 78 | var posthtml = require('gulp-posthtml'); 79 | var gulp = require('gulp'); 80 | var jsonPath = '/data/posthtml-head-elements.json'; 81 | 82 | gulp.task('posthtml', function() { 83 | 84 | var plugins = [ 85 | require('posthtml-head-elements')({headElements: jsonPath}) 86 | ]; 87 | 88 | return gulp.src('/app/index.html') 89 | .pipe(posthtml(plugins)) 90 | .pipe(gulp.dest('/build/')); 91 | 92 | }); 93 | 94 | ``` 95 | 96 | Note that the HTML head elements are inserted into the document in the spatial order they are laid out - from top to bottom 97 | 98 | It is possible to mix the head elements, but the JSON syntax requires a unique key. Therefore, if you are using more than one head element, place an underscore immediately afterwards. 99 | 100 | An example of a JSON file with multiple head elements: 101 | 102 | ```json 103 | { 104 | "meta": [ 105 | { 106 | "charset": "utf-8" 107 | }, 108 | { 109 | "http-equiv": "X-UA-Compatible", 110 | "content": "IE=edge" 111 | }, 112 | { 113 | "name": "description", 114 | "content": "A front-end template that helps you build fast, modern mobile web apps." 115 | }, 116 | { 117 | "name": "viewport", 118 | "content": "width=device-width, initial-scale=1" 119 | } 120 | ], 121 | "title": "Web Starter Kit", 122 | "link": [ 123 | { 124 | "rel": "manifest", 125 | "href": "manifest.json" 126 | } 127 | ], 128 | "meta_1": [ 129 | { 130 | "name": "mobile-web-app-capable", 131 | "content": "yes" 132 | }, 133 | { 134 | "name": "application-name", 135 | "content": "Web Starter Kit" 136 | } 137 | ], 138 | "link_1": [ 139 | { 140 | "rel": "icon", 141 | "sizes": "192x192", 142 | "href": "images/touch/chrome-touch-icon-192x192.png" 143 | } 144 | ], 145 | "meta_2": [ 146 | { 147 | "name": "apple-mobile-web-app-capable", 148 | "content": "yes" 149 | }, 150 | { 151 | "name": "apple-mobile-web-app-status-bar-style", 152 | "content": "black" 153 | }, 154 | { 155 | "name": "apple-mobile-web-app-title", 156 | "content": "Web Starter Kit" 157 | } 158 | ], 159 | "link_2": [ 160 | { 161 | "rel": "apple-touch-icon", 162 | "href": "images/touch/apple-touch-icon.png" 163 | } 164 | ], 165 | "meta_3": [ 166 | { 167 | "name": "msapplication-TileImage", 168 | "content": "mages/touch/ms-touch-icon-144x144-precomposed.png" 169 | }, 170 | { 171 | "name": "msapplication-TileColor", 172 | "content": "3372DF" 173 | }, 174 | { 175 | "name": "theme-color", 176 | "content": "#3372DF" 177 | } 178 | ], 179 | "link_3": [ 180 | { 181 | "rel": "stylesheet", 182 | "href": "styles/main.css" 183 | } 184 | ] 185 | } 186 | ``` 187 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | 5 | /** 6 | * 7 | * @param type {string} 8 | * @param attrsArr {array} 9 | * @returns {Array} 10 | */ 11 | function nonString(type, attrsArr) { 12 | return attrsArr.map(function(attrs) { 13 | return {tag: type, attrs: attrs}; 14 | }); 15 | } 16 | 17 | /** 18 | * 19 | * @param type {string} 20 | * @param content {array} 21 | * @returns {string[]} 22 | */ 23 | function nonArray(type, content) { 24 | return {tag: type, content: [content]}; 25 | } 26 | 27 | /** 28 | * 29 | * @param type {string} 30 | * @param objectData {object} 31 | * @returns {*} 32 | */ 33 | function findElmType(type, objectData) { 34 | 35 | var elementType = { 36 | 'meta': function() { 37 | 38 | if (Array.isArray(objectData)) { 39 | return nonString(type, objectData); 40 | } else { 41 | util.log('posthtml-head-elements: Please use the correct syntax for a meta element'); 42 | } 43 | 44 | }, 45 | 'title': function() { 46 | 47 | if (typeof objectData === 'string') { 48 | return nonArray('title', objectData); 49 | } else { 50 | util.log('posthtml-head-elements: Please use the correct syntax for a title element'); 51 | } 52 | 53 | }, 54 | 'link': function() { 55 | 56 | if (Array.isArray(objectData)) { 57 | return nonString(type, objectData); 58 | } else { 59 | util.log('posthtml-head-elements: Please use the correct syntax for a link element'); 60 | } 61 | 62 | }, 63 | 'script': function() { 64 | 65 | if (Array.isArray(objectData)) { 66 | return nonString(type, objectData); 67 | } else { 68 | util.log('posthtml-head-elements: Please use the correct syntax for a script element'); 69 | } 70 | 71 | }, 72 | 'base': function() { 73 | 74 | if (Array.isArray(objectData)) { 75 | return nonString(type, objectData); 76 | } else { 77 | util.log('posthtml-head-elements: Please use the correct syntax for a base element'); 78 | } 79 | 80 | }, 81 | 'default': function() { 82 | util.log('posthtml-head-elements: Please make sure the HTML head type is correct'); 83 | } 84 | }; 85 | 86 | if (type.indexOf('_') !== -1) { 87 | type = type.substr(0, type.indexOf('_')); 88 | } 89 | 90 | return (elementType[type]() || elementType['default']()); 91 | } 92 | 93 | /** 94 | * 95 | * @param headElements {object} 96 | * @returns {Array.} 97 | */ 98 | function buildNewTree(headElements, EOL) { 99 | 100 | var newHeadElements = []; 101 | 102 | Object.keys(headElements).forEach(function(value) { 103 | 104 | newHeadElements.push(findElmType(value, headElements[value])); 105 | 106 | }); 107 | 108 | function cnct(arr) { 109 | return Array.prototype.concat.apply([], arr); 110 | } 111 | 112 | return cnct(cnct(newHeadElements).map(function(elem) { 113 | return [elem, EOL]; 114 | })); 115 | } 116 | 117 | module.exports = function(options) { 118 | options = options || {}; 119 | options.headElementsTag = options.headElementsTag || 'posthtml-head-elements'; 120 | 121 | if (!options.headElements) { 122 | util.log('posthtml-head-elements: Don\'t forget to add a link to the JSON file containing the head elements to insert'); 123 | } 124 | var jsonOne = typeof options.headElements !== 'string' ? options.headElements : require(options.headElements); 125 | 126 | return function posthtmlHeadElements(tree) { 127 | 128 | tree.match({tag: options.headElementsTag}, function() { 129 | return { 130 | tag: false, // delete this node, safe content 131 | content: buildNewTree(jsonOne, options.EOL || '\n') 132 | }; 133 | }); 134 | 135 | return tree; 136 | 137 | }; 138 | 139 | }; 140 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "posthtml-head-elements", 3 | "version": "0.5.1", 4 | "description": "Build HTML head elements from a JSON file", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "chai": "^4.1.2", 8 | "coveralls": "^3.0.1", 9 | "cz-conventional-changelog": "^2.1.0", 10 | "jscs": "^3.0.7", 11 | "jshint": "^2.9.5", 12 | "mocha": "^5.1.1", 13 | "posthtml": "^0.11.3", 14 | "version-bump-prompt": "^4.1.0" 15 | }, 16 | "peerDependencies": {}, 17 | "scripts": { 18 | "build": "bump --prompt", 19 | "test": "jscs index.js && jscs test/test.js && jshint index.js && jshint test/test.js && mocha test/test.js" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/posthtml/posthtml-head-elements.git" 24 | }, 25 | "keywords": [ 26 | "posthtml", 27 | "posthtml-plugin", 28 | "html" 29 | ], 30 | "author": "Andy Walpole", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/posthtml/posthtml-head-elements/issues" 34 | }, 35 | "homepage": "https://github.com/posthtml/posthtml-head-elements#readme", 36 | "engines": { 37 | "node": ">=6.11.3", 38 | "npm": ">=3.10.10" 39 | }, 40 | "config": { 41 | "commitizen": { 42 | "path": "./node_modules/cz-conventional-changelog" 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /test/data/data_one.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": [ 3 | { 4 | "charset": "utf-8" 5 | }, 6 | { 7 | "http-equiv": "X-UA-Compatible", 8 | "content": "IE=edge" 9 | }, 10 | { 11 | "name": "description", 12 | "content": "A front-end template that helps you build fast, modern mobile web apps." 13 | }, 14 | { 15 | "name": "viewport", 16 | "content": "width=device-width, initial-scale=1" 17 | } 18 | ], 19 | "title": "Web Starter Kit", 20 | "link": [ 21 | { 22 | "rel": "manifest", 23 | "href": "manifest.json" 24 | }, 25 | { 26 | "rel": "icon", 27 | "sizes": "192x192", 28 | "href": "images/touch/chrome-touch-icon-192x192.png" 29 | } 30 | ], 31 | "script": [ 32 | { 33 | "src": "//cdn.polyfill.io/v1/polyfill.min.js" 34 | } 35 | ], 36 | "base": [ 37 | { 38 | "href": "/" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /test/data/data_two.json: -------------------------------------------------------------------------------- 1 | { 2 | "meta": [ 3 | { 4 | "charset": "utf-8" 5 | }, 6 | { 7 | "http-equiv": "X-UA-Compatible", 8 | "content": "IE=edge" 9 | }, 10 | { 11 | "name": "description", 12 | "content": "A front-end template that helps you build fast, modern mobile web apps." 13 | }, 14 | { 15 | "name": "viewport", 16 | "content": "width=device-width, initial-scale=1" 17 | } 18 | ], 19 | "title": "Web Starter Kit", 20 | "link": [ 21 | { 22 | "rel": "manifest", 23 | "href": "manifest.json" 24 | } 25 | ], 26 | "meta_1": [ 27 | { 28 | "name": "mobile-web-app-capable", 29 | "content": "yes" 30 | }, 31 | { 32 | "name": "application-name", 33 | "content": "Web Starter Kit" 34 | } 35 | ], 36 | "link_1": [ 37 | { 38 | "rel": "icon", 39 | "sizes": "192x192", 40 | "href": "images/touch/chrome-touch-icon-192x192.png" 41 | } 42 | ], 43 | "meta_2": [ 44 | { 45 | "name": "apple-mobile-web-app-capable", 46 | "content": "yes" 47 | }, 48 | { 49 | "name": "apple-mobile-web-app-status-bar-style", 50 | "content": "black" 51 | }, 52 | { 53 | "name": "apple-mobile-web-app-title", 54 | "content": "Web Starter Kit" 55 | } 56 | ], 57 | "link_2": [ 58 | { 59 | "rel": "apple-touch-icon", 60 | "href": "images/touch/apple-touch-icon.png" 61 | } 62 | ], 63 | "meta_3": [ 64 | { 65 | "name": "msapplication-TileImage", 66 | "content": "mages/touch/ms-touch-icon-144x144-precomposed.png" 67 | }, 68 | { 69 | "name": "msapplication-TileColor", 70 | "content": "3372DF" 71 | }, 72 | { 73 | "name": "theme-color", 74 | "content": "#3372DF" 75 | } 76 | ], 77 | "link_3": [ 78 | { 79 | "rel": "stylesheet", 80 | "href": "styles/main.css" 81 | } 82 | ] 83 | } -------------------------------------------------------------------------------- /test/html/page_one.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 33 |

Web Starter Kit

34 |
35 | 36 | 37 |
38 |
39 |
40 | 41 | 49 | 50 |
51 |

Hello!

52 |

Welcome to Web Starter Kit.

53 | 54 |

Get Started.

55 |

Read how to Get Started or check out the Style Guide.

56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /test/html/page_three.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 |

Web Starter Kit

10 |
11 | 12 | 13 |
14 |
15 |
16 | 17 | 25 | 26 |
27 |

Hello!

28 |

Welcome to Web Starter Kit.

29 | 30 |

Get Started.

31 |

Read how to Get Started or check out the Style Guide.

32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /test/html/page_three_result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 |

Web Starter Kit

10 |
11 | 12 | 13 |
14 |
15 |
16 | 17 | 25 | 26 |
27 |

Hello!

28 |

Welcome to Web Starter Kit.

29 | 30 |

Get Started.

31 |

Read how to Get Started or check out the Style Guide.

32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /test/html/page_two.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 | 10 |

Web Starter Kit

11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 | 26 | 27 |
28 |

Hello!

29 |

Welcome to Web Starter Kit.

30 | 31 |

Get Started.

32 |

Read how to Get Started or check out the Style Guide.

33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /test/html/page_two_result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Web Starter Kit 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 | 26 |

Web Starter Kit

27 |
28 | 29 | 30 |
31 |
32 |
33 | 34 | 42 | 43 |
44 |

Hello!

45 | 46 |

Welcome to Web Starter Kit.

47 | 48 |

Get Started.

49 | 50 |

Read how to Get Started or check out the Style Guide.

52 |
53 | 54 | 55 | 56 | 57 | 58 | 59 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // jshint maxstatements:10 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var posthtml = require('posthtml'); 6 | var expect = require('chai').expect; 7 | var posthtmlHeadElements = require('..'); 8 | 9 | /** 10 | * @param file {string} 11 | * @returns {*} 12 | */ 13 | function absolutePath(file) { 14 | return path.join(__dirname, file); 15 | } 16 | 17 | var jsonOne = './test/data/data_one.json'; 18 | var pageTwo = fs.readFileSync(absolutePath('html/page_two.html'), 'utf8').toString(); 19 | var pageTwoResult = fs.readFileSync(absolutePath('html/page_two_result.html'), 'utf8').toString(); 20 | var jsonTwo = './test/data/data_two.json'; 21 | var pageThree = fs.readFileSync(absolutePath('html/page_three.html'), 'utf8').toString(); 22 | var pageThreeResult = fs.readFileSync(absolutePath('html/page_three_result.html'), 'utf8').toString(); 23 | 24 | function testOne(input, output, jsonFile, done) { 25 | posthtml() 26 | .use(posthtmlHeadElements({headElements: jsonFile})) 27 | .process(input) 28 | .then(function(result) { 29 | expect(output).to.eql(result.html); 30 | done(); 31 | }).catch(function(error) { 32 | done(error); 33 | }); 34 | } 35 | 36 | function testTwo(input, output, jsonFile, done) { 37 | posthtml() 38 | .use(posthtmlHeadElements({headElements: jsonFile})) 39 | .process(input) 40 | .then(function(result) { 41 | 42 | expect(result.html).to.have.string(''); 43 | expect(result.html).to.have.string('Web Starter Kit'); 44 | expect(result.html).to.have.string(''); 45 | expect(result.html).to.have.string(''); 46 | expect(result.html).to.have.string(''); 47 | expect(result.html).to.have.string(''); 48 | expect(result.html).to.have.string(''); 49 | 50 | done(); 51 | }).catch(function(error) { 52 | done(error); 53 | }); 54 | } 55 | 56 | function testThree(input, output, jsonFile, done) { 57 | posthtml() 58 | .use(posthtmlHeadElements({headElements: jsonFile})) 59 | .process(input) 60 | .then(function(result) { 61 | 62 | expect(result.html).to.not.have.string(''); 63 | expect(result.html).to.not.have.string('Web Starter Kit'); 64 | expect(result.html).to.not.have.string(''); 65 | expect(result.html).to.not.have.string(''); 66 | expect(result.html).to.not.have.string(''); 67 | expect(result.html).to.not.have.string(''); 68 | expect(result.html).to.not.have.string(''); 69 | 70 | done(); 71 | }).catch(function(error) { 72 | done(error); 73 | }); 74 | } 75 | 76 | it('Test one: basic search and replace', function(done) { 77 | var input = ''; 78 | var output = [ 79 | '', 80 | '', 81 | '', 82 | '', 83 | 'Web Starter Kit', 84 | '', 85 | '', 86 | '', 87 | '' 88 | ].join('\n'); 89 | output = output + '\n'; 90 | testOne(input, output, jsonOne, done); 91 | }); 92 | 93 | it('Test two: complete search and replace', function(done) { 94 | testTwo(pageTwo, pageTwoResult, jsonTwo, done); 95 | }); 96 | 97 | it('Test three: failed search and replace. HTML head document does not contain custom element, ', function(done) { 98 | testThree(pageThree, pageThreeResult, jsonTwo, done); 99 | }); 100 | 101 | --------------------------------------------------------------------------------