Welcome to mirror list, hosted at ThFree Co, Russian Federation.

compiler.js « vue3migration « config - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a2c82584227f8e5d67b302755b1639fb0a21749a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const { parse, compile: compilerDomCompile } = require('@vue/compiler-dom');

const COMMENT_NODE_TYPE = 3;

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);

    // We do not want to switch to whitespace: collapse mode which is Vue.js 3 default
    // It will be too devastating to codebase

    // However, without `whitespace: condense` Vue will treat spaces between comments
    // and nodes itself as text nodes, resulting in multi-root component
    // For multi-root component passing classes / attributes fallthrough will not work

    // See https://github.com/vuejs/core/issues/7909 for details

    // To fix that we simply drop all component comments only on top-level
    rootNode.children = rootNode.children.filter((n) => n.type !== COMMENT_NODE_TYPE);

    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);
  },
};