Comparing version 2.0.1 to 2.0.2
@@ -10,3 +10,2 @@ var fs ; | ||
var ok = require('assert').ok; | ||
@@ -22,2 +21,5 @@ var nodePath = require('path'); | ||
var safeVarName = /^[A-Za-z_$][A-Za-z0-9_]*$/; | ||
var bodyFunctionRegExp = /^([A-Za-z_$][A-Za-z0-9_]*)(?:\(([^)]*)\))?$/; | ||
function exists(path) { | ||
@@ -197,2 +199,25 @@ try { | ||
}, | ||
bodyFunction: function(value) { | ||
var parts = bodyFunctionRegExp.exec(value); | ||
if (!parts) { | ||
throw new Error('Invalid value of "' + value + '" for "body-function". Expected value to be of the following form: <function-name>([param1, param2, ...])'); | ||
} | ||
var functionName = parts[1]; | ||
var params = parts[2]; | ||
if (params) { | ||
params = params.trim().split(/\s*,\s*/); | ||
for (var i=0; i<params.length; i++) { | ||
if (params[i].length === 0) { | ||
throw new Error('Invalid parameters for body-function with value of "' + value + '"'); | ||
} else if (!safeVarName.test(params[i])) { | ||
throw new Error('Invalid parameter name of "' + params[i] + '" for body-function with value of "' + value + '"'); | ||
} | ||
} | ||
} else { | ||
params = []; | ||
} | ||
tag.setBodyFunction(functionName, params); | ||
}, | ||
vars: function(value) { | ||
@@ -199,0 +224,0 @@ if (value) { |
@@ -91,2 +91,3 @@ /* | ||
this.patternAttributes = []; | ||
this.bodyFunction = null; | ||
}, | ||
@@ -186,2 +187,8 @@ inheritFrom: function (superTag) { | ||
this.transformers[key] = transformer; | ||
}, | ||
setBodyFunction: function(name, params) { | ||
this.bodyFunction = { | ||
name: name, | ||
params: params | ||
}; | ||
} | ||
@@ -188,0 +195,0 @@ }); |
@@ -137,3 +137,3 @@ /* | ||
this.incIndent(delta); | ||
func.call(thisObj); | ||
func.call(thisObj, this); | ||
this.decIndent(delta); | ||
@@ -268,4 +268,4 @@ } else if (typeof arguments[0] === 'string') { | ||
this.writer = newWriter; | ||
func.call(thisObj); | ||
return newWriter.getOutput(); | ||
var value = func.call(thisObj); | ||
return value == null ? newWriter.getOutput() : value; | ||
} finally { | ||
@@ -272,0 +272,0 @@ this.writer = oldWriter; |
@@ -28,4 +28,4 @@ { | ||
"htmlparser2": "^3.7.2", | ||
"marko-async": "^1.2.12", | ||
"marko-layout": "^1.1.0", | ||
"marko-async": "^2.0.0", | ||
"marko-layout": "^2.0.0", | ||
"minimatch": "^0.2.14", | ||
@@ -62,3 +62,3 @@ "property-handlers": "^1.0.0", | ||
}, | ||
"version": "2.0.1" | ||
"version": "2.0.2" | ||
} |
@@ -1386,3 +1386,3 @@ Marko | ||
If, and only if, a tag has nested content, then a special `invokeBody` method will be added to the `input` object. If a renderer wants to render the nested body content then it must call the `invokeBody` method. For example: | ||
If, and only if, a tag has nested content, then a special `renderBody` method will be added to the `input` object. If a renderer wants to render the nested body content then it must call the `renderBody` method. For example: | ||
@@ -1392,4 +1392,4 @@ ```javascript | ||
out.write('BEFORE BODY'); | ||
if (input.invokeBody) { | ||
input.invokeBody(); | ||
if (input.renderBody) { | ||
input.renderBody(out); | ||
} | ||
@@ -1536,3 +1536,3 @@ out.write('AFTER BODY'); | ||
"renderer": "./tabs-tag", | ||
"var": "tabs" | ||
"body-function": "getTabs(__tabsHelper)" | ||
}, | ||
@@ -1542,3 +1542,3 @@ "ui-tab": { | ||
"import-var": { | ||
"tabs": "tabs" | ||
"tabs": "__tabsHelper" | ||
}, | ||
@@ -1564,12 +1564,18 @@ "attributes": { | ||
exports.render = function(input, out) { | ||
var nestedTabs = []; | ||
var nestedTabs; | ||
// Invoke the body function to discover nested <ui-tab> tags | ||
input.invokeBody({ // Invoke the body with the scoped "tabs" variable | ||
addTab: function(tab) { | ||
tab.id = tab.id || ("tab" + tabs.length); | ||
nestedTabs.push(tab); | ||
} | ||
}); | ||
if (input.getTabs) { | ||
nestedTabs = []; | ||
// Invoke the body function to discover nested <ui-tab> tags | ||
input.getTabs({ // Invoke the body with the scoped "tabs" variable | ||
addTab: function(tab) { | ||
tab.id = tab.id || ("tab" + tabs.length); | ||
nestedTabs.push(tab); | ||
} | ||
}); | ||
} else { | ||
nestedTabs = input.tabs || []; | ||
} | ||
// Now render the markup for the tabs: | ||
@@ -1604,3 +1610,3 @@ template.render({ | ||
<div id="${tab.id}" class="tab-pane" for="tab in data.tabs"> | ||
<invoke function="tab.invokeBody()"/> | ||
<invoke function="tab.renderBody(out)"/> | ||
</div> | ||
@@ -1607,0 +1613,0 @@ </div> |
@@ -10,2 +10,4 @@ var escapeXml = require('raptor-util/escapeXml'); | ||
var req = require; | ||
var arrayFromArguments = require('raptor-util/arrayFromArguments'); | ||
var logger = require('raptor-logging').logger(module); | ||
@@ -24,2 +26,4 @@ function notEmpty(o) { | ||
var WARNED_INVOKE_BODY = 0; | ||
module.exports = { | ||
@@ -137,3 +141,3 @@ s: function(str) { | ||
*/ | ||
t: function (out, renderFunc, input, body) { | ||
t: function (out, renderFunc, input, body, hasOutParam) { | ||
if (!input) { | ||
@@ -144,3 +148,17 @@ input = {}; | ||
if (body) { | ||
input.invokeBody = body; | ||
input.renderBody = body; | ||
input.invokeBody = function() { | ||
if (!WARNED_INVOKE_BODY) { | ||
WARNED_INVOKE_BODY = 1; | ||
logger.warn('invokeBody(...) deprecated. Use renderBody(out) instead.', new Error().stack); | ||
} | ||
if (!hasOutParam) { | ||
var args = arrayFromArguments(arguments); | ||
args.unshift(out); | ||
body.apply(this, args); | ||
} else { | ||
body.apply(this, arguments); | ||
} | ||
}; | ||
} | ||
@@ -147,0 +165,0 @@ |
@@ -302,4 +302,2 @@ /* | ||
function handleProp(name, value, attrDef, attr) { | ||
node.setProperty(name, value); | ||
if (attrDef.setFlag) { | ||
@@ -306,0 +304,0 @@ node.setFlag(attrDef.setFlag); |
@@ -37,3 +37,11 @@ /* | ||
if (typeof value === 'function') { | ||
value = value(); | ||
value = template.captureCode(function() { | ||
return value(template); | ||
}); | ||
if (!value) { | ||
throw new Error('Invalid value for property "' + name + '"'); | ||
} | ||
value = template.makeExpression(value); | ||
} | ||
@@ -55,3 +63,2 @@ | ||
if (propsArray.length) { | ||
@@ -107,6 +114,7 @@ return '{\n' + propsArray.join(',\n') + '\n' + template.indentStr() + '}'; | ||
template.addStaticVar('__renderer', '__helpers.r'); | ||
var _this = this; | ||
var rendererPath = template.getRequirePath(this.tag.renderer); // Resolve a path to the renderer relative to the directory of the template | ||
var handlerVar = addHandlerVar(template, rendererPath); | ||
var tagHelperVar = template.addStaticVar('__tag', '__helpers.t'); | ||
var bodyFunction = this.tag.bodyFunction; | ||
@@ -117,3 +125,10 @@ this.tag.forEachImportedVariable(function (importedVariable) { | ||
var _this = this; | ||
if (bodyFunction) { | ||
this.setProperty(bodyFunction.name, function(template) { | ||
template.code('function(' + bodyFunction.params + ') {\n').indent(function () { | ||
_this.generateCodeForChildren(template); | ||
}).indent().code('}'); | ||
}); | ||
} | ||
var variableNames = []; | ||
@@ -172,10 +187,28 @@ _this.tag.forEachVariable(function (nestedVar) { | ||
} | ||
if (_this.hasChildren()) { | ||
if (_this.hasChildren() && !_this.tag.bodyFunction) { | ||
var bodyParams = []; | ||
var hasOutParam = false; | ||
variableNames.forEach(function (varName) { | ||
if (varName === 'out') { | ||
hasOutParam = true; | ||
} | ||
bodyParams.push(varName); | ||
}); | ||
template.code(',\n').line('function(' + bodyParams.join(',') + ') {').indent(function () { | ||
var params; | ||
if (hasOutParam) { | ||
params = bodyParams.join(','); | ||
} else { | ||
params = 'out' + (bodyParams.length ? ',' + bodyParams.join(',') : ''); | ||
} | ||
template.code(',\n').line('function(' + params + ') {').indent(function () { | ||
_this.generateCodeForChildren(template); | ||
}).indent().code('}'); | ||
if (hasOutParam) { | ||
template.code(',\n').code(template.indentStr() + '1'); | ||
} | ||
} | ||
@@ -182,0 +215,0 @@ }); |
@@ -63,3 +63,3 @@ 'use strict'; | ||
describe('marko/marko' , function() { | ||
describe('marko/render' , function() { | ||
@@ -66,0 +66,0 @@ beforeEach(function(done) { |
@@ -29,2 +29,15 @@ { | ||
}, | ||
"test-tabs-new": { | ||
"renderer": "./tabs-new-tag.js", | ||
"body-function": "buildTabs(__tabsHelper)" | ||
}, | ||
"test-tab-new": { | ||
"renderer": "./tab-new-tag.js", | ||
"import-var": { | ||
"tabs": "__tabsHelper" | ||
}, | ||
"attributes": { | ||
"title": "string" | ||
} | ||
}, | ||
"test-dynamic-attributes": { | ||
@@ -31,0 +44,0 @@ "renderer": "./dynamic-attributes-tag.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
468023
383
8561
1733
+ Addedmarko-async@2.2.2(transitive)
+ Addedmarko-layout@2.0.2(transitive)
- Removedmarko-async@1.2.19(transitive)
- Removedmarko-layout@1.2.6(transitive)
Updatedmarko-async@^2.0.0
Updatedmarko-layout@^2.0.0