├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bower.json ├── demo ├── index.html └── tv-show.js ├── dist ├── template7.d.ts ├── template7.esm.js ├── template7.js ├── template7.js.map ├── template7.min.js └── template7.min.js.map ├── gulpfile.js ├── package-lock.json ├── package.json └── src ├── context.js ├── helpers.js ├── template7-class.js ├── template7.d.ts ├── template7.js └── utils.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | end_of_line = lf 10 | # editorconfig-tools is unable to ignore longs strings or urls 11 | max_line_length = null# tab | space 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | node_modules 4 | demo 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "airbnb-base", 3 | "plugins": [ 4 | "import" 5 | ], 6 | "rules": { 7 | "prefer-destructuring": ["off"], 8 | "no-continue": ["off"], 9 | "max-len": ["error", 1000, 2, { 10 | ignoreUrls: true, 11 | ignoreComments: false, 12 | ignoreRegExpLiterals: true, 13 | ignoreStrings: true, 14 | ignoreTemplateLiterals: true, 15 | }], 16 | }, 17 | "globals": { 18 | "window": true 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .DS_Store 4 | 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node" : true, 3 | "browser" : true, 4 | "esnext" : true, 5 | "bitwise" : false, 6 | "curly" : false, 7 | "eqeqeq" : true, 8 | "eqnull" : true, 9 | "immed" : true, 10 | "latedef" : true, 11 | "newcap" : true, 12 | "noarg" : true, 13 | "undef" : true, 14 | "strict" : true, 15 | "smarttabs" : true, 16 | "quotmark" : "single", 17 | "indent" : 4, 18 | "globals":{ 19 | "document": true, 20 | "WebKitCSSMatrix": true, 21 | "Document": true, 22 | "window": true, 23 | "$":true, 24 | "t7": true, 25 | "Framework7":true, 26 | "Template7":true, 27 | "Dom7":true, 28 | "Swiper":true, 29 | "Modernizr":true, 30 | "Event":true, 31 | "DocumentTouch":true, 32 | "app":true 33 | } 34 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | demo 3 | build 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | before_script: 5 | - npm install --global gulp -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Template7 v1.4.2 - Released on June 14, 2019 4 | * `escape` helper won't throw errors when `undefined` or `null` passed, it will just return empty string 5 | * Fixed issue when referencing array or object in `js_if @root` could throw errors 6 | 7 | ## Template7 v1.4.1 - Released on February 5, 2019 8 | * Relaxed `escape` helper to escape only `<>&"'` characters 9 | * Improved variables parsing in `js` and `js_if` helpers 10 | 11 | ## Template7 v1.4.0 - Released on August 31, 2018 12 | * Added TypeScript definitions 13 | 14 | ## Template7 v1.3.8 - Released on July 24, 2018 15 | * Fixed issue with parsing parents in `js` and `js_if` helpers when properties contain `$` character 16 | 17 | ## Template7 v1.3.7 - Released on July 17, 2018 18 | * Fixed issue when Template7 used in Node.js environment 19 | 20 | ## Template7 v1.3.6 - Released on June 11, 2018 21 | * Better `@global` parsing in `js` and `js_if` helpers 22 | 23 | ## Template7 v1.3.5 - Released on January 22, 2018 24 | * Fixed helpers access when used as ES module 25 | * Added support for dynamic helper names and partials by encapsulating their names in `[]` square brackets 26 | 27 | ## Template7 v1.3.1 - Released on October 25, 2017 28 | * Added new `{{#raw}}...{{/raw}}` block helper to bypass template compilation inside of this block 29 | * Less strict rules for spaces inside of expressions. Expressions like `{{ name }}` works now as expected 30 | * ES-module package renamed from `template7.module.js` to `template7.esm.js` 31 | 32 | ## Template7 v1.3.0 - Released on September 13, 2017 33 | * Small performance improvements with decreased number of `eval` calls 34 | * Source-code restructure into more ES-next modules 35 | 36 | ## Template7 v1.2.5 - Released on August 2, 2017 37 | * `js_compare` helper has been renamed to `js_if` helper. `js_compare` is still available for backwards compatibility 38 | * Added support for `@index`, `@first`, `@last`, `@key`, `@root`, `@global` variables to `js` and `js_if` helpers 39 | * Added support for parent access (e.g. `../title`) to `js` and `js_if` helpers 40 | * Added support for parent data access within loops, e.g. `../../@index` 41 | 42 | ## Template7 v1.2.3 - Released on May 12, 2017 43 | * Fixed ES2015 module build to have ES 2015 syntax 44 | 45 | ## Template7 v1.2.1 - Released on April 19, 2017 46 | * Added ES2015 module build 47 | 48 | ## Template7 v1.2.0 - Released on April 15, 2017 49 | * Added support for node.js and commonjs 50 | 51 | ## Template7 v1.1.4 - Released on December 12, 2016 52 | * Fixed issue with quotes being added to helpers hash content 53 | 54 | ## Template7 v1.1.2 - Released on September 1, 2016 55 | * Added number, boolean, and single-quote-strings argument types support for template helpers #19 56 | * Ability to use single/double quotes in helpers and mix them 57 | 58 | ## Template7 v1.1.0 - Released on October 3, 2015 59 | * Access to data (@index, @key) and root context (@root) in partials 60 | 61 | ## Template7 v1.0.7 - Released on September 28, 2015 62 | * Added check is variable is `null` and don't output it in this case 63 | 64 | ## Template7 v1.0.6 - Released on June 20, 2015 65 | * Partials support: 66 | * `registerPartial(name, template)` method to register partial 67 | * `unregisterPartial(name, template)` method to unregister partial 68 | * `>` helper to include partials like `{{> list}}` 69 | * New `escape` helper for escaping strings 70 | 71 | ## Template7 v1.0.5 - Released on March 28, 2015 72 | * Support for root context that may be used in templates as `{{@root.someVar}}` 73 | * Improved support for paths: 74 | * Support to access arrays directly by index `{{someArray.2}}` 75 | * Better support for context "level up" `{{../../../someVar}}` 76 | * New JS helpers with direct JS execution: 77 | * `{{js "this.price * 2"}} - inline helper to modify context on the fly 78 | * `{{#js_compare "this.price > 1000"}}Too expensive{{/js_compare}} - block helper for easier compares of variables 79 | 80 | ## Template7 v1.0.2 - Released on November 27, 2014 81 | * Support for global context `Template7.global` that may be used in templates as `{{@global.someVar}}` 82 | 83 | ## Template7 v1.0.1 - Released on October 7, 2014 84 | * Allow helpers without context 85 | * New `.unregisterHelper` method to remove registered helpers 86 | 87 | ## Template7 v1.0.0 - Released on September 12, 2014 88 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting Vladimir Kharlampidi . All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vladimir Kharlampidi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![devDependency Status](https://david-dm.org/nolimits4web/template7/dev-status.svg)](https://david-dm.org/nolimits4web/template7#info=devDependencies) 3 | 4 | Template7 5 | ========= 6 | 7 | JavaScript template engine with syntax similar to Handlebars. 8 | 9 | Template7 is the default template engine in [Framework7](http://idangero.us/framework7/), but also can be used separately. 10 | 11 | ## Docs 12 | 13 | http://www.idangero.us/template7/ 14 | 15 | http://www.idangero.us/framework7/docs/template7.html 16 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Template7", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/nolimits4web/Template7.git" 6 | }, 7 | "description": "Mobile-first JavaScript template engine", 8 | "version": "1.3.5", 9 | "author": "Vladimir Kharlampidi", 10 | "homepage": "http://www.idangero.us/template7/", 11 | "keywords": [ 12 | "mobile", 13 | "template", 14 | "javascript", 15 | "ios7", 16 | "ios8", 17 | "ios 8", 18 | "iphone", 19 | "ipad", 20 | "phonegap", 21 | "framework7", 22 | "handlebars", 23 | "mustache" 24 | ], 25 | "scripts": [ 26 | "dist/template7.js", 27 | "dist/template7.min.js" 28 | ], 29 | "main": [ 30 | "dist/template7.js" 31 | ], 32 | "license": ["MIT"], 33 | "dependencies": { 34 | }, 35 | "ignore": [ 36 | ".*", 37 | "build", 38 | "Gruntfile.js", 39 | "node_modules", 40 | "package.json" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Template7 6 | 147 | 148 | 149 |
150 |
151 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 244 | 245 | 246 | 247 | -------------------------------------------------------------------------------- /dist/template7.d.ts: -------------------------------------------------------------------------------- 1 | interface Template7{ 2 | global?: any 3 | templates?: any; 4 | compile? (string: string): any; 5 | registerHelper? (name: string, helper: Function): any; 6 | unregisterHelper? (name: string) : void; 7 | registerPartial? (name: string, template: string) : void; 8 | unregisterPartial? (name: string) : void; 9 | } 10 | 11 | declare const Template7 : Template7; 12 | 13 | export default Template7 14 | -------------------------------------------------------------------------------- /dist/template7.esm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Template7 1.4.2 3 | * Mobile-first HTML template engine 4 | * 5 | * http://www.idangero.us/template7/ 6 | * 7 | * Copyright 2019, Vladimir Kharlampidi 8 | * The iDangero.us 9 | * http://www.idangero.us/ 10 | * 11 | * Licensed under MIT 12 | * 13 | * Released on: June 14, 2019 14 | */ 15 | 16 | let t7ctx; 17 | if (typeof window !== 'undefined') { 18 | t7ctx = window; 19 | } else if (typeof global !== 'undefined') { 20 | t7ctx = global; 21 | } else { 22 | t7ctx = undefined; 23 | } 24 | 25 | const Template7Context = t7ctx; 26 | 27 | const Template7Utils = { 28 | quoteSingleRexExp: new RegExp('\'', 'g'), 29 | quoteDoubleRexExp: new RegExp('"', 'g'), 30 | isFunction(func) { 31 | return typeof func === 'function'; 32 | }, 33 | escape(string = '') { 34 | return string 35 | .replace(/&/g, '&') 36 | .replace(//g, '>') 38 | .replace(/"/g, '"') 39 | .replace(/'/g, '''); 40 | }, 41 | helperToSlices(string) { 42 | const { quoteDoubleRexExp, quoteSingleRexExp } = Template7Utils; 43 | const helperParts = string.replace(/[{}#}]/g, '').trim().split(' '); 44 | const slices = []; 45 | let shiftIndex; 46 | let i; 47 | let j; 48 | for (i = 0; i < helperParts.length; i += 1) { 49 | let part = helperParts[i]; 50 | let blockQuoteRegExp; 51 | let openingQuote; 52 | if (i === 0) slices.push(part); 53 | else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { 54 | blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 55 | openingQuote = part.indexOf('"') === 0 ? '"' : '\''; 56 | // Plain String 57 | if (part.match(blockQuoteRegExp).length === 2) { 58 | // One word string 59 | slices.push(part); 60 | } else { 61 | // Find closed Index 62 | shiftIndex = 0; 63 | for (j = i + 1; j < helperParts.length; j += 1) { 64 | part += ` ${helperParts[j]}`; 65 | if (helperParts[j].indexOf(openingQuote) >= 0) { 66 | shiftIndex = j; 67 | slices.push(part); 68 | break; 69 | } 70 | } 71 | if (shiftIndex) i = shiftIndex; 72 | } 73 | } else if (part.indexOf('=') > 0) { 74 | // Hash 75 | const hashParts = part.split('='); 76 | const hashName = hashParts[0]; 77 | let hashContent = hashParts[1]; 78 | if (!blockQuoteRegExp) { 79 | blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 80 | openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; 81 | } 82 | if (hashContent.match(blockQuoteRegExp).length !== 2) { 83 | shiftIndex = 0; 84 | for (j = i + 1; j < helperParts.length; j += 1) { 85 | hashContent += ` ${helperParts[j]}`; 86 | if (helperParts[j].indexOf(openingQuote) >= 0) { 87 | shiftIndex = j; 88 | break; 89 | } 90 | } 91 | if (shiftIndex) i = shiftIndex; 92 | } 93 | const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; 94 | slices.push(hash); 95 | } else { 96 | // Plain variable 97 | slices.push(part); 98 | } 99 | } 100 | return slices; 101 | }, 102 | stringToBlocks(string) { 103 | const blocks = []; 104 | let i; 105 | let j; 106 | if (!string) return []; 107 | const stringBlocks = string.split(/({{[^{^}]*}})/); 108 | for (i = 0; i < stringBlocks.length; i += 1) { 109 | let block = stringBlocks[i]; 110 | if (block === '') continue; 111 | if (block.indexOf('{{') < 0) { 112 | blocks.push({ 113 | type: 'plain', 114 | content: block, 115 | }); 116 | } else { 117 | if (block.indexOf('{/') >= 0) { 118 | continue; 119 | } 120 | block = block 121 | .replace(/{{([#/])*([ ])*/, '{{$1') 122 | .replace(/([ ])*}}/, '}}'); 123 | if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { 124 | // Simple variable 125 | blocks.push({ 126 | type: 'variable', 127 | contextName: block.replace(/[{}]/g, ''), 128 | }); 129 | continue; 130 | } 131 | // Helpers 132 | const helperSlices = Template7Utils.helperToSlices(block); 133 | let helperName = helperSlices[0]; 134 | const isPartial = helperName === '>'; 135 | const helperContext = []; 136 | const helperHash = {}; 137 | for (j = 1; j < helperSlices.length; j += 1) { 138 | const slice = helperSlices[j]; 139 | if (Array.isArray(slice)) { 140 | // Hash 141 | helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; 142 | } else { 143 | helperContext.push(slice); 144 | } 145 | } 146 | 147 | if (block.indexOf('{#') >= 0) { 148 | // Condition/Helper 149 | let helperContent = ''; 150 | let elseContent = ''; 151 | let toSkip = 0; 152 | let shiftIndex; 153 | let foundClosed = false; 154 | let foundElse = false; 155 | let depth = 0; 156 | for (j = i + 1; j < stringBlocks.length; j += 1) { 157 | if (stringBlocks[j].indexOf('{{#') >= 0) { 158 | depth += 1; 159 | } 160 | if (stringBlocks[j].indexOf('{{/') >= 0) { 161 | depth -= 1; 162 | } 163 | if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) { 164 | helperContent += stringBlocks[j]; 165 | if (foundElse) elseContent += stringBlocks[j]; 166 | toSkip += 1; 167 | } else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) { 168 | if (toSkip > 0) { 169 | toSkip -= 1; 170 | helperContent += stringBlocks[j]; 171 | if (foundElse) elseContent += stringBlocks[j]; 172 | } else { 173 | shiftIndex = j; 174 | foundClosed = true; 175 | break; 176 | } 177 | } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { 178 | foundElse = true; 179 | } else { 180 | if (!foundElse) helperContent += stringBlocks[j]; 181 | if (foundElse) elseContent += stringBlocks[j]; 182 | } 183 | } 184 | if (foundClosed) { 185 | if (shiftIndex) i = shiftIndex; 186 | if (helperName === 'raw') { 187 | blocks.push({ 188 | type: 'plain', 189 | content: helperContent, 190 | }); 191 | } else { 192 | blocks.push({ 193 | type: 'helper', 194 | helperName, 195 | contextName: helperContext, 196 | content: helperContent, 197 | inverseContent: elseContent, 198 | hash: helperHash, 199 | }); 200 | } 201 | } 202 | } else if (block.indexOf(' ') > 0) { 203 | if (isPartial) { 204 | helperName = '_partial'; 205 | if (helperContext[0]) { 206 | if (helperContext[0].indexOf('[') === 0) helperContext[0] = helperContext[0].replace(/[[\]]/g, ''); 207 | else helperContext[0] = `"${helperContext[0].replace(/"|'/g, '')}"`; 208 | } 209 | } 210 | blocks.push({ 211 | type: 'helper', 212 | helperName, 213 | contextName: helperContext, 214 | hash: helperHash, 215 | }); 216 | } 217 | } 218 | } 219 | return blocks; 220 | }, 221 | parseJsVariable(expression, replace, object) { 222 | return expression.split(/([+ \-*/^()&=|<>!%:?])/g).reduce((arr, part) => { 223 | if (!part) { 224 | return arr; 225 | } 226 | if (part.indexOf(replace) < 0) { 227 | arr.push(part); 228 | return arr; 229 | } 230 | if (!object) { 231 | arr.push(JSON.stringify('')); 232 | return arr; 233 | } 234 | 235 | let variable = object; 236 | if (part.indexOf(`${replace}.`) >= 0) { 237 | part.split(`${replace}.`)[1].split('.').forEach((partName) => { 238 | if (partName in variable) variable = variable[partName]; 239 | else variable = undefined; 240 | }); 241 | } 242 | if ( 243 | (typeof variable === 'string') 244 | || Array.isArray(variable) 245 | || (variable.constructor && variable.constructor === Object) 246 | ) { 247 | variable = JSON.stringify(variable); 248 | } 249 | if (variable === undefined) variable = 'undefined'; 250 | 251 | arr.push(variable); 252 | return arr; 253 | }, []).join(''); 254 | 255 | }, 256 | parseJsParents(expression, parents) { 257 | return expression.split(/([+ \-*^()&=|<>!%:?])/g).reduce((arr, part) => { 258 | if (!part) { 259 | return arr; 260 | } 261 | 262 | if (part.indexOf('../') < 0) { 263 | arr.push(part); 264 | return arr; 265 | } 266 | 267 | if (!parents || parents.length === 0) { 268 | arr.push(JSON.stringify('')); 269 | return arr; 270 | } 271 | 272 | const levelsUp = part.split('../').length - 1; 273 | const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; 274 | 275 | let variable = parentData; 276 | const parentPart = part.replace(/..\//g, ''); 277 | parentPart.split('.').forEach((partName) => { 278 | if (typeof variable[partName] !== 'undefined') variable = variable[partName]; 279 | else variable = 'undefined'; 280 | }); 281 | if (variable === false || variable === true) { 282 | arr.push(JSON.stringify(variable)); 283 | return arr; 284 | } 285 | if (variable === null || variable === 'undefined') { 286 | arr.push(JSON.stringify('')); 287 | return arr; 288 | } 289 | arr.push(JSON.stringify(variable)); 290 | return arr; 291 | }, []).join(''); 292 | }, 293 | getCompileVar(name, ctx, data = 'data_1') { 294 | let variable = ctx; 295 | let parts; 296 | let levelsUp = 0; 297 | let newDepth; 298 | if (name.indexOf('../') === 0) { 299 | levelsUp = name.split('../').length - 1; 300 | newDepth = variable.split('_')[1] - levelsUp; 301 | variable = `ctx_${newDepth >= 1 ? newDepth : 1}`; 302 | parts = name.split('../')[levelsUp].split('.'); 303 | } else if (name.indexOf('@global') === 0) { 304 | variable = 'Template7.global'; 305 | parts = name.split('@global.')[1].split('.'); 306 | } else if (name.indexOf('@root') === 0) { 307 | variable = 'root'; 308 | parts = name.split('@root.')[1].split('.'); 309 | } else { 310 | parts = name.split('.'); 311 | } 312 | for (let i = 0; i < parts.length; i += 1) { 313 | const part = parts[i]; 314 | if (part.indexOf('@') === 0) { 315 | let dataLevel = data.split('_')[1]; 316 | if (levelsUp > 0) { 317 | dataLevel = newDepth; 318 | } 319 | if (i > 0) { 320 | variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`; 321 | } else { 322 | variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`; 323 | } 324 | } else if (Number.isFinite ? Number.isFinite(part) : Template7Context.isFinite(part)) { 325 | variable += `[${part}]`; 326 | } else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { 327 | variable = part.replace('this', ctx); 328 | } else { 329 | variable += `.${part}`; 330 | } 331 | } 332 | return variable; 333 | }, 334 | getCompiledArguments(contextArray, ctx, data) { 335 | const arr = []; 336 | for (let i = 0; i < contextArray.length; i += 1) { 337 | if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]); 338 | else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]); 339 | else { 340 | arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data)); 341 | } 342 | } 343 | 344 | return arr.join(', '); 345 | }, 346 | }; 347 | 348 | /* eslint no-eval: "off" */ 349 | 350 | const Template7Helpers = { 351 | _partial(partialName, options) { 352 | const ctx = this; 353 | const p = Template7Class.partials[partialName]; 354 | if (!p || (p && !p.template)) return ''; 355 | if (!p.compiled) { 356 | p.compiled = new Template7Class(p.template).compile(); 357 | } 358 | Object.keys(options.hash).forEach((hashName) => { 359 | ctx[hashName] = options.hash[hashName]; 360 | }); 361 | return p.compiled(ctx, options.data, options.root); 362 | }, 363 | escape(context) { 364 | if (typeof context === 'undefined' || context === null) return ''; 365 | if (typeof context !== 'string') { 366 | throw new Error('Template7: Passed context to "escape" helper should be a string'); 367 | } 368 | return Template7Utils.escape(context); 369 | }, 370 | if(context, options) { 371 | let ctx = context; 372 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 373 | if (ctx) { 374 | return options.fn(this, options.data); 375 | } 376 | 377 | return options.inverse(this, options.data); 378 | }, 379 | unless(context, options) { 380 | let ctx = context; 381 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 382 | if (!ctx) { 383 | return options.fn(this, options.data); 384 | } 385 | 386 | return options.inverse(this, options.data); 387 | }, 388 | each(context, options) { 389 | let ctx = context; 390 | let ret = ''; 391 | let i = 0; 392 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 393 | if (Array.isArray(ctx)) { 394 | if (options.hash.reverse) { 395 | ctx = ctx.reverse(); 396 | } 397 | for (i = 0; i < ctx.length; i += 1) { 398 | ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); 399 | } 400 | if (options.hash.reverse) { 401 | ctx = ctx.reverse(); 402 | } 403 | } else { 404 | // eslint-disable-next-line 405 | for (const key in ctx) { 406 | i += 1; 407 | ret += options.fn(ctx[key], { key }); 408 | } 409 | } 410 | if (i > 0) return ret; 411 | return options.inverse(this); 412 | }, 413 | with(context, options) { 414 | let ctx = context; 415 | if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); } 416 | return options.fn(ctx); 417 | }, 418 | join(context, options) { 419 | let ctx = context; 420 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 421 | return ctx.join(options.hash.delimiter || options.hash.delimeter); 422 | }, 423 | js(expression, options) { 424 | const data = options.data; 425 | let func; 426 | let execute = expression; 427 | ('index first last key').split(' ').forEach((prop) => { 428 | if (typeof data[prop] !== 'undefined') { 429 | const re1 = new RegExp(`this.@${prop}`, 'g'); 430 | const re2 = new RegExp(`@${prop}`, 'g'); 431 | execute = execute 432 | .replace(re1, JSON.stringify(data[prop])) 433 | .replace(re2, JSON.stringify(data[prop])); 434 | } 435 | }); 436 | if (options.root && execute.indexOf('@root') >= 0) { 437 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 438 | } 439 | if (execute.indexOf('@global') >= 0) { 440 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 441 | } 442 | if (execute.indexOf('../') >= 0) { 443 | execute = Template7Utils.parseJsParents(execute, options.parents); 444 | } 445 | if (execute.indexOf('return') >= 0) { 446 | func = `(function(){${execute}})`; 447 | } else { 448 | func = `(function(){return (${execute})})`; 449 | } 450 | return eval(func).call(this); 451 | }, 452 | js_if(expression, options) { 453 | const data = options.data; 454 | let func; 455 | let execute = expression; 456 | ('index first last key').split(' ').forEach((prop) => { 457 | if (typeof data[prop] !== 'undefined') { 458 | const re1 = new RegExp(`this.@${prop}`, 'g'); 459 | const re2 = new RegExp(`@${prop}`, 'g'); 460 | execute = execute 461 | .replace(re1, JSON.stringify(data[prop])) 462 | .replace(re2, JSON.stringify(data[prop])); 463 | } 464 | }); 465 | if (options.root && execute.indexOf('@root') >= 0) { 466 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 467 | } 468 | if (execute.indexOf('@global') >= 0) { 469 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 470 | } 471 | if (execute.indexOf('../') >= 0) { 472 | execute = Template7Utils.parseJsParents(execute, options.parents); 473 | } 474 | if (execute.indexOf('return') >= 0) { 475 | func = `(function(){${execute}})`; 476 | } else { 477 | func = `(function(){return (${execute})})`; 478 | } 479 | const condition = eval(func).call(this); 480 | if (condition) { 481 | return options.fn(this, options.data); 482 | } 483 | 484 | return options.inverse(this, options.data); 485 | }, 486 | }; 487 | Template7Helpers.js_compare = Template7Helpers.js_if; 488 | 489 | const Template7Options = {}; 490 | const Template7Partials = {}; 491 | 492 | class Template7Class { 493 | constructor(template) { 494 | const t = this; 495 | t.template = template; 496 | } 497 | compile(template = this.template, depth = 1) { 498 | const t = this; 499 | if (t.compiled) return t.compiled; 500 | 501 | if (typeof template !== 'string') { 502 | throw new Error('Template7: Template must be a string'); 503 | } 504 | const { stringToBlocks, getCompileVar, getCompiledArguments } = Template7Utils; 505 | 506 | const blocks = stringToBlocks(template); 507 | const ctx = `ctx_${depth}`; 508 | const data = `data_${depth}`; 509 | if (blocks.length === 0) { 510 | return function empty() { return ''; }; 511 | } 512 | 513 | function getCompileFn(block, newDepth) { 514 | if (block.content) return t.compile(block.content, newDepth); 515 | return function empty() { return ''; }; 516 | } 517 | function getCompileInverse(block, newDepth) { 518 | if (block.inverseContent) return t.compile(block.inverseContent, newDepth); 519 | return function empty() { return ''; }; 520 | } 521 | 522 | let resultString = ''; 523 | if (depth === 1) { 524 | resultString += `(function (${ctx}, ${data}, root) {\n`; 525 | } else { 526 | resultString += `(function (${ctx}, ${data}) {\n`; 527 | } 528 | if (depth === 1) { 529 | resultString += 'function isArray(arr){return Array.isArray(arr);}\n'; 530 | resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; 531 | resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; 532 | resultString += 'root = root || ctx_1 || {};\n'; 533 | } 534 | resultString += 'var r = \'\';\n'; 535 | let i; 536 | for (i = 0; i < blocks.length; i += 1) { 537 | const block = blocks[i]; 538 | // Plain block 539 | if (block.type === 'plain') { 540 | // eslint-disable-next-line 541 | resultString += `r +='${(block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')}';`; 542 | continue; 543 | } 544 | let variable; 545 | let compiledArguments; 546 | // Variable block 547 | if (block.type === 'variable') { 548 | variable = getCompileVar(block.contextName, ctx, data); 549 | resultString += `r += c(${variable}, ${ctx});`; 550 | } 551 | // Helpers block 552 | if (block.type === 'helper') { 553 | let parents; 554 | if (ctx !== 'ctx_1') { 555 | const level = ctx.split('_')[1]; 556 | let parentsString = `ctx_${level - 1}`; 557 | for (let j = level - 2; j >= 1; j -= 1) { 558 | parentsString += `, ctx_${j}`; 559 | } 560 | parents = `[${parentsString}]`; 561 | } else { 562 | parents = `[${ctx}]`; 563 | } 564 | let dynamicHelper; 565 | if (block.helperName.indexOf('[') === 0) { 566 | block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data); 567 | dynamicHelper = true; 568 | } 569 | if (dynamicHelper || block.helperName in Template7Helpers) { 570 | compiledArguments = getCompiledArguments(block.contextName, ctx, data); 571 | resultString += `r += (Template7Helpers${dynamicHelper ? `[${block.helperName}]` : `.${block.helperName}`}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 572 | } else if (block.contextName.length > 0) { 573 | throw new Error(`Template7: Missing helper: "${block.helperName}"`); 574 | } else { 575 | variable = getCompileVar(block.helperName, ctx, data); 576 | resultString += `if (${variable}) {`; 577 | resultString += `if (isArray(${variable})) {`; 578 | resultString += `r += (Template7Helpers.each).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 579 | resultString += '}else {'; 580 | resultString += `r += (Template7Helpers.with).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 581 | resultString += '}}'; 582 | } 583 | } 584 | } 585 | resultString += '\nreturn r;})'; 586 | 587 | if (depth === 1) { 588 | // eslint-disable-next-line 589 | t.compiled = eval(resultString); 590 | return t.compiled; 591 | } 592 | return resultString; 593 | } 594 | static get options() { 595 | return Template7Options; 596 | } 597 | static get partials() { 598 | return Template7Partials; 599 | } 600 | static get helpers() { 601 | return Template7Helpers; 602 | } 603 | } 604 | 605 | function Template7(...args) { 606 | const [template, data] = args; 607 | if (args.length === 2) { 608 | let instance = new Template7Class(template); 609 | const rendered = instance.compile()(data); 610 | instance = null; 611 | return (rendered); 612 | } 613 | return new Template7Class(template); 614 | } 615 | Template7.registerHelper = function registerHelper(name, fn) { 616 | Template7Class.helpers[name] = fn; 617 | }; 618 | Template7.unregisterHelper = function unregisterHelper(name) { 619 | Template7Class.helpers[name] = undefined; 620 | delete Template7Class.helpers[name]; 621 | }; 622 | Template7.registerPartial = function registerPartial(name, template) { 623 | Template7Class.partials[name] = { template }; 624 | }; 625 | Template7.unregisterPartial = function unregisterPartial(name) { 626 | if (Template7Class.partials[name]) { 627 | Template7Class.partials[name] = undefined; 628 | delete Template7Class.partials[name]; 629 | } 630 | }; 631 | Template7.compile = function compile(template, options) { 632 | const instance = new Template7Class(template, options); 633 | return instance.compile(); 634 | }; 635 | 636 | Template7.options = Template7Class.options; 637 | Template7.helpers = Template7Class.helpers; 638 | Template7.partials = Template7Class.partials; 639 | 640 | export default Template7; 641 | -------------------------------------------------------------------------------- /dist/template7.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Template7 1.4.2 3 | * Mobile-first HTML template engine 4 | * 5 | * http://www.idangero.us/template7/ 6 | * 7 | * Copyright 2019, Vladimir Kharlampidi 8 | * The iDangero.us 9 | * http://www.idangero.us/ 10 | * 11 | * Licensed under MIT 12 | * 13 | * Released on: June 14, 2019 14 | */ 15 | 16 | (function (global, factory) { 17 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 18 | typeof define === 'function' && define.amd ? define(factory) : 19 | (global = global || self, global.Template7 = factory()); 20 | }(this, function () { 'use strict'; 21 | 22 | var t7ctx; 23 | if (typeof window !== 'undefined') { 24 | t7ctx = window; 25 | } else if (typeof global !== 'undefined') { 26 | t7ctx = global; 27 | } else { 28 | t7ctx = undefined; 29 | } 30 | 31 | var Template7Context = t7ctx; 32 | 33 | var Template7Utils = { 34 | quoteSingleRexExp: new RegExp('\'', 'g'), 35 | quoteDoubleRexExp: new RegExp('"', 'g'), 36 | isFunction: function isFunction(func) { 37 | return typeof func === 'function'; 38 | }, 39 | escape: function escape(string) { 40 | if ( string === void 0 ) string = ''; 41 | 42 | return string 43 | .replace(/&/g, '&') 44 | .replace(//g, '>') 46 | .replace(/"/g, '"') 47 | .replace(/'/g, '''); 48 | }, 49 | helperToSlices: function helperToSlices(string) { 50 | var quoteDoubleRexExp = Template7Utils.quoteDoubleRexExp; 51 | var quoteSingleRexExp = Template7Utils.quoteSingleRexExp; 52 | var helperParts = string.replace(/[{}#}]/g, '').trim().split(' '); 53 | var slices = []; 54 | var shiftIndex; 55 | var i; 56 | var j; 57 | for (i = 0; i < helperParts.length; i += 1) { 58 | var part = helperParts[i]; 59 | var blockQuoteRegExp = (void 0); 60 | var openingQuote = (void 0); 61 | if (i === 0) { slices.push(part); } 62 | else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { 63 | blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 64 | openingQuote = part.indexOf('"') === 0 ? '"' : '\''; 65 | // Plain String 66 | if (part.match(blockQuoteRegExp).length === 2) { 67 | // One word string 68 | slices.push(part); 69 | } else { 70 | // Find closed Index 71 | shiftIndex = 0; 72 | for (j = i + 1; j < helperParts.length; j += 1) { 73 | part += " " + (helperParts[j]); 74 | if (helperParts[j].indexOf(openingQuote) >= 0) { 75 | shiftIndex = j; 76 | slices.push(part); 77 | break; 78 | } 79 | } 80 | if (shiftIndex) { i = shiftIndex; } 81 | } 82 | } else if (part.indexOf('=') > 0) { 83 | // Hash 84 | var hashParts = part.split('='); 85 | var hashName = hashParts[0]; 86 | var hashContent = hashParts[1]; 87 | if (!blockQuoteRegExp) { 88 | blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 89 | openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; 90 | } 91 | if (hashContent.match(blockQuoteRegExp).length !== 2) { 92 | shiftIndex = 0; 93 | for (j = i + 1; j < helperParts.length; j += 1) { 94 | hashContent += " " + (helperParts[j]); 95 | if (helperParts[j].indexOf(openingQuote) >= 0) { 96 | shiftIndex = j; 97 | break; 98 | } 99 | } 100 | if (shiftIndex) { i = shiftIndex; } 101 | } 102 | var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; 103 | slices.push(hash); 104 | } else { 105 | // Plain variable 106 | slices.push(part); 107 | } 108 | } 109 | return slices; 110 | }, 111 | stringToBlocks: function stringToBlocks(string) { 112 | var blocks = []; 113 | var i; 114 | var j; 115 | if (!string) { return []; } 116 | var stringBlocks = string.split(/({{[^{^}]*}})/); 117 | for (i = 0; i < stringBlocks.length; i += 1) { 118 | var block = stringBlocks[i]; 119 | if (block === '') { continue; } 120 | if (block.indexOf('{{') < 0) { 121 | blocks.push({ 122 | type: 'plain', 123 | content: block, 124 | }); 125 | } else { 126 | if (block.indexOf('{/') >= 0) { 127 | continue; 128 | } 129 | block = block 130 | .replace(/{{([#/])*([ ])*/, '{{$1') 131 | .replace(/([ ])*}}/, '}}'); 132 | if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { 133 | // Simple variable 134 | blocks.push({ 135 | type: 'variable', 136 | contextName: block.replace(/[{}]/g, ''), 137 | }); 138 | continue; 139 | } 140 | // Helpers 141 | var helperSlices = Template7Utils.helperToSlices(block); 142 | var helperName = helperSlices[0]; 143 | var isPartial = helperName === '>'; 144 | var helperContext = []; 145 | var helperHash = {}; 146 | for (j = 1; j < helperSlices.length; j += 1) { 147 | var slice = helperSlices[j]; 148 | if (Array.isArray(slice)) { 149 | // Hash 150 | helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; 151 | } else { 152 | helperContext.push(slice); 153 | } 154 | } 155 | 156 | if (block.indexOf('{#') >= 0) { 157 | // Condition/Helper 158 | var helperContent = ''; 159 | var elseContent = ''; 160 | var toSkip = 0; 161 | var shiftIndex = (void 0); 162 | var foundClosed = false; 163 | var foundElse = false; 164 | var depth = 0; 165 | for (j = i + 1; j < stringBlocks.length; j += 1) { 166 | if (stringBlocks[j].indexOf('{{#') >= 0) { 167 | depth += 1; 168 | } 169 | if (stringBlocks[j].indexOf('{{/') >= 0) { 170 | depth -= 1; 171 | } 172 | if (stringBlocks[j].indexOf(("{{#" + helperName)) >= 0) { 173 | helperContent += stringBlocks[j]; 174 | if (foundElse) { elseContent += stringBlocks[j]; } 175 | toSkip += 1; 176 | } else if (stringBlocks[j].indexOf(("{{/" + helperName)) >= 0) { 177 | if (toSkip > 0) { 178 | toSkip -= 1; 179 | helperContent += stringBlocks[j]; 180 | if (foundElse) { elseContent += stringBlocks[j]; } 181 | } else { 182 | shiftIndex = j; 183 | foundClosed = true; 184 | break; 185 | } 186 | } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { 187 | foundElse = true; 188 | } else { 189 | if (!foundElse) { helperContent += stringBlocks[j]; } 190 | if (foundElse) { elseContent += stringBlocks[j]; } 191 | } 192 | } 193 | if (foundClosed) { 194 | if (shiftIndex) { i = shiftIndex; } 195 | if (helperName === 'raw') { 196 | blocks.push({ 197 | type: 'plain', 198 | content: helperContent, 199 | }); 200 | } else { 201 | blocks.push({ 202 | type: 'helper', 203 | helperName: helperName, 204 | contextName: helperContext, 205 | content: helperContent, 206 | inverseContent: elseContent, 207 | hash: helperHash, 208 | }); 209 | } 210 | } 211 | } else if (block.indexOf(' ') > 0) { 212 | if (isPartial) { 213 | helperName = '_partial'; 214 | if (helperContext[0]) { 215 | if (helperContext[0].indexOf('[') === 0) { helperContext[0] = helperContext[0].replace(/[[\]]/g, ''); } 216 | else { helperContext[0] = "\"" + (helperContext[0].replace(/"|'/g, '')) + "\""; } 217 | } 218 | } 219 | blocks.push({ 220 | type: 'helper', 221 | helperName: helperName, 222 | contextName: helperContext, 223 | hash: helperHash, 224 | }); 225 | } 226 | } 227 | } 228 | return blocks; 229 | }, 230 | parseJsVariable: function parseJsVariable(expression, replace, object) { 231 | return expression.split(/([+ \-*/^()&=|<>!%:?])/g).reduce(function (arr, part) { 232 | if (!part) { 233 | return arr; 234 | } 235 | if (part.indexOf(replace) < 0) { 236 | arr.push(part); 237 | return arr; 238 | } 239 | if (!object) { 240 | arr.push(JSON.stringify('')); 241 | return arr; 242 | } 243 | 244 | var variable = object; 245 | if (part.indexOf((replace + ".")) >= 0) { 246 | part.split((replace + "."))[1].split('.').forEach(function (partName) { 247 | if (partName in variable) { variable = variable[partName]; } 248 | else { variable = undefined; } 249 | }); 250 | } 251 | if ( 252 | (typeof variable === 'string') 253 | || Array.isArray(variable) 254 | || (variable.constructor && variable.constructor === Object) 255 | ) { 256 | variable = JSON.stringify(variable); 257 | } 258 | if (variable === undefined) { variable = 'undefined'; } 259 | 260 | arr.push(variable); 261 | return arr; 262 | }, []).join(''); 263 | 264 | }, 265 | parseJsParents: function parseJsParents(expression, parents) { 266 | return expression.split(/([+ \-*^()&=|<>!%:?])/g).reduce(function (arr, part) { 267 | if (!part) { 268 | return arr; 269 | } 270 | 271 | if (part.indexOf('../') < 0) { 272 | arr.push(part); 273 | return arr; 274 | } 275 | 276 | if (!parents || parents.length === 0) { 277 | arr.push(JSON.stringify('')); 278 | return arr; 279 | } 280 | 281 | var levelsUp = part.split('../').length - 1; 282 | var parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; 283 | 284 | var variable = parentData; 285 | var parentPart = part.replace(/..\//g, ''); 286 | parentPart.split('.').forEach(function (partName) { 287 | if (typeof variable[partName] !== 'undefined') { variable = variable[partName]; } 288 | else { variable = 'undefined'; } 289 | }); 290 | if (variable === false || variable === true) { 291 | arr.push(JSON.stringify(variable)); 292 | return arr; 293 | } 294 | if (variable === null || variable === 'undefined') { 295 | arr.push(JSON.stringify('')); 296 | return arr; 297 | } 298 | arr.push(JSON.stringify(variable)); 299 | return arr; 300 | }, []).join(''); 301 | }, 302 | getCompileVar: function getCompileVar(name, ctx, data) { 303 | if ( data === void 0 ) data = 'data_1'; 304 | 305 | var variable = ctx; 306 | var parts; 307 | var levelsUp = 0; 308 | var newDepth; 309 | if (name.indexOf('../') === 0) { 310 | levelsUp = name.split('../').length - 1; 311 | newDepth = variable.split('_')[1] - levelsUp; 312 | variable = "ctx_" + (newDepth >= 1 ? newDepth : 1); 313 | parts = name.split('../')[levelsUp].split('.'); 314 | } else if (name.indexOf('@global') === 0) { 315 | variable = 'Template7.global'; 316 | parts = name.split('@global.')[1].split('.'); 317 | } else if (name.indexOf('@root') === 0) { 318 | variable = 'root'; 319 | parts = name.split('@root.')[1].split('.'); 320 | } else { 321 | parts = name.split('.'); 322 | } 323 | for (var i = 0; i < parts.length; i += 1) { 324 | var part = parts[i]; 325 | if (part.indexOf('@') === 0) { 326 | var dataLevel = data.split('_')[1]; 327 | if (levelsUp > 0) { 328 | dataLevel = newDepth; 329 | } 330 | if (i > 0) { 331 | variable += "[(data_" + dataLevel + " && data_" + dataLevel + "." + (part.replace('@', '')) + ")]"; 332 | } else { 333 | variable = "(data_" + dataLevel + " && data_" + dataLevel + "." + (part.replace('@', '')) + ")"; 334 | } 335 | } else if (Number.isFinite ? Number.isFinite(part) : Template7Context.isFinite(part)) { 336 | variable += "[" + part + "]"; 337 | } else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { 338 | variable = part.replace('this', ctx); 339 | } else { 340 | variable += "." + part; 341 | } 342 | } 343 | return variable; 344 | }, 345 | getCompiledArguments: function getCompiledArguments(contextArray, ctx, data) { 346 | var arr = []; 347 | for (var i = 0; i < contextArray.length; i += 1) { 348 | if (/^['"]/.test(contextArray[i])) { arr.push(contextArray[i]); } 349 | else if (/^(true|false|\d+)$/.test(contextArray[i])) { arr.push(contextArray[i]); } 350 | else { 351 | arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data)); 352 | } 353 | } 354 | 355 | return arr.join(', '); 356 | }, 357 | }; 358 | 359 | /* eslint no-eval: "off" */ 360 | 361 | var Template7Helpers = { 362 | _partial: function _partial(partialName, options) { 363 | var ctx = this; 364 | var p = Template7Class.partials[partialName]; 365 | if (!p || (p && !p.template)) { return ''; } 366 | if (!p.compiled) { 367 | p.compiled = new Template7Class(p.template).compile(); 368 | } 369 | Object.keys(options.hash).forEach(function (hashName) { 370 | ctx[hashName] = options.hash[hashName]; 371 | }); 372 | return p.compiled(ctx, options.data, options.root); 373 | }, 374 | escape: function escape(context) { 375 | if (typeof context === 'undefined' || context === null) { return ''; } 376 | if (typeof context !== 'string') { 377 | throw new Error('Template7: Passed context to "escape" helper should be a string'); 378 | } 379 | return Template7Utils.escape(context); 380 | }, 381 | if: function if$1(context, options) { 382 | var ctx = context; 383 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 384 | if (ctx) { 385 | return options.fn(this, options.data); 386 | } 387 | 388 | return options.inverse(this, options.data); 389 | }, 390 | unless: function unless(context, options) { 391 | var ctx = context; 392 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 393 | if (!ctx) { 394 | return options.fn(this, options.data); 395 | } 396 | 397 | return options.inverse(this, options.data); 398 | }, 399 | each: function each(context, options) { 400 | var ctx = context; 401 | var ret = ''; 402 | var i = 0; 403 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 404 | if (Array.isArray(ctx)) { 405 | if (options.hash.reverse) { 406 | ctx = ctx.reverse(); 407 | } 408 | for (i = 0; i < ctx.length; i += 1) { 409 | ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); 410 | } 411 | if (options.hash.reverse) { 412 | ctx = ctx.reverse(); 413 | } 414 | } else { 415 | // eslint-disable-next-line 416 | for (var key in ctx) { 417 | i += 1; 418 | ret += options.fn(ctx[key], { key: key }); 419 | } 420 | } 421 | if (i > 0) { return ret; } 422 | return options.inverse(this); 423 | }, 424 | with: function with$1(context, options) { 425 | var ctx = context; 426 | if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); } 427 | return options.fn(ctx); 428 | }, 429 | join: function join(context, options) { 430 | var ctx = context; 431 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 432 | return ctx.join(options.hash.delimiter || options.hash.delimeter); 433 | }, 434 | js: function js(expression, options) { 435 | var data = options.data; 436 | var func; 437 | var execute = expression; 438 | ('index first last key').split(' ').forEach(function (prop) { 439 | if (typeof data[prop] !== 'undefined') { 440 | var re1 = new RegExp(("this.@" + prop), 'g'); 441 | var re2 = new RegExp(("@" + prop), 'g'); 442 | execute = execute 443 | .replace(re1, JSON.stringify(data[prop])) 444 | .replace(re2, JSON.stringify(data[prop])); 445 | } 446 | }); 447 | if (options.root && execute.indexOf('@root') >= 0) { 448 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 449 | } 450 | if (execute.indexOf('@global') >= 0) { 451 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 452 | } 453 | if (execute.indexOf('../') >= 0) { 454 | execute = Template7Utils.parseJsParents(execute, options.parents); 455 | } 456 | if (execute.indexOf('return') >= 0) { 457 | func = "(function(){" + execute + "})"; 458 | } else { 459 | func = "(function(){return (" + execute + ")})"; 460 | } 461 | return eval(func).call(this); 462 | }, 463 | js_if: function js_if(expression, options) { 464 | var data = options.data; 465 | var func; 466 | var execute = expression; 467 | ('index first last key').split(' ').forEach(function (prop) { 468 | if (typeof data[prop] !== 'undefined') { 469 | var re1 = new RegExp(("this.@" + prop), 'g'); 470 | var re2 = new RegExp(("@" + prop), 'g'); 471 | execute = execute 472 | .replace(re1, JSON.stringify(data[prop])) 473 | .replace(re2, JSON.stringify(data[prop])); 474 | } 475 | }); 476 | if (options.root && execute.indexOf('@root') >= 0) { 477 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 478 | } 479 | if (execute.indexOf('@global') >= 0) { 480 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 481 | } 482 | if (execute.indexOf('../') >= 0) { 483 | execute = Template7Utils.parseJsParents(execute, options.parents); 484 | } 485 | if (execute.indexOf('return') >= 0) { 486 | func = "(function(){" + execute + "})"; 487 | } else { 488 | func = "(function(){return (" + execute + ")})"; 489 | } 490 | var condition = eval(func).call(this); 491 | if (condition) { 492 | return options.fn(this, options.data); 493 | } 494 | 495 | return options.inverse(this, options.data); 496 | }, 497 | }; 498 | Template7Helpers.js_compare = Template7Helpers.js_if; 499 | 500 | var Template7Options = {}; 501 | var Template7Partials = {}; 502 | 503 | var Template7Class = function Template7Class(template) { 504 | var t = this; 505 | t.template = template; 506 | }; 507 | 508 | var staticAccessors = { options: { configurable: true },partials: { configurable: true },helpers: { configurable: true } }; 509 | Template7Class.prototype.compile = function compile (template, depth) { 510 | if ( template === void 0 ) template = this.template; 511 | if ( depth === void 0 ) depth = 1; 512 | 513 | var t = this; 514 | if (t.compiled) { return t.compiled; } 515 | 516 | if (typeof template !== 'string') { 517 | throw new Error('Template7: Template must be a string'); 518 | } 519 | var stringToBlocks = Template7Utils.stringToBlocks; 520 | var getCompileVar = Template7Utils.getCompileVar; 521 | var getCompiledArguments = Template7Utils.getCompiledArguments; 522 | 523 | var blocks = stringToBlocks(template); 524 | var ctx = "ctx_" + depth; 525 | var data = "data_" + depth; 526 | if (blocks.length === 0) { 527 | return function empty() { return ''; }; 528 | } 529 | 530 | function getCompileFn(block, newDepth) { 531 | if (block.content) { return t.compile(block.content, newDepth); } 532 | return function empty() { return ''; }; 533 | } 534 | function getCompileInverse(block, newDepth) { 535 | if (block.inverseContent) { return t.compile(block.inverseContent, newDepth); } 536 | return function empty() { return ''; }; 537 | } 538 | 539 | var resultString = ''; 540 | if (depth === 1) { 541 | resultString += "(function (" + ctx + ", " + data + ", root) {\n"; 542 | } else { 543 | resultString += "(function (" + ctx + ", " + data + ") {\n"; 544 | } 545 | if (depth === 1) { 546 | resultString += 'function isArray(arr){return Array.isArray(arr);}\n'; 547 | resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; 548 | resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; 549 | resultString += 'root = root || ctx_1 || {};\n'; 550 | } 551 | resultString += 'var r = \'\';\n'; 552 | var i; 553 | for (i = 0; i < blocks.length; i += 1) { 554 | var block = blocks[i]; 555 | // Plain block 556 | if (block.type === 'plain') { 557 | // eslint-disable-next-line 558 | resultString += "r +='" + ((block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')) + "';"; 559 | continue; 560 | } 561 | var variable = (void 0); 562 | var compiledArguments = (void 0); 563 | // Variable block 564 | if (block.type === 'variable') { 565 | variable = getCompileVar(block.contextName, ctx, data); 566 | resultString += "r += c(" + variable + ", " + ctx + ");"; 567 | } 568 | // Helpers block 569 | if (block.type === 'helper') { 570 | var parents = (void 0); 571 | if (ctx !== 'ctx_1') { 572 | var level = ctx.split('_')[1]; 573 | var parentsString = "ctx_" + (level - 1); 574 | for (var j = level - 2; j >= 1; j -= 1) { 575 | parentsString += ", ctx_" + j; 576 | } 577 | parents = "[" + parentsString + "]"; 578 | } else { 579 | parents = "[" + ctx + "]"; 580 | } 581 | var dynamicHelper = (void 0); 582 | if (block.helperName.indexOf('[') === 0) { 583 | block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data); 584 | dynamicHelper = true; 585 | } 586 | if (dynamicHelper || block.helperName in Template7Helpers) { 587 | compiledArguments = getCompiledArguments(block.contextName, ctx, data); 588 | resultString += "r += (Template7Helpers" + (dynamicHelper ? ("[" + (block.helperName) + "]") : ("." + (block.helperName))) + ").call(" + ctx + ", " + (compiledArguments && ((compiledArguments + ", "))) + "{hash:" + (JSON.stringify(block.hash)) + ", data: " + data + " || {}, fn: " + (getCompileFn(block, depth + 1)) + ", inverse: " + (getCompileInverse(block, depth + 1)) + ", root: root, parents: " + parents + "});"; 589 | } else if (block.contextName.length > 0) { 590 | throw new Error(("Template7: Missing helper: \"" + (block.helperName) + "\"")); 591 | } else { 592 | variable = getCompileVar(block.helperName, ctx, data); 593 | resultString += "if (" + variable + ") {"; 594 | resultString += "if (isArray(" + variable + ")) {"; 595 | resultString += "r += (Template7Helpers.each).call(" + ctx + ", " + variable + ", {hash:" + (JSON.stringify(block.hash)) + ", data: " + data + " || {}, fn: " + (getCompileFn(block, depth + 1)) + ", inverse: " + (getCompileInverse(block, depth + 1)) + ", root: root, parents: " + parents + "});"; 596 | resultString += '}else {'; 597 | resultString += "r += (Template7Helpers.with).call(" + ctx + ", " + variable + ", {hash:" + (JSON.stringify(block.hash)) + ", data: " + data + " || {}, fn: " + (getCompileFn(block, depth + 1)) + ", inverse: " + (getCompileInverse(block, depth + 1)) + ", root: root, parents: " + parents + "});"; 598 | resultString += '}}'; 599 | } 600 | } 601 | } 602 | resultString += '\nreturn r;})'; 603 | 604 | if (depth === 1) { 605 | // eslint-disable-next-line 606 | t.compiled = eval(resultString); 607 | return t.compiled; 608 | } 609 | return resultString; 610 | }; 611 | staticAccessors.options.get = function () { 612 | return Template7Options; 613 | }; 614 | staticAccessors.partials.get = function () { 615 | return Template7Partials; 616 | }; 617 | staticAccessors.helpers.get = function () { 618 | return Template7Helpers; 619 | }; 620 | 621 | Object.defineProperties( Template7Class, staticAccessors ); 622 | 623 | function Template7() { 624 | var args = [], len = arguments.length; 625 | while ( len-- ) args[ len ] = arguments[ len ]; 626 | 627 | var template = args[0]; 628 | var data = args[1]; 629 | if (args.length === 2) { 630 | var instance = new Template7Class(template); 631 | var rendered = instance.compile()(data); 632 | instance = null; 633 | return (rendered); 634 | } 635 | return new Template7Class(template); 636 | } 637 | Template7.registerHelper = function registerHelper(name, fn) { 638 | Template7Class.helpers[name] = fn; 639 | }; 640 | Template7.unregisterHelper = function unregisterHelper(name) { 641 | Template7Class.helpers[name] = undefined; 642 | delete Template7Class.helpers[name]; 643 | }; 644 | Template7.registerPartial = function registerPartial(name, template) { 645 | Template7Class.partials[name] = { template: template }; 646 | }; 647 | Template7.unregisterPartial = function unregisterPartial(name) { 648 | if (Template7Class.partials[name]) { 649 | Template7Class.partials[name] = undefined; 650 | delete Template7Class.partials[name]; 651 | } 652 | }; 653 | Template7.compile = function compile(template, options) { 654 | var instance = new Template7Class(template, options); 655 | return instance.compile(); 656 | }; 657 | 658 | Template7.options = Template7Class.options; 659 | Template7.helpers = Template7Class.helpers; 660 | Template7.partials = Template7Class.partials; 661 | 662 | return Template7; 663 | 664 | })); 665 | //# sourceMappingURL=template7.js.map 666 | -------------------------------------------------------------------------------- /dist/template7.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"template7.js.map","sources":["../src/context.js","../src/utils.js","../src/helpers.js","../src/template7-class.js","../src/template7.js"],"sourcesContent":["let t7ctx;\nif (typeof window !== 'undefined') {\n t7ctx = window;\n} else if (typeof global !== 'undefined') {\n t7ctx = global;\n} else {\n t7ctx = this;\n}\n\nconst Template7Context = t7ctx;\n\nexport default Template7Context;\n","import Template7Context from './context';\n\nconst Template7Utils = {\n quoteSingleRexExp: new RegExp('\\'', 'g'),\n quoteDoubleRexExp: new RegExp('\"', 'g'),\n isFunction(func) {\n return typeof func === 'function';\n },\n escape(string = '') {\n return string\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n helperToSlices(string) {\n const { quoteDoubleRexExp, quoteSingleRexExp } = Template7Utils;\n const helperParts = string.replace(/[{}#}]/g, '').trim().split(' ');\n const slices = [];\n let shiftIndex;\n let i;\n let j;\n for (i = 0; i < helperParts.length; i += 1) {\n let part = helperParts[i];\n let blockQuoteRegExp;\n let openingQuote;\n if (i === 0) slices.push(part);\n else if (part.indexOf('\"') === 0 || part.indexOf('\\'') === 0) {\n blockQuoteRegExp = part.indexOf('\"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;\n openingQuote = part.indexOf('\"') === 0 ? '\"' : '\\'';\n // Plain String\n if (part.match(blockQuoteRegExp).length === 2) {\n // One word string\n slices.push(part);\n } else {\n // Find closed Index\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j += 1) {\n part += ` ${helperParts[j]}`;\n if (helperParts[j].indexOf(openingQuote) >= 0) {\n shiftIndex = j;\n slices.push(part);\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n } else if (part.indexOf('=') > 0) {\n // Hash\n const hashParts = part.split('=');\n const hashName = hashParts[0];\n let hashContent = hashParts[1];\n if (!blockQuoteRegExp) {\n blockQuoteRegExp = hashContent.indexOf('\"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;\n openingQuote = hashContent.indexOf('\"') === 0 ? '\"' : '\\'';\n }\n if (hashContent.match(blockQuoteRegExp).length !== 2) {\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j += 1) {\n hashContent += ` ${helperParts[j]}`;\n if (helperParts[j].indexOf(openingQuote) >= 0) {\n shiftIndex = j;\n break;\n }\n }\n if (shiftIndex) i = shiftIndex;\n }\n const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')];\n slices.push(hash);\n } else {\n // Plain variable\n slices.push(part);\n }\n }\n return slices;\n },\n stringToBlocks(string) {\n const blocks = [];\n let i;\n let j;\n if (!string) return [];\n const stringBlocks = string.split(/({{[^{^}]*}})/);\n for (i = 0; i < stringBlocks.length; i += 1) {\n let block = stringBlocks[i];\n if (block === '') continue;\n if (block.indexOf('{{') < 0) {\n blocks.push({\n type: 'plain',\n content: block,\n });\n } else {\n if (block.indexOf('{/') >= 0) {\n continue;\n }\n block = block\n .replace(/{{([#/])*([ ])*/, '{{$1')\n .replace(/([ ])*}}/, '}}');\n if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {\n // Simple variable\n blocks.push({\n type: 'variable',\n contextName: block.replace(/[{}]/g, ''),\n });\n continue;\n }\n // Helpers\n const helperSlices = Template7Utils.helperToSlices(block);\n let helperName = helperSlices[0];\n const isPartial = helperName === '>';\n const helperContext = [];\n const helperHash = {};\n for (j = 1; j < helperSlices.length; j += 1) {\n const slice = helperSlices[j];\n if (Array.isArray(slice)) {\n // Hash\n helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];\n } else {\n helperContext.push(slice);\n }\n }\n\n if (block.indexOf('{#') >= 0) {\n // Condition/Helper\n let helperContent = '';\n let elseContent = '';\n let toSkip = 0;\n let shiftIndex;\n let foundClosed = false;\n let foundElse = false;\n let depth = 0;\n for (j = i + 1; j < stringBlocks.length; j += 1) {\n if (stringBlocks[j].indexOf('{{#') >= 0) {\n depth += 1;\n }\n if (stringBlocks[j].indexOf('{{/') >= 0) {\n depth -= 1;\n }\n if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) {\n helperContent += stringBlocks[j];\n if (foundElse) elseContent += stringBlocks[j];\n toSkip += 1;\n } else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) {\n if (toSkip > 0) {\n toSkip -= 1;\n helperContent += stringBlocks[j];\n if (foundElse) elseContent += stringBlocks[j];\n } else {\n shiftIndex = j;\n foundClosed = true;\n break;\n }\n } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) {\n foundElse = true;\n } else {\n if (!foundElse) helperContent += stringBlocks[j];\n if (foundElse) elseContent += stringBlocks[j];\n }\n }\n if (foundClosed) {\n if (shiftIndex) i = shiftIndex;\n if (helperName === 'raw') {\n blocks.push({\n type: 'plain',\n content: helperContent,\n });\n } else {\n blocks.push({\n type: 'helper',\n helperName,\n contextName: helperContext,\n content: helperContent,\n inverseContent: elseContent,\n hash: helperHash,\n });\n }\n }\n } else if (block.indexOf(' ') > 0) {\n if (isPartial) {\n helperName = '_partial';\n if (helperContext[0]) {\n if (helperContext[0].indexOf('[') === 0) helperContext[0] = helperContext[0].replace(/[[\\]]/g, '');\n else helperContext[0] = `\"${helperContext[0].replace(/\"|'/g, '')}\"`;\n }\n }\n blocks.push({\n type: 'helper',\n helperName,\n contextName: helperContext,\n hash: helperHash,\n });\n }\n }\n }\n return blocks;\n },\n parseJsVariable(expression, replace, object) {\n return expression.split(/([+ \\-*/^()&=|<>!%:?])/g).reduce((arr, part) => {\n if (!part) {\n return arr;\n }\n if (part.indexOf(replace) < 0) {\n arr.push(part);\n return arr;\n }\n if (!object) {\n arr.push(JSON.stringify(''));\n return arr;\n }\n\n let variable = object;\n if (part.indexOf(`${replace}.`) >= 0) {\n part.split(`${replace}.`)[1].split('.').forEach((partName) => {\n if (partName in variable) variable = variable[partName];\n else variable = undefined;\n });\n }\n if (\n (typeof variable === 'string')\n || Array.isArray(variable)\n || (variable.constructor && variable.constructor === Object)\n ) {\n variable = JSON.stringify(variable);\n }\n if (variable === undefined) variable = 'undefined';\n\n arr.push(variable);\n return arr;\n }, []).join('');\n\n },\n parseJsParents(expression, parents) {\n return expression.split(/([+ \\-*^()&=|<>!%:?])/g).reduce((arr, part) => {\n if (!part) {\n return arr;\n }\n\n if (part.indexOf('../') < 0) {\n arr.push(part);\n return arr;\n }\n\n if (!parents || parents.length === 0) {\n arr.push(JSON.stringify(''));\n return arr;\n }\n\n const levelsUp = part.split('../').length - 1;\n const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1];\n\n let variable = parentData;\n const parentPart = part.replace(/..\\//g, '');\n parentPart.split('.').forEach((partName) => {\n if (typeof variable[partName] !== 'undefined') variable = variable[partName];\n else variable = 'undefined';\n });\n if (variable === false || variable === true) {\n arr.push(JSON.stringify(variable));\n return arr;\n }\n if (variable === null || variable === 'undefined') {\n arr.push(JSON.stringify(''));\n return arr;\n }\n arr.push(JSON.stringify(variable));\n return arr;\n }, []).join('');\n },\n getCompileVar(name, ctx, data = 'data_1') {\n let variable = ctx;\n let parts;\n let levelsUp = 0;\n let newDepth;\n if (name.indexOf('../') === 0) {\n levelsUp = name.split('../').length - 1;\n newDepth = variable.split('_')[1] - levelsUp;\n variable = `ctx_${newDepth >= 1 ? newDepth : 1}`;\n parts = name.split('../')[levelsUp].split('.');\n } else if (name.indexOf('@global') === 0) {\n variable = 'Template7.global';\n parts = name.split('@global.')[1].split('.');\n } else if (name.indexOf('@root') === 0) {\n variable = 'root';\n parts = name.split('@root.')[1].split('.');\n } else {\n parts = name.split('.');\n }\n for (let i = 0; i < parts.length; i += 1) {\n const part = parts[i];\n if (part.indexOf('@') === 0) {\n let dataLevel = data.split('_')[1];\n if (levelsUp > 0) {\n dataLevel = newDepth;\n }\n if (i > 0) {\n variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`;\n } else {\n variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`;\n }\n } else if (Number.isFinite ? Number.isFinite(part) : Template7Context.isFinite(part)) {\n variable += `[${part}]`;\n } else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) {\n variable = part.replace('this', ctx);\n } else {\n variable += `.${part}`;\n }\n }\n return variable;\n },\n getCompiledArguments(contextArray, ctx, data) {\n const arr = [];\n for (let i = 0; i < contextArray.length; i += 1) {\n if (/^['\"]/.test(contextArray[i])) arr.push(contextArray[i]);\n else if (/^(true|false|\\d+)$/.test(contextArray[i])) arr.push(contextArray[i]);\n else {\n arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data));\n }\n }\n\n return arr.join(', ');\n },\n};\n\nexport default Template7Utils;\n","/* eslint no-eval: \"off\" */\nimport Template7Utils from './utils';\nimport Template7Class from './template7-class';\nimport Template7Context from './context';\n\nconst Template7Helpers = {\n _partial(partialName, options) {\n const ctx = this;\n const p = Template7Class.partials[partialName];\n if (!p || (p && !p.template)) return '';\n if (!p.compiled) {\n p.compiled = new Template7Class(p.template).compile();\n }\n Object.keys(options.hash).forEach((hashName) => {\n ctx[hashName] = options.hash[hashName];\n });\n return p.compiled(ctx, options.data, options.root);\n },\n escape(context) {\n if (typeof context === 'undefined' || context === null) return '';\n if (typeof context !== 'string') {\n throw new Error('Template7: Passed context to \"escape\" helper should be a string');\n }\n return Template7Utils.escape(context);\n },\n if(context, options) {\n let ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (ctx) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n unless(context, options) {\n let ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (!ctx) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n each(context, options) {\n let ctx = context;\n let ret = '';\n let i = 0;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (Array.isArray(ctx)) {\n if (options.hash.reverse) {\n ctx = ctx.reverse();\n }\n for (i = 0; i < ctx.length; i += 1) {\n ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i });\n }\n if (options.hash.reverse) {\n ctx = ctx.reverse();\n }\n } else {\n // eslint-disable-next-line\n for (const key in ctx) {\n i += 1;\n ret += options.fn(ctx[key], { key });\n }\n }\n if (i > 0) return ret;\n return options.inverse(this);\n },\n with(context, options) {\n let ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); }\n return options.fn(ctx);\n },\n join(context, options) {\n let ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n return ctx.join(options.hash.delimiter || options.hash.delimeter);\n },\n js(expression, options) {\n const data = options.data;\n let func;\n let execute = expression;\n ('index first last key').split(' ').forEach((prop) => {\n if (typeof data[prop] !== 'undefined') {\n const re1 = new RegExp(`this.@${prop}`, 'g');\n const re2 = new RegExp(`@${prop}`, 'g');\n execute = execute\n .replace(re1, JSON.stringify(data[prop]))\n .replace(re2, JSON.stringify(data[prop]));\n }\n });\n if (options.root && execute.indexOf('@root') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@root', options.root);\n }\n if (execute.indexOf('@global') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);\n }\n if (execute.indexOf('../') >= 0) {\n execute = Template7Utils.parseJsParents(execute, options.parents);\n }\n if (execute.indexOf('return') >= 0) {\n func = `(function(){${execute}})`;\n } else {\n func = `(function(){return (${execute})})`;\n }\n return eval(func).call(this);\n },\n js_if(expression, options) {\n const data = options.data;\n let func;\n let execute = expression;\n ('index first last key').split(' ').forEach((prop) => {\n if (typeof data[prop] !== 'undefined') {\n const re1 = new RegExp(`this.@${prop}`, 'g');\n const re2 = new RegExp(`@${prop}`, 'g');\n execute = execute\n .replace(re1, JSON.stringify(data[prop]))\n .replace(re2, JSON.stringify(data[prop]));\n }\n });\n if (options.root && execute.indexOf('@root') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@root', options.root);\n }\n if (execute.indexOf('@global') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);\n }\n if (execute.indexOf('../') >= 0) {\n execute = Template7Utils.parseJsParents(execute, options.parents);\n }\n if (execute.indexOf('return') >= 0) {\n func = `(function(){${execute}})`;\n } else {\n func = `(function(){return (${execute})})`;\n }\n const condition = eval(func).call(this);\n if (condition) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n};\nTemplate7Helpers.js_compare = Template7Helpers.js_if;\n\nexport default Template7Helpers;\n","import Template7Utils from './utils';\nimport Template7Helpers from './helpers';\n\nconst Template7Options = {};\nconst Template7Partials = {};\n\nclass Template7Class {\n constructor(template) {\n const t = this;\n t.template = template;\n }\n compile(template = this.template, depth = 1) {\n const t = this;\n if (t.compiled) return t.compiled;\n\n if (typeof template !== 'string') {\n throw new Error('Template7: Template must be a string');\n }\n const { stringToBlocks, getCompileVar, getCompiledArguments } = Template7Utils;\n\n const blocks = stringToBlocks(template);\n const ctx = `ctx_${depth}`;\n const data = `data_${depth}`;\n if (blocks.length === 0) {\n return function empty() { return ''; };\n }\n\n function getCompileFn(block, newDepth) {\n if (block.content) return t.compile(block.content, newDepth);\n return function empty() { return ''; };\n }\n function getCompileInverse(block, newDepth) {\n if (block.inverseContent) return t.compile(block.inverseContent, newDepth);\n return function empty() { return ''; };\n }\n\n let resultString = '';\n if (depth === 1) {\n resultString += `(function (${ctx}, ${data}, root) {\\n`;\n } else {\n resultString += `(function (${ctx}, ${data}) {\\n`;\n }\n if (depth === 1) {\n resultString += 'function isArray(arr){return Array.isArray(arr);}\\n';\n resultString += 'function isFunction(func){return (typeof func === \\'function\\');}\\n';\n resultString += 'function c(val, ctx) {if (typeof val !== \"undefined\" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return \"\";}\\n';\n resultString += 'root = root || ctx_1 || {};\\n';\n }\n resultString += 'var r = \\'\\';\\n';\n let i;\n for (i = 0; i < blocks.length; i += 1) {\n const block = blocks[i];\n // Plain block\n if (block.type === 'plain') {\n // eslint-disable-next-line\n resultString += `r +='${(block.content).replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n').replace(/'/g, '\\\\' + '\\'')}';`;\n continue;\n }\n let variable;\n let compiledArguments;\n // Variable block\n if (block.type === 'variable') {\n variable = getCompileVar(block.contextName, ctx, data);\n resultString += `r += c(${variable}, ${ctx});`;\n }\n // Helpers block\n if (block.type === 'helper') {\n let parents;\n if (ctx !== 'ctx_1') {\n const level = ctx.split('_')[1];\n let parentsString = `ctx_${level - 1}`;\n for (let j = level - 2; j >= 1; j -= 1) {\n parentsString += `, ctx_${j}`;\n }\n parents = `[${parentsString}]`;\n } else {\n parents = `[${ctx}]`;\n }\n let dynamicHelper;\n if (block.helperName.indexOf('[') === 0) {\n block.helperName = getCompileVar(block.helperName.replace(/[[\\]]/g, ''), ctx, data);\n dynamicHelper = true;\n }\n if (dynamicHelper || block.helperName in Template7Helpers) {\n compiledArguments = getCompiledArguments(block.contextName, ctx, data);\n resultString += `r += (Template7Helpers${dynamicHelper ? `[${block.helperName}]` : `.${block.helperName}`}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`;\n } else if (block.contextName.length > 0) {\n throw new Error(`Template7: Missing helper: \"${block.helperName}\"`);\n } else {\n variable = getCompileVar(block.helperName, ctx, data);\n resultString += `if (${variable}) {`;\n resultString += `if (isArray(${variable})) {`;\n resultString += `r += (Template7Helpers.each).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`;\n resultString += '}else {';\n resultString += `r += (Template7Helpers.with).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`;\n resultString += '}}';\n }\n }\n }\n resultString += '\\nreturn r;})';\n\n if (depth === 1) {\n // eslint-disable-next-line\n t.compiled = eval(resultString);\n return t.compiled;\n }\n return resultString;\n }\n static get options() {\n return Template7Options;\n }\n static get partials() {\n return Template7Partials;\n }\n static get helpers() {\n return Template7Helpers;\n }\n}\nexport default Template7Class;\n","import Template7Class from './template7-class';\n\nfunction Template7(...args) {\n const [template, data] = args;\n if (args.length === 2) {\n let instance = new Template7Class(template);\n const rendered = instance.compile()(data);\n instance = null;\n return (rendered);\n }\n return new Template7Class(template);\n}\nTemplate7.registerHelper = function registerHelper(name, fn) {\n Template7Class.helpers[name] = fn;\n};\nTemplate7.unregisterHelper = function unregisterHelper(name) {\n Template7Class.helpers[name] = undefined;\n delete Template7Class.helpers[name];\n};\nTemplate7.registerPartial = function registerPartial(name, template) {\n Template7Class.partials[name] = { template };\n};\nTemplate7.unregisterPartial = function unregisterPartial(name) {\n if (Template7Class.partials[name]) {\n Template7Class.partials[name] = undefined;\n delete Template7Class.partials[name];\n }\n};\nTemplate7.compile = function compile(template, options) {\n const instance = new Template7Class(template, options);\n return instance.compile();\n};\n\nTemplate7.options = Template7Class.options;\nTemplate7.helpers = Template7Class.helpers;\nTemplate7.partials = Template7Class.partials;\n\nexport default Template7;\n"],"names":["let","this","const"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/template7.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Template7 1.4.2 3 | * Mobile-first HTML template engine 4 | * 5 | * http://www.idangero.us/template7/ 6 | * 7 | * Copyright 2019, Vladimir Kharlampidi 8 | * The iDangero.us 9 | * http://www.idangero.us/ 10 | * 11 | * Licensed under MIT 12 | * 13 | * Released on: June 14, 2019 14 | */ 15 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Template7=t()}(this,function(){"use strict";var t7ctx;t7ctx="undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;var Template7Context=t7ctx,Template7Utils={quoteSingleRexExp:new RegExp("'","g"),quoteDoubleRexExp:new RegExp('"',"g"),isFunction:function(e){return"function"==typeof e},escape:function(e){return void 0===e&&(e=""),e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},helperToSlices:function(e){var t,r,i,n=Template7Utils.quoteDoubleRexExp,l=Template7Utils.quoteSingleRexExp,a=e.replace(/[{}#}]/g,"").trim().split(" "),s=[];for(r=0;r"===s,p=[],c={};for(r=1;r!%:?])/g).reduce(function(e,t){if(!t)return e;if(t.indexOf(i)<0)return e.push(t),e;if(!n)return e.push(JSON.stringify("")),e;var r=n;return 0<=t.indexOf(i+".")&&t.split(i+".")[1].split(".").forEach(function(e){r=e in r?r[e]:void 0}),("string"==typeof r||Array.isArray(r)||r.constructor&&r.constructor===Object)&&(r=JSON.stringify(r)),void 0===r&&(r="undefined"),e.push(r),e},[]).join("")},parseJsParents:function(e,n){return e.split(/([+ \-*^()&=|<>!%:?])/g).reduce(function(e,t){if(!t)return e;if(t.indexOf("../")<0)return e.push(t),e;if(!n||0===n.length)return e.push(JSON.stringify("")),e;var r=t.split("../").length-1,i=r>n.length?n[n.length-1]:n[r-1];return t.replace(/..\//g,"").split(".").forEach(function(e){i=void 0!==i[e]?i[e]:"undefined"}),!1===i||!0===i?e.push(JSON.stringify(i)):null===i||"undefined"===i?e.push(JSON.stringify("")):e.push(JSON.stringify(i)),e},[]).join("")},getCompileVar:function(e,t,r){void 0===r&&(r="data_1");var i,n,l=t,a=0;i=0===e.indexOf("../")?(a=e.split("../").length-1,l="ctx_"+(1<=(n=l.split("_")[1]-a)?n:1),e.split("../")[a].split(".")):0===e.indexOf("@global")?(l="Template7.global",e.split("@global.")[1].split(".")):0===e.indexOf("@root")?(l="root",e.split("@root.")[1].split(".")):e.split(".");for(var s=0;s/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n },\n helperToSlices: function helperToSlices(string) {\n var quoteDoubleRexExp = Template7Utils.quoteDoubleRexExp;\n var quoteSingleRexExp = Template7Utils.quoteSingleRexExp;\n var helperParts = string.replace(/[{}#}]/g, '').trim().split(' ');\n var slices = [];\n var shiftIndex;\n var i;\n var j;\n for (i = 0; i < helperParts.length; i += 1) {\n var part = helperParts[i];\n var blockQuoteRegExp = (void 0);\n var openingQuote = (void 0);\n if (i === 0) { slices.push(part); }\n else if (part.indexOf('\"') === 0 || part.indexOf('\\'') === 0) {\n blockQuoteRegExp = part.indexOf('\"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;\n openingQuote = part.indexOf('\"') === 0 ? '\"' : '\\'';\n // Plain String\n if (part.match(blockQuoteRegExp).length === 2) {\n // One word string\n slices.push(part);\n } else {\n // Find closed Index\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j += 1) {\n part += \" \" + (helperParts[j]);\n if (helperParts[j].indexOf(openingQuote) >= 0) {\n shiftIndex = j;\n slices.push(part);\n break;\n }\n }\n if (shiftIndex) { i = shiftIndex; }\n }\n } else if (part.indexOf('=') > 0) {\n // Hash\n var hashParts = part.split('=');\n var hashName = hashParts[0];\n var hashContent = hashParts[1];\n if (!blockQuoteRegExp) {\n blockQuoteRegExp = hashContent.indexOf('\"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;\n openingQuote = hashContent.indexOf('\"') === 0 ? '\"' : '\\'';\n }\n if (hashContent.match(blockQuoteRegExp).length !== 2) {\n shiftIndex = 0;\n for (j = i + 1; j < helperParts.length; j += 1) {\n hashContent += \" \" + (helperParts[j]);\n if (helperParts[j].indexOf(openingQuote) >= 0) {\n shiftIndex = j;\n break;\n }\n }\n if (shiftIndex) { i = shiftIndex; }\n }\n var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')];\n slices.push(hash);\n } else {\n // Plain variable\n slices.push(part);\n }\n }\n return slices;\n },\n stringToBlocks: function stringToBlocks(string) {\n var blocks = [];\n var i;\n var j;\n if (!string) { return []; }\n var stringBlocks = string.split(/({{[^{^}]*}})/);\n for (i = 0; i < stringBlocks.length; i += 1) {\n var block = stringBlocks[i];\n if (block === '') { continue; }\n if (block.indexOf('{{') < 0) {\n blocks.push({\n type: 'plain',\n content: block,\n });\n } else {\n if (block.indexOf('{/') >= 0) {\n continue;\n }\n block = block\n .replace(/{{([#/])*([ ])*/, '{{$1')\n .replace(/([ ])*}}/, '}}');\n if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {\n // Simple variable\n blocks.push({\n type: 'variable',\n contextName: block.replace(/[{}]/g, ''),\n });\n continue;\n }\n // Helpers\n var helperSlices = Template7Utils.helperToSlices(block);\n var helperName = helperSlices[0];\n var isPartial = helperName === '>';\n var helperContext = [];\n var helperHash = {};\n for (j = 1; j < helperSlices.length; j += 1) {\n var slice = helperSlices[j];\n if (Array.isArray(slice)) {\n // Hash\n helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];\n } else {\n helperContext.push(slice);\n }\n }\n\n if (block.indexOf('{#') >= 0) {\n // Condition/Helper\n var helperContent = '';\n var elseContent = '';\n var toSkip = 0;\n var shiftIndex = (void 0);\n var foundClosed = false;\n var foundElse = false;\n var depth = 0;\n for (j = i + 1; j < stringBlocks.length; j += 1) {\n if (stringBlocks[j].indexOf('{{#') >= 0) {\n depth += 1;\n }\n if (stringBlocks[j].indexOf('{{/') >= 0) {\n depth -= 1;\n }\n if (stringBlocks[j].indexOf((\"{{#\" + helperName)) >= 0) {\n helperContent += stringBlocks[j];\n if (foundElse) { elseContent += stringBlocks[j]; }\n toSkip += 1;\n } else if (stringBlocks[j].indexOf((\"{{/\" + helperName)) >= 0) {\n if (toSkip > 0) {\n toSkip -= 1;\n helperContent += stringBlocks[j];\n if (foundElse) { elseContent += stringBlocks[j]; }\n } else {\n shiftIndex = j;\n foundClosed = true;\n break;\n }\n } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) {\n foundElse = true;\n } else {\n if (!foundElse) { helperContent += stringBlocks[j]; }\n if (foundElse) { elseContent += stringBlocks[j]; }\n }\n }\n if (foundClosed) {\n if (shiftIndex) { i = shiftIndex; }\n if (helperName === 'raw') {\n blocks.push({\n type: 'plain',\n content: helperContent,\n });\n } else {\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n content: helperContent,\n inverseContent: elseContent,\n hash: helperHash,\n });\n }\n }\n } else if (block.indexOf(' ') > 0) {\n if (isPartial) {\n helperName = '_partial';\n if (helperContext[0]) {\n if (helperContext[0].indexOf('[') === 0) { helperContext[0] = helperContext[0].replace(/[[\\]]/g, ''); }\n else { helperContext[0] = \"\\\"\" + (helperContext[0].replace(/\"|'/g, '')) + \"\\\"\"; }\n }\n }\n blocks.push({\n type: 'helper',\n helperName: helperName,\n contextName: helperContext,\n hash: helperHash,\n });\n }\n }\n }\n return blocks;\n },\n parseJsVariable: function parseJsVariable(expression, replace, object) {\n return expression.split(/([+ \\-*/^()&=|<>!%:?])/g).reduce(function (arr, part) {\n if (!part) {\n return arr;\n }\n if (part.indexOf(replace) < 0) {\n arr.push(part);\n return arr;\n }\n if (!object) {\n arr.push(JSON.stringify(''));\n return arr;\n }\n\n var variable = object;\n if (part.indexOf((replace + \".\")) >= 0) {\n part.split((replace + \".\"))[1].split('.').forEach(function (partName) {\n if (partName in variable) { variable = variable[partName]; }\n else { variable = undefined; }\n });\n }\n if (\n (typeof variable === 'string')\n || Array.isArray(variable)\n || (variable.constructor && variable.constructor === Object)\n ) {\n variable = JSON.stringify(variable);\n }\n if (variable === undefined) { variable = 'undefined'; }\n\n arr.push(variable);\n return arr;\n }, []).join('');\n\n },\n parseJsParents: function parseJsParents(expression, parents) {\n return expression.split(/([+ \\-*^()&=|<>!%:?])/g).reduce(function (arr, part) {\n if (!part) {\n return arr;\n }\n\n if (part.indexOf('../') < 0) {\n arr.push(part);\n return arr;\n }\n\n if (!parents || parents.length === 0) {\n arr.push(JSON.stringify(''));\n return arr;\n }\n\n var levelsUp = part.split('../').length - 1;\n var parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1];\n\n var variable = parentData;\n var parentPart = part.replace(/..\\//g, '');\n parentPart.split('.').forEach(function (partName) {\n if (typeof variable[partName] !== 'undefined') { variable = variable[partName]; }\n else { variable = 'undefined'; }\n });\n if (variable === false || variable === true) {\n arr.push(JSON.stringify(variable));\n return arr;\n }\n if (variable === null || variable === 'undefined') {\n arr.push(JSON.stringify(''));\n return arr;\n }\n arr.push(JSON.stringify(variable));\n return arr;\n }, []).join('');\n },\n getCompileVar: function getCompileVar(name, ctx, data) {\n if ( data === void 0 ) data = 'data_1';\n\n var variable = ctx;\n var parts;\n var levelsUp = 0;\n var newDepth;\n if (name.indexOf('../') === 0) {\n levelsUp = name.split('../').length - 1;\n newDepth = variable.split('_')[1] - levelsUp;\n variable = \"ctx_\" + (newDepth >= 1 ? newDepth : 1);\n parts = name.split('../')[levelsUp].split('.');\n } else if (name.indexOf('@global') === 0) {\n variable = 'Template7.global';\n parts = name.split('@global.')[1].split('.');\n } else if (name.indexOf('@root') === 0) {\n variable = 'root';\n parts = name.split('@root.')[1].split('.');\n } else {\n parts = name.split('.');\n }\n for (var i = 0; i < parts.length; i += 1) {\n var part = parts[i];\n if (part.indexOf('@') === 0) {\n var dataLevel = data.split('_')[1];\n if (levelsUp > 0) {\n dataLevel = newDepth;\n }\n if (i > 0) {\n variable += \"[(data_\" + dataLevel + \" && data_\" + dataLevel + \".\" + (part.replace('@', '')) + \")]\";\n } else {\n variable = \"(data_\" + dataLevel + \" && data_\" + dataLevel + \".\" + (part.replace('@', '')) + \")\";\n }\n } else if (Number.isFinite ? Number.isFinite(part) : Template7Context.isFinite(part)) {\n variable += \"[\" + part + \"]\";\n } else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) {\n variable = part.replace('this', ctx);\n } else {\n variable += \".\" + part;\n }\n }\n return variable;\n },\n getCompiledArguments: function getCompiledArguments(contextArray, ctx, data) {\n var arr = [];\n for (var i = 0; i < contextArray.length; i += 1) {\n if (/^['\"]/.test(contextArray[i])) { arr.push(contextArray[i]); }\n else if (/^(true|false|\\d+)$/.test(contextArray[i])) { arr.push(contextArray[i]); }\n else {\n arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data));\n }\n }\n\n return arr.join(', ');\n },\n };\n\n /* eslint no-eval: \"off\" */\n\n var Template7Helpers = {\n _partial: function _partial(partialName, options) {\n var ctx = this;\n var p = Template7Class.partials[partialName];\n if (!p || (p && !p.template)) { return ''; }\n if (!p.compiled) {\n p.compiled = new Template7Class(p.template).compile();\n }\n Object.keys(options.hash).forEach(function (hashName) {\n ctx[hashName] = options.hash[hashName];\n });\n return p.compiled(ctx, options.data, options.root);\n },\n escape: function escape(context) {\n if (typeof context === 'undefined' || context === null) { return ''; }\n if (typeof context !== 'string') {\n throw new Error('Template7: Passed context to \"escape\" helper should be a string');\n }\n return Template7Utils.escape(context);\n },\n if: function if$1(context, options) {\n var ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (ctx) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n unless: function unless(context, options) {\n var ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (!ctx) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n each: function each(context, options) {\n var ctx = context;\n var ret = '';\n var i = 0;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n if (Array.isArray(ctx)) {\n if (options.hash.reverse) {\n ctx = ctx.reverse();\n }\n for (i = 0; i < ctx.length; i += 1) {\n ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i });\n }\n if (options.hash.reverse) {\n ctx = ctx.reverse();\n }\n } else {\n // eslint-disable-next-line\n for (var key in ctx) {\n i += 1;\n ret += options.fn(ctx[key], { key: key });\n }\n }\n if (i > 0) { return ret; }\n return options.inverse(this);\n },\n with: function with$1(context, options) {\n var ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); }\n return options.fn(ctx);\n },\n join: function join(context, options) {\n var ctx = context;\n if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }\n return ctx.join(options.hash.delimiter || options.hash.delimeter);\n },\n js: function js(expression, options) {\n var data = options.data;\n var func;\n var execute = expression;\n ('index first last key').split(' ').forEach(function (prop) {\n if (typeof data[prop] !== 'undefined') {\n var re1 = new RegExp((\"this.@\" + prop), 'g');\n var re2 = new RegExp((\"@\" + prop), 'g');\n execute = execute\n .replace(re1, JSON.stringify(data[prop]))\n .replace(re2, JSON.stringify(data[prop]));\n }\n });\n if (options.root && execute.indexOf('@root') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@root', options.root);\n }\n if (execute.indexOf('@global') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);\n }\n if (execute.indexOf('../') >= 0) {\n execute = Template7Utils.parseJsParents(execute, options.parents);\n }\n if (execute.indexOf('return') >= 0) {\n func = \"(function(){\" + execute + \"})\";\n } else {\n func = \"(function(){return (\" + execute + \")})\";\n }\n return eval(func).call(this);\n },\n js_if: function js_if(expression, options) {\n var data = options.data;\n var func;\n var execute = expression;\n ('index first last key').split(' ').forEach(function (prop) {\n if (typeof data[prop] !== 'undefined') {\n var re1 = new RegExp((\"this.@\" + prop), 'g');\n var re2 = new RegExp((\"@\" + prop), 'g');\n execute = execute\n .replace(re1, JSON.stringify(data[prop]))\n .replace(re2, JSON.stringify(data[prop]));\n }\n });\n if (options.root && execute.indexOf('@root') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@root', options.root);\n }\n if (execute.indexOf('@global') >= 0) {\n execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);\n }\n if (execute.indexOf('../') >= 0) {\n execute = Template7Utils.parseJsParents(execute, options.parents);\n }\n if (execute.indexOf('return') >= 0) {\n func = \"(function(){\" + execute + \"})\";\n } else {\n func = \"(function(){return (\" + execute + \")})\";\n }\n var condition = eval(func).call(this);\n if (condition) {\n return options.fn(this, options.data);\n }\n\n return options.inverse(this, options.data);\n },\n };\n Template7Helpers.js_compare = Template7Helpers.js_if;\n\n var Template7Options = {};\n var Template7Partials = {};\n\n var Template7Class = function Template7Class(template) {\n var t = this;\n t.template = template;\n };\n\n var staticAccessors = { options: { configurable: true },partials: { configurable: true },helpers: { configurable: true } };\n Template7Class.prototype.compile = function compile (template, depth) {\n if ( template === void 0 ) template = this.template;\n if ( depth === void 0 ) depth = 1;\n\n var t = this;\n if (t.compiled) { return t.compiled; }\n\n if (typeof template !== 'string') {\n throw new Error('Template7: Template must be a string');\n }\n var stringToBlocks = Template7Utils.stringToBlocks;\n var getCompileVar = Template7Utils.getCompileVar;\n var getCompiledArguments = Template7Utils.getCompiledArguments;\n\n var blocks = stringToBlocks(template);\n var ctx = \"ctx_\" + depth;\n var data = \"data_\" + depth;\n if (blocks.length === 0) {\n return function empty() { return ''; };\n }\n\n function getCompileFn(block, newDepth) {\n if (block.content) { return t.compile(block.content, newDepth); }\n return function empty() { return ''; };\n }\n function getCompileInverse(block, newDepth) {\n if (block.inverseContent) { return t.compile(block.inverseContent, newDepth); }\n return function empty() { return ''; };\n }\n\n var resultString = '';\n if (depth === 1) {\n resultString += \"(function (\" + ctx + \", \" + data + \", root) {\\n\";\n } else {\n resultString += \"(function (\" + ctx + \", \" + data + \") {\\n\";\n }\n if (depth === 1) {\n resultString += 'function isArray(arr){return Array.isArray(arr);}\\n';\n resultString += 'function isFunction(func){return (typeof func === \\'function\\');}\\n';\n resultString += 'function c(val, ctx) {if (typeof val !== \"undefined\" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return \"\";}\\n';\n resultString += 'root = root || ctx_1 || {};\\n';\n }\n resultString += 'var r = \\'\\';\\n';\n var i;\n for (i = 0; i < blocks.length; i += 1) {\n var block = blocks[i];\n // Plain block\n if (block.type === 'plain') {\n // eslint-disable-next-line\n resultString += \"r +='\" + ((block.content).replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n').replace(/'/g, '\\\\' + '\\'')) + \"';\";\n continue;\n }\n var variable = (void 0);\n var compiledArguments = (void 0);\n // Variable block\n if (block.type === 'variable') {\n variable = getCompileVar(block.contextName, ctx, data);\n resultString += \"r += c(\" + variable + \", \" + ctx + \");\";\n }\n // Helpers block\n if (block.type === 'helper') {\n var parents = (void 0);\n if (ctx !== 'ctx_1') {\n var level = ctx.split('_')[1];\n var parentsString = \"ctx_\" + (level - 1);\n for (var j = level - 2; j >= 1; j -= 1) {\n parentsString += \", ctx_\" + j;\n }\n parents = \"[\" + parentsString + \"]\";\n } else {\n parents = \"[\" + ctx + \"]\";\n }\n var dynamicHelper = (void 0);\n if (block.helperName.indexOf('[') === 0) {\n block.helperName = getCompileVar(block.helperName.replace(/[[\\]]/g, ''), ctx, data);\n dynamicHelper = true;\n }\n if (dynamicHelper || block.helperName in Template7Helpers) {\n compiledArguments = getCompiledArguments(block.contextName, ctx, data);\n resultString += \"r += (Template7Helpers\" + (dynamicHelper ? (\"[\" + (block.helperName) + \"]\") : (\".\" + (block.helperName))) + \").call(\" + ctx + \", \" + (compiledArguments && ((compiledArguments + \", \"))) + \"{hash:\" + (JSON.stringify(block.hash)) + \", data: \" + data + \" || {}, fn: \" + (getCompileFn(block, depth + 1)) + \", inverse: \" + (getCompileInverse(block, depth + 1)) + \", root: root, parents: \" + parents + \"});\";\n } else if (block.contextName.length > 0) {\n throw new Error((\"Template7: Missing helper: \\\"\" + (block.helperName) + \"\\\"\"));\n } else {\n variable = getCompileVar(block.helperName, ctx, data);\n resultString += \"if (\" + variable + \") {\";\n resultString += \"if (isArray(\" + variable + \")) {\";\n resultString += \"r += (Template7Helpers.each).call(\" + ctx + \", \" + variable + \", {hash:\" + (JSON.stringify(block.hash)) + \", data: \" + data + \" || {}, fn: \" + (getCompileFn(block, depth + 1)) + \", inverse: \" + (getCompileInverse(block, depth + 1)) + \", root: root, parents: \" + parents + \"});\";\n resultString += '}else {';\n resultString += \"r += (Template7Helpers.with).call(\" + ctx + \", \" + variable + \", {hash:\" + (JSON.stringify(block.hash)) + \", data: \" + data + \" || {}, fn: \" + (getCompileFn(block, depth + 1)) + \", inverse: \" + (getCompileInverse(block, depth + 1)) + \", root: root, parents: \" + parents + \"});\";\n resultString += '}}';\n }\n }\n }\n resultString += '\\nreturn r;})';\n\n if (depth === 1) {\n // eslint-disable-next-line\n t.compiled = eval(resultString);\n return t.compiled;\n }\n return resultString;\n };\n staticAccessors.options.get = function () {\n return Template7Options;\n };\n staticAccessors.partials.get = function () {\n return Template7Partials;\n };\n staticAccessors.helpers.get = function () {\n return Template7Helpers;\n };\n\n Object.defineProperties( Template7Class, staticAccessors );\n\n function Template7() {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var template = args[0];\n var data = args[1];\n if (args.length === 2) {\n var instance = new Template7Class(template);\n var rendered = instance.compile()(data);\n instance = null;\n return (rendered);\n }\n return new Template7Class(template);\n }\n Template7.registerHelper = function registerHelper(name, fn) {\n Template7Class.helpers[name] = fn;\n };\n Template7.unregisterHelper = function unregisterHelper(name) {\n Template7Class.helpers[name] = undefined;\n delete Template7Class.helpers[name];\n };\n Template7.registerPartial = function registerPartial(name, template) {\n Template7Class.partials[name] = { template: template };\n };\n Template7.unregisterPartial = function unregisterPartial(name) {\n if (Template7Class.partials[name]) {\n Template7Class.partials[name] = undefined;\n delete Template7Class.partials[name];\n }\n };\n Template7.compile = function compile(template, options) {\n var instance = new Template7Class(template, options);\n return instance.compile();\n };\n\n Template7.options = Template7Class.options;\n Template7.helpers = Template7Class.helpers;\n Template7.partials = Template7Class.partials;\n\n return Template7;\n\n}));\n//# sourceMappingURL=template7.js.map\n"]} -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const gulp = require('gulp'); 3 | const connect = require('gulp-connect'); 4 | const open = require('gulp-open'); 5 | const rename = require('gulp-rename'); 6 | const header = require('gulp-header'); 7 | const uglify = require('gulp-uglify'); 8 | const sourcemaps = require('gulp-sourcemaps'); 9 | const rollup = require('rollup'); 10 | const buble = require('rollup-plugin-buble'); 11 | const pkg = require('./package.json'); 12 | 13 | const paths = { 14 | root: './', 15 | build: 'build/', 16 | dist: 'dist/', 17 | demo: 'demo/', 18 | source: 'src/', 19 | }; 20 | 21 | const date = { 22 | year: new Date().getFullYear(), 23 | month: ('January February March April May June July August September October November December').split(' ')[new Date().getMonth()], 24 | day: new Date().getDate(), 25 | }; 26 | 27 | const t7 = { 28 | filename: 'template7', 29 | pkg, 30 | banner: [ 31 | '/**', 32 | ` * Template7 ${pkg.version}`, 33 | ` * ${pkg.description}`, 34 | ' * ', 35 | ` * ${pkg.homepage}`, 36 | ' * ', 37 | ` * Copyright ${date.year}, ${pkg.author}`, 38 | ' * The iDangero.us', 39 | ' * http://www.idangero.us/', 40 | ' * ', 41 | ` * Licensed under ${pkg.license}`, 42 | ' * ', 43 | ` * Released on: ${date.month} ${date.day}, ${date.year}`, 44 | ' */', 45 | ''].join('\n'), 46 | }; 47 | 48 | // Build 49 | gulp.task('build', (cb) => { 50 | fs.copyFileSync('./src/template7.d.ts', './build/template7.d.ts'); 51 | rollup.rollup({ 52 | input: './src/template7.js', 53 | plugins: [buble()], 54 | }).then((bundle) => { // eslint-disable-line 55 | return bundle.write({ 56 | strict: true, 57 | file: './build/template7.js', 58 | format: 'umd', 59 | name: 'Template7', 60 | sourcemap: true, 61 | sourcemapFile: './build/template7.js.map', 62 | }); 63 | }).then(() => { 64 | cb(); 65 | }); 66 | }); 67 | 68 | function umd(cb) { 69 | rollup.rollup({ 70 | input: './src/template7.js', 71 | plugins: [buble()], 72 | }).then((bundle) => { // eslint-disable-line 73 | return bundle.write({ 74 | strict: true, 75 | file: './dist/template7.js', 76 | format: 'umd', 77 | name: 'Template7', 78 | sourcemap: true, 79 | sourcemapFile: './dist/template7.js.map', 80 | banner: t7.banner, 81 | }); 82 | }).then(() => { 83 | gulp.src('./dist/template7.js') 84 | .pipe(sourcemaps.init()) 85 | .pipe(uglify()) 86 | .pipe(header(t7.banner)) 87 | .pipe(rename('template7.min.js')) 88 | .pipe(sourcemaps.write('./')) 89 | .pipe(gulp.dest('./dist/')) 90 | .on('end', () => { 91 | if (cb) cb(); 92 | }); 93 | }); 94 | } 95 | function es(cb) { 96 | rollup.rollup({ 97 | input: './src/template7.js', 98 | }).then((bundle) => { // eslint-disable-line 99 | return bundle.write({ 100 | strict: true, 101 | file: './dist/template7.esm.js', 102 | format: 'es', 103 | name: 'Template7', 104 | banner: t7.banner, 105 | }); 106 | }).then(() => { 107 | cb(); 108 | }); 109 | } 110 | // Dist 111 | gulp.task('dist', (cb) => { 112 | let cbs = 0; 113 | fs.copyFileSync('./src/template7.d.ts', './dist/template7.d.ts'); 114 | umd(() => { 115 | cbs += 1; 116 | if (cbs === 2) cb(); 117 | }); 118 | es(() => { 119 | cbs += 1; 120 | if (cbs === 2) cb(); 121 | }); 122 | }); 123 | 124 | gulp.task('watch', () => { 125 | gulp.watch('./src/*.js', gulp.series(['build'])); 126 | }); 127 | 128 | gulp.task('connect', () => connect.server({ 129 | root: [paths.root], 130 | livereload: true, 131 | port: '3000', 132 | })); 133 | 134 | gulp.task('open', () => gulp.src(`${paths.demo}index.html`).pipe(open({ uri: `http://localhost:3000/${paths.demo}index.html` }))); 135 | 136 | gulp.task('server', gulp.parallel(['watch', 'connect', 'open'])); 137 | 138 | gulp.task('default', gulp.series(['server'])); 139 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template7", 3 | "version": "1.4.2", 4 | "description": "Mobile-first HTML template engine", 5 | "main": "dist/template7.js", 6 | "types": "dist/template7.d.ts", 7 | "jsnext:main": "dist/template7.esm.js", 8 | "module": "dist/template7.esm.js", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/nolimits4web/template7.git" 12 | }, 13 | "scripts": { 14 | "lint": "eslint .", 15 | "test": "gulp build && npm run lint" 16 | }, 17 | "keywords": [ 18 | "mobile", 19 | "template", 20 | "javascript", 21 | "ios7", 22 | "ios8", 23 | "ios 8", 24 | "iphone", 25 | "ipad", 26 | "phonegap", 27 | "framework7", 28 | "handlebars", 29 | "mustache" 30 | ], 31 | "author": "Vladimir Kharlampidi", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/nolimits4web/template7/issues" 35 | }, 36 | "homepage": "http://www.idangero.us/template7/", 37 | "engines": { 38 | "node": ">= 0.10.0" 39 | }, 40 | "devDependencies": { 41 | "eslint": "^4.9.0", 42 | "eslint-config-airbnb": "^16.1.0", 43 | "eslint-config-airbnb-base": "^12.1.0", 44 | "eslint-plugin-import": "^2.8.0", 45 | "eslint-plugin-jsx-a11y": "^6.0.2", 46 | "eslint-plugin-react": "^7.4.0", 47 | "gulp": "^4.0.0", 48 | "gulp-connect": "^5.7.0", 49 | "gulp-header": "^2.0.7", 50 | "gulp-open": "^3.0.1", 51 | "gulp-rename": "^1.4.0", 52 | "gulp-sourcemaps": "^2.6.4", 53 | "gulp-uglify": "^3.0.1", 54 | "rollup": "^1.1.2", 55 | "rollup-plugin-buble": "^0.19.6" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/context.js: -------------------------------------------------------------------------------- 1 | let t7ctx; 2 | if (typeof window !== 'undefined') { 3 | t7ctx = window; 4 | } else if (typeof global !== 'undefined') { 5 | t7ctx = global; 6 | } else { 7 | t7ctx = this; 8 | } 9 | 10 | const Template7Context = t7ctx; 11 | 12 | export default Template7Context; 13 | -------------------------------------------------------------------------------- /src/helpers.js: -------------------------------------------------------------------------------- 1 | /* eslint no-eval: "off" */ 2 | import Template7Utils from './utils'; 3 | import Template7Class from './template7-class'; 4 | import Template7Context from './context'; 5 | 6 | const Template7Helpers = { 7 | _partial(partialName, options) { 8 | const ctx = this; 9 | const p = Template7Class.partials[partialName]; 10 | if (!p || (p && !p.template)) return ''; 11 | if (!p.compiled) { 12 | p.compiled = new Template7Class(p.template).compile(); 13 | } 14 | Object.keys(options.hash).forEach((hashName) => { 15 | ctx[hashName] = options.hash[hashName]; 16 | }); 17 | return p.compiled(ctx, options.data, options.root); 18 | }, 19 | escape(context) { 20 | if (typeof context === 'undefined' || context === null) return ''; 21 | if (typeof context !== 'string') { 22 | throw new Error('Template7: Passed context to "escape" helper should be a string'); 23 | } 24 | return Template7Utils.escape(context); 25 | }, 26 | if(context, options) { 27 | let ctx = context; 28 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 29 | if (ctx) { 30 | return options.fn(this, options.data); 31 | } 32 | 33 | return options.inverse(this, options.data); 34 | }, 35 | unless(context, options) { 36 | let ctx = context; 37 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 38 | if (!ctx) { 39 | return options.fn(this, options.data); 40 | } 41 | 42 | return options.inverse(this, options.data); 43 | }, 44 | each(context, options) { 45 | let ctx = context; 46 | let ret = ''; 47 | let i = 0; 48 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 49 | if (Array.isArray(ctx)) { 50 | if (options.hash.reverse) { 51 | ctx = ctx.reverse(); 52 | } 53 | for (i = 0; i < ctx.length; i += 1) { 54 | ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); 55 | } 56 | if (options.hash.reverse) { 57 | ctx = ctx.reverse(); 58 | } 59 | } else { 60 | // eslint-disable-next-line 61 | for (const key in ctx) { 62 | i += 1; 63 | ret += options.fn(ctx[key], { key }); 64 | } 65 | } 66 | if (i > 0) return ret; 67 | return options.inverse(this); 68 | }, 69 | with(context, options) { 70 | let ctx = context; 71 | if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); } 72 | return options.fn(ctx); 73 | }, 74 | join(context, options) { 75 | let ctx = context; 76 | if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } 77 | return ctx.join(options.hash.delimiter || options.hash.delimeter); 78 | }, 79 | js(expression, options) { 80 | const data = options.data; 81 | let func; 82 | let execute = expression; 83 | ('index first last key').split(' ').forEach((prop) => { 84 | if (typeof data[prop] !== 'undefined') { 85 | const re1 = new RegExp(`this.@${prop}`, 'g'); 86 | const re2 = new RegExp(`@${prop}`, 'g'); 87 | execute = execute 88 | .replace(re1, JSON.stringify(data[prop])) 89 | .replace(re2, JSON.stringify(data[prop])); 90 | } 91 | }); 92 | if (options.root && execute.indexOf('@root') >= 0) { 93 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 94 | } 95 | if (execute.indexOf('@global') >= 0) { 96 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 97 | } 98 | if (execute.indexOf('../') >= 0) { 99 | execute = Template7Utils.parseJsParents(execute, options.parents); 100 | } 101 | if (execute.indexOf('return') >= 0) { 102 | func = `(function(){${execute}})`; 103 | } else { 104 | func = `(function(){return (${execute})})`; 105 | } 106 | return eval(func).call(this); 107 | }, 108 | js_if(expression, options) { 109 | const data = options.data; 110 | let func; 111 | let execute = expression; 112 | ('index first last key').split(' ').forEach((prop) => { 113 | if (typeof data[prop] !== 'undefined') { 114 | const re1 = new RegExp(`this.@${prop}`, 'g'); 115 | const re2 = new RegExp(`@${prop}`, 'g'); 116 | execute = execute 117 | .replace(re1, JSON.stringify(data[prop])) 118 | .replace(re2, JSON.stringify(data[prop])); 119 | } 120 | }); 121 | if (options.root && execute.indexOf('@root') >= 0) { 122 | execute = Template7Utils.parseJsVariable(execute, '@root', options.root); 123 | } 124 | if (execute.indexOf('@global') >= 0) { 125 | execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); 126 | } 127 | if (execute.indexOf('../') >= 0) { 128 | execute = Template7Utils.parseJsParents(execute, options.parents); 129 | } 130 | if (execute.indexOf('return') >= 0) { 131 | func = `(function(){${execute}})`; 132 | } else { 133 | func = `(function(){return (${execute})})`; 134 | } 135 | const condition = eval(func).call(this); 136 | if (condition) { 137 | return options.fn(this, options.data); 138 | } 139 | 140 | return options.inverse(this, options.data); 141 | }, 142 | }; 143 | Template7Helpers.js_compare = Template7Helpers.js_if; 144 | 145 | export default Template7Helpers; 146 | -------------------------------------------------------------------------------- /src/template7-class.js: -------------------------------------------------------------------------------- 1 | import Template7Utils from './utils'; 2 | import Template7Helpers from './helpers'; 3 | 4 | const Template7Options = {}; 5 | const Template7Partials = {}; 6 | 7 | class Template7Class { 8 | constructor(template) { 9 | const t = this; 10 | t.template = template; 11 | } 12 | compile(template = this.template, depth = 1) { 13 | const t = this; 14 | if (t.compiled) return t.compiled; 15 | 16 | if (typeof template !== 'string') { 17 | throw new Error('Template7: Template must be a string'); 18 | } 19 | const { stringToBlocks, getCompileVar, getCompiledArguments } = Template7Utils; 20 | 21 | const blocks = stringToBlocks(template); 22 | const ctx = `ctx_${depth}`; 23 | const data = `data_${depth}`; 24 | if (blocks.length === 0) { 25 | return function empty() { return ''; }; 26 | } 27 | 28 | function getCompileFn(block, newDepth) { 29 | if (block.content) return t.compile(block.content, newDepth); 30 | return function empty() { return ''; }; 31 | } 32 | function getCompileInverse(block, newDepth) { 33 | if (block.inverseContent) return t.compile(block.inverseContent, newDepth); 34 | return function empty() { return ''; }; 35 | } 36 | 37 | let resultString = ''; 38 | if (depth === 1) { 39 | resultString += `(function (${ctx}, ${data}, root) {\n`; 40 | } else { 41 | resultString += `(function (${ctx}, ${data}) {\n`; 42 | } 43 | if (depth === 1) { 44 | resultString += 'function isArray(arr){return Array.isArray(arr);}\n'; 45 | resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; 46 | resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; 47 | resultString += 'root = root || ctx_1 || {};\n'; 48 | } 49 | resultString += 'var r = \'\';\n'; 50 | let i; 51 | for (i = 0; i < blocks.length; i += 1) { 52 | const block = blocks[i]; 53 | // Plain block 54 | if (block.type === 'plain') { 55 | // eslint-disable-next-line 56 | resultString += `r +='${(block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')}';`; 57 | continue; 58 | } 59 | let variable; 60 | let compiledArguments; 61 | // Variable block 62 | if (block.type === 'variable') { 63 | variable = getCompileVar(block.contextName, ctx, data); 64 | resultString += `r += c(${variable}, ${ctx});`; 65 | } 66 | // Helpers block 67 | if (block.type === 'helper') { 68 | let parents; 69 | if (ctx !== 'ctx_1') { 70 | const level = ctx.split('_')[1]; 71 | let parentsString = `ctx_${level - 1}`; 72 | for (let j = level - 2; j >= 1; j -= 1) { 73 | parentsString += `, ctx_${j}`; 74 | } 75 | parents = `[${parentsString}]`; 76 | } else { 77 | parents = `[${ctx}]`; 78 | } 79 | let dynamicHelper; 80 | if (block.helperName.indexOf('[') === 0) { 81 | block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data); 82 | dynamicHelper = true; 83 | } 84 | if (dynamicHelper || block.helperName in Template7Helpers) { 85 | compiledArguments = getCompiledArguments(block.contextName, ctx, data); 86 | resultString += `r += (Template7Helpers${dynamicHelper ? `[${block.helperName}]` : `.${block.helperName}`}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 87 | } else if (block.contextName.length > 0) { 88 | throw new Error(`Template7: Missing helper: "${block.helperName}"`); 89 | } else { 90 | variable = getCompileVar(block.helperName, ctx, data); 91 | resultString += `if (${variable}) {`; 92 | resultString += `if (isArray(${variable})) {`; 93 | resultString += `r += (Template7Helpers.each).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 94 | resultString += '}else {'; 95 | resultString += `r += (Template7Helpers.with).call(${ctx}, ${variable}, {hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; 96 | resultString += '}}'; 97 | } 98 | } 99 | } 100 | resultString += '\nreturn r;})'; 101 | 102 | if (depth === 1) { 103 | // eslint-disable-next-line 104 | t.compiled = eval(resultString); 105 | return t.compiled; 106 | } 107 | return resultString; 108 | } 109 | static get options() { 110 | return Template7Options; 111 | } 112 | static get partials() { 113 | return Template7Partials; 114 | } 115 | static get helpers() { 116 | return Template7Helpers; 117 | } 118 | } 119 | export default Template7Class; 120 | -------------------------------------------------------------------------------- /src/template7.d.ts: -------------------------------------------------------------------------------- 1 | interface Template7{ 2 | global?: any 3 | templates?: any; 4 | compile? (string: string): any; 5 | registerHelper? (name: string, helper: Function): any; 6 | unregisterHelper? (name: string) : void; 7 | registerPartial? (name: string, template: string) : void; 8 | unregisterPartial? (name: string) : void; 9 | } 10 | 11 | declare const Template7 : Template7; 12 | 13 | export default Template7 14 | -------------------------------------------------------------------------------- /src/template7.js: -------------------------------------------------------------------------------- 1 | import Template7Class from './template7-class'; 2 | 3 | function Template7(...args) { 4 | const [template, data] = args; 5 | if (args.length === 2) { 6 | let instance = new Template7Class(template); 7 | const rendered = instance.compile()(data); 8 | instance = null; 9 | return (rendered); 10 | } 11 | return new Template7Class(template); 12 | } 13 | Template7.registerHelper = function registerHelper(name, fn) { 14 | Template7Class.helpers[name] = fn; 15 | }; 16 | Template7.unregisterHelper = function unregisterHelper(name) { 17 | Template7Class.helpers[name] = undefined; 18 | delete Template7Class.helpers[name]; 19 | }; 20 | Template7.registerPartial = function registerPartial(name, template) { 21 | Template7Class.partials[name] = { template }; 22 | }; 23 | Template7.unregisterPartial = function unregisterPartial(name) { 24 | if (Template7Class.partials[name]) { 25 | Template7Class.partials[name] = undefined; 26 | delete Template7Class.partials[name]; 27 | } 28 | }; 29 | Template7.compile = function compile(template, options) { 30 | const instance = new Template7Class(template, options); 31 | return instance.compile(); 32 | }; 33 | 34 | Template7.options = Template7Class.options; 35 | Template7.helpers = Template7Class.helpers; 36 | Template7.partials = Template7Class.partials; 37 | 38 | export default Template7; 39 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | import Template7Context from './context'; 2 | 3 | const Template7Utils = { 4 | quoteSingleRexExp: new RegExp('\'', 'g'), 5 | quoteDoubleRexExp: new RegExp('"', 'g'), 6 | isFunction(func) { 7 | return typeof func === 'function'; 8 | }, 9 | escape(string = '') { 10 | return string 11 | .replace(/&/g, '&') 12 | .replace(//g, '>') 14 | .replace(/"/g, '"') 15 | .replace(/'/g, '''); 16 | }, 17 | helperToSlices(string) { 18 | const { quoteDoubleRexExp, quoteSingleRexExp } = Template7Utils; 19 | const helperParts = string.replace(/[{}#}]/g, '').trim().split(' '); 20 | const slices = []; 21 | let shiftIndex; 22 | let i; 23 | let j; 24 | for (i = 0; i < helperParts.length; i += 1) { 25 | let part = helperParts[i]; 26 | let blockQuoteRegExp; 27 | let openingQuote; 28 | if (i === 0) slices.push(part); 29 | else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { 30 | blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 31 | openingQuote = part.indexOf('"') === 0 ? '"' : '\''; 32 | // Plain String 33 | if (part.match(blockQuoteRegExp).length === 2) { 34 | // One word string 35 | slices.push(part); 36 | } else { 37 | // Find closed Index 38 | shiftIndex = 0; 39 | for (j = i + 1; j < helperParts.length; j += 1) { 40 | part += ` ${helperParts[j]}`; 41 | if (helperParts[j].indexOf(openingQuote) >= 0) { 42 | shiftIndex = j; 43 | slices.push(part); 44 | break; 45 | } 46 | } 47 | if (shiftIndex) i = shiftIndex; 48 | } 49 | } else if (part.indexOf('=') > 0) { 50 | // Hash 51 | const hashParts = part.split('='); 52 | const hashName = hashParts[0]; 53 | let hashContent = hashParts[1]; 54 | if (!blockQuoteRegExp) { 55 | blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; 56 | openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; 57 | } 58 | if (hashContent.match(blockQuoteRegExp).length !== 2) { 59 | shiftIndex = 0; 60 | for (j = i + 1; j < helperParts.length; j += 1) { 61 | hashContent += ` ${helperParts[j]}`; 62 | if (helperParts[j].indexOf(openingQuote) >= 0) { 63 | shiftIndex = j; 64 | break; 65 | } 66 | } 67 | if (shiftIndex) i = shiftIndex; 68 | } 69 | const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; 70 | slices.push(hash); 71 | } else { 72 | // Plain variable 73 | slices.push(part); 74 | } 75 | } 76 | return slices; 77 | }, 78 | stringToBlocks(string) { 79 | const blocks = []; 80 | let i; 81 | let j; 82 | if (!string) return []; 83 | const stringBlocks = string.split(/({{[^{^}]*}})/); 84 | for (i = 0; i < stringBlocks.length; i += 1) { 85 | let block = stringBlocks[i]; 86 | if (block === '') continue; 87 | if (block.indexOf('{{') < 0) { 88 | blocks.push({ 89 | type: 'plain', 90 | content: block, 91 | }); 92 | } else { 93 | if (block.indexOf('{/') >= 0) { 94 | continue; 95 | } 96 | block = block 97 | .replace(/{{([#/])*([ ])*/, '{{$1') 98 | .replace(/([ ])*}}/, '}}'); 99 | if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { 100 | // Simple variable 101 | blocks.push({ 102 | type: 'variable', 103 | contextName: block.replace(/[{}]/g, ''), 104 | }); 105 | continue; 106 | } 107 | // Helpers 108 | const helperSlices = Template7Utils.helperToSlices(block); 109 | let helperName = helperSlices[0]; 110 | const isPartial = helperName === '>'; 111 | const helperContext = []; 112 | const helperHash = {}; 113 | for (j = 1; j < helperSlices.length; j += 1) { 114 | const slice = helperSlices[j]; 115 | if (Array.isArray(slice)) { 116 | // Hash 117 | helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; 118 | } else { 119 | helperContext.push(slice); 120 | } 121 | } 122 | 123 | if (block.indexOf('{#') >= 0) { 124 | // Condition/Helper 125 | let helperContent = ''; 126 | let elseContent = ''; 127 | let toSkip = 0; 128 | let shiftIndex; 129 | let foundClosed = false; 130 | let foundElse = false; 131 | let depth = 0; 132 | for (j = i + 1; j < stringBlocks.length; j += 1) { 133 | if (stringBlocks[j].indexOf('{{#') >= 0) { 134 | depth += 1; 135 | } 136 | if (stringBlocks[j].indexOf('{{/') >= 0) { 137 | depth -= 1; 138 | } 139 | if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) { 140 | helperContent += stringBlocks[j]; 141 | if (foundElse) elseContent += stringBlocks[j]; 142 | toSkip += 1; 143 | } else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) { 144 | if (toSkip > 0) { 145 | toSkip -= 1; 146 | helperContent += stringBlocks[j]; 147 | if (foundElse) elseContent += stringBlocks[j]; 148 | } else { 149 | shiftIndex = j; 150 | foundClosed = true; 151 | break; 152 | } 153 | } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { 154 | foundElse = true; 155 | } else { 156 | if (!foundElse) helperContent += stringBlocks[j]; 157 | if (foundElse) elseContent += stringBlocks[j]; 158 | } 159 | } 160 | if (foundClosed) { 161 | if (shiftIndex) i = shiftIndex; 162 | if (helperName === 'raw') { 163 | blocks.push({ 164 | type: 'plain', 165 | content: helperContent, 166 | }); 167 | } else { 168 | blocks.push({ 169 | type: 'helper', 170 | helperName, 171 | contextName: helperContext, 172 | content: helperContent, 173 | inverseContent: elseContent, 174 | hash: helperHash, 175 | }); 176 | } 177 | } 178 | } else if (block.indexOf(' ') > 0) { 179 | if (isPartial) { 180 | helperName = '_partial'; 181 | if (helperContext[0]) { 182 | if (helperContext[0].indexOf('[') === 0) helperContext[0] = helperContext[0].replace(/[[\]]/g, ''); 183 | else helperContext[0] = `"${helperContext[0].replace(/"|'/g, '')}"`; 184 | } 185 | } 186 | blocks.push({ 187 | type: 'helper', 188 | helperName, 189 | contextName: helperContext, 190 | hash: helperHash, 191 | }); 192 | } 193 | } 194 | } 195 | return blocks; 196 | }, 197 | parseJsVariable(expression, replace, object) { 198 | return expression.split(/([+ \-*/^()&=|<>!%:?])/g).reduce((arr, part) => { 199 | if (!part) { 200 | return arr; 201 | } 202 | if (part.indexOf(replace) < 0) { 203 | arr.push(part); 204 | return arr; 205 | } 206 | if (!object) { 207 | arr.push(JSON.stringify('')); 208 | return arr; 209 | } 210 | 211 | let variable = object; 212 | if (part.indexOf(`${replace}.`) >= 0) { 213 | part.split(`${replace}.`)[1].split('.').forEach((partName) => { 214 | if (partName in variable) variable = variable[partName]; 215 | else variable = undefined; 216 | }); 217 | } 218 | if ( 219 | (typeof variable === 'string') 220 | || Array.isArray(variable) 221 | || (variable.constructor && variable.constructor === Object) 222 | ) { 223 | variable = JSON.stringify(variable); 224 | } 225 | if (variable === undefined) variable = 'undefined'; 226 | 227 | arr.push(variable); 228 | return arr; 229 | }, []).join(''); 230 | 231 | }, 232 | parseJsParents(expression, parents) { 233 | return expression.split(/([+ \-*^()&=|<>!%:?])/g).reduce((arr, part) => { 234 | if (!part) { 235 | return arr; 236 | } 237 | 238 | if (part.indexOf('../') < 0) { 239 | arr.push(part); 240 | return arr; 241 | } 242 | 243 | if (!parents || parents.length === 0) { 244 | arr.push(JSON.stringify('')); 245 | return arr; 246 | } 247 | 248 | const levelsUp = part.split('../').length - 1; 249 | const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; 250 | 251 | let variable = parentData; 252 | const parentPart = part.replace(/..\//g, ''); 253 | parentPart.split('.').forEach((partName) => { 254 | if (typeof variable[partName] !== 'undefined') variable = variable[partName]; 255 | else variable = 'undefined'; 256 | }); 257 | if (variable === false || variable === true) { 258 | arr.push(JSON.stringify(variable)); 259 | return arr; 260 | } 261 | if (variable === null || variable === 'undefined') { 262 | arr.push(JSON.stringify('')); 263 | return arr; 264 | } 265 | arr.push(JSON.stringify(variable)); 266 | return arr; 267 | }, []).join(''); 268 | }, 269 | getCompileVar(name, ctx, data = 'data_1') { 270 | let variable = ctx; 271 | let parts; 272 | let levelsUp = 0; 273 | let newDepth; 274 | if (name.indexOf('../') === 0) { 275 | levelsUp = name.split('../').length - 1; 276 | newDepth = variable.split('_')[1] - levelsUp; 277 | variable = `ctx_${newDepth >= 1 ? newDepth : 1}`; 278 | parts = name.split('../')[levelsUp].split('.'); 279 | } else if (name.indexOf('@global') === 0) { 280 | variable = 'Template7.global'; 281 | parts = name.split('@global.')[1].split('.'); 282 | } else if (name.indexOf('@root') === 0) { 283 | variable = 'root'; 284 | parts = name.split('@root.')[1].split('.'); 285 | } else { 286 | parts = name.split('.'); 287 | } 288 | for (let i = 0; i < parts.length; i += 1) { 289 | const part = parts[i]; 290 | if (part.indexOf('@') === 0) { 291 | let dataLevel = data.split('_')[1]; 292 | if (levelsUp > 0) { 293 | dataLevel = newDepth; 294 | } 295 | if (i > 0) { 296 | variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`; 297 | } else { 298 | variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`; 299 | } 300 | } else if (Number.isFinite ? Number.isFinite(part) : Template7Context.isFinite(part)) { 301 | variable += `[${part}]`; 302 | } else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { 303 | variable = part.replace('this', ctx); 304 | } else { 305 | variable += `.${part}`; 306 | } 307 | } 308 | return variable; 309 | }, 310 | getCompiledArguments(contextArray, ctx, data) { 311 | const arr = []; 312 | for (let i = 0; i < contextArray.length; i += 1) { 313 | if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]); 314 | else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]); 315 | else { 316 | arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data)); 317 | } 318 | } 319 | 320 | return arr.join(', '); 321 | }, 322 | }; 323 | 324 | export default Template7Utils; 325 | --------------------------------------------------------------------------------