mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #508 - Bugs in the static sub-tree optimization for VDOM compilation
This commit is contained in:
parent
0d7839c533
commit
29d7482c90
@ -21,12 +21,37 @@ c) Else, generate one of the following:
|
||||
|
||||
*/
|
||||
|
||||
|
||||
const Node = require('../../ast/Node');
|
||||
const nextConstIdFuncSymbol = Symbol();
|
||||
const OPTIMIZER_CONTEXT_KEY = Symbol();
|
||||
|
||||
const OPTIONS_DEFAULT = { optimizeTextNodes: true, optimizeStaticNodes: true };
|
||||
const OPTIONS_OPTIMIZE_TEXT_NODES = { optimizeTextNodes: true, optimizeStaticNodes: false };
|
||||
|
||||
class OptimizerContext {
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
|
||||
this.nextAttrsId = 0;
|
||||
this.nextNodeId = 0;
|
||||
this._nextConstIdFunc = null;
|
||||
}
|
||||
|
||||
get nextConstIdFunc() {
|
||||
let nextConstIdFunc = this._nextConstIdFunc;
|
||||
if (!nextConstIdFunc) {
|
||||
let context = this.context;
|
||||
let builder = context.builder;
|
||||
let constId = this.context.helper('const');
|
||||
let fingerprintLiteral = builder.literal(context.getFingerprint(6));
|
||||
nextConstIdFunc = this._nextConstIdFunc = context.addStaticVar(
|
||||
'marko_const_nextId',
|
||||
builder.functionCall(constId, [ fingerprintLiteral ]));
|
||||
}
|
||||
return nextConstIdFunc;
|
||||
}
|
||||
}
|
||||
|
||||
class NodeVDOM extends Node {
|
||||
constructor(variableIdentifier) {
|
||||
super('NodeVDOM');
|
||||
@ -54,8 +79,10 @@ class NodeVDOM extends Node {
|
||||
|
||||
function generateNodesForArray(nodes, context, options) {
|
||||
let builder = context.builder;
|
||||
let nextNodeId = 0;
|
||||
let nextAttrsId = 0;
|
||||
|
||||
var optimizerContext = context[OPTIMIZER_CONTEXT_KEY] ||
|
||||
(context[OPTIMIZER_CONTEXT_KEY] = new OptimizerContext(context));
|
||||
|
||||
|
||||
var optimizeStaticNodes = options.optimizeStaticNodes !== false;
|
||||
|
||||
@ -66,17 +93,10 @@ function generateNodesForArray(nodes, context, options) {
|
||||
node.createTextId = context.importModule('marko_createText', 'marko/vdom/createText');
|
||||
}*/
|
||||
|
||||
let nextConstIdFunc = context.data[nextConstIdFuncSymbol];
|
||||
if (!nextConstIdFunc) {
|
||||
let constId = context.helper('const');
|
||||
let fingerprintLiteral = builder.literal(context.getFingerprint(6));
|
||||
nextConstIdFunc = context.data[nextConstIdFuncSymbol] = context.addStaticVar('marko_const_nextId', builder.functionCall(constId, [ fingerprintLiteral ]));
|
||||
}
|
||||
|
||||
node.nextConstId = builder.functionCall(nextConstIdFunc, []);
|
||||
node.nextConstId = builder.functionCall(optimizerContext.nextConstIdFunc, []);
|
||||
|
||||
node.isStaticRoot = true;
|
||||
let staticNodeId = context.addStaticVar('marko_node' + (nextNodeId++), node);
|
||||
let staticNodeId = context.addStaticVar('marko_node' + (optimizerContext.nextNodeId++), node);
|
||||
|
||||
return new NodeVDOM(staticNodeId);
|
||||
}
|
||||
@ -85,7 +105,7 @@ function generateNodesForArray(nodes, context, options) {
|
||||
var attributesArg = node.attributesArg;
|
||||
if (attributesArg) {
|
||||
node.isStaticRoot = true;
|
||||
let staticAttrsId = context.addStaticVar('marko_attrs' + (nextAttrsId++), attributesArg);
|
||||
let staticAttrsId = context.addStaticVar('marko_attrs' + (optimizerContext.nextAttrsId++), attributesArg);
|
||||
node.attributesArg = staticAttrsId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,8 @@ var marko_template = module.exports = require("marko/vdom").t(),
|
||||
marko_const = marko_helpers.const,
|
||||
marko_const_nextId = marko_const("6597f2"),
|
||||
marko_node0 = marko_createElement("div", null, 1, marko_const_nextId())
|
||||
.t("No colors!"),
|
||||
marko_node1 = marko_createElement("div", null, 1, marko_const_nextId())
|
||||
.t("No colors!");
|
||||
|
||||
function render(data, out) {
|
||||
@ -37,7 +39,7 @@ function render(data, out) {
|
||||
|
||||
out.ee();
|
||||
} else {
|
||||
out.n(marko_node0);
|
||||
out.n(marko_node1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
test/autotests/render/static-trees/expected.html
Normal file
1
test/autotests/render/static-trees/expected.html
Normal file
@ -0,0 +1 @@
|
||||
<div id="prodHolder"><div class="A"><div class="B">yes</div><div class="C"></div><div class="C"></div></div><div class="D"><div class="E"><div class="F"><div class="G">yes</div><div class="H">H-yes</div></div><div class="I"><div class="J">yes</div></div></div><div class="K"><div class="L"><div class="M"><div class="N">yes</div></div></div><div class="O">yes</div><div class="P">P-yes</div></div><div class="Q">Q-body: This div should have a class of Q</div></div></div>
|
||||
44
test/autotests/render/static-trees/template.marko
Normal file
44
test/autotests/render/static-trees/template.marko
Normal file
@ -0,0 +1,44 @@
|
||||
<div id="prodHolder">
|
||||
<div class="A">
|
||||
<div class="B">
|
||||
${true ? 'yes' : 'no'}
|
||||
</div>
|
||||
<div class="C" for(var i=0;i<2;i++)>
|
||||
</div>
|
||||
</div>
|
||||
<div class="D">
|
||||
<div class="E">
|
||||
<div class="F">
|
||||
<div class="G">
|
||||
${true ? 'yes' : 'no'}
|
||||
</div>
|
||||
<div class="H">
|
||||
${true ? 'H-yes' : 'H-no'}
|
||||
</div>
|
||||
</div>
|
||||
<div class="I">
|
||||
<if(1 > 0)>
|
||||
<div class="J">${true ? 'yes' : 'no'}</div>
|
||||
</if>
|
||||
</div>
|
||||
</div>
|
||||
<div class="K">
|
||||
<div class="L">
|
||||
<div class="M">
|
||||
<div class="N">
|
||||
$!{true ? 'yes' : 'no'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="O">
|
||||
${true ? 'yes' : 'no'}
|
||||
</div>
|
||||
<div class="P">
|
||||
${true ? 'P-yes' : 'P-no'}
|
||||
</div>
|
||||
</div>
|
||||
<div class="Q">
|
||||
Q-body: ${true ? 'This div should have a class of Q' : 'no'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user