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 ok = require('assert').ok;
|
||||
var tagLoader;
|
||||
var Node = require('./Node');
|
||||
|
||||
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 {
|
||||
constructor(el, tagDef) {
|
||||
super(el);
|
||||
@ -168,6 +214,8 @@ class CustomTag extends HtmlElement {
|
||||
this._condition = null;
|
||||
this._foundNestedTagsByName = {};
|
||||
this._hasDynamicNestedTags = false;
|
||||
this._additionalProps = null;
|
||||
this._rendererPath = null;
|
||||
}
|
||||
|
||||
buildInputProps(codegen) {
|
||||
@ -342,6 +390,26 @@ class CustomTag extends HtmlElement {
|
||||
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) {
|
||||
if (!this._nestedTagVar) {
|
||||
var tagDef = this.tagDef;
|
||||
@ -364,25 +432,22 @@ class CustomTag extends HtmlElement {
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
processDirectlyNestedTags(this, codegen);
|
||||
var body = codegen.generateCode(this.body);
|
||||
context.popData(CUSTOM_TAG_KEY);
|
||||
|
||||
// console.log(module.id, 'generateCode END:', this.tagName);
|
||||
|
||||
var isNestedTag = tagDef.isNestedTag === true;
|
||||
if (isNestedTag) {
|
||||
parentCustomTag = context.getData(CUSTOM_TAG_KEY);
|
||||
|
||||
// console.log('parentCustomTag:', parentCustomTag.tagName, 'child:', tagDef.name);
|
||||
|
||||
if (!parentCustomTag) {
|
||||
if (tagDef.parentTagName) {
|
||||
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);
|
||||
|
||||
// if (isNestedTag) {
|
||||
// isRepeated = tagDef.isRepeated === true;
|
||||
// targetProperty = tagDef.targetProperty;
|
||||
// parentTagVar = parentCustomTag.getNestedTagVar(context);
|
||||
// }
|
||||
|
||||
var renderBodyFunction;
|
||||
|
||||
if (body && body.length) {
|
||||
@ -481,29 +540,31 @@ class CustomTag extends HtmlElement {
|
||||
bodyOnlyIf = null;
|
||||
}
|
||||
|
||||
inputProps = builder.literal(inputProps);
|
||||
var argExpression;
|
||||
|
||||
var argument = this.argument;
|
||||
if (this.argument) {
|
||||
argExpression = builder.parseExpression(this.argument);
|
||||
}
|
||||
|
||||
if (argument) {
|
||||
argument = builder.parseExpression(argument);
|
||||
var additionalProps = this._additionalProps;
|
||||
|
||||
if (Object.keys(inputProps.value).length === 0) {
|
||||
inputProps = argument;
|
||||
} else {
|
||||
var mergeVar = context.helper('merge');
|
||||
inputProps = builder.functionCall(mergeVar, [
|
||||
inputProps, // Input props from the attributes take precedence
|
||||
argument
|
||||
]);
|
||||
}
|
||||
if (additionalProps) {
|
||||
inputProps = merge(additionalProps, inputProps, context);
|
||||
}
|
||||
|
||||
if (argExpression) {
|
||||
inputProps = merge(argExpression, inputProps, context);
|
||||
}
|
||||
|
||||
if (!(inputProps instanceof Node)) {
|
||||
inputProps = builder.literal(inputProps);
|
||||
}
|
||||
|
||||
if (hasDynamicNestedTags) {
|
||||
inputProps = builder.functionCall(context.helper('mergeNestedTagsHelper'), [ inputProps ]);
|
||||
}
|
||||
|
||||
var rendererPath = tagDef.renderer;
|
||||
var rendererPath = this._rendererPath || tagDef.renderer;
|
||||
var rendererRequirePath;
|
||||
var requireRendererFunctionCall;
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
"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-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-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",
|
||||
|
||||
@ -7,7 +7,7 @@ function classListHelper(arg, classNames) {
|
||||
if (arg) {
|
||||
if (typeof arg === 'string') {
|
||||
if (arg) {
|
||||
classNames.push(arg);
|
||||
classNames.push(arg);
|
||||
}
|
||||
} else if (typeof (len = arg.length) === 'number') {
|
||||
for (var i=0; i<len; i++) {
|
||||
@ -250,5 +250,4 @@ exports.cl = function classListHelper() {
|
||||
/**
|
||||
* Loads a template (__helpers.l --> marko_loadTemplate(path))
|
||||
*/
|
||||
exports.l = require('./loader');
|
||||
exports.i = require('./include');
|
||||
exports.l = require('./loader');
|
||||
@ -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';
|
||||
var removeHyphens = require('../../compiler/util/removeDashes');
|
||||
|
||||
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;
|
||||
module.exports = function include(input, out) {
|
||||
var target = input._target;
|
||||
var arg = input._arg || input;
|
||||
|
||||
if (target) {
|
||||
if (target.type === 'Literal') {
|
||||
target = codegen.context.importTemplate(target.value);
|
||||
isTemplate = true;
|
||||
}
|
||||
}
|
||||
|
||||
let finalData = {};
|
||||
let attrs = el.getAttributes();
|
||||
attrs.forEach((attr) => {
|
||||
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'));
|
||||
if (typeof target === 'function') {
|
||||
target(out, arg);
|
||||
} else if (typeof target === 'object') {
|
||||
if (target.renderBody) {
|
||||
target.renderBody(out, arg);
|
||||
} else if (target.renderer) {
|
||||
target.renderer(arg, out);
|
||||
} else if (target.render) {
|
||||
target.render(arg, out);
|
||||
}
|
||||
|
||||
let includeVar = codegen.context.helper('include');
|
||||
let includeArgs = [ target, builder.identifierOut() ];
|
||||
|
||||
if (finalData) {
|
||||
includeArgs.push(finalData);
|
||||
}
|
||||
|
||||
return builder.functionCall(includeVar, includeArgs);
|
||||
} else {
|
||||
throw new Error('Invalid include target: ' + target);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -79,7 +79,8 @@
|
||||
"code-generator": "./import-tag"
|
||||
},
|
||||
"<include>": {
|
||||
"code-generator": "./include-tag",
|
||||
"renderer": "./include-tag",
|
||||
"transformer": "./include-tag-transformer",
|
||||
"autocomplete": [
|
||||
{
|
||||
"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]) ...>');
|
||||
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 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() {
|
||||
if (this.containingWidgetNode !== undefined) {
|
||||
@ -22,7 +7,7 @@ function getContainingWidgetNode() {
|
||||
var curNode = this.el;
|
||||
|
||||
while (true) {
|
||||
if (curNode.tagName === 'w-widget') {
|
||||
if (curNode.tagName === '_widget') {
|
||||
this.containingWidgetNode = curNode;
|
||||
return this.containingWidgetNode;
|
||||
} else if (curNode.isFlagSet('hasWidgetExtend')) {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var includeTagForWidgets = require.resolve('../include-tag');
|
||||
|
||||
module.exports = function(includeNode) {
|
||||
var builder = this.builder;
|
||||
var context = this.context;
|
||||
@ -11,15 +13,13 @@ module.exports = function(includeNode) {
|
||||
|
||||
var parentNode = includeNode.parentNode;
|
||||
|
||||
var parentTransformHelper;
|
||||
|
||||
parentNode._normalizeChildTextNodes(context);
|
||||
|
||||
if (parentNode.childCount === 1) {
|
||||
parentTransformHelper = this.getTransformHelper(parentNode);
|
||||
let parentTransformHelper = this.getTransformHelper(parentNode);
|
||||
|
||||
if (includeNode.argument) {
|
||||
var widgetIdInfo = parentTransformHelper.assignWidgetId(true /* repeated */);
|
||||
let widgetIdInfo = parentTransformHelper.assignWidgetId(true /* repeated */);
|
||||
if (!widgetIdInfo.idVarNode) {
|
||||
let idVarNode = widgetIdInfo.createIdVarNode();
|
||||
parentNode.onBeforeGenerateCode((event) => {
|
||||
@ -30,35 +30,44 @@ module.exports = function(includeNode) {
|
||||
parentTransformHelper.assignWidgetId(false /* not repeated */);
|
||||
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) {
|
||||
data = builder.literal(null);
|
||||
}
|
||||
|
||||
let includeVar = context.importModule('marko_widget_include', this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/include'));
|
||||
|
||||
let includeArgs = [
|
||||
target,
|
||||
builder.identifierOut(),
|
||||
data
|
||||
];
|
||||
|
||||
if (parentTransformHelper) {
|
||||
includeArgs = includeArgs.concat([
|
||||
parentTransformHelper.getIdExpression(),
|
||||
builder.identifier('widget')
|
||||
]);
|
||||
}
|
||||
|
||||
return builder.functionCall(includeVar, includeArgs);
|
||||
};
|
||||
// includeNode.generateCodeForDynamicInclude = (options, codegen) => {
|
||||
// var target = options.target;
|
||||
// var data = options.data;
|
||||
//
|
||||
// if (!data) {
|
||||
// data = builder.literal(null);
|
||||
// }
|
||||
//
|
||||
// let includeVar = context.importModule('marko_widget_include', this.getMarkoWidgetsRequirePath('marko/widgets/taglib/helpers/include'));
|
||||
//
|
||||
// let includeArgs = [
|
||||
// target,
|
||||
// builder.identifierOut(),
|
||||
// data
|
||||
// ];
|
||||
//
|
||||
// if (parentTransformHelper) {
|
||||
// includeArgs = includeArgs.concat([
|
||||
// parentTransformHelper.getIdExpression(),
|
||||
//
|
||||
// ]);
|
||||
// }
|
||||
//
|
||||
// return builder.functionCall(includeVar, includeArgs);
|
||||
// };
|
||||
};
|
||||
@ -165,7 +165,7 @@ module.exports = function handleWidgetBind() {
|
||||
widgetAttrs.id = id;
|
||||
}
|
||||
|
||||
let widgetNode = context.createNodeForEl('w-widget', widgetAttrs);
|
||||
let widgetNode = context.createNodeForEl('_widget', widgetAttrs);
|
||||
el.wrapWith(widgetNode);
|
||||
|
||||
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"
|
||||
},
|
||||
"<w-widget>": {
|
||||
"<_widget>": {
|
||||
"renderer": "./widget-tag.js",
|
||||
"@type": "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';
|
||||
var markoWidgets = require('../');
|
||||
var extend = require('raptor-util/extend');
|
||||
var widgetArgsId = require('../widget-args-id');
|
||||
var includeHelper = require('./helpers/include');
|
||||
var includeTag = require('./include-tag');
|
||||
|
||||
var DUMMY_WIDGET_DEF = {
|
||||
elId: function () {
|
||||
@ -50,7 +34,10 @@ function preserveWidgetEl(existingWidget, out, widgetsContext, widgetBody) {
|
||||
|
||||
if (widgetBody && existingWidget.bodyEl) {
|
||||
hasUnpreservedBody = true;
|
||||
includeHelper(widgetBody, out, null, existingWidget.bodyEl.id, existingWidget.bodyEl.id);
|
||||
includeTag({
|
||||
_target: widgetBody,
|
||||
_widgetId: existingWidget.bodyEl.id
|
||||
}, out);
|
||||
}
|
||||
|
||||
out.endElement();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user