handlebars-jaylinski 4.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE +19 -0
  2. package/README.markdown +169 -0
  3. package/bin/.eslintrc.js +6 -0
  4. package/bin/handlebars +176 -0
  5. package/dist/amd/handlebars/base.js +106 -0
  6. package/dist/amd/handlebars/compiler/ast.js +31 -0
  7. package/dist/amd/handlebars/compiler/base.js +45 -0
  8. package/dist/amd/handlebars/compiler/code-gen.js +165 -0
  9. package/dist/amd/handlebars/compiler/compiler.js +562 -0
  10. package/dist/amd/handlebars/compiler/helpers.js +228 -0
  11. package/dist/amd/handlebars/compiler/javascript-compiler.js +1150 -0
  12. package/dist/amd/handlebars/compiler/parser.js +737 -0
  13. package/dist/amd/handlebars/compiler/printer.js +186 -0
  14. package/dist/amd/handlebars/compiler/visitor.js +138 -0
  15. package/dist/amd/handlebars/compiler/whitespace-control.js +219 -0
  16. package/dist/amd/handlebars/decorators/inline.js +25 -0
  17. package/dist/amd/handlebars/decorators.js +16 -0
  18. package/dist/amd/handlebars/exception.js +64 -0
  19. package/dist/amd/handlebars/helpers/block-helper-missing.js +35 -0
  20. package/dist/amd/handlebars/helpers/each.js +99 -0
  21. package/dist/amd/handlebars/helpers/helper-missing.js +22 -0
  22. package/dist/amd/handlebars/helpers/if.js +41 -0
  23. package/dist/amd/handlebars/helpers/log.js +24 -0
  24. package/dist/amd/handlebars/helpers/lookup.js +14 -0
  25. package/dist/amd/handlebars/helpers/with.js +38 -0
  26. package/dist/amd/handlebars/helpers.js +44 -0
  27. package/dist/amd/handlebars/internal/create-new-lookup-object.js +22 -0
  28. package/dist/amd/handlebars/internal/proto-access.js +71 -0
  29. package/dist/amd/handlebars/internal/wrapHelper.js +21 -0
  30. package/dist/amd/handlebars/logger.js +44 -0
  31. package/dist/amd/handlebars/no-conflict.js +28 -0
  32. package/dist/amd/handlebars/runtime.js +356 -0
  33. package/dist/amd/handlebars/safe-string.js +15 -0
  34. package/dist/amd/handlebars/utils.js +126 -0
  35. package/dist/amd/handlebars.js +52 -0
  36. package/dist/amd/handlebars.runtime.js +44 -0
  37. package/dist/amd/precompiler.js +314 -0
  38. package/dist/cjs/handlebars/base.js +116 -0
  39. package/dist/cjs/handlebars/compiler/ast.js +31 -0
  40. package/dist/cjs/handlebars/compiler/base.js +57 -0
  41. package/dist/cjs/handlebars/compiler/code-gen.js +168 -0
  42. package/dist/cjs/handlebars/compiler/compiler.js +566 -0
  43. package/dist/cjs/handlebars/compiler/helpers.js +228 -0
  44. package/dist/cjs/handlebars/compiler/javascript-compiler.js +1158 -0
  45. package/dist/cjs/handlebars/compiler/parser.js +737 -0
  46. package/dist/cjs/handlebars/compiler/printer.js +186 -0
  47. package/dist/cjs/handlebars/compiler/visitor.js +140 -0
  48. package/dist/cjs/handlebars/compiler/whitespace-control.js +221 -0
  49. package/dist/cjs/handlebars/decorators/inline.js +29 -0
  50. package/dist/cjs/handlebars/decorators.js +16 -0
  51. package/dist/cjs/handlebars/exception.js +64 -0
  52. package/dist/cjs/handlebars/helpers/block-helper-missing.js +39 -0
  53. package/dist/cjs/handlebars/helpers/each.js +104 -0
  54. package/dist/cjs/handlebars/helpers/helper-missing.js +25 -0
  55. package/dist/cjs/handlebars/helpers/if.js +46 -0
  56. package/dist/cjs/handlebars/helpers/log.js +26 -0
  57. package/dist/cjs/handlebars/helpers/lookup.js +16 -0
  58. package/dist/cjs/handlebars/helpers/with.js +43 -0
  59. package/dist/cjs/handlebars/helpers.js +56 -0
  60. package/dist/cjs/handlebars/internal/create-new-lookup-object.js +22 -0
  61. package/dist/cjs/handlebars/internal/proto-access.js +73 -0
  62. package/dist/cjs/handlebars/internal/wrapHelper.js +19 -0
  63. package/dist/cjs/handlebars/logger.js +47 -0
  64. package/dist/cjs/handlebars/no-conflict.js +30 -0
  65. package/dist/cjs/handlebars/runtime.js +372 -0
  66. package/dist/cjs/handlebars/safe-string.js +15 -0
  67. package/dist/cjs/handlebars/utils.js +124 -0
  68. package/dist/cjs/handlebars.js +66 -0
  69. package/dist/cjs/handlebars.runtime.js +66 -0
  70. package/dist/cjs/precompiler.js +328 -0
  71. package/dist/handlebars.amd.js +4639 -0
  72. package/dist/handlebars.amd.min.js +29 -0
  73. package/dist/handlebars.js +5972 -0
  74. package/dist/handlebars.min.js +29 -0
  75. package/dist/handlebars.runtime.amd.js +1302 -0
  76. package/dist/handlebars.runtime.amd.min.js +27 -0
  77. package/dist/handlebars.runtime.js +2563 -0
  78. package/dist/handlebars.runtime.min.js +27 -0
  79. package/lib/.eslintrc.js +8 -0
  80. package/lib/handlebars/base.js +94 -0
  81. package/lib/handlebars/compiler/ast.js +32 -0
  82. package/lib/handlebars/compiler/base.js +34 -0
  83. package/lib/handlebars/compiler/code-gen.js +171 -0
  84. package/lib/handlebars/compiler/compiler.js +594 -0
  85. package/lib/handlebars/compiler/helpers.js +219 -0
  86. package/lib/handlebars/compiler/javascript-compiler.js +1293 -0
  87. package/lib/handlebars/compiler/parser.js +622 -0
  88. package/lib/handlebars/compiler/printer.js +178 -0
  89. package/lib/handlebars/compiler/visitor.js +136 -0
  90. package/lib/handlebars/compiler/whitespace-control.js +234 -0
  91. package/lib/handlebars/decorators/inline.js +22 -0
  92. package/lib/handlebars/decorators.js +5 -0
  93. package/lib/handlebars/exception.js +68 -0
  94. package/lib/handlebars/helpers/block-helper-missing.js +35 -0
  95. package/lib/handlebars/helpers/each.js +101 -0
  96. package/lib/handlebars/helpers/helper-missing.js +15 -0
  97. package/lib/handlebars/helpers/if.js +33 -0
  98. package/lib/handlebars/helpers/log.js +19 -0
  99. package/lib/handlebars/helpers/lookup.js +9 -0
  100. package/lib/handlebars/helpers/with.js +39 -0
  101. package/lib/handlebars/helpers.js +26 -0
  102. package/lib/handlebars/internal/create-new-lookup-object.js +11 -0
  103. package/lib/handlebars/internal/proto-access.js +70 -0
  104. package/lib/handlebars/internal/wrapHelper.js +13 -0
  105. package/lib/handlebars/logger.js +39 -0
  106. package/lib/handlebars/no-conflict.js +23 -0
  107. package/lib/handlebars/runtime.js +450 -0
  108. package/lib/handlebars/safe-string.js +10 -0
  109. package/lib/handlebars/utils.js +116 -0
  110. package/lib/handlebars.js +46 -0
  111. package/lib/handlebars.runtime.js +37 -0
  112. package/lib/index.js +26 -0
  113. package/lib/precompiler.js +341 -0
  114. package/package.json +135 -0
  115. package/release-notes.md +1101 -0
  116. package/runtime.d.ts +5 -0
  117. package/runtime.js +3 -0
  118. package/types/index.d.ts +422 -0
@@ -0,0 +1,178 @@
1
+ /* eslint-disable new-cap */
2
+ import Visitor from './visitor';
3
+
4
+ export function print(ast) {
5
+ return new PrintVisitor().accept(ast);
6
+ }
7
+
8
+ export function PrintVisitor() {
9
+ this.padding = 0;
10
+ }
11
+
12
+ PrintVisitor.prototype = new Visitor();
13
+
14
+ PrintVisitor.prototype.pad = function(string) {
15
+ let out = '';
16
+
17
+ for (let i = 0, l = this.padding; i < l; i++) {
18
+ out += ' ';
19
+ }
20
+
21
+ out += string + '\n';
22
+ return out;
23
+ };
24
+
25
+ PrintVisitor.prototype.Program = function(program) {
26
+ let out = '',
27
+ body = program.body,
28
+ i,
29
+ l;
30
+
31
+ if (program.blockParams) {
32
+ let blockParams = 'BLOCK PARAMS: [';
33
+ for (i = 0, l = program.blockParams.length; i < l; i++) {
34
+ blockParams += ' ' + program.blockParams[i];
35
+ }
36
+ blockParams += ' ]';
37
+ out += this.pad(blockParams);
38
+ }
39
+
40
+ for (i = 0, l = body.length; i < l; i++) {
41
+ out += this.accept(body[i]);
42
+ }
43
+
44
+ this.padding--;
45
+
46
+ return out;
47
+ };
48
+
49
+ PrintVisitor.prototype.MustacheStatement = function(mustache) {
50
+ return this.pad('{{ ' + this.SubExpression(mustache) + ' }}');
51
+ };
52
+ PrintVisitor.prototype.Decorator = function(mustache) {
53
+ return this.pad('{{ DIRECTIVE ' + this.SubExpression(mustache) + ' }}');
54
+ };
55
+
56
+ PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function(
57
+ block
58
+ ) {
59
+ let out = '';
60
+
61
+ out += this.pad(
62
+ (block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:'
63
+ );
64
+ this.padding++;
65
+ out += this.pad(this.SubExpression(block));
66
+ if (block.program) {
67
+ out += this.pad('PROGRAM:');
68
+ this.padding++;
69
+ out += this.accept(block.program);
70
+ this.padding--;
71
+ }
72
+ if (block.inverse) {
73
+ if (block.program) {
74
+ this.padding++;
75
+ }
76
+ out += this.pad('{{^}}');
77
+ this.padding++;
78
+ out += this.accept(block.inverse);
79
+ this.padding--;
80
+ if (block.program) {
81
+ this.padding--;
82
+ }
83
+ }
84
+ this.padding--;
85
+
86
+ return out;
87
+ };
88
+
89
+ PrintVisitor.prototype.PartialStatement = function(partial) {
90
+ let content = 'PARTIAL:' + partial.name.original;
91
+ if (partial.params[0]) {
92
+ content += ' ' + this.accept(partial.params[0]);
93
+ }
94
+ if (partial.hash) {
95
+ content += ' ' + this.accept(partial.hash);
96
+ }
97
+ return this.pad('{{> ' + content + ' }}');
98
+ };
99
+ PrintVisitor.prototype.PartialBlockStatement = function(partial) {
100
+ let content = 'PARTIAL BLOCK:' + partial.name.original;
101
+ if (partial.params[0]) {
102
+ content += ' ' + this.accept(partial.params[0]);
103
+ }
104
+ if (partial.hash) {
105
+ content += ' ' + this.accept(partial.hash);
106
+ }
107
+
108
+ content += ' ' + this.pad('PROGRAM:');
109
+ this.padding++;
110
+ content += this.accept(partial.program);
111
+ this.padding--;
112
+
113
+ return this.pad('{{> ' + content + ' }}');
114
+ };
115
+
116
+ PrintVisitor.prototype.ContentStatement = function(content) {
117
+ return this.pad("CONTENT[ '" + content.value + "' ]");
118
+ };
119
+
120
+ PrintVisitor.prototype.CommentStatement = function(comment) {
121
+ return this.pad("{{! '" + comment.value + "' }}");
122
+ };
123
+
124
+ PrintVisitor.prototype.SubExpression = function(sexpr) {
125
+ let params = sexpr.params,
126
+ paramStrings = [],
127
+ hash;
128
+
129
+ for (let i = 0, l = params.length; i < l; i++) {
130
+ paramStrings.push(this.accept(params[i]));
131
+ }
132
+
133
+ params = '[' + paramStrings.join(', ') + ']';
134
+
135
+ hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : '';
136
+
137
+ return this.accept(sexpr.path) + ' ' + params + hash;
138
+ };
139
+
140
+ PrintVisitor.prototype.PathExpression = function(id) {
141
+ let path = id.parts.join('/');
142
+ return (id.data ? '@' : '') + 'PATH:' + path;
143
+ };
144
+
145
+ PrintVisitor.prototype.StringLiteral = function(string) {
146
+ return '"' + string.value + '"';
147
+ };
148
+
149
+ PrintVisitor.prototype.NumberLiteral = function(number) {
150
+ return 'NUMBER{' + number.value + '}';
151
+ };
152
+
153
+ PrintVisitor.prototype.BooleanLiteral = function(bool) {
154
+ return 'BOOLEAN{' + bool.value + '}';
155
+ };
156
+
157
+ PrintVisitor.prototype.UndefinedLiteral = function() {
158
+ return 'UNDEFINED';
159
+ };
160
+
161
+ PrintVisitor.prototype.NullLiteral = function() {
162
+ return 'NULL';
163
+ };
164
+
165
+ PrintVisitor.prototype.Hash = function(hash) {
166
+ let pairs = hash.pairs,
167
+ joinedPairs = [];
168
+
169
+ for (let i = 0, l = pairs.length; i < l; i++) {
170
+ joinedPairs.push(this.accept(pairs[i]));
171
+ }
172
+
173
+ return 'HASH{' + joinedPairs.join(', ') + '}';
174
+ };
175
+ PrintVisitor.prototype.HashPair = function(pair) {
176
+ return pair.key + '=' + this.accept(pair.value);
177
+ };
178
+ /* eslint-enable new-cap */
@@ -0,0 +1,136 @@
1
+ import Exception from '../exception';
2
+
3
+ function Visitor() {
4
+ this.parents = [];
5
+ }
6
+
7
+ Visitor.prototype = {
8
+ constructor: Visitor,
9
+ mutating: false,
10
+
11
+ // Visits a given value. If mutating, will replace the value if necessary.
12
+ acceptKey: function(node, name) {
13
+ let value = this.accept(node[name]);
14
+ if (this.mutating) {
15
+ // Hacky sanity check: This may have a few false positives for type for the helper
16
+ // methods but will generally do the right thing without a lot of overhead.
17
+ if (value && !Visitor.prototype[value.type]) {
18
+ throw new Exception(
19
+ 'Unexpected node type "' +
20
+ value.type +
21
+ '" found when accepting ' +
22
+ name +
23
+ ' on ' +
24
+ node.type
25
+ );
26
+ }
27
+ node[name] = value;
28
+ }
29
+ },
30
+
31
+ // Performs an accept operation with added sanity check to ensure
32
+ // required keys are not removed.
33
+ acceptRequired: function(node, name) {
34
+ this.acceptKey(node, name);
35
+
36
+ if (!node[name]) {
37
+ throw new Exception(node.type + ' requires ' + name);
38
+ }
39
+ },
40
+
41
+ // Traverses a given array. If mutating, empty respnses will be removed
42
+ // for child elements.
43
+ acceptArray: function(array) {
44
+ for (let i = 0, l = array.length; i < l; i++) {
45
+ this.acceptKey(array, i);
46
+
47
+ if (!array[i]) {
48
+ array.splice(i, 1);
49
+ i--;
50
+ l--;
51
+ }
52
+ }
53
+ },
54
+
55
+ accept: function(object) {
56
+ if (!object) {
57
+ return;
58
+ }
59
+
60
+ /* istanbul ignore next: Sanity code */
61
+ if (!this[object.type]) {
62
+ throw new Exception('Unknown type: ' + object.type, object);
63
+ }
64
+
65
+ if (this.current) {
66
+ this.parents.unshift(this.current);
67
+ }
68
+ this.current = object;
69
+
70
+ let ret = this[object.type](object);
71
+
72
+ this.current = this.parents.shift();
73
+
74
+ if (!this.mutating || ret) {
75
+ return ret;
76
+ } else if (ret !== false) {
77
+ return object;
78
+ }
79
+ },
80
+
81
+ Program: function(program) {
82
+ this.acceptArray(program.body);
83
+ },
84
+
85
+ MustacheStatement: visitSubExpression,
86
+ Decorator: visitSubExpression,
87
+
88
+ BlockStatement: visitBlock,
89
+ DecoratorBlock: visitBlock,
90
+
91
+ PartialStatement: visitPartial,
92
+ PartialBlockStatement: function(partial) {
93
+ visitPartial.call(this, partial);
94
+
95
+ this.acceptKey(partial, 'program');
96
+ },
97
+
98
+ ContentStatement: function(/* content */) {},
99
+ CommentStatement: function(/* comment */) {},
100
+
101
+ SubExpression: visitSubExpression,
102
+
103
+ PathExpression: function(/* path */) {},
104
+
105
+ StringLiteral: function(/* string */) {},
106
+ NumberLiteral: function(/* number */) {},
107
+ BooleanLiteral: function(/* bool */) {},
108
+ UndefinedLiteral: function(/* literal */) {},
109
+ NullLiteral: function(/* literal */) {},
110
+
111
+ Hash: function(hash) {
112
+ this.acceptArray(hash.pairs);
113
+ },
114
+ HashPair: function(pair) {
115
+ this.acceptRequired(pair, 'value');
116
+ }
117
+ };
118
+
119
+ function visitSubExpression(mustache) {
120
+ this.acceptRequired(mustache, 'path');
121
+ this.acceptArray(mustache.params);
122
+ this.acceptKey(mustache, 'hash');
123
+ }
124
+ function visitBlock(block) {
125
+ visitSubExpression.call(this, block);
126
+
127
+ this.acceptKey(block, 'program');
128
+ this.acceptKey(block, 'inverse');
129
+ }
130
+ function visitPartial(partial) {
131
+ this.acceptRequired(partial, 'name');
132
+ this.acceptArray(partial.params);
133
+ this.acceptKey(partial, 'hash');
134
+ }
135
+
136
+ export default Visitor;
@@ -0,0 +1,234 @@
1
+ import Visitor from './visitor';
2
+
3
+ function WhitespaceControl(options = {}) {
4
+ this.options = options;
5
+ }
6
+ WhitespaceControl.prototype = new Visitor();
7
+
8
+ WhitespaceControl.prototype.Program = function(program) {
9
+ const doStandalone = !this.options.ignoreStandalone;
10
+
11
+ let isRoot = !this.isRootSeen;
12
+ this.isRootSeen = true;
13
+
14
+ let body = program.body;
15
+ for (let i = 0, l = body.length; i < l; i++) {
16
+ let current = body[i],
17
+ strip = this.accept(current);
18
+
19
+ if (!strip) {
20
+ continue;
21
+ }
22
+
23
+ let _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
24
+ _isNextWhitespace = isNextWhitespace(body, i, isRoot),
25
+ openStandalone = strip.openStandalone && _isPrevWhitespace,
26
+ closeStandalone = strip.closeStandalone && _isNextWhitespace,
27
+ inlineStandalone =
28
+ strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
29
+
30
+ if (strip.close) {
31
+ omitRight(body, i, true);
32
+ }
33
+ if (strip.open) {
34
+ omitLeft(body, i, true);
35
+ }
36
+
37
+ if (doStandalone && inlineStandalone) {
38
+ omitRight(body, i);
39
+
40
+ if (omitLeft(body, i)) {
41
+ // If we are on a standalone node, save the indent info for partials
42
+ if (current.type === 'PartialStatement') {
43
+ // Pull out the whitespace from the final line
44
+ current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
45
+ }
46
+ }
47
+ }
48
+ if (doStandalone && openStandalone) {
49
+ omitRight((current.program || current.inverse).body);
50
+
51
+ // Strip out the previous content node if it's whitespace only
52
+ omitLeft(body, i);
53
+ }
54
+ if (doStandalone && closeStandalone) {
55
+ // Always strip the next node
56
+ omitRight(body, i);
57
+
58
+ omitLeft((current.inverse || current.program).body);
59
+ }
60
+ }
61
+
62
+ return program;
63
+ };
64
+
65
+ WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function(
66
+ block
67
+ ) {
68
+ this.accept(block.program);
69
+ this.accept(block.inverse);
70
+
71
+ // Find the inverse program that is involed with whitespace stripping.
72
+ let program = block.program || block.inverse,
73
+ inverse = block.program && block.inverse,
74
+ firstInverse = inverse,
75
+ lastInverse = inverse;
76
+
77
+ if (inverse && inverse.chained) {
78
+ firstInverse = inverse.body[0].program;
79
+
80
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
81
+ while (lastInverse.chained) {
82
+ lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
83
+ }
84
+ }
85
+
86
+ let strip = {
87
+ open: block.openStrip.open,
88
+ close: block.closeStrip.close,
89
+
90
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
91
+ // so our parent can determine if we actually are standalone
92
+ openStandalone: isNextWhitespace(program.body),
93
+ closeStandalone: isPrevWhitespace((firstInverse || program).body)
94
+ };
95
+
96
+ if (block.openStrip.close) {
97
+ omitRight(program.body, null, true);
98
+ }
99
+
100
+ if (inverse) {
101
+ let inverseStrip = block.inverseStrip;
102
+
103
+ if (inverseStrip.open) {
104
+ omitLeft(program.body, null, true);
105
+ }
106
+
107
+ if (inverseStrip.close) {
108
+ omitRight(firstInverse.body, null, true);
109
+ }
110
+ if (block.closeStrip.open) {
111
+ omitLeft(lastInverse.body, null, true);
112
+ }
113
+
114
+ // Find standalone else statments
115
+ if (
116
+ !this.options.ignoreStandalone &&
117
+ isPrevWhitespace(program.body) &&
118
+ isNextWhitespace(firstInverse.body)
119
+ ) {
120
+ omitLeft(program.body);
121
+ omitRight(firstInverse.body);
122
+ }
123
+ } else if (block.closeStrip.open) {
124
+ omitLeft(program.body, null, true);
125
+ }
126
+
127
+ return strip;
128
+ };
129
+
130
+ WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function(
131
+ mustache
132
+ ) {
133
+ return mustache.strip;
134
+ };
135
+
136
+ WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function(
137
+ node
138
+ ) {
139
+ /* istanbul ignore next */
140
+ let strip = node.strip || {};
141
+ return {
142
+ inlineStandalone: true,
143
+ open: strip.open,
144
+ close: strip.close
145
+ };
146
+ };
147
+
148
+ function isPrevWhitespace(body, i, isRoot) {
149
+ if (i === undefined) {
150
+ i = body.length;
151
+ }
152
+
153
+ // Nodes that end with newlines are considered whitespace (but are special
154
+ // cased for strip operations)
155
+ let prev = body[i - 1],
156
+ sibling = body[i - 2];
157
+ if (!prev) {
158
+ return isRoot;
159
+ }
160
+
161
+ if (prev.type === 'ContentStatement') {
162
+ return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(
163
+ prev.original
164
+ );
165
+ }
166
+ }
167
+ function isNextWhitespace(body, i, isRoot) {
168
+ if (i === undefined) {
169
+ i = -1;
170
+ }
171
+
172
+ let next = body[i + 1],
173
+ sibling = body[i + 2];
174
+ if (!next) {
175
+ return isRoot;
176
+ }
177
+
178
+ if (next.type === 'ContentStatement') {
179
+ return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(
180
+ next.original
181
+ );
182
+ }
183
+ }
184
+
185
+ // Marks the node to the right of the position as omitted.
186
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
187
+ //
188
+ // If i is undefined, then the first child will be marked as such.
189
+ //
190
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
191
+ // content is met.
192
+ function omitRight(body, i, multiple) {
193
+ let current = body[i == null ? 0 : i + 1];
194
+ if (
195
+ !current ||
196
+ current.type !== 'ContentStatement' ||
197
+ (!multiple && current.rightStripped)
198
+ ) {
199
+ return;
200
+ }
201
+
202
+ let original = current.value;
203
+ current.value = current.value.replace(
204
+ multiple ? /^\s+/ : /^[ \t]*\r?\n?/,
205
+ ''
206
+ );
207
+ current.rightStripped = current.value !== original;
208
+ }
209
+
210
+ // Marks the node to the left of the position as omitted.
211
+ // I.e. ' '{{foo}} will mark the ' ' node as omitted.
212
+ //
213
+ // If i is undefined then the last child will be marked as such.
214
+ //
215
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
216
+ // content is met.
217
+ function omitLeft(body, i, multiple) {
218
+ let current = body[i == null ? body.length - 1 : i - 1];
219
+ if (
220
+ !current ||
221
+ current.type !== 'ContentStatement' ||
222
+ (!multiple && current.leftStripped)
223
+ ) {
224
+ return;
225
+ }
226
+
227
+ // We omit the last node if it's whitespace only and not preceded by a non-content node.
228
+ let original = current.value;
229
+ current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
230
+ current.leftStripped = current.value !== original;
231
+ return current.leftStripped;
232
+ }
233
+
234
+ export default WhitespaceControl;
@@ -0,0 +1,22 @@
1
+ import { extend } from '../utils';
2
+
3
+ export default function(instance) {
4
+ instance.registerDecorator('inline', function(fn, props, container, options) {
5
+ let ret = fn;
6
+ if (!props.partials) {
7
+ props.partials = {};
8
+ ret = function(context, options) {
9
+ // Create a new partials stack frame prior to exec.
10
+ let original = container.partials;
11
+ container.partials = extend({}, original, props.partials);
12
+ let ret = fn(context, options);
13
+ container.partials = original;
14
+ return ret;
15
+ };
16
+ }
17
+
18
+ props.partials[options.args[0]] = options.fn;
19
+
20
+ return ret;
21
+ });
22
+ }
@@ -0,0 +1,5 @@
1
+ import registerInline from './decorators/inline';
2
+
3
+ export function registerDefaultDecorators(instance) {
4
+ registerInline(instance);
5
+ }
@@ -0,0 +1,68 @@
1
+ const errorProps = [
2
+ 'description',
3
+ 'fileName',
4
+ 'lineNumber',
5
+ 'endLineNumber',
6
+ 'message',
7
+ 'name',
8
+ 'number',
9
+ 'stack'
10
+ ];
11
+
12
+ function Exception(message, node) {
13
+ let loc = node && node.loc,
14
+ line,
15
+ endLineNumber,
16
+ column,
17
+ endColumn;
18
+
19
+ if (loc) {
20
+ line = loc.start.line;
21
+ endLineNumber = loc.end.line;
22
+ column = loc.start.column;
23
+ endColumn = loc.end.column;
24
+
25
+ message += ' - ' + line + ':' + column;
26
+ }
27
+
28
+ let tmp = Error.prototype.constructor.call(this, message);
29
+
30
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
31
+ for (let idx = 0; idx < errorProps.length; idx++) {
32
+ this[errorProps[idx]] = tmp[errorProps[idx]];
33
+ }
34
+
35
+ /* istanbul ignore else */
36
+ if (Error.captureStackTrace) {
37
+ Error.captureStackTrace(this, Exception);
38
+ }
39
+
40
+ try {
41
+ if (loc) {
42
+ this.lineNumber = line;
43
+ this.endLineNumber = endLineNumber;
44
+
45
+ // Work around issue under safari where we can't directly set the column value
46
+ /* istanbul ignore next */
47
+ if (Object.defineProperty) {
48
+ Object.defineProperty(this, 'column', {
49
+ value: column,
50
+ enumerable: true
51
+ });
52
+ Object.defineProperty(this, 'endColumn', {
53
+ value: endColumn,
54
+ enumerable: true
55
+ });
56
+ } else {
57
+ this.column = column;
58
+ this.endColumn = endColumn;
59
+ }
60
+ }
61
+ } catch (nop) {
62
+ /* Ignore if the browser is very particular */
63
+ }
64
+ }
65
+
66
+ Exception.prototype = new Error();
67
+
68
+ export default Exception;
@@ -0,0 +1,35 @@
1
+ import { appendContextPath, createFrame, isArray } from '../utils';
2
+
3
+ export default function(instance) {
4
+ instance.registerHelper('blockHelperMissing', function(context, options) {
5
+ let inverse = options.inverse,
6
+ fn = options.fn;
7
+
8
+ if (context === true) {
9
+ return fn(this);
10
+ } else if (context === false || context == null) {
11
+ return inverse(this);
12
+ } else if (isArray(context)) {
13
+ if (context.length > 0) {
14
+ if (options.ids) {
15
+ options.ids = [options.name];
16
+ }
17
+
18
+ return instance.helpers.each(context, options);
19
+ } else {
20
+ return inverse(this);
21
+ }
22
+ } else {
23
+ if (options.data && options.ids) {
24
+ let data = createFrame(options.data);
25
+ data.contextPath = appendContextPath(
26
+ options.data.contextPath,
27
+ options.name
28
+ );
29
+ options = { data: data };
30
+ }
31
+
32
+ return fn(context, options);
33
+ }
34
+ });
35
+ }