99
1010import { BUILD } from '@build-conditionals' ;
1111import { isMemberInElement , plt } from '@platform' ;
12- import { isComplexType , toLowerCase } from '@utils' ;
12+ import { isComplexType } from '@utils' ;
1313import { VNODE_FLAGS , XLINK_NS } from '../runtime-constants' ;
1414
1515export const setAccessor = ( elm : HTMLElement , memberName : string , oldValue : any , newValue : any , isSvg : boolean , flags : number ) => {
1616 if ( oldValue === newValue ) {
1717 return ;
1818 }
19+ let isProp = isMemberInElement ( elm , memberName ) ;
20+ let ln = memberName . toLowerCase ( ) ;
1921 if ( BUILD . vdomClass && memberName === 'class' ) {
2022 const classList = elm . classList ;
2123 parseClassList ( oldValue ) . forEach ( cls => classList . remove ( cls ) ) ;
2224 parseClassList ( newValue ) . forEach ( cls => classList . add ( cls ) ) ;
25+
2326 } else if ( BUILD . vdomStyle && memberName === 'style' ) {
2427 // update style attribute, css properties and values
2528 if ( BUILD . updatable ) {
@@ -52,26 +55,34 @@ export const setAccessor = (elm: HTMLElement, memberName: string, oldValue: any,
5255 newValue ( elm ) ;
5356 }
5457
55- } else if ( BUILD . vdomListener && memberName . startsWith ( 'on' ) && ! isMemberInElement ( elm , memberName ) ) {
58+ } else if ( BUILD . vdomListener && ! isProp && memberName [ 0 ] === 'o' && memberName [ 1 ] === 'n' ) {
5659 // Event Handlers
5760 // so if the member name starts with "on" and the 3rd characters is
5861 // a capital letter, and it's not already a member on the element,
5962 // then we're assuming it's an event listener
60-
61- if ( isMemberInElement ( elm , toLowerCase ( memberName ) ) ) {
63+ if ( memberName [ 2 ] === '-' ) {
64+ // on- prefixed events
65+ // allows to be explicit about the dom event to listen without any magic
66+ // under the hood:
67+ // <my-cmp on-click> // listens for "click"
68+ // <my-cmp on-Click> // listens for "Click"
69+ // <my-cmp on-ionChange> // listens for "ionChange"
70+ // <my-cmp on-EVENTS> // listens for "EVENTS"
71+ memberName = memberName . substr ( 3 ) ;
72+ } else if ( isMemberInElement ( elm , ln ) ) {
6273 // standard event
6374 // the JSX attribute could have been "onMouseOver" and the
6475 // member name "onmouseover" is on the element's prototype
6576 // so let's add the listener "mouseover", which is all lowercased
66- memberName = toLowerCase ( memberName . substring ( 2 ) ) ;
77+ memberName = ln . substr ( 2 ) ;
6778
6879 } else {
6980 // custom event
7081 // the JSX attribute could have been "onMyCustomEvent"
7182 // so let's trim off the "on" prefix and lowercase the first character
7283 // and add the listener "myCustomEvent"
7384 // except for the first character, we keep the event name case
74- memberName = toLowerCase ( memberName [ 2 ] ) + memberName . substring ( 3 ) ;
85+ memberName = ln [ 2 ] + memberName . substr ( 3 ) ;
7586 }
7687 if ( oldValue ) {
7788 plt . rel ( elm , memberName , oldValue , false ) ;
@@ -82,8 +93,18 @@ export const setAccessor = (elm: HTMLElement, memberName: string, oldValue: any,
8293
8394 } else {
8495 // Set property if it exists and it's not a SVG
85- const isProp = isMemberInElement ( elm , memberName ) ;
8696 const isComplex = isComplexType ( newValue ) ;
97+
98+ /**
99+ * Need to manually update attribute if:
100+ * - memberName is not an attribute
101+ * - if we are rendering the host element in order to reflect attribute
102+ * - if it's a SVG, since properties might not work in <svg>
103+ * - if the newValue is null/undefined or 'false'.
104+ */
105+ const namespace = BUILD . svg && isSvg && ( ln !== ( ln = ln . replace ( / ^ x l i n k \: ? / , '' ) ) )
106+ ? XLINK_NS
107+ : null ;
87108 if ( ( isProp || ( isComplex && newValue !== null ) ) && ! isSvg ) {
88109 try {
89110 if ( ! elm . tagName . includes ( '-' ) ) {
@@ -99,28 +120,11 @@ export const setAccessor = (elm: HTMLElement, memberName: string, oldValue: any,
99120 } catch ( e ) { }
100121 }
101122
102-
103- /**
104- * Need to manually update attribute if:
105- * - memberName is not an attribute
106- * - if we are rendering the host element in order to reflect attribute
107- * - if it's a SVG, since properties might not work in <svg>
108- * - if the newValue is null/undefined or 'false'.
109- */
110- const isXlinkNs = BUILD . svg && isSvg && ( memberName !== ( memberName = memberName . replace ( / ^ x l i n k \: ? / , '' ) ) ) ? true : false ;
111123 if ( newValue == null || newValue === false ) {
112- if ( isXlinkNs ) {
113- elm . removeAttributeNS ( XLINK_NS , toLowerCase ( memberName ) ) ;
114- } else {
115- elm . removeAttribute ( memberName ) ;
116- }
124+ elm . removeAttributeNS ( namespace , ln ) ;
117125 } else if ( ( ! isProp || ( flags & VNODE_FLAGS . isHost ) || isSvg ) && ! isComplex ) {
118- newValue = newValue === true ? '' : newValue . toString ( ) ;
119- if ( isXlinkNs ) {
120- elm . setAttributeNS ( XLINK_NS , toLowerCase ( memberName ) , newValue ) ;
121- } else {
122- elm . setAttribute ( memberName , newValue ) ;
123- }
126+ newValue = newValue === true ? '' : newValue ;
127+ elm . setAttributeNS ( namespace , ln , newValue ) ;
124128 }
125129 }
126130} ;
0 commit comments