Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions packages/compiler/src/schema/dom_element_schema_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ function normalizeTagName(tagName: string): string {
// =================================================================================================

export const SCHEMA: string[] = [
'[Element]|textContent,%ariaActiveDescendantElement,%ariaAtomic,%ariaAutoComplete,%ariaBusy,%ariaChecked,%ariaColCount,%ariaColIndex,%ariaColIndexText,%ariaColSpan,%ariaControlsElements,%ariaCurrent,%ariaDescribedByElements,%ariaDescription,%ariaDetailsElements,%ariaDisabled,%ariaErrorMessageElements,%ariaExpanded,%ariaFlowToElements,%ariaHasPopup,%ariaHidden,%ariaInvalid,%ariaKeyShortcuts,%ariaLabel,%ariaLabelledByElements,%ariaLevel,%ariaLive,%ariaModal,%ariaMultiLine,%ariaMultiSelectable,%ariaOrientation,%ariaOwnsElements,%ariaPlaceholder,%ariaPosInSet,%ariaPressed,%ariaReadOnly,%ariaRelevant,%ariaRequired,%ariaRoleDescription,%ariaRowCount,%ariaRowIndex,%ariaRowIndexText,%ariaRowSpan,%ariaSelected,%ariaSetSize,%ariaSort,%ariaValueMax,%ariaValueMin,%ariaValueNow,%ariaValueText,%classList,className,elementTiming,id,innerHTML,*beforecopy,*beforecut,*beforepaste,*fullscreenchange,*fullscreenerror,*search,*webkitfullscreenchange,*webkitfullscreenerror,outerHTML,%part,#scrollLeft,#scrollTop,slot' +
'[Element]|textContent,%ariaActiveDescendantElement,%ariaAtomic,%ariaAutoComplete,ariaBrailleLabel,ariaBrailleRoleDescription,%ariaBusy,%ariaChecked,%ariaColCount,%ariaColIndex,%ariaColIndexText,%ariaColSpan,%ariaControlsElements,%ariaCurrent,%ariaDescribedByElements,%ariaDescription,%ariaDetailsElements,%ariaDisabled,%ariaErrorMessageElements,%ariaExpanded,%ariaFlowToElements,%ariaHasPopup,%ariaHidden,%ariaInvalid,%ariaKeyShortcuts,%ariaLabel,%ariaLabelledByElements,%ariaLevel,%ariaLive,%ariaModal,%ariaMultiLine,%ariaMultiSelectable,%ariaOrientation,%ariaOwnsElements,%ariaPlaceholder,%ariaPosInSet,%ariaPressed,%ariaReadOnly,%ariaRelevant,%ariaRequired,%ariaRoleDescription,%ariaRowCount,%ariaRowIndex,%ariaRowIndexText,%ariaRowSpan,%ariaSelected,%ariaSetSize,%ariaSort,%ariaValueMax,%ariaValueMin,%ariaValueNow,%ariaValueText,%classList,className,elementTiming,id,innerHTML,*beforecopy,*beforecut,*beforepaste,*fullscreenchange,*fullscreenerror,*search,*webkitfullscreenchange,*webkitfullscreenerror,outerHTML,%part,#scrollLeft,#scrollTop,slot' +
/* added manually to avoid breaking changes */
',*message,*mozfullscreenchange,*mozfullscreenerror,*mozpointerlockchange,*mozpointerlockerror,*webglcontextcreationerror,*webglcontextlost,*webglcontextrestored',
'[HTMLElement]^[Element]|accessKey,autocapitalize,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,!inert,innerText,inputMode,lang,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,popover,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
'[HTMLElement]^[Element]|accessKey,autocapitalize,autocorrect,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,!inert,innerText,inputMode,lang,nonce,*abort,*animationcancel,*animationend,*animationiteration,*animationstart,*auxclick,*beforeinput,*beforematch,*beforetoggle,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*command,*compositionend,*compositionstart,*compositionupdate,*contentvisibilityautostatechange,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*focusin,*focusout,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*scrollend,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,popover,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT: Small catch on autocorrect: even though the HTML attribute takes "on" or "off", SCHEMA models the DOM IDL property type, and HTMLElement.prototype.autocorrect is a boolean in both the HTML spec and TypeScript's lib.dom.d.ts (matching !spellcheck and !translate on this line). Assigning "off" in JS coerces to true, so we should restore the ! prefix here:

Suggested change
'[HTMLElement]^[Element]|accessKey,autocapitalize,autocorrect,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,!inert,innerText,inputMode,lang,nonce,*abort,*animationcancel,*animationend,*animationiteration,*animationstart,*auxclick,*beforeinput,*beforematch,*beforetoggle,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*command,*compositionend,*compositionstart,*compositionupdate,*contentvisibilityautostatechange,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*focusin,*focusout,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*scrollend,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,popover,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
'[HTMLElement]^[Element]|accessKey,autocapitalize,!autocorrect,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,!inert,innerText,inputMode,lang,nonce,*abort,*animationcancel,*animationend,*animationiteration,*animationstart,*auxclick,*beforeinput,*beforematch,*beforetoggle,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*command,*compositionend,*compositionstart,*compositionupdate,*contentvisibilityautostatechange,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*focusin,*focusout,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*scrollend,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,popover,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',

'abbr,address,article,aside,b,bdi,bdo,cite,content,code,dd,dfn,dt,em,figcaption,figure,footer,header,hgroup,i,kbd,main,mark,nav,noscript,rb,rp,rt,rtc,ruby,s,samp,search,section,small,strong,sub,sup,u,var,wbr^[HTMLElement]|accessKey,autocapitalize,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,innerText,inputMode,lang,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
'media^[HTMLElement]|!autoplay,!controls,%controlsList,%crossOrigin,#currentTime,!defaultMuted,#defaultPlaybackRate,!disableRemotePlayback,!loop,!muted,*encrypted,*waitingforkey,#playbackRate,preload,!preservesPitch,src,%srcObject,#volume',
':svg:^[HTMLElement]|!autofocus,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,%style,#tabIndex',
Expand All @@ -102,20 +102,20 @@ export const SCHEMA: string[] = [
'br^[HTMLElement]|clear',
'base^[HTMLElement]|href,target',
'body^[HTMLElement]|aLink,background,bgColor,link,*afterprint,*beforeprint,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*messageerror,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,text,vLink',
'button^[HTMLElement]|!disabled,formAction,formEnctype,formMethod,!formNoValidate,formTarget,name,popoverTargetAction,%popoverTargetElement,type,value',
'button^[HTMLElement]|command,%commandForElement,!disabled,formAction,formEnctype,formMethod,!formNoValidate,formTarget,name,popoverTargetAction,%popoverTargetElement,type,value',
Comment thread
aminesbdev marked this conversation as resolved.
Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT: It looks like the language-service commit (22fb98a668) mentioned in your earlier comment was dropped in the latest force push, and it hasn't landed on main yet.

Because *command is still on [HTMLElement] (line 88), buildAttributeCompletionTable (packages/language-service/src/attribute_completions.ts:417-422) inserts 'command' as DomAttribute for <button> and then overwrites it with DomEvent. That prevents <button [com|]> from suggesting [command] and also lets the 12 new events overwrite same named directive @Input() completions.

If you'd prefer to keep the language-service fix in a separate PR, let's get that landed first (ideally keying DomEvent entries distinctly such as (${event}) so neither [command] nor (command) hides the other), or restore the fix into this PR.

'canvas^[HTMLElement]|#height,#width',
'content^[HTMLElement]|select',
'dl^[HTMLElement]|!compact',
'data^[HTMLElement]|value',
'datalist^[HTMLElement]|',
'details^[HTMLElement]|!open',
'details^[HTMLElement]|name,!open',
'dialog^[HTMLElement]|!open,returnValue',
'dir^[HTMLElement]|!compact',
'div^[HTMLElement]|align',
'embed^[HTMLElement]|align,height,name,src,type,width',
'fieldset^[HTMLElement]|!disabled,name',
'font^[HTMLElement]|color,face,size',
'form^[HTMLElement]|acceptCharset,action,autocomplete,encoding,enctype,method,name,!noValidate,target',
'form^[HTMLElement]|acceptCharset,action,autocomplete,encoding,enctype,method,name,!noValidate,rel,target',
'frame^[HTMLElement]|frameBorder,longDesc,marginHeight,marginWidth,name,!noResize,scrolling,src',
'frameset^[HTMLElement]|cols,*afterprint,*beforeprint,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*messageerror,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,rows',
'geolocation^[HTMLElement]|accuracymode,!autolocate,*location,*promptaction,*promptdismiss,*validationstatuschange,!watch',
Expand All @@ -124,12 +124,12 @@ export const SCHEMA: string[] = [
'h1,h2,h3,h4,h5,h6^[HTMLElement]|align',
'html^[HTMLElement]|version',
'iframe^[HTMLElement]|align,allow,!allowFullscreen,!allowPaymentRequest,csp,!credentialless,frameBorder,height,loading,longDesc,marginHeight,marginWidth,name,referrerPolicy,%sandbox,scrolling,src,srcdoc,width',
'img^[HTMLElement]|align,alt,border,%crossOrigin,decoding,#height,#hspace,!isMap,loading,longDesc,lowsrc,name,referrerPolicy,sizes,src,srcset,useMap,#vspace,#width',
'input^[HTMLElement]|accept,align,alt,autocomplete,!checked,!defaultChecked,defaultValue,dirName,!disabled,%files,formAction,formEnctype,formMethod,!formNoValidate,formTarget,#height,!incremental,!indeterminate,max,#maxLength,min,#minLength,!multiple,name,pattern,placeholder,popoverTargetAction,%popoverTargetElement,!readOnly,!required,selectionDirection,#selectionEnd,#selectionStart,#size,src,step,type,useMap,value,%valueAsDate,#valueAsNumber,#width',
'img^[HTMLElement]|align,alt,border,%crossOrigin,decoding,fetchPriority,#height,#hspace,!isMap,loading,longDesc,lowsrc,name,referrerPolicy,sizes,src,srcset,useMap,#vspace,#width',
'input^[HTMLElement]|accept,align,alt,autocomplete,!checked,!defaultChecked,defaultValue,dirName,!disabled,%files,formAction,formEnctype,formMethod,!formNoValidate,formTarget,#height,!incremental,!indeterminate,max,#maxLength,min,#minLength,!multiple,name,pattern,placeholder,popoverTargetAction,%popoverTargetElement,!readOnly,!required,selectionDirection,#selectionEnd,#selectionStart,#size,src,step,type,useMap,value,%valueAsDate,#valueAsNumber,!webkitdirectory,#width',
'li^[HTMLElement]|type,#value',
'label^[HTMLElement]|htmlFor',
'legend^[HTMLElement]|align',
'link^[HTMLElement]|as,charset,%crossOrigin,!disabled,href,hreflang,imageSizes,imageSrcset,integrity,media,referrerPolicy,rel,%relList,rev,%sizes,target,type',
'link^[HTMLElement]|as,charset,%crossOrigin,!disabled,fetchPriority,href,hreflang,imageSizes,imageSrcset,integrity,media,referrerPolicy,rel,%relList,rev,%sizes,target,type',
'map^[HTMLElement]|name',
'marquee^[HTMLElement]|behavior,bgColor,direction,height,#hspace,#loop,#scrollAmount,#scrollDelay,!trueSpeed,#vspace,width',
'menu^[HTMLElement]|!compact',
Expand All @@ -146,8 +146,8 @@ export const SCHEMA: string[] = [
'picture^[HTMLElement]|',
'pre^[HTMLElement]|#width',
'progress^[HTMLElement]|#max,#value',
'q,blockquote,cite^[HTMLElement]|',
'script^[HTMLElement]|!async,charset,%crossOrigin,!defer,event,htmlFor,integrity,!noModule,%referrerPolicy,src,text,type',
'q,blockquote^[HTMLElement]|cite',
Comment thread
aminesbdev marked this conversation as resolved.
Resolved
'script^[HTMLElement]|!async,charset,%crossOrigin,!defer,event,fetchPriority,htmlFor,integrity,!noModule,%referrerPolicy,src,text,type',
'select^[HTMLElement]|autocomplete,!disabled,#length,!multiple,name,!required,#selectedIndex,#size,value',
'selectedcontent^[HTMLElement]|',
'slot^[HTMLElement]|name',
Expand All @@ -169,7 +169,7 @@ export const SCHEMA: string[] = [
'ul^[HTMLElement]|!compact,type',
'unknown^[HTMLElement]|',
'video^media|!disablePictureInPicture,#height,*enterpictureinpicture,*leavepictureinpicture,!playsInline,poster,#width',
':svg:a^:svg:graphics|',
':svg:a^:svg:graphics|rel',
':svg:animate^:svg:animation|',
':svg:animateMotion^:svg:animation|',
':svg:animateTransform^:svg:animation|',
Expand Down Expand Up @@ -207,7 +207,7 @@ export const SCHEMA: string[] = [
':svg:filter^:svg:|',
':svg:foreignObject^:svg:graphics|',
':svg:g^:svg:graphics|',
':svg:image^:svg:graphics|decoding',
':svg:image^:svg:graphics|%crossOrigin,decoding',
':svg:line^:svg:geometry|',
':svg:linearGradient^:svg:gradient|',
':svg:mpath^:svg:|',
Expand Down Expand Up @@ -274,6 +274,7 @@ export const SCHEMA: string[] = [
export const _ATTR_TO_PROP = new Map(
Object.entries({
'class': 'className',
'fetchpriority': 'fetchPriority',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT: Adding 'fetchpriority': 'fetchPriority' here lets <img [fetchpriority]="..."> pass template typechecking (REGISTRY.getMappedPropName), however codegen keeps the raw binding name (mapPropertyName is false in r3_template_transform.ts). Unlike aria-* attributes, entries in _ATTR_TO_PROP also need to exist in DOM_PROPERTY_REMAPPING (packages/compiler/src/template/pipeline/src/phases/reify.ts) and mapPropName (packages/core/src/render3/instructions/shared.ts), neither of which remaps 'fetchpriority'.

As a result, <img [fetchpriority]="'high'"> compiles without NG8002 in AOT and silently writes a dead img.fetchpriority expando property at runtime instead of img.fetchPriority, while logging NG0303 in JIT dev mode.

Other camelCase properties like crossOrigin and referrerPolicy are intentionally omitted here so they are bound as [crossOrigin] or [attr.fetchpriority] without adding extra branches to mapPropName in @angular/core. Let's drop 'fetchpriority' here (and update the commit message accordingly):

Suggested change
'fetchpriority': 'fetchPriority',

'for': 'htmlFor',
'formaction': 'formAction',
'innerHtml': 'innerHTML',
Expand All @@ -284,6 +285,8 @@ export const _ATTR_TO_PROP = new Map(
'aria-activedescendant': 'ariaActiveDescendantElement',
'aria-atomic': 'ariaAtomic',
'aria-autocomplete': 'ariaAutoComplete',
'aria-braillelabel': 'ariaBrailleLabel',
'aria-brailleroledescription': 'ariaBrailleRoleDescription',
'aria-busy': 'ariaBusy',
'aria-checked': 'ariaChecked',
'aria-colcount': 'ariaColCount',
Expand Down
37 changes: 37 additions & 0 deletions packages/compiler/test/schema/dom_element_schema_registry_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('DOMElementSchema', () => {
it('should detect elements', () => {
expect(registry.hasElement('div', [])).toBeTruthy();
expect(registry.hasElement('b', [])).toBeTruthy();
expect(registry.hasElement('cite', [])).toBeTruthy();
expect(registry.hasElement('ng-container', [])).toBeTruthy();
expect(registry.hasElement('ng-content', [])).toBeTruthy();

Expand All @@ -49,6 +50,22 @@ describe('DOMElementSchema', () => {
expect(registry.hasProperty('button', 'popoverTargetElement', [])).toBeTruthy();
expect(registry.hasProperty('input', 'popoverTargetAction', [])).toBeTruthy();
expect(registry.hasProperty('input', 'popoverTargetElement', [])).toBeTruthy();
expect(registry.hasProperty('div', 'autocorrect', [])).toBeTruthy();
expect(registry.hasProperty('div', 'ariaBrailleLabel', [])).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT: Since *command is also registered on [HTMLElement], let's add a check that command isn't exposed as a bindable property on non button elements:

Suggested change
expect(registry.hasProperty('div', 'ariaBrailleLabel', [])).toBeTruthy();
expect(registry.hasProperty('button', 'command', [])).toBeTruthy();
expect(registry.hasProperty('div', 'command', [])).toBeFalsy();

expect(registry.hasProperty('div', 'ariaBrailleRoleDescription', [])).toBeTruthy();
expect(registry.hasProperty('button', 'command', [])).toBeTruthy();
expect(registry.hasProperty('button', 'commandForElement', [])).toBeTruthy();
expect(registry.hasProperty('details', 'name', [])).toBeTruthy();
expect(registry.hasProperty('input', 'webkitdirectory', [])).toBeTruthy();
expect(registry.hasProperty('form', 'rel', [])).toBeTruthy();
expect(registry.hasProperty('img', 'fetchPriority', [])).toBeTruthy();
expect(registry.hasProperty('link', 'fetchPriority', [])).toBeTruthy();
expect(registry.hasProperty('script', 'fetchPriority', [])).toBeTruthy();
expect(registry.hasProperty(':svg:a', 'rel', [])).toBeTruthy();
expect(registry.hasProperty(':svg:image', 'crossOrigin', [])).toBeTruthy();
expect(registry.hasProperty('blockquote', 'cite', [])).toBeTruthy();
expect(registry.hasProperty('q', 'cite', [])).toBeTruthy();
expect(registry.hasProperty('cite', 'cite', [])).toBeFalsy();
expect(registry.hasProperty('h1', 'align', [])).toBeTruthy();
expect(registry.hasProperty('h2', 'align', [])).toBeTruthy();
expect(registry.hasProperty('h3', 'align', [])).toBeTruthy();
Expand Down Expand Up @@ -83,6 +100,22 @@ describe('DOMElementSchema', () => {
expect(registry.hasProperty('video', 'click', [])).toBeFalsy();
});

it('should detect events on regular elements', () => {
const events = registry.allKnownEventsOfElement('div');
expect(events).toContain('animationcancel');
expect(events).toContain('beforeinput');
expect(events).toContain('beforematch');
expect(events).toContain('beforetoggle');
expect(events).toContain('command');
expect(events).toContain('compositionend');
expect(events).toContain('compositionstart');
expect(events).toContain('compositionupdate');
expect(events).toContain('contentvisibilityautostatechange');
expect(events).toContain('focusin');
expect(events).toContain('focusout');
expect(events).toContain('scrollend');
});

it('should treat custom elements as an unknown element by default', () => {
expect(registry.hasProperty('custom-like', 'unknown', [])).toBe(false);
expect(registry.hasProperty('custom-like', 'className', [])).toBeTruthy();
Expand All @@ -106,6 +139,10 @@ describe('DOMElementSchema', () => {

it('should re-map property names that are specified in DOM facade', () => {
expect(registry.getMappedPropName('readonly')).toEqual('readOnly');
expect(registry.getMappedPropName('aria-braillelabel')).toEqual('ariaBrailleLabel');
Comment thread
aminesbdev marked this conversation as resolved.
Resolved
expect(registry.getMappedPropName('aria-brailleroledescription')).toEqual(
'ariaBrailleRoleDescription',
);
});

it('should not re-map property names that are not specified in DOM facade', () => {
Expand Down
Loading