mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #452 - Deprecate the layout taglib
This commit is contained in:
parent
9e372967c3
commit
abbe88dfca
@ -5,6 +5,7 @@ var removeDashes = require('../util/removeDashes');
|
|||||||
var safeVarName = require('../util/safeVarName');
|
var safeVarName = require('../util/safeVarName');
|
||||||
var ok = require('assert').ok;
|
var ok = require('assert').ok;
|
||||||
var tagLoader;
|
var tagLoader;
|
||||||
|
var Node = require('./Node');
|
||||||
|
|
||||||
var CUSTOM_TAG_KEY = Symbol('CustomTag');
|
var CUSTOM_TAG_KEY = Symbol('CustomTag');
|
||||||
|
|
||||||
@ -156,6 +157,51 @@ function processDirectlyNestedTags(node, codegen) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function merge(props1, props2, context) {
|
||||||
|
if (!props2) {
|
||||||
|
return props1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(props2 instanceof Node)) {
|
||||||
|
if (Object.keys(props2).length === 0) {
|
||||||
|
return props1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props1 instanceof Node) {
|
||||||
|
let mergeVar = context.helper('merge');
|
||||||
|
if (!(props2 instanceof Node)) {
|
||||||
|
props2 = context.builder.literal(props2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.builder.functionCall(mergeVar, [
|
||||||
|
props2, // Input props from the attributes take precedence
|
||||||
|
props1
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
if (props2 instanceof Node) {
|
||||||
|
let mergeVar = context.helper('merge');
|
||||||
|
|
||||||
|
return context.builder.functionCall(mergeVar, [
|
||||||
|
props2, // Input props from the attributes take precedence
|
||||||
|
props1
|
||||||
|
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
if (props1._arg) {
|
||||||
|
let mergeVar = context.helper('merge');
|
||||||
|
props1._arg = context.builder.functionCall(mergeVar, [
|
||||||
|
context.builder.literal(props2), // Input props from the attributes take precedence
|
||||||
|
props1._arg
|
||||||
|
]);
|
||||||
|
return props1;
|
||||||
|
} else {
|
||||||
|
return Object.assign(props1, props2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CustomTag extends HtmlElement {
|
class CustomTag extends HtmlElement {
|
||||||
constructor(el, tagDef) {
|
constructor(el, tagDef) {
|
||||||
super(el);
|
super(el);
|
||||||
@ -168,6 +214,8 @@ class CustomTag extends HtmlElement {
|
|||||||
this._condition = null;
|
this._condition = null;
|
||||||
this._foundNestedTagsByName = {};
|
this._foundNestedTagsByName = {};
|
||||||
this._hasDynamicNestedTags = false;
|
this._hasDynamicNestedTags = false;
|
||||||
|
this._additionalProps = null;
|
||||||
|
this._rendererPath = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildInputProps(codegen) {
|
buildInputProps(codegen) {
|
||||||
@ -342,6 +390,26 @@ class CustomTag extends HtmlElement {
|
|||||||
byNameArray.push(nestedTag);
|
byNameArray.push(nestedTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addProps(additionalProps) {
|
||||||
|
if (!this._additionalProps) {
|
||||||
|
this._additionalProps = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this._additionalProps, additionalProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
addProp(name, value) {
|
||||||
|
if (!this._additionalProps) {
|
||||||
|
this._additionalProps = {};
|
||||||
|
}
|
||||||
|
this._additionalProps[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRendererPath(path) {
|
||||||
|
ok(typeof path === 'string', '"path" should be a string');
|
||||||
|
this._rendererPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
getNestedTagVar(context) {
|
getNestedTagVar(context) {
|
||||||
if (!this._nestedTagVar) {
|
if (!this._nestedTagVar) {
|
||||||
var tagDef = this.tagDef;
|
var tagDef = this.tagDef;
|
||||||
@ -364,25 +432,22 @@ class CustomTag extends HtmlElement {
|
|||||||
|
|
||||||
var tagDef = this.resolveTagDef(codegen);
|
var tagDef = this.resolveTagDef(codegen);
|
||||||
|
|
||||||
|
if (!tagDef) {
|
||||||
|
// The tag def was not able to be resolved and an error should have already
|
||||||
|
// been added to the context
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var parentCustomTag;
|
var parentCustomTag;
|
||||||
|
|
||||||
// console.log('BEGIN:', JSON.stringify(this, null, 2));
|
|
||||||
|
|
||||||
// console.log(module.id, 'generateCode BEGIN:', this.tagName, new Error().stack);
|
|
||||||
|
|
||||||
context.pushData(CUSTOM_TAG_KEY, this);
|
context.pushData(CUSTOM_TAG_KEY, this);
|
||||||
processDirectlyNestedTags(this, codegen);
|
processDirectlyNestedTags(this, codegen);
|
||||||
var body = codegen.generateCode(this.body);
|
var body = codegen.generateCode(this.body);
|
||||||
context.popData(CUSTOM_TAG_KEY);
|
context.popData(CUSTOM_TAG_KEY);
|
||||||
|
|
||||||
// console.log(module.id, 'generateCode END:', this.tagName);
|
|
||||||
|
|
||||||
var isNestedTag = tagDef.isNestedTag === true;
|
var isNestedTag = tagDef.isNestedTag === true;
|
||||||
if (isNestedTag) {
|
if (isNestedTag) {
|
||||||
parentCustomTag = context.getData(CUSTOM_TAG_KEY);
|
parentCustomTag = context.getData(CUSTOM_TAG_KEY);
|
||||||
|
|
||||||
// console.log('parentCustomTag:', parentCustomTag.tagName, 'child:', tagDef.name);
|
|
||||||
|
|
||||||
if (!parentCustomTag) {
|
if (!parentCustomTag) {
|
||||||
if (tagDef.parentTagName) {
|
if (tagDef.parentTagName) {
|
||||||
codegen.addError(`Invalid usage of the <${this.tagName}> nested tag. Tag not nested within a <${tagDef.parentTagName}> tag.`);
|
codegen.addError(`Invalid usage of the <${this.tagName}> nested tag. Tag not nested within a <${tagDef.parentTagName}> tag.`);
|
||||||
@ -435,12 +500,6 @@ class CustomTag extends HtmlElement {
|
|||||||
|
|
||||||
var inputProps = this.buildInputProps(codegen);
|
var inputProps = this.buildInputProps(codegen);
|
||||||
|
|
||||||
// if (isNestedTag) {
|
|
||||||
// isRepeated = tagDef.isRepeated === true;
|
|
||||||
// targetProperty = tagDef.targetProperty;
|
|
||||||
// parentTagVar = parentCustomTag.getNestedTagVar(context);
|
|
||||||
// }
|
|
||||||
|
|
||||||
var renderBodyFunction;
|
var renderBodyFunction;
|
||||||
|
|
||||||
if (body && body.length) {
|
if (body && body.length) {
|
||||||
@ -481,29 +540,31 @@ class CustomTag extends HtmlElement {
|
|||||||
bodyOnlyIf = null;
|
bodyOnlyIf = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputProps = builder.literal(inputProps);
|
var argExpression;
|
||||||
|
|
||||||
var argument = this.argument;
|
if (this.argument) {
|
||||||
|
argExpression = builder.parseExpression(this.argument);
|
||||||
|
}
|
||||||
|
|
||||||
if (argument) {
|
var additionalProps = this._additionalProps;
|
||||||
argument = builder.parseExpression(argument);
|
|
||||||
|
|
||||||
if (Object.keys(inputProps.value).length === 0) {
|
if (additionalProps) {
|
||||||
inputProps = argument;
|
inputProps = merge(additionalProps, inputProps, context);
|
||||||
} else {
|
}
|
||||||
var mergeVar = context.helper('merge');
|
|
||||||
inputProps = builder.functionCall(mergeVar, [
|
if (argExpression) {
|
||||||
inputProps, // Input props from the attributes take precedence
|
inputProps = merge(argExpression, inputProps, context);
|
||||||
argument
|
}
|
||||||
]);
|
|
||||||
}
|
if (!(inputProps instanceof Node)) {
|
||||||
|
inputProps = builder.literal(inputProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasDynamicNestedTags) {
|
if (hasDynamicNestedTags) {
|
||||||
inputProps = builder.functionCall(context.helper('mergeNestedTagsHelper'), [ inputProps ]);
|
inputProps = builder.functionCall(context.helper('mergeNestedTagsHelper'), [ inputProps ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var rendererPath = tagDef.renderer;
|
var rendererPath = this._rendererPath || tagDef.renderer;
|
||||||
var rendererRequirePath;
|
var rendererRequirePath;
|
||||||
var requireRendererFunctionCall;
|
var requireRendererFunctionCall;
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
"test-express": "mocha --ui bdd --reporter spec ./test/express-test",
|
"test-express": "mocha --ui bdd --reporter spec ./test/express-test",
|
||||||
"test-widgets": "npm run test-widgets-browser -s && npm run test-widgets-browser-deprecated -s && npm run jshint --silent",
|
"test-widgets": "npm run test-widgets-browser -s && npm run test-widgets-browser-deprecated -s && npm run jshint --silent",
|
||||||
"test-widgets-browser": "node test/browser-tests-runner/cli.js test/widgets-browser-tests.js --automated && npm run test-widgets-browser-pages",
|
"test-widgets-browser": "node test/browser-tests-runner/cli.js test/widgets-browser-tests.js --automated && npm run test-widgets-browser-pages",
|
||||||
"test-widgets-browser-deprecated": "node test/browser-tests-runner/cli.js test/widgets-browser-deprecated-tests.js --automated && npm run test-widgets-browser-pages",
|
"test-widgets-browser-deprecated": "node test/browser-tests-runner/cli.js test/deprecated-widgets-browser-tests.js --automated && npm run test-widgets-browser-pages",
|
||||||
"test-widgets-browser-pages": "node test/browser-tests-runner/cli.js --pages --automated",
|
"test-widgets-browser-pages": "node test/browser-tests-runner/cli.js --pages --automated",
|
||||||
"test-widgets-browser-dev": "browser-refresh test/browser-tests-runner/cli.js test/widgets-browser-tests.js --server",
|
"test-widgets-browser-dev": "browser-refresh test/browser-tests-runner/cli.js test/widgets-browser-tests.js --server",
|
||||||
"test-widgets-page": "browser-refresh test/browser-tests-runner/cli.js test/widgets-browser-tests.js --server --page",
|
"test-widgets-page": "browser-refresh test/browser-tests-runner/cli.js test/widgets-browser-tests.js --server --page",
|
||||||
|
|||||||
@ -251,4 +251,3 @@ exports.cl = function classListHelper() {
|
|||||||
* Loads a template (__helpers.l --> marko_loadTemplate(path))
|
* Loads a template (__helpers.l --> marko_loadTemplate(path))
|
||||||
*/
|
*/
|
||||||
exports.l = require('./loader');
|
exports.l = require('./loader');
|
||||||
exports.i = require('./include');
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
module.exports = function include(target, out, data) {
|
|
||||||
if (target) {
|
|
||||||
if (typeof target === 'function') {
|
|
||||||
target(out, data);
|
|
||||||
} else if (typeof target === 'object') {
|
|
||||||
if (target.renderBody) {
|
|
||||||
target.renderBody(out, data);
|
|
||||||
} else if (target.renderer) {
|
|
||||||
target.renderer(data, out);
|
|
||||||
} else if (target.render) {
|
|
||||||
target.render(data, out);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('Invalid include target: ' + target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
34
taglibs/core/include-tag-transformer.js
Normal file
34
taglibs/core/include-tag-transformer.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function codeGenerator(el, context) {
|
||||||
|
let builder = context.builder;
|
||||||
|
|
||||||
|
let target;
|
||||||
|
let arg;
|
||||||
|
|
||||||
|
if (el.argument) {
|
||||||
|
let args = el.argument && builder.parseJavaScriptArgs(el.argument);
|
||||||
|
el.argument = null;
|
||||||
|
|
||||||
|
target = args[0];
|
||||||
|
arg = args[1];
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.type === 'Literal') {
|
||||||
|
target = context.importTemplate(target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeProps = {
|
||||||
|
_target: target
|
||||||
|
};
|
||||||
|
|
||||||
|
if (arg) {
|
||||||
|
includeProps._arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.data.includeTarget = target;
|
||||||
|
|
||||||
|
el.addProps(includeProps);
|
||||||
|
};
|
||||||
@ -1,87 +1,20 @@
|
|||||||
'use strict';
|
module.exports = function include(input, out) {
|
||||||
var removeHyphens = require('../../compiler/util/removeDashes');
|
var target = input._target;
|
||||||
|
var arg = input._arg || input;
|
||||||
module.exports = function codeGenerator(el, codegen) {
|
|
||||||
let builder = codegen.builder;
|
|
||||||
|
|
||||||
let target;
|
|
||||||
let data;
|
|
||||||
|
|
||||||
if (el.argument) {
|
|
||||||
let args = el.argument && builder.parseJavaScriptArgs(el.argument);
|
|
||||||
target = args[0];
|
|
||||||
data = args[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
var isTemplate = false;
|
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
if (target.type === 'Literal') {
|
if (typeof target === 'function') {
|
||||||
target = codegen.context.importTemplate(target.value);
|
target(out, arg);
|
||||||
isTemplate = true;
|
} else if (typeof target === 'object') {
|
||||||
}
|
if (target.renderBody) {
|
||||||
}
|
target.renderBody(out, arg);
|
||||||
|
} else if (target.renderer) {
|
||||||
let finalData = {};
|
target.renderer(arg, out);
|
||||||
let attrs = el.getAttributes();
|
} else if (target.render) {
|
||||||
attrs.forEach((attr) => {
|
target.render(arg, out);
|
||||||
var propName = attr.name;
|
|
||||||
if (propName.indexOf('-') !== -1) {
|
|
||||||
propName = removeHyphens(propName); // Convert the property name to camel case
|
|
||||||
}
|
|
||||||
|
|
||||||
finalData[propName] = attr.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (el.body && el.body.length) {
|
|
||||||
finalData.renderBody = builder.renderBodyFunction(el.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
if (Object.keys(finalData).length === 0) {
|
|
||||||
finalData = data;
|
|
||||||
} else {
|
|
||||||
let mergeVar = codegen.context.helper('merge');
|
|
||||||
finalData = builder.functionCall(mergeVar, [
|
|
||||||
builder.literal(finalData), // Input props from the attributes take precedence
|
|
||||||
data // The template data object is passed as the second argument: <include("./foo.marko", { ... })/>
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Object.keys(finalData).length === 0) {
|
|
||||||
finalData = null;
|
|
||||||
} else {
|
|
||||||
finalData = builder.literal(finalData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTemplate) {
|
|
||||||
let renderMethod = builder.memberExpression(target, builder.identifier('render'));
|
|
||||||
if (!finalData) {
|
|
||||||
finalData = builder.literal({});
|
|
||||||
}
|
|
||||||
let renderArgs = [ finalData, builder.identifierOut() ];
|
|
||||||
let renderFunctionCall = builder.functionCall(renderMethod, renderArgs);
|
|
||||||
return renderFunctionCall;
|
|
||||||
} else {
|
|
||||||
if (this.generateCodeForDynamicInclude) {
|
|
||||||
return this.generateCodeForDynamicInclude({
|
|
||||||
target: target,
|
|
||||||
data: finalData
|
|
||||||
}, codegen);
|
|
||||||
} else {
|
|
||||||
if (!target) {
|
|
||||||
target = builder.memberExpression(builder.identifier('data'), builder.identifier('renderBody'));
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
let includeVar = codegen.context.helper('include');
|
throw new Error('Invalid include target: ' + target);
|
||||||
let includeArgs = [ target, builder.identifierOut() ];
|
|
||||||
|
|
||||||
if (finalData) {
|
|
||||||
includeArgs.push(finalData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.functionCall(includeVar, includeArgs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -79,7 +79,8 @@
|
|||||||
"code-generator": "./import-tag"
|
"code-generator": "./import-tag"
|
||||||
},
|
},
|
||||||
"<include>": {
|
"<include>": {
|
||||||
"code-generator": "./include-tag",
|
"renderer": "./include-tag",
|
||||||
|
"transformer": "./include-tag-transformer",
|
||||||
"autocomplete": [
|
"autocomplete": [
|
||||||
{
|
{
|
||||||
"displayText": "include(<template>)",
|
"displayText": "include(<template>)",
|
||||||
|
|||||||
@ -6,6 +6,9 @@ module.exports = function transform(el, context) {
|
|||||||
context.addError(el, 'Invalid <layout-use> tag. Expected: <layout-use(template[, data]) ...>');
|
context.addError(el, 'Invalid <layout-use> tag. Expected: <layout-use(template[, data]) ...>');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.warn('The <layout-use> tag is deprecated. Please use <include> instead. See: https://github.com/marko-js/marko/issues/452 (' + (el.pos ? context.getPosInfo(el.pos) : context.filename) + ')');
|
||||||
|
|
||||||
var builder = context.builder;
|
var builder = context.builder;
|
||||||
|
|
||||||
var args = builder.parseJavaScriptArgs(argument);
|
var args = builder.parseJavaScriptArgs(argument);
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
<div>BODY CONTENT</div> ---- <h1>DEFAULT TITLE</h1><div>BODY CONTENT</div><h1>FOOTER CONTENT</h1>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<h1 if(data.showHeader !== false)>
|
||||||
|
<if(data.header)>
|
||||||
|
<include(data.header)/>
|
||||||
|
</if>
|
||||||
|
<else>
|
||||||
|
DEFAULT TITLE
|
||||||
|
</else>
|
||||||
|
</h1>
|
||||||
|
<div>
|
||||||
|
<include(data.body)/>
|
||||||
|
</div>
|
||||||
|
<h1 if(data.showFooter !== false)>
|
||||||
|
<if(data.footer)>
|
||||||
|
<include(data.footer)/>
|
||||||
|
</if>
|
||||||
|
<else>
|
||||||
|
DEFAULT FOOTER
|
||||||
|
</else>
|
||||||
|
</h1>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
-------
|
||||||
|
<include("./layout-default.marko", {showHeader: false}) show-footer=false>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
----
|
||||||
|
<include("./layout-default.marko", {showHeader: false}) show-header=true>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
-------
|
||||||
3
test/autotests/render/include-layout-data-attrs/test.js
Normal file
3
test/autotests/render/include-layout-data-attrs/test.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
exports.templateData = {
|
||||||
|
layoutDynamic: require('./layout-default.marko')
|
||||||
|
};
|
||||||
1
test/autotests/render/include-layout-data/expected.html
Normal file
1
test/autotests/render/include-layout-data/expected.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div>BODY CONTENT</div>FOOTER CONTENT ---- <h1>DEFAULT TITLE</h1><div>BODY CONTENT2</div>FOOTER CONTENT2 ---- <h1>My Title</h1><div>BODY CONTENT2</div>FOOTER CONTENT2
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<h1 if(data.showHeader !== false)>
|
||||||
|
<if(data.header)>
|
||||||
|
<include(data.header)/>
|
||||||
|
</if>
|
||||||
|
<else>
|
||||||
|
DEFAULT TITLE
|
||||||
|
</else>
|
||||||
|
</h1>
|
||||||
|
<div>
|
||||||
|
<include(data.body)/>
|
||||||
|
</div>
|
||||||
|
<include(data.footer)/>
|
||||||
|
<include(data.empty)/>
|
||||||
17
test/autotests/render/include-layout-data/template.marko
Normal file
17
test/autotests/render/include-layout-data/template.marko
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---------
|
||||||
|
<include("./layout-default.marko", {showHeader: false})>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
----
|
||||||
|
<include("./layout-default.marko", {showHeader: true})>
|
||||||
|
<@body>BODY CONTENT2</@body>
|
||||||
|
<@footer>FOOTER CONTENT2</@footer>
|
||||||
|
</include>
|
||||||
|
----
|
||||||
|
<include("./layout-default.marko", {showHeader: true})>
|
||||||
|
<@header>My Title</@header>
|
||||||
|
<@body>BODY CONTENT2</@body>
|
||||||
|
<@footer>FOOTER CONTENT2</@footer>
|
||||||
|
</include>
|
||||||
|
---------
|
||||||
3
test/autotests/render/include-layout-data/test.js
Normal file
3
test/autotests/render/include-layout-data/test.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
exports.templateData = {
|
||||||
|
layoutDynamic: require('./layout-default.marko')
|
||||||
|
};
|
||||||
1
test/autotests/render/include-layout/expected.html
Normal file
1
test/autotests/render/include-layout/expected.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div>BODY CONTENT</div>FOOTER CONTENT<h1>HEADER CONTENT</h1><div>BODY CONTENT</div>FOOTER CONTENT<h1>VALUE HEADER</h1><div>BODY CONTENT</div>FOOTER CONTENT<h1>DEFAULT TITLE</h1><div>BODY CONTENT</div>FOOTER CONTENT
|
||||||
13
test/autotests/render/include-layout/layout-default.marko
Normal file
13
test/autotests/render/include-layout/layout-default.marko
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<h1 if(data.showHeader !== false)>
|
||||||
|
<if(data.header)>
|
||||||
|
<include(data.header)/>
|
||||||
|
</if>
|
||||||
|
<else>
|
||||||
|
DEFAULT TITLE
|
||||||
|
</else>
|
||||||
|
</h1>
|
||||||
|
<div>
|
||||||
|
<include(data.body)/>
|
||||||
|
</div>
|
||||||
|
<include(data.footer)/>
|
||||||
|
<include(data.empty)/>
|
||||||
18
test/autotests/render/include-layout/template.marko
Normal file
18
test/autotests/render/include-layout/template.marko
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<include("./layout-default.marko") show-header=false>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
<include("./layout-default.marko") show-header=true>
|
||||||
|
<@header>HEADER CONTENT</@header>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
<include("./layout-default.marko") show-header=true>
|
||||||
|
<@header>VALUE HEADER</@header>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
|
<include(data.layoutDynamic) show-header=true>
|
||||||
|
<@body>BODY CONTENT</@body>
|
||||||
|
<@footer>FOOTER CONTENT</@footer>
|
||||||
|
</include>
|
||||||
3
test/autotests/render/include-layout/test.js
Normal file
3
test/autotests/render/include-layout/test.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
exports.templateData = {
|
||||||
|
layoutDynamic: require('./layout-default.marko')
|
||||||
|
};
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<div>Frank:10</div>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<include(data.renderBody, {name: 'Frank'}) age=10/>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
exports.templateData = {
|
||||||
|
renderBody(out, data) {
|
||||||
|
out.beginElement('div');
|
||||||
|
out.text(data.name + ':' + data.age);
|
||||||
|
out.endElement();
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,5 +0,0 @@
|
|||||||
<div>
|
|
||||||
<h1>
|
|
||||||
Hello World!
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
22
test/deprecated-render-test.js
Normal file
22
test/deprecated-render-test.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
'use strict';
|
||||||
|
require('./util/patch-module');
|
||||||
|
|
||||||
|
var chai = require('chai');
|
||||||
|
chai.config.includeStack = true;
|
||||||
|
var path = require('path');
|
||||||
|
var autotest = require('./autotest');
|
||||||
|
var runRenderTest = require('./util/runRenderTest');
|
||||||
|
|
||||||
|
require('../node-require').install();
|
||||||
|
|
||||||
|
describe('render', function() {
|
||||||
|
var autoTestDir = path.join(__dirname, 'autotests/render-deprecated');
|
||||||
|
|
||||||
|
autotest.scanDir(
|
||||||
|
autoTestDir,
|
||||||
|
function run(dir, helpers, done) {
|
||||||
|
runRenderTest(dir, helpers, done, {
|
||||||
|
output: 'html'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,18 +1,3 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 eBay Software Foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function getContainingWidgetNode() {
|
function getContainingWidgetNode() {
|
||||||
if (this.containingWidgetNode !== undefined) {
|
if (this.containingWidgetNode !== undefined) {
|
||||||
@ -22,7 +7,7 @@ function getContainingWidgetNode() {
|
|||||||
var curNode = this.el;
|
var curNode = this.el;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (curNode.tagName === 'w-widget') {
|
if (curNode.tagName === '_widget') {
|
||||||
this.containingWidgetNode = curNode;
|
this.containingWidgetNode = curNode;
|
||||||
return this.containingWidgetNode;
|
return this.containingWidgetNode;
|
||||||
} else if (curNode.isFlagSet('hasWidgetExtend')) {
|
} else if (curNode.isFlagSet('hasWidgetExtend')) {
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var includeTagForWidgets = require.resolve('../include-tag');
|
||||||
|
|
||||||
module.exports = function(includeNode) {
|
module.exports = function(includeNode) {
|
||||||
var builder = this.builder;
|
var builder = this.builder;
|
||||||
var context = this.context;
|
var context = this.context;
|
||||||
@ -11,15 +13,13 @@ module.exports = function(includeNode) {
|
|||||||
|
|
||||||
var parentNode = includeNode.parentNode;
|
var parentNode = includeNode.parentNode;
|
||||||
|
|
||||||
var parentTransformHelper;
|
|
||||||
|
|
||||||
parentNode._normalizeChildTextNodes(context);
|
parentNode._normalizeChildTextNodes(context);
|
||||||
|
|
||||||
if (parentNode.childCount === 1) {
|
if (parentNode.childCount === 1) {
|
||||||
parentTransformHelper = this.getTransformHelper(parentNode);
|
let parentTransformHelper = this.getTransformHelper(parentNode);
|
||||||
|
|
||||||
if (includeNode.argument) {
|
if (includeNode.argument) {
|
||||||
var widgetIdInfo = parentTransformHelper.assignWidgetId(true /* repeated */);
|
let widgetIdInfo = parentTransformHelper.assignWidgetId(true /* repeated */);
|
||||||
if (!widgetIdInfo.idVarNode) {
|
if (!widgetIdInfo.idVarNode) {
|
||||||
let idVarNode = widgetIdInfo.createIdVarNode();
|
let idVarNode = widgetIdInfo.createIdVarNode();
|
||||||
parentNode.onBeforeGenerateCode((event) => {
|
parentNode.onBeforeGenerateCode((event) => {
|
||||||
@ -30,35 +30,44 @@ module.exports = function(includeNode) {
|
|||||||
parentTransformHelper.assignWidgetId(false /* not repeated */);
|
parentTransformHelper.assignWidgetId(false /* not repeated */);
|
||||||
widgetTagNode.setAttributeValue('body', parentTransformHelper.getNestedIdExpression());
|
widgetTagNode.setAttributeValue('body', parentTransformHelper.getNestedIdExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!includeNode.data.includeTarget) {
|
||||||
|
includeNode.addProp('_target', builder.memberExpression(builder.identifier('data'), builder.identifier('widgetBody')));
|
||||||
|
}
|
||||||
|
|
||||||
|
includeNode.setRendererPath(includeTagForWidgets);
|
||||||
|
|
||||||
|
includeNode.onBeforeGenerateCode(function() {
|
||||||
|
includeNode.addProp('_widgetId', parentTransformHelper.getIdExpression());
|
||||||
|
includeNode.addProp('_widget', builder.identifier('widget'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
includeNode.generateCodeForDynamicInclude = (options, codegen) => {
|
|
||||||
var target = options.target;
|
|
||||||
var data = options.data;
|
|
||||||
|
|
||||||
if (!target) {
|
|
||||||
target = builder.memberExpression(builder.identifier('data'), builder.identifier('widgetBody'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data) {
|
// includeNode.generateCodeForDynamicInclude = (options, codegen) => {
|
||||||
data = builder.literal(null);
|
// var target = options.target;
|
||||||
}
|
// var data = options.data;
|
||||||
|
//
|
||||||
let includeVar = context.importModule('marko_widget_include', this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/include'));
|
// if (!data) {
|
||||||
|
// data = builder.literal(null);
|
||||||
let includeArgs = [
|
// }
|
||||||
target,
|
//
|
||||||
builder.identifierOut(),
|
// let includeVar = context.importModule('marko_widget_include', this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/include'));
|
||||||
data
|
//
|
||||||
];
|
// let includeArgs = [
|
||||||
|
// target,
|
||||||
if (parentTransformHelper) {
|
// builder.identifierOut(),
|
||||||
includeArgs = includeArgs.concat([
|
// data
|
||||||
parentTransformHelper.getIdExpression(),
|
// ];
|
||||||
builder.identifier('widget')
|
//
|
||||||
]);
|
// if (parentTransformHelper) {
|
||||||
}
|
// includeArgs = includeArgs.concat([
|
||||||
|
// parentTransformHelper.getIdExpression(),
|
||||||
return builder.functionCall(includeVar, includeArgs);
|
//
|
||||||
};
|
// ]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return builder.functionCall(includeVar, includeArgs);
|
||||||
|
// };
|
||||||
};
|
};
|
||||||
@ -165,7 +165,7 @@ module.exports = function handleWidgetBind() {
|
|||||||
widgetAttrs.id = id;
|
widgetAttrs.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let widgetNode = context.createNodeForEl('w-widget', widgetAttrs);
|
let widgetNode = context.createNodeForEl('_widget', widgetAttrs);
|
||||||
el.wrapWith(widgetNode);
|
el.wrapWith(widgetNode);
|
||||||
|
|
||||||
el.setAttributeValue('id', builder.memberExpression(builder.identifier('widget'), builder.identifier('id')));
|
el.setAttributeValue('id', builder.memberExpression(builder.identifier('widget'), builder.identifier('id')));
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
var isBrowser = typeof window !== 'undefined';
|
|
||||||
var normalInclude = require('../../../runtime/include');
|
|
||||||
var markoWidgets = require('../../');
|
|
||||||
|
|
||||||
module.exports = function include(target, out, data, id, widget) {
|
|
||||||
if (typeof target === 'string') {
|
|
||||||
out.text(target);
|
|
||||||
} else if (target) {
|
|
||||||
normalInclude(target, out, data || widget);
|
|
||||||
} else if (isBrowser) {
|
|
||||||
if (id) {
|
|
||||||
// There is no body content so let's see if we should reuse
|
|
||||||
// the existing body content in the DOM
|
|
||||||
var existingEl = document.getElementById(id);
|
|
||||||
if (existingEl) {
|
|
||||||
var widgetsContext = markoWidgets.getWidgetsContext(out);
|
|
||||||
widgetsContext.addPreservedDOMNode(existingEl, true /* body only */);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('Invalid include');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
23
widgets/taglib/include-tag.js
Normal file
23
widgets/taglib/include-tag.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
var isBrowser = typeof window !== 'undefined';
|
||||||
|
var normalInclude = require('../../taglibs/core/include-tag');
|
||||||
|
var markoWidgets = require('../');
|
||||||
|
|
||||||
|
module.exports = function include(input, out) {
|
||||||
|
var target = input._target;
|
||||||
|
|
||||||
|
if (typeof target === 'string') {
|
||||||
|
out.text(target);
|
||||||
|
} else if (target) {
|
||||||
|
normalInclude(input, out);
|
||||||
|
} else if (isBrowser) {
|
||||||
|
var widgetId = input._widgetId;
|
||||||
|
|
||||||
|
// Thereis no body content so let's see if we should reuse
|
||||||
|
// the existing body content in the DOM
|
||||||
|
var existingEl = document.getElementById(widgetId);
|
||||||
|
if (existingEl) {
|
||||||
|
var widgetsContext = markoWidgets.getWidgetsContext(out);
|
||||||
|
widgetsContext.addPreservedDOMNode(existingEl, true /* body only */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -195,7 +195,7 @@
|
|||||||
},
|
},
|
||||||
"transformer": "./widgets-transformer.js"
|
"transformer": "./widgets-transformer.js"
|
||||||
},
|
},
|
||||||
"<w-widget>": {
|
"<_widget>": {
|
||||||
"renderer": "./widget-tag.js",
|
"renderer": "./widget-tag.js",
|
||||||
"@type": "object",
|
"@type": "object",
|
||||||
"@config": "object",
|
"@config": "object",
|
||||||
|
|||||||
@ -1,24 +1,8 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 eBay Software Foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
var markoWidgets = require('../');
|
var markoWidgets = require('../');
|
||||||
var extend = require('raptor-util/extend');
|
var extend = require('raptor-util/extend');
|
||||||
var widgetArgsId = require('../widget-args-id');
|
var widgetArgsId = require('../widget-args-id');
|
||||||
var includeHelper = require('./helpers/include');
|
var includeTag = require('./include-tag');
|
||||||
|
|
||||||
var DUMMY_WIDGET_DEF = {
|
var DUMMY_WIDGET_DEF = {
|
||||||
elId: function () {
|
elId: function () {
|
||||||
@ -50,7 +34,10 @@ function preserveWidgetEl(existingWidget, out, widgetsContext, widgetBody) {
|
|||||||
|
|
||||||
if (widgetBody && existingWidget.bodyEl) {
|
if (widgetBody && existingWidget.bodyEl) {
|
||||||
hasUnpreservedBody = true;
|
hasUnpreservedBody = true;
|
||||||
includeHelper(widgetBody, out, null, existingWidget.bodyEl.id, existingWidget.bodyEl.id);
|
includeTag({
|
||||||
|
_target: widgetBody,
|
||||||
|
_widgetId: existingWidget.bodyEl.id
|
||||||
|
}, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.endElement();
|
out.endElement();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user