diff options
Diffstat (limited to 'config/vue3migration/compiler.js')
-rw-r--r-- | config/vue3migration/compiler.js | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/config/vue3migration/compiler.js b/config/vue3migration/compiler.js new file mode 100644 index 00000000000..bb92e1e2356 --- /dev/null +++ b/config/vue3migration/compiler.js @@ -0,0 +1,50 @@ +const { parse, compile: compilerDomCompile } = require('@vue/compiler-dom'); + +const getPropIndex = (node, prop) => node.props?.findIndex((p) => p.name === prop) ?? -1; + +function modifyKeysInsideTemplateTag(templateNode) { + let keyCandidate = null; + for (const node of templateNode.children) { + const keyBindingIndex = node.props + ? node.props.findIndex((prop) => prop.arg && prop.arg.content === 'key') + : -1; + + if (keyBindingIndex !== -1 && getPropIndex(node, 'for') === -1) { + if (!keyCandidate) { + keyCandidate = node.props[keyBindingIndex]; + } + node.props.splice(keyBindingIndex, 1); + } + } + + if (keyCandidate) { + templateNode.props.push(keyCandidate); + } +} + +module.exports = { + parse, + compile(template, options) { + const rootNode = parse(template, options); + const pendingNodes = [rootNode]; + while (pendingNodes.length) { + const currentNode = pendingNodes.pop(); + if (getPropIndex(currentNode, 'for') !== -1) { + if (currentNode.tag === 'template') { + // This one will be dropped all together with compiler when we drop Vue.js 2 support + modifyKeysInsideTemplateTag(currentNode); + } + + // This one will be dropped when https://github.com/vuejs/core/issues/7725 will be fixed + const vOncePropIndex = getPropIndex(currentNode, 'once'); + if (vOncePropIndex !== -1) { + currentNode.props.splice(vOncePropIndex, 1); + } + } + + currentNode.children?.forEach((child) => pendingNodes.push(child)); + } + + return compilerDomCompile(rootNode, options); + }, +}; |