From 9cb32d850af6341b8c25958a4b89d0c9aae492b4 Mon Sep 17 00:00:00 2001
From: chenzhihui <18281682921@qqcom>
Date: Tue, 18 Oct 2022 10:24:06 +0800
Subject: [PATCH 01/10] fix(compiler-core):consistent behavior of
@update:modelValue and @update:model-value
---
.../__tests__/transforms/vOn.spec.ts | 37 +++++++++++++++++++
packages/compiler-core/src/transforms/vOn.ts | 4 +-
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
index 8f943a7491f..3243e0eead3 100644
--- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
@@ -68,6 +68,43 @@ describe('compiler: transform v-on', () => {
})
})
+ // # fix: #6900 Ensure consistent behavior of @update:modelValue and @update:model-value
+ test('consistent behavior of @update:modelValue and @update:model-value', () => {
+ const { node } = parseWithVOn(`
`)
+ const { node: nodeV } = parseWithVOn(
+ ``
+ )
+ expect((node.codegenNode as VNodeCall).props).toMatchObject({
+ properties: [
+ {
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'onUpdate:modelValue'
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `handler`,
+ isStatic: false
+ }
+ }
+ ]
+ })
+ expect((nodeV.codegenNode as VNodeCall).props).toMatchObject({
+ properties: [
+ {
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'onUpdate:modelValue'
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `handler`,
+ isStatic: false
+ }
+ }
+ ]
+ })
+ })
test('dynamic arg', () => {
const { node } = parseWithVOn(``)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index ed39ecee12f..1e56b543226 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -50,7 +50,8 @@ export const transformOn: DirectiveTransform = (
const eventString =
node.tagType === ElementTypes.COMPONENT ||
rawName.startsWith('vnode') ||
- !/[A-Z]/.test(rawName)
+ !/[A-Z]/.test(rawName) ||
+ rawName === 'update:modelValue'
? // for component and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
toHandlerKey(camelize(rawName))
@@ -162,7 +163,6 @@ export const transformOn: DirectiveTransform = (
)
]
}
-
// apply extended compiler augmentor
if (augmentor) {
ret = augmentor(ret)
From 1807ed9cd4a761e933673724502d468bd378bb11 Mon Sep 17 00:00:00 2001
From: chenzhihui <18281682921@qqcom>
Date: Tue, 18 Oct 2022 10:33:30 +0800
Subject: [PATCH 02/10] fix(compiler-core): update
---
packages/compiler-core/src/transforms/vOn.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index 1e56b543226..cb830e409a5 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -50,8 +50,8 @@ export const transformOn: DirectiveTransform = (
const eventString =
node.tagType === ElementTypes.COMPONENT ||
rawName.startsWith('vnode') ||
- !/[A-Z]/.test(rawName) ||
- rawName === 'update:modelValue'
+ (!/[A-Z]/.test(rawName) ||
+ rawName === 'update:modelValue')
? // for component and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
toHandlerKey(camelize(rawName))
From 4abb5220f82f4543f21e2db9c734c5624b990bac Mon Sep 17 00:00:00 2001
From: chenzhihui <18281682921@qqcom>
Date: Tue, 18 Oct 2022 11:02:32 +0800
Subject: [PATCH 03/10] fix(compiler-core): added code comments
---
packages/compiler-core/src/transforms/vOn.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index cb830e409a5..37387bfe250 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -51,6 +51,8 @@ export const transformOn: DirectiveTransform = (
node.tagType === ElementTypes.COMPONENT ||
rawName.startsWith('vnode') ||
(!/[A-Z]/.test(rawName) ||
+ // See issue #6900,Ensure consistent behavior of
+ // @update:modelValue and @update:model-value
rawName === 'update:modelValue')
? // for component and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
From 3694df4087546dde9230f54b24d4f74556c4b5da Mon Sep 17 00:00:00 2001
From: baiwusanyu <740132583@qq.com>
Date: Tue, 18 Oct 2022 20:58:11 +0800
Subject: [PATCH 04/10] fix(compiler-core):avoid removing/adding empty linves
---
packages/compiler-core/src/transforms/vOn.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index 37387bfe250..a6ef0da027f 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -165,6 +165,7 @@ export const transformOn: DirectiveTransform = (
)
]
}
+
// apply extended compiler augmentor
if (augmentor) {
ret = augmentor(ret)
From 563ef08669fd4f52af48329b622cab81a682d692 Mon Sep 17 00:00:00 2001
From: baiwusanyu <740132583@qq.com>
Date: Tue, 18 Oct 2022 22:43:37 +0800
Subject: [PATCH 05/10] fix(compiler-core):update
---
.../__tests__/transforms/vOn.spec.ts | 24 +++++++++++--------
.../__tests__/transforms/vSlot.spec.ts | 2 +-
packages/compiler-core/src/transforms/vOn.ts | 6 ++---
3 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
index 3243e0eead3..afa16ff24c0 100644
--- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
@@ -8,11 +8,12 @@ import {
NodeTypes,
ObjectExpression,
transform,
- VNodeCall
+ VNodeCall, RenderSlotCall,
} from '../../src'
import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
+import {parseWithSlots} from "./vSlot.spec";
function parseWithVOn(template: string, options: CompilerOptions = {}) {
const ast = parse(template, options)
@@ -68,18 +69,17 @@ describe('compiler: transform v-on', () => {
})
})
- // # fix: #6900 Ensure consistent behavior of @update:modelValue and @update:model-value
+ // # fix: #6900
test('consistent behavior of @update:modelValue and @update:model-value', () => {
- const { node } = parseWithVOn(``)
- const { node: nodeV } = parseWithVOn(
- ``
- )
- expect((node.codegenNode as VNodeCall).props).toMatchObject({
+ const { root:rootUpper } = parseWithSlots(`
`)
+ const slotNodeUpper = ((rootUpper).codegenNode! as VNodeCall).children as ElementNode[]
+ const propertiesObjUpper= (slotNodeUpper[0].codegenNode! as RenderSlotCall).arguments[2]
+ expect(propertiesObjUpper).toMatchObject({
properties: [
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onUpdate:modelValue'
+ content: 'onFoo:modelValue',
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
@@ -89,12 +89,16 @@ describe('compiler: transform v-on', () => {
}
]
})
- expect((nodeV.codegenNode as VNodeCall).props).toMatchObject({
+
+ const { root } = parseWithSlots(`
`)
+ const slotNode = ((root).codegenNode! as VNodeCall).children as ElementNode[]
+ const propertiesObj = (slotNode[0].codegenNode! as RenderSlotCall).arguments[2]
+ expect(propertiesObj).toMatchObject({
properties: [
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onUpdate:modelValue'
+ content: 'onFoo:modelValue',
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
index 93dafe9a25b..b5a60340909 100644
--- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
@@ -28,7 +28,7 @@ import { PatchFlags } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
-function parseWithSlots(template: string, options: CompilerOptions = {}) {
+export function parseWithSlots(template: string, options: CompilerOptions = {}) {
const ast = parse(template, {
whitespace: options.whitespace
})
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index a6ef0da027f..385777e9c41 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -49,11 +49,9 @@ export const transformOn: DirectiveTransform = (
}
const eventString =
node.tagType === ElementTypes.COMPONENT ||
+ node.tagType === ElementTypes.SLOT ||
rawName.startsWith('vnode') ||
- (!/[A-Z]/.test(rawName) ||
- // See issue #6900,Ensure consistent behavior of
- // @update:modelValue and @update:model-value
- rawName === 'update:modelValue')
+ !/[A-Z]/.test(rawName)
? // for component and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
toHandlerKey(camelize(rawName))
From 73bd5a143a98a0dbb9aa54c2a88d4e5c65f95001 Mon Sep 17 00:00:00 2001
From: baiwusanyu <740132583@qq.com>
Date: Tue, 18 Oct 2022 22:55:46 +0800
Subject: [PATCH 06/10] fix(compiler-core):added code comments
---
packages/compiler-core/src/transforms/vOn.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index 385777e9c41..1f855d79c0d 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -49,6 +49,7 @@ export const transformOn: DirectiveTransform = (
}
const eventString =
node.tagType === ElementTypes.COMPONENT ||
+ // fix:6900
node.tagType === ElementTypes.SLOT ||
rawName.startsWith('vnode') ||
!/[A-Z]/.test(rawName)
From 22150c9298f8c482fd7016a824853c033c6a4443 Mon Sep 17 00:00:00 2001
From: chenzhihui <18281682921@qqcom>
Date: Wed, 19 Oct 2022 08:50:55 +0800
Subject: [PATCH 07/10] fix(compiler-core): format code
---
.../__tests__/transforms/vOn.spec.ts | 28 ++++++++++++-------
.../__tests__/transforms/vSlot.spec.ts | 5 +++-
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
index afa16ff24c0..10b163b3557 100644
--- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
@@ -8,12 +8,13 @@ import {
NodeTypes,
ObjectExpression,
transform,
- VNodeCall, RenderSlotCall,
+ VNodeCall,
+ RenderSlotCall
} from '../../src'
import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
-import {parseWithSlots} from "./vSlot.spec";
+import { parseWithSlots } from './vSlot.spec'
function parseWithVOn(template: string, options: CompilerOptions = {}) {
const ast = parse(template, options)
@@ -71,15 +72,19 @@ describe('compiler: transform v-on', () => {
// # fix: #6900
test('consistent behavior of @update:modelValue and @update:model-value', () => {
- const { root:rootUpper } = parseWithSlots(`
`)
- const slotNodeUpper = ((rootUpper).codegenNode! as VNodeCall).children as ElementNode[]
- const propertiesObjUpper= (slotNodeUpper[0].codegenNode! as RenderSlotCall).arguments[2]
+ const { root: rootUpper } = parseWithSlots(
+ `
`
+ )
+ const slotNodeUpper = (rootUpper.codegenNode! as VNodeCall)
+ .children as ElementNode[]
+ const propertiesObjUpper = (slotNodeUpper[0].codegenNode! as RenderSlotCall)
+ .arguments[2]
expect(propertiesObjUpper).toMatchObject({
properties: [
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue',
+ content: 'onFoo:modelValue'
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
@@ -90,15 +95,18 @@ describe('compiler: transform v-on', () => {
]
})
- const { root } = parseWithSlots(`
`)
- const slotNode = ((root).codegenNode! as VNodeCall).children as ElementNode[]
- const propertiesObj = (slotNode[0].codegenNode! as RenderSlotCall).arguments[2]
+ const { root } = parseWithSlots(
+ `
`
+ )
+ const slotNode = (root.codegenNode! as VNodeCall).children as ElementNode[]
+ const propertiesObj = (slotNode[0].codegenNode! as RenderSlotCall)
+ .arguments[2]
expect(propertiesObj).toMatchObject({
properties: [
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue',
+ content: 'onFoo:modelValue'
},
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
index b5a60340909..52d78b03188 100644
--- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
@@ -28,7 +28,10 @@ import { PatchFlags } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
-export function parseWithSlots(template: string, options: CompilerOptions = {}) {
+export function parseWithSlots(
+ template: string,
+ options: CompilerOptions = {}
+) {
const ast = parse(template, {
whitespace: options.whitespace
})
From d3de83acb3acb92f12049ab6a269d50242a69e8a Mon Sep 17 00:00:00 2001
From: chenzhihui <18281682921@qqcom>
Date: Wed, 19 Oct 2022 15:54:35 +0800
Subject: [PATCH 08/10] fix(compiler-core): move unit test
---
.../__tests__/transforms/vOn.spec.ts | 51 +---------------
.../__tests__/transforms/vSlot.spec.ts | 58 +++++++++++++++++--
2 files changed, 54 insertions(+), 55 deletions(-)
diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
index 10b163b3557..8f943a7491f 100644
--- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts
@@ -8,13 +8,11 @@ import {
NodeTypes,
ObjectExpression,
transform,
- VNodeCall,
- RenderSlotCall
+ VNodeCall
} from '../../src'
import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
-import { parseWithSlots } from './vSlot.spec'
function parseWithVOn(template: string, options: CompilerOptions = {}) {
const ast = parse(template, options)
@@ -70,53 +68,6 @@ describe('compiler: transform v-on', () => {
})
})
- // # fix: #6900
- test('consistent behavior of @update:modelValue and @update:model-value', () => {
- const { root: rootUpper } = parseWithSlots(
- `
`
- )
- const slotNodeUpper = (rootUpper.codegenNode! as VNodeCall)
- .children as ElementNode[]
- const propertiesObjUpper = (slotNodeUpper[0].codegenNode! as RenderSlotCall)
- .arguments[2]
- expect(propertiesObjUpper).toMatchObject({
- properties: [
- {
- key: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue'
- },
- value: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `handler`,
- isStatic: false
- }
- }
- ]
- })
-
- const { root } = parseWithSlots(
- `
`
- )
- const slotNode = (root.codegenNode! as VNodeCall).children as ElementNode[]
- const propertiesObj = (slotNode[0].codegenNode! as RenderSlotCall)
- .arguments[2]
- expect(propertiesObj).toMatchObject({
- properties: [
- {
- key: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: 'onFoo:modelValue'
- },
- value: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: `handler`,
- isStatic: false
- }
- }
- ]
- })
- })
test('dynamic arg', () => {
const { node } = parseWithVOn(``)
expect((node.codegenNode as VNodeCall).props).toMatchObject({
diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
index 52d78b03188..c166f8d160a 100644
--- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
@@ -11,7 +11,8 @@ import {
VNodeCall,
SlotsExpression,
ObjectExpression,
- SimpleExpressionNode
+ SimpleExpressionNode,
+ RenderSlotCall
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn'
@@ -28,10 +29,7 @@ import { PatchFlags } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
-export function parseWithSlots(
- template: string,
- options: CompilerOptions = {}
-) {
+function parseWithSlots(template: string, options: CompilerOptions = {}) {
const ast = parse(template, {
whitespace: options.whitespace
})
@@ -791,6 +789,56 @@ describe('compiler: transform component slots', () => {
const { slots } = parseWithSlots(``)
expect(slots).toMatchObject(toMatch)
})
+
+ // # fix: #6900
+ test('consistent behavior of @xxx:modelValue and @xxx:model-value', () => {
+ const { root: rootUpper } = parseWithSlots(
+ `
`
+ )
+ const slotNodeUpper = (rootUpper.codegenNode! as VNodeCall)
+ .children as ElementNode[]
+ const propertiesObjUpper = (
+ slotNodeUpper[0].codegenNode! as RenderSlotCall
+ ).arguments[2]
+ expect(propertiesObjUpper).toMatchObject({
+ properties: [
+ {
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'onFoo:modelValue'
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `handler`,
+ isStatic: false
+ }
+ }
+ ]
+ })
+
+ const { root } = parseWithSlots(
+ `
`
+ )
+ const slotNode = (root.codegenNode! as VNodeCall)
+ .children as ElementNode[]
+ const propertiesObj = (slotNode[0].codegenNode! as RenderSlotCall)
+ .arguments[2]
+ expect(propertiesObj).toMatchObject({
+ properties: [
+ {
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'onFoo:modelValue'
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: `handler`,
+ isStatic: false
+ }
+ }
+ ]
+ })
+ })
})
describe('errors', () => {
From c1702540309caa75450f207591d2fef251bb1f9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=99=BD=E9=9B=BE=E4=B8=89=E8=AF=AD?=
<32354856+baiwusanyu-c@users.noreply.github.com>
Date: Sat, 29 Oct 2022 21:05:16 +0800
Subject: [PATCH 09/10] Update packages/compiler-core/src/transforms/vOn.ts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: 三咲智子 (Kevin)
---
packages/compiler-core/src/transforms/vOn.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index 1f855d79c0d..386fa186457 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -49,7 +49,7 @@ export const transformOn: DirectiveTransform = (
}
const eventString =
node.tagType === ElementTypes.COMPONENT ||
- // fix:6900
+ // fix #6900
node.tagType === ElementTypes.SLOT ||
rawName.startsWith('vnode') ||
!/[A-Z]/.test(rawName)
From ad4df716ffdee5d58b06199b5fcfea502cea2128 Mon Sep 17 00:00:00 2001
From: Evan You
Date: Tue, 8 Nov 2022 21:50:39 -0500
Subject: [PATCH 10/10] Update vOn.ts
---
packages/compiler-core/src/transforms/vOn.ts | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts
index a216bbfe007..9fe8b6ab61c 100644
--- a/packages/compiler-core/src/transforms/vOn.ts
+++ b/packages/compiler-core/src/transforms/vOn.ts
@@ -48,12 +48,10 @@ export const transformOn: DirectiveTransform = (
rawName = `vnode-${rawName.slice(4)}`
}
const eventString =
- node.tagType === ElementTypes.COMPONENT ||
- // fix #6900
- node.tagType === ElementTypes.SLOT ||
+ node.tagType !== ElementTypes.ELEMENT ||
rawName.startsWith('vnode') ||
!/[A-Z]/.test(rawName)
- ? // for component and vnode lifecycle event listeners, auto convert
+ ? // for non-element and vnode lifecycle event listeners, auto convert
// it to camelCase. See issue #2249
toHandlerKey(camelize(rawName))
: // preserve case for plain element listeners that have uppercase