Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function properties (e.g. vs element keys) #268

Open
Thorin-Oakenpants opened this issue Dec 16, 2023 · 12 comments
Open

function properties (e.g. vs element keys) #268

Thorin-Oakenpants opened this issue Dec 16, 2023 · 12 comments
Labels

Comments

@Thorin-Oakenpants
Copy link
Contributor

FYI: @abrahamjuliot

htmlelement keys as per TZP (and creepy)

  • so we're getting keys on a div element, right? what about other element types?
	const id = "html-element-version"
	const element = document.createElement("div")
	element.setAttribute("id", id)
	document.body.appendChild(element)
	const htmlElement = document.getElementById(id)
	const keys = []
	for (const key in htmlElement) {keys.push(key)}
	//... etc .. using same mini hashing function as creepy
	try {document.getElementById(id).remove()} catch(e) {} // cleanup

HTML*Element keys - see https://arkenfox.github.io/TZP/tests/htmlelements.html

more to follow

@Thorin-Oakenpants
Copy link
Contributor Author

  • things to keep in mind
    • each of these contain a constructor, so we can detect items after constructor (in gecko at least [1] ) which exposes some extra extension fuckery entropy 🎉
    • it's performant (1 ms on my machine)
    • my grouping is handwavey and based on some gecko analysis
    • we can drop some HTML*Element items from a FP test

[1] items post constructor: here's chrome with no extensions - this is NOT the case with gecko

blink

more to follow

@Thorin-Oakenpants
Copy link
Contributor Author

groups

  • super boring is pretty much that, never changes and matches blink, even unsorted (not that we need engine differences, we have enough)
  • the other three groups, most/some of them are different with blink especially when unsorted
    • not that we care about finding yet more engine diffs
  • stable hasn't changed for 18 months in gecko
    • but a couple of them do exhibit extension fuckery in gecko
  • the others seem more volatile at least in gecko

I think most of this is just equivalency of engine and version - but some things are definitely behind prefs/flags

  • e.g. media.setsinkid.enabled controls setSinkId + sinkId in HTMMediaElement
  • not that I think most users will be changing these prefs, but I don't think we catch e.g. setSinkId + sinkId anywhere else, so it adds information that is currently missing

So that said

  • pros
    • speedy AF
      • we could drop super boring to reduce data: maybe drop a couple of other keys
    • gecko at least: detects fuckery with post contructor (NoScript, JSShelter)
    • AFAICT adds information
    • reinforces engine diffs
  • limitations
    • we don't automate HTML*Element items, so it's a manual list
    • we'll need to cater for unsupported features, which could add perf costs [1]
      • but we could do this once in a global var
      • e.g. HTMLDialogElement
      • maybe we can code the list to loop differently, just using the key name?
      • so we should probably do this for a bunch of items for backwards compat?
        • for gecko desktop that was the only one I found since FF52+
  • cons (if you can call it that)
    • lots of (mostly) boring data
      • depending on how you record it, because of duplication between each test
        • e.g. overall, including constructor = 815 keys
        • e.g. deduped = 448 keys
        • ^ on FF122 (nightly)

[1] e.g.

let htmlList = {
	// ... etc
	HTMLAreaElement: HTMLAreaElement.prototype,
	HTMLDialogElement: undefined, // FF98+ HTMLDialogElement.prototype,
}

try {
	if (HTMLDialogElement.prototype !== undefined) {
		htmlList["HTMLDialogElement"] = HTMLDialogElement.prototype
	}
} catch(e) {}

more to follow

@Thorin-Oakenpants
Copy link
Contributor Author

So I'm trying to understand htmlelement keys vs HTML*Element keys, so I did a diff, using FF122 Nightly (using TZP not creepy's result). I combined all the values into a single array, deduped it, removed constructor

// HTML*Elements: 447

let aPOC = ['ERROR','HAVE_CURRENT_DATA','HAVE_ENOUGH_DATA','HAVE_FUTURE_DATA','HAVE_METADATA','HAVE_NOTHING','LOADED','LOADING','NETWORK_EMPTY','NETWORK_IDLE','NETWORK_LOADING','NETWORK_NO_SOURCE','NONE','aLink','abbr','accept','acceptCharset','accessKey','accessKeyLabel','action','add','addTextTrack','align','allow','allowFullscreen','allowedToPlay','alt','archive','areas','as','async','attachInternals','autocapitalize','autocomplete','autofocus','autoplay','axis','background','bgColor','blur','border','buffered','canPlayType','caption','captureStream','cellIndex','cellPadding','cellSpacing','cells','ch','chOff','charset','checkValidity','checked','cite','clear','click','close','code','codeBase','codeType','colSpan','color','cols','compact','complete','content','contentDocument','contentEditable','contentWindow','control','controls','coords','createCaption','createTBody','createTFoot','createTHead','crossOrigin','currentSrc','currentTime','data','dataset','dateTime','declare','decode','decoding','default','defaultChecked','defaultMuted','defaultPlaybackRate','defaultSelected','defaultValue','defer','deleteCaption','deleteCell','deleteRow','deleteTFoot','deleteTHead','dir','dirName','disablePictureInPicture','disabled','download','draggable','duration','elements','encoding','enctype','ended','enterKeyHint','error','event','fastSeek','files','focus','form','formAction','formEnctype','formMethod','formNoValidate','formTarget','frame','frameBorder','getContext','getSVGDocument','getVideoPlaybackQuality','hash','headers','height','hidden','hidePopover','high','host','hostname','href','hreflang','hspace','htmlFor','httpEquiv','imageSizes','imageSrcset','indeterminate','index','inert','innerText','inputMode','insertCell','insertRow','integrity','isContentEditable','isMap','item','kind','label','labels','lang','length','link','list','load','loading','longDesc','loop','low','lowsrc','marginHeight','marginWidth','max','maxLength','media','mediaKeys','method','min','minLength','mozAudioCaptured','mozCaptureStream','mozCaptureStreamUntilEnded','mozDecodedFrames','mozFragmentEnd','mozFrameDelay','mozGetMetadata','mozHasAudio','mozIsTextField','mozOpaque','mozPaintedFrames','mozParsedFrames','mozPresentedFrames','mozPrintCallback','multiple','muted','name','namedItem','naturalHeight','naturalWidth','networkState','noHref','noModule','noResize','noShade','noValidate','noWrap','nonce','offsetHeight','offsetLeft','offsetParent','offsetTop','offsetWidth','onabort','onafterprint','onanimationcancel','onanimationend','onanimationiteration','onanimationstart','onauxclick','onbeforeinput','onbeforeprint','onbeforetoggle','onbeforeunload','onblur','oncancel','oncanplay','oncanplaythrough','onchange','onclick','onclose','oncontextmenu','oncopy','oncuechange','oncut','ondblclick','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','ondurationchange','onemptied','onencrypted','onended','onerror','onfocus','onformdata','ongamepadconnected','ongamepaddisconnected','ongotpointercapture','onhashchange','oninput','oninvalid','onkeydown','onkeypress','onkeyup','onlanguagechange','onload','onloadeddata','onloadedmetadata','onloadstart','onlostpointercapture','onmessage','onmessageerror','onmousedown','onmouseenter','onmouseleave','onmousemove','onmouseout','onmouseover','onmouseup','onmozfullscreenchange','onmozfullscreenerror','onoffline','ononline','onpagehide','onpageshow','onpaste','onpause','onplay','onplaying','onpointercancel','onpointerdown','onpointerenter','onpointerleave','onpointermove','onpointerout','onpointerover','onpointerup','onpopstate','onprogress','onratechange','onrejectionhandled','onreset','onresize','onscroll','onscrollend','onsecuritypolicyviolation','onseeked','onseeking','onselect','onselectionchange','onselectstart','onslotchange','onstalled','onstorage','onsubmit','onsuspend','ontimeupdate','ontoggle','ontransitioncancel','ontransitionend','ontransitionrun','ontransitionstart','onunhandledrejection','onunload','onvolumechange','onwaiting','onwaitingforkey','onwebkitanimationend','onwebkitanimationiteration','onwebkitanimationstart','onwebkittransitionend','onwheel','open','optimum','options','origin','outerText','password','pathname','pattern','pause','paused','ping','placeholder','play','playbackRate','played','popover','popoverTargetAction','popoverTargetElement','port','position','poster','preload','preservesPitch','protocol','readOnly','readyState','referrerPolicy','rel','relList','remove','reportValidity','requestSubmit','required','reset','returnValue','rev','reversed','rowIndex','rowSpan','rows','rules','sandbox','scheme','scope','scrolling','search','sectionRowIndex','seekToNextFrame','seekable','seeking','select','selected','selectedIndex','selectedOptions','selectionDirection','selectionEnd','selectionStart','setCustomValidity','setMediaKeys','setRangeText','setSelectionRange','setSinkId','shadowRootDelegatesFocus','shadowRootMode','shape','sheet','show','showModal','showPicker','showPopover','sinkId','size','sizes','span','spellcheck','src','srcObject','srcdoc','srclang','srcset','standby','start','step','stepDown','stepUp','style','submit','summary','tBodies','tFoot','tHead','tabIndex','target','text','textLength','textTracks','title','toBlob','toDataURL','toString','togglePopover','track','transferControlToOffscreen','translate','type','useMap','username','vAlign','vLink','validationMessage','validity','value','valueAsDate','valueAsNumber','version','videoHeight','videoWidth','volume','vspace','webkitEntries','webkitdirectory','width','willValidate','wrap','x','y']

// HTMLElement TZP: 312 
let aTZP = ['ATTRIBUTE_NODE','CDATA_SECTION_NODE','COMMENT_NODE','DOCUMENT_FRAGMENT_NODE','DOCUMENT_NODE','DOCUMENT_POSITION_CONTAINED_BY','DOCUMENT_POSITION_CONTAINS','DOCUMENT_POSITION_DISCONNECTED','DOCUMENT_POSITION_FOLLOWING','DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC','DOCUMENT_POSITION_PRECEDING','DOCUMENT_TYPE_NODE','ELEMENT_NODE','ENTITY_NODE','ENTITY_REFERENCE_NODE','NOTATION_NODE','PROCESSING_INSTRUCTION_NODE','TEXT_NODE','accessKey','accessKeyLabel','addEventListener','after','align','animate','append','appendChild','ariaAtomic','ariaAutoComplete','ariaBusy','ariaChecked','ariaColCount','ariaColIndex','ariaColIndexText','ariaColSpan','ariaCurrent','ariaDescription','ariaDisabled','ariaExpanded','ariaHasPopup','ariaHidden','ariaInvalid','ariaKeyShortcuts','ariaLabel','ariaLevel','ariaLive','ariaModal','ariaMultiLine','ariaMultiSelectable','ariaOrientation','ariaPlaceholder','ariaPosInSet','ariaPressed','ariaReadOnly','ariaRelevant','ariaRequired','ariaRoleDescription','ariaRowCount','ariaRowIndex','ariaRowIndexText','ariaRowSpan','ariaSelected','ariaSetSize','ariaSort','ariaValueMax','ariaValueMin','ariaValueNow','ariaValueText','assignedSlot','attachInternals','attachShadow','attributes','autocapitalize','autofocus','baseURI','before','blur','checkVisibility','childElementCount','childNodes','children','classList','className','click','clientHeight','clientLeft','clientTop','clientWidth','cloneNode','closest','compareDocumentPosition','contains','contentEditable','convertPointFromNode','convertQuadFromNode','convertRectFromNode','dataset','dir','dispatchEvent','draggable','enterKeyHint','firstChild','firstElementChild','focus','getAnimations','getAttribute','getAttributeNS','getAttributeNames','getAttributeNode','getAttributeNodeNS','getBoundingClientRect','getBoxQuads','getClientRects','getElementsByClassName','getElementsByTagName','getElementsByTagNameNS','getRootNode','hasAttribute','hasAttributeNS','hasAttributes','hasChildNodes','hasPointerCapture','hidden','hidePopover','id','inert','innerHTML','innerText','inputMode','insertAdjacentElement','insertAdjacentHTML','insertAdjacentText','insertBefore','isConnected','isContentEditable','isDefaultNamespace','isEqualNode','isSameNode','lang','lastChild','lastElementChild','localName','lookupNamespaceURI','lookupPrefix','matches','mozMatchesSelector','mozRequestFullScreen','namespaceURI','nextElementSibling','nextSibling','nodeName','nodeType','nodeValue','nonce','normalize','offsetHeight','offsetLeft','offsetParent','offsetTop','offsetWidth','onabort','onanimationcancel','onanimationend','onanimationiteration','onanimationstart','onauxclick','onbeforeinput','onbeforetoggle','onblur','oncancel','oncanplay','oncanplaythrough','onchange','onclick','onclose','oncontextmenu','oncopy','oncuechange','oncut','ondblclick','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','ondurationchange','onemptied','onended','onerror','onfocus','onformdata','onfullscreenchange','onfullscreenerror','ongotpointercapture','oninput','oninvalid','onkeydown','onkeypress','onkeyup','onload','onloadeddata','onloadedmetadata','onloadstart','onlostpointercapture','onmousedown','onmouseenter','onmouseleave','onmousemove','onmouseout','onmouseover','onmouseup','onmozfullscreenchange','onmozfullscreenerror','onpaste','onpause','onplay','onplaying','onpointercancel','onpointerdown','onpointerenter','onpointerleave','onpointermove','onpointerout','onpointerover','onpointerup','onprogress','onratechange','onreset','onresize','onscroll','onscrollend','onsecuritypolicyviolation','onseeked','onseeking','onselect','onselectionchange','onselectstart','onslotchange','onstalled','onsubmit','onsuspend','ontimeupdate','ontoggle','ontransitioncancel','ontransitionend','ontransitionrun','ontransitionstart','onvolumechange','onwaiting','onwebkitanimationend','onwebkitanimationiteration','onwebkitanimationstart','onwebkittransitionend','onwheel','outerHTML','outerText','ownerDocument','parentElement','parentNode','part','popover','prefix','prepend','previousElementSibling','previousSibling','querySelector','querySelectorAll','releaseCapture','releasePointerCapture','remove','removeAttribute','removeAttributeNS','removeAttributeNode','removeChild','removeEventListener','replaceChild','replaceChildren','replaceWith','requestFullscreen','requestPointerLock','role','scroll','scrollBy','scrollHeight','scrollIntoView','scrollLeft','scrollLeftMax','scrollTo','scrollTop','scrollTopMax','scrollWidth','setAttribute','setAttributeNS','setAttributeNode','setAttributeNodeNS','setCapture','setHTMLUnsafe','setPointerCapture','shadowRoot','showPopover','slot','spellcheck','style','tabIndex','tagName','textContent','title','toggleAttribute','togglePopover','translate','webkitMatchesSelector']

let onlyTZP = aTZP.filter(x => !aPOC.includes(x))
let onlyPOC = aPOC.filter(x => !aTZP.includes(x))
let aCommon = aPOC.filter(x => aTZP.includes(x))
console.log("onlyTZP", onlyTZP.length+"\n", "['"+ onlyTZP.join("','") +"']" )
console.log("onlyPOC", onlyPOC.length+"\n", "['"+ onlyPOC.join("','") +"']" )
console.log("aCommon", aCommon.length+"\n", "['"+ aCommon.join("','") +"']" )

results

onlyTZP 181

['ATTRIBUTE_NODE','CDATA_SECTION_NODE','COMMENT_NODE','DOCUMENT_FRAGMENT_NODE','DOCUMENT_NODE','DOCUMENT_POSITION_CONTAINED_BY','DOCUMENT_POSITION_CONTAINS','DOCUMENT_POSITION_DISCONNECTED','DOCUMENT_POSITION_FOLLOWING','DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC','DOCUMENT_POSITION_PRECEDING','DOCUMENT_TYPE_NODE','ELEMENT_NODE','ENTITY_NODE','ENTITY_REFERENCE_NODE','NOTATION_NODE','PROCESSING_INSTRUCTION_NODE','TEXT_NODE','addEventListener','after','animate','append','appendChild','ariaAtomic','ariaAutoComplete','ariaBusy','ariaChecked','ariaColCount','ariaColIndex','ariaColIndexText','ariaColSpan','ariaCurrent','ariaDescription','ariaDisabled','ariaExpanded','ariaHasPopup','ariaHidden','ariaInvalid','ariaKeyShortcuts','ariaLabel','ariaLevel','ariaLive','ariaModal','ariaMultiLine','ariaMultiSelectable','ariaOrientation','ariaPlaceholder','ariaPosInSet','ariaPressed','ariaReadOnly','ariaRelevant','ariaRequired','ariaRoleDescription','ariaRowCount','ariaRowIndex','ariaRowIndexText','ariaRowSpan','ariaSelected','ariaSetSize','ariaSort','ariaValueMax','ariaValueMin','ariaValueNow','ariaValueText','assignedSlot','attachShadow','attributes','baseURI','before','checkVisibility','childElementCount','childNodes','children','classList','className','clientHeight','clientLeft','clientTop','clientWidth','cloneNode','closest','compareDocumentPosition','contains','convertPointFromNode','convertQuadFromNode','convertRectFromNode','dispatchEvent','firstChild','firstElementChild','getAnimations','getAttribute','getAttributeNS','getAttributeNames','getAttributeNode','getAttributeNodeNS','getBoundingClientRect','getBoxQuads','getClientRects','getElementsByClassName','getElementsByTagName','getElementsByTagNameNS','getRootNode','hasAttribute','hasAttributeNS','hasAttributes','hasChildNodes','hasPointerCapture','id','innerHTML','insertAdjacentElement','insertAdjacentHTML','insertAdjacentText','insertBefore','isConnected','isDefaultNamespace','isEqualNode','isSameNode','lastChild','lastElementChild','localName','lookupNamespaceURI','lookupPrefix','matches','mozMatchesSelector','mozRequestFullScreen','namespaceURI','nextElementSibling','nextSibling','nodeName','nodeType','nodeValue','normalize','onfullscreenchange','onfullscreenerror','outerHTML','ownerDocument','parentElement','parentNode','part','prefix','prepend','previousElementSibling','previousSibling','querySelector','querySelectorAll','releaseCapture','releasePointerCapture','removeAttribute','removeAttributeNS','removeAttributeNode','removeChild','removeEventListener','replaceChild','replaceChildren','replaceWith','requestFullscreen','requestPointerLock','role','scroll','scrollBy','scrollHeight','scrollIntoView','scrollLeft','scrollLeftMax','scrollTo','scrollTop','scrollTopMax','scrollWidth','setAttribute','setAttributeNS','setAttributeNode','setAttributeNodeNS','setCapture','setHTMLUnsafe','setPointerCapture','shadowRoot','slot','tagName','textContent','toggleAttribute','webkitMatchesSelector']

onlyPOC 316

['ERROR','HAVE_CURRENT_DATA','HAVE_ENOUGH_DATA','HAVE_FUTURE_DATA','HAVE_METADATA','HAVE_NOTHING','LOADED','LOADING','NETWORK_EMPTY','NETWORK_IDLE','NETWORK_LOADING','NETWORK_NO_SOURCE','NONE','aLink','abbr','accept','acceptCharset','action','add','addTextTrack','allow','allowFullscreen','allowedToPlay','alt','archive','areas','as','async','autocomplete','autoplay','axis','background','bgColor','border','buffered','canPlayType','caption','captureStream','cellIndex','cellPadding','cellSpacing','cells','ch','chOff','charset','checkValidity','checked','cite','clear','close','code','codeBase','codeType','colSpan','color','cols','compact','complete','content','contentDocument','contentWindow','control','controls','coords','createCaption','createTBody','createTFoot','createTHead','crossOrigin','currentSrc','currentTime','data','dateTime','declare','decode','decoding','default','defaultChecked','defaultMuted','defaultPlaybackRate','defaultSelected','defaultValue','defer','deleteCaption','deleteCell','deleteRow','deleteTFoot','deleteTHead','dirName','disablePictureInPicture','disabled','download','duration','elements','encoding','enctype','ended','error','event','fastSeek','files','form','formAction','formEnctype','formMethod','formNoValidate','formTarget','frame','frameBorder','getContext','getSVGDocument','getVideoPlaybackQuality','hash','headers','height','high','host','hostname','href','hreflang','hspace','htmlFor','httpEquiv','imageSizes','imageSrcset','indeterminate','index','insertCell','insertRow','integrity','isMap','item','kind','label','labels','length','link','list','load','loading','longDesc','loop','low','lowsrc','marginHeight','marginWidth','max','maxLength','media','mediaKeys','method','min','minLength','mozAudioCaptured','mozCaptureStream','mozCaptureStreamUntilEnded','mozDecodedFrames','mozFragmentEnd','mozFrameDelay','mozGetMetadata','mozHasAudio','mozIsTextField','mozOpaque','mozPaintedFrames','mozParsedFrames','mozPresentedFrames','mozPrintCallback','multiple','muted','name','namedItem','naturalHeight','naturalWidth','networkState','noHref','noModule','noResize','noShade','noValidate','noWrap','onafterprint','onbeforeprint','onbeforeunload','onencrypted','ongamepadconnected','ongamepaddisconnected','onhashchange','onlanguagechange','onmessage','onmessageerror','onoffline','ononline','onpagehide','onpageshow','onpopstate','onrejectionhandled','onstorage','onunhandledrejection','onunload','onwaitingforkey','open','optimum','options','origin','password','pathname','pattern','pause','paused','ping','placeholder','play','playbackRate','played','popoverTargetAction','popoverTargetElement','port','position','poster','preload','preservesPitch','protocol','readOnly','readyState','referrerPolicy','rel','relList','reportValidity','requestSubmit','required','reset','returnValue','rev','reversed','rowIndex','rowSpan','rows','rules','sandbox','scheme','scope','scrolling','search','sectionRowIndex','seekToNextFrame','seekable','seeking','select','selected','selectedIndex','selectedOptions','selectionDirection','selectionEnd','selectionStart','setCustomValidity','setMediaKeys','setRangeText','setSelectionRange','setSinkId','shadowRootDelegatesFocus','shadowRootMode','shape','sheet','show','showModal','showPicker','sinkId','size','sizes','span','src','srcObject','srcdoc','srclang','srcset','standby','start','step','stepDown','stepUp','submit','summary','tBodies','tFoot','tHead','target','text','textLength','textTracks','toBlob','toDataURL','toString','track','transferControlToOffscreen','type','useMap','username','vAlign','vLink','validationMessage','validity','value','valueAsDate','valueAsNumber','version','videoHeight','videoWidth','volume','vspace','webkitEntries','webkitdirectory','width','willValidate','wrap','x','y']

aCommon 131
['accessKey','accessKeyLabel','align','attachInternals','autocapitalize','autofocus','blur','click','contentEditable','dataset','dir','draggable','enterKeyHint','focus','hidden','hidePopover','inert','innerText','inputMode','isContentEditable','lang','nonce','offsetHeight','offsetLeft','offsetParent','offsetTop','offsetWidth','onabort','onanimationcancel','onanimationend','onanimationiteration','onanimationstart','onauxclick','onbeforeinput','onbeforetoggle','onblur','oncancel','oncanplay','oncanplaythrough','onchange','onclick','onclose','oncontextmenu','oncopy','oncuechange','oncut','ondblclick','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','ondurationchange','onemptied','onended','onerror','onfocus','onformdata','ongotpointercapture','oninput','oninvalid','onkeydown','onkeypress','onkeyup','onload','onloadeddata','onloadedmetadata','onloadstart','onlostpointercapture','onmousedown','onmouseenter','onmouseleave','onmousemove','onmouseout','onmouseover','onmouseup','onmozfullscreenchange','onmozfullscreenerror','onpaste','onpause','onplay','onplaying','onpointercancel','onpointerdown','onpointerenter','onpointerleave','onpointermove','onpointerout','onpointerover','onpointerup','onprogress','onratechange','onreset','onresize','onscroll','onscrollend','onsecuritypolicyviolation','onseeked','onseeking','onselect','onselectionchange','onselectstart','onslotchange','onstalled','onsubmit','onsuspend','ontimeupdate','ontoggle','ontransitioncancel','ontransitionend','ontransitionrun','ontransitionstart','onvolumechange','onwaiting','onwebkitanimationend','onwebkitanimationiteration','onwebkitanimationstart','onwebkittransitionend','onwheel','outerText','popover','remove','showPopover','spellcheck','style','tabIndex','title','togglePopover','translate']

@Thorin-Oakenpants
Copy link
Contributor Author

Thorin-Oakenpants commented Dec 16, 2023

and then there's canvas element and svg*elements .. what else? which I could add to canvas/svg sections, except in the past I decided to not bother with canvas because it was equivalency

edit: OK: I can programmatically check from an array of strings by checking window["string" !== undefined - so that makes it much cleaner

and I might call this element_keys and add canvas, svg* and other items

@Thorin-Oakenpants
Copy link
Contributor Author

OK, did a revamp of groups (was 4 now 5), and I now pass an array of strings, so we can programmatically detect when a window property is not supported

note: not that I expected any diffs

- no diffs between TB vs MB
- no diffs between normal vs PB mode
- diffs in ESR115 vs TB115 = NoScript items after constructor
   - safer vs standard is the same

here's some notes: re gecko

MAIN (tested FF98+)
- fe0afef4 98 99 100
- 1a8bac8e 101 102 103 104 105 106 107
- 6f6c2c2c 108
- d86ef2f5 109
- 5effddba 110
- 6f73c31f 111
- e0d40c29 112 113 114
- af1a4fc2 115
- ea95cba8 116
- 1ad127ed 117 118 119 120
- 56ecfec9 121
- c9837eeb Nightly122
INTERESTING (98+)
- fc5ce086 98 99 100 101 102 103 104
- 8defb74e 105
- c9d1d31a 106 107
- 27b7e075 108 109 110
- d8ca9a75 111+ (so far up to FF122 Nightly)
STABLE 98+
- f2b2dd31 97
- bd1065f2 98-121 + FF122 Nightly (98+ then has HTMLDialogElement)
both tested FF52-FF122

STABLE 52+ 
- d3ce4fc4

note: super boring (since FF70) - so ignoring old gecko, this group is still basically the same blink etc
SUPER BORING
- 519394f3 52 53 54 55 56
- f1348dd5 57
- c198622c 58
- c198622c 59
- dbb978ae 60
- b2da0015 61 62 63 64 65 66 67
- f9944755 68
- 5da63490 69
- 078ef8c3 70-121 + FF122 Nightly (HTMLDocument drops to constructor only)

@Thorin-Oakenpants Thorin-Oakenpants changed the title htmlelement keys vs HTML*Element keys HTML*Element keys Dec 16, 2023
@Thorin-Oakenpants
Copy link
Contributor Author

so we're getting keys on a div element, right? what about other element types?

html poc
<html>
<head><title>element keys</title><style>.mono {font-family: monospace;}</style></head><body>

<br><div class="mono" id="results"></div>
<script>
'use strict';

let oHash = {}
let oData = {}

function mini(str) {
	// https://stackoverflow.com/a/22429679
	const json = `${JSON.stringify(str)}`
	let i, len, hash = 0x811c9dc5
	for (i = 0, len = json.length; i < len; i++) {
		hash = Math.imul(31, hash) + json.charCodeAt(i) | 0
	}
	return ('0000000' + (hash >>> 0).toString(16)).slice(-8)
}

//https://w3c.github.io/elements-of-html/
	// ignore: checked in gecko + blink (desktop)
let ignore = [
'caption','h1','h2','h3','h4','h5','h6','p', // = div
'ins', // = del
'xmp', // = pre
'colgroup', // = col
'dl','menu', // = dir
'q', // = blockquote
'tfoot','thead', // = tbody

// = span
'abbr','acronym','address','applet','article','aside','b',
'basefont','bdi','bdo','big','center','cite','code','dd','dfn','dt','em',
'figcaption','figure','footer','head','header','hgroup','i','isindex',
'kbd','keygen','main','mark','menuitem','nav','nextid','noframes','noscript',
'picture','plaintext','rb','rbc','rp','rt','rtc','ruby','s','samp','section',
'small','span','strike','strong','sub','summary','sup','tt','u','var','wbr',

// input types = input
'input|button','input|checkbox','input|color','input|date','input|datetime',
'input|datetime-local','input|file','input|image','input|month','input|number',
'input|password','input|radio','input|range','input|reset','input|search',
'input|submit','input|tel','input|text','input|time','input|url','input|week',
]


let elements = [
'a','area','audio',
'base','blockquote','body','br','button',
'canvas','col',
'data','datalist','del','details','dialog','dir','div',
'embed',
'fieldset','font','form','frame','frameset',
'hr','html',
'iframe','img','input',
'label','legend','li','link',
'map','meta','meter',
'object','ol','optgroup','option','output',
'param','pre','progress',
'script','select','source','style',
'table','tbody','td','template','textarea','th','time','title','tr','track',
'ul','video',
]
elements.sort() // why not
console.log("'"+ elements.join("','")+"'")

let aEverything = []

try {
	elements.forEach(function(el) {
		let item = el.split("|")[0]
		let type = el.split("|")[1]
		try {
			const id = "target"+el
			const element = document.createElement(item)
			element.setAttribute("id", id)
			document.body.appendChild(element)
			if (type !== undefined) {
				document.getElementById(id).type = type
			}
			const htmlElement = document.getElementById(id)
			let keys = []
			for (const key in htmlElement) {keys.push(key)}
			keys.forEach(function(j) {
				aEverything.push(j)
			})
			try {document.getElementById(id).remove()} catch(e) {}
			let hash = mini(keys)
			if (oHash[hash] == undefined) {
				oHash[hash] = {"count": keys.length, "data": []}
				oData[hash] = "['"+ keys.join("', '") +"']"
			}
			oHash[hash]["data"].push(el)
		} catch(e) {
			oHash.push(item +" "+ e.name)
		}
	})
	let display = []
	display.push("<u><b>RESULTS</b></u><br>")
	for (const k of Object.keys(oData).sort()) {
		display.push(k +" ["+ oHash[k].count +"]: "+ oHash[k]["data"].join(", ")
			+ "<br><details>"+ oData[k] +"</details>"
		)
	}
	document.getElementById("results").innerHTML = display.join("<br>")

	//* everything
	//console.log(aEverything) // 815 all : 749 (no constructors)
	aEverything.sort() // order is artifical due to htmlList so lets remove that here
	aEverything = aEverything.filter(function(item, position) {return aEverything.indexOf(item) === position}) // deduped
	let aPOC = aEverything.filter(x => !["constructor"].includes(x)) // remove constructor
	console.log("EVERYTHING: " + mini(aEverything) +" ["+ aEverything.length +"]\n", "'"+ aPOC.join("','") +"'")
	//EVERYTHING: d6d0fc0e [630]
	//*/

} catch (e) {
	document.getElementById("results").innerHTML = e+""
}
</script></body></html>

I tested a larger set of elements, but removed those that duplicated hashes - the results of duplication were the same in blink + gecko

results (minus the detail data)
045f3baa [335]: select
04627128 [314]: label
04d0413f [313]: optgroup
04f094bf [323]: script
10c5964d [378]: video
1350567e [313]: map
187228f3 [313]: del
192b19bf [337]: img
290e48e5 [337]: object
2b8187f6 [318]: meter
2c19580d [312]: details
2e2d6614 [316]: hr
2e415ab6 [313]: li
331f88fe [315]: ol
33cf08c6 [313]: legend
350b9971 [329]: form
3b7b37fc [319]: option
42bcca60 [312]: blockquote
43c289ca [312]: div
4dcefde9 [312]: pre
516705de [312]: data
5a98dc08 [321]: tr
5b358425 [324]: output
5b62e5ca [312]: title
5c196c4d [318]: embed
65962d9c [312]: time
65dc4743 [330]: iframe
6b855982 [312]: br
71b3b699 [316]: dialog
7228580f [341]: textarea
723b0754 [318]: source
7a1ee797 [312]: html
87975368 [314]: font
8801769c [315]: progress
8a0118c4 [320]: canvas
8a724ccc [321]: frame
8e33586a [365]: audio
97b3aa83 [333]: area
a218def6 [334]: table
a2698900 [326]: td, th
a69d9e2e [330]: button
a7027d5a [317]: col
aeb18ccf [314]: template
afb65ed1 [313]: base
b648182e [315]: param
b80bc3bc [322]: track
c4be344c [335]: body
c9218fd5 [371]: input
d5afc0ec [312]: dir
d78b2ffe [315]: style
d986cb2e [337]: a
dc2fda70 [329]: link
de2d64b2 [331]: frameset
ec5d1579 [318]: tbody
ecae4380 [316]: meta
f310b3e8 [313]: ul
fc0790a8 [322]: fieldset
fd835711 [312]: datalist

this was on FF122 nightly ... combined I get 630 unique keys

@Thorin-Oakenpants
Copy link
Contributor Author

so I think we could expand the creepy/tzp "html element keys" test - because currently it's not that, it's a "div element" keys test

then we have HTLM*Element tests in my PoC, which can be expanded to include other window items

Is one test duplicitous of the other? I should see if I can get my PoC to 630 unique values (i.e start adding in CanvasRenderingContext2D and everything else I can find? Note I we can use any list, so I can pass the list for each test, e.g. AVG section, canvas section, elements section

the problem them becomes in the elements section I would have two html_element_keys metric names (assuming we expand the div test to be more than one element) - so we need to think of something better - what say you @abrahamjuliot ?

@Thorin-Oakenpants
Copy link
Contributor Author

anyway - moved the test to https://arkenfox.github.io/TZP/tests/functionprops.html - because we're enumerating properties on functions - and I started adding items in lists, so you can run Element or Canvas or Audio etc

@Thorin-Oakenpants Thorin-Oakenpants changed the title HTML*Element keys function properties (e.g. vs element keys) Dec 19, 2023
@abrahamjuliot
Copy link
Collaborator

abrahamjuliot commented Dec 19, 2023

Nice. We could also query elements on the page and see if anything was added or removed or re-ordered.

scriptElems = [...document.querySelectorAll('script')].map((el) => el.attributes)

document.querySelectorAll('body *') // Everything. Probably too much
document.querySelectorAll('body > *') // The main skeleton

@Thorin-Oakenpants
Copy link
Contributor Author

hah ... this is FF with JShelter

relevant prototypeLies courtesy of creepy

  "AnalyserNode.fftSize",
  "AnalyserNode.frequencyBinCount",
  "AnalyserNode.get fftSize",
  "AnalyserNode.get frequencyBinCount",
  "AnalyserNode.get maxDecibels",
  "AnalyserNode.get minDecibels",
  "AnalyserNode.get smoothingTimeConstant",
  "AnalyserNode.getByteFrequencyData",
  "AnalyserNode.getByteTimeDomainData",
  "AnalyserNode.getFloatFrequencyData",
  "AnalyserNode.getFloatTimeDomainData",
  "AnalyserNode.maxDecibels",
  "AnalyserNode.minDecibels",
  "AnalyserNode.set fftSize",
  "AnalyserNode.set maxDecibels",
  "AnalyserNode.set minDecibels",
  "AnalyserNode.set smoothingTimeConstant",
  "AnalyserNode.smoothingTimeConstant",
  "AudioBuffer.copyFromChannel",
  "AudioBuffer.getChannelData",

looks like I scored higher!!! nah nah nah nah ..

hah

@Thorin-Oakenpants
Copy link
Contributor Author

Thorin-Oakenpants commented Dec 19, 2023

looks like I scored higher

well, actually .. not ... I'm not ... I just picked up some things you didn't because I check a few more functions. And I miss some stuff e.g. in Analyser.Node - I guess that's because I'm not checking "sub-functions" of function properties .. etc

@Aszezo
Copy link

Aszezo commented Aug 14, 2024

.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants