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

Cataloging ECMAScript #579

Open
Elchi3 opened this issue Feb 2, 2024 · 14 comments
Open

Cataloging ECMAScript #579

Elchi3 opened this issue Feb 2, 2024 · 14 comments

Comments

@Elchi3
Copy link
Collaborator

Elchi3 commented Feb 2, 2024

I think if we want to catalog the web platform it requires a Birds Eye view down to the individual features. So I thought it'd be a good exercise to do that with everything defined in ECMAScript as it doesn't really interfere with the other technologies (unlike HTML, CSS which have API reflections etc.). I removed Temporal and Intl out of the discussion for now and then this exercise is about how to sort 901 features present in the javascript.* BCD tree. I would love to hear what others think about how to catalog ECMAScript.

I'm building on the idea of snapshots and capabilities in #558 (comment) and I'm using BCD's tags. A branch with tags applied to BCD can be found here: mdn/browser-compat-data@main...Elchi3:browser-compat-data:ecmascript-tags


First, I came up with snapshots tags (in BCD I tagged them as "web-features:ecmascript-1" etc. but we could also make clear these are snapshots by using a prefix or so: "web-features-snapshot:ecmascript-1"). I went through the specs and categorized ~750/901 features by their snapshot (rest TBD):

ECMAScript 1 (194 features)

  • javascript.builtins.Array
  • javascript.builtins.Array.Array
  • javascript.builtins.Array.join
  • javascript.builtins.Array.length
  • javascript.builtins.Array.reverse
  • javascript.builtins.Array.sort
  • javascript.builtins.Array.toString
  • javascript.builtins.Boolean
  • javascript.builtins.Boolean.Boolean
  • javascript.builtins.Boolean.toString
  • javascript.builtins.Boolean.valueOf
  • javascript.builtins.Date
  • javascript.builtins.Date.Date
  • javascript.builtins.Date.UTC
  • javascript.builtins.Date.getDate
  • javascript.builtins.Date.getDay
  • javascript.builtins.Date.getFullYear
  • javascript.builtins.Date.getHours
  • javascript.builtins.Date.getMilliseconds
  • javascript.builtins.Date.getMinutes
  • javascript.builtins.Date.getMonth
  • javascript.builtins.Date.getSeconds
  • javascript.builtins.Date.getTime
  • javascript.builtins.Date.getTimezoneOffset
  • javascript.builtins.Date.getUTCDate
  • javascript.builtins.Date.getUTCDay
  • javascript.builtins.Date.getUTCFullYear
  • javascript.builtins.Date.getUTCHours
  • javascript.builtins.Date.getUTCMilliseconds
  • javascript.builtins.Date.getUTCMinutes
  • javascript.builtins.Date.getUTCMonth
  • javascript.builtins.Date.getUTCSeconds
  • javascript.builtins.Date.getYear
  • javascript.builtins.Date.parse
  • javascript.builtins.Date.setDate
  • javascript.builtins.Date.setFullYear
  • javascript.builtins.Date.setHours
  • javascript.builtins.Date.setMilliseconds
  • javascript.builtins.Date.setMinutes
  • javascript.builtins.Date.setMonth
  • javascript.builtins.Date.setSeconds
  • javascript.builtins.Date.setTime
  • javascript.builtins.Date.setUTCDate
  • javascript.builtins.Date.setUTCFullYear
  • javascript.builtins.Date.setUTCHours
  • javascript.builtins.Date.setUTCMilliseconds
  • javascript.builtins.Date.setUTCMinutes
  • javascript.builtins.Date.setUTCMonth
  • javascript.builtins.Date.setUTCSeconds
  • javascript.builtins.Date.setYear
  • javascript.builtins.Date.toGMTString
  • javascript.builtins.Date.toLocaleString
  • javascript.builtins.Date.toString
  • javascript.builtins.Date.toUTCString
  • javascript.builtins.Date.valueOf
  • javascript.builtins.Function
  • javascript.builtins.Function.Function
  • javascript.builtins.Function.length
  • javascript.builtins.Function.toString
  • javascript.builtins.Math
  • javascript.builtins.Math.E
  • javascript.builtins.Math.LN10
  • javascript.builtins.Math.LN2
  • javascript.builtins.Math.LOG10E
  • javascript.builtins.Math.LOG2E
  • javascript.builtins.Math.PI
  • javascript.builtins.Math.SQRT1_2
  • javascript.builtins.Math.SQRT2
  • javascript.builtins.Math.abs
  • javascript.builtins.Math.acos
  • javascript.builtins.Math.asin
  • javascript.builtins.Math.atan
  • javascript.builtins.Math.atan2
  • javascript.builtins.Math.ceil
  • javascript.builtins.Math.cos
  • javascript.builtins.Math.exp
  • javascript.builtins.Math.floor
  • javascript.builtins.Math.log
  • javascript.builtins.Math.max
  • javascript.builtins.Math.min
  • javascript.builtins.Math.pow
  • javascript.builtins.Math.random
  • javascript.builtins.Math.round
  • javascript.builtins.Math.sin
  • javascript.builtins.Math.sqrt
  • javascript.builtins.Math.tan
  • javascript.builtins.Number
  • javascript.builtins.Number.MAX_VALUE
  • javascript.builtins.Number.MIN_VALUE
  • javascript.builtins.Number.NaN
  • javascript.builtins.Number.NEGATIVE_INFINITY
  • javascript.builtins.Number.Number
  • javascript.builtins.Number.POSITIVE_INFINITY
  • javascript.builtins.Number.toString
  • javascript.builtins.Number.valueOf
  • javascript.builtins.Object
  • javascript.builtins.Object.Object
  • javascript.builtins.Object.toString
  • javascript.builtins.Object.valueOf
  • javascript.builtins.String
  • javascript.builtins.String.String
  • javascript.builtins.String.charAt
  • javascript.builtins.String.charCodeAt
  • javascript.builtins.String.fromCharCode
  • javascript.builtins.String.indexOf
  • javascript.builtins.String.lastIndexOf
  • javascript.builtins.String.length
  • javascript.builtins.String.split
  • javascript.builtins.String.substring
  • javascript.builtins.String.toLowerCase
  • javascript.builtins.String.toString
  • javascript.builtins.String.toUpperCase
  • javascript.builtins.String.valueOf
  • javascript.builtins.Infinity
  • javascript.builtins.NaN
  • javascript.builtins.escape
  • javascript.builtins.eval
  • javascript.builtins.isFinite
  • javascript.builtins.isNaN
  • javascript.builtins.parseFloat
  • javascript.builtins.parseInt
  • javascript.builtins.undefined
  • javascript.builtins.unescape
  • javascript.functions
  • javascript.functions.arguments
  • javascript.functions.arguments.callee
  • javascript.functions.arguments.length
  • javascript.grammar.boolean_literals
  • javascript.grammar.decimal_numeric_literals
  • javascript.grammar.hexadecimal_numeric_literals
  • javascript.grammar.null_literal
  • javascript.grammar.string_literals
  • javascript.grammar.unicode_escape_sequences
  • javascript.operators.addition
  • javascript.operators.addition_assignment
  • javascript.operators.assignment
  • javascript.operators.bitwise_and
  • javascript.operators.bitwise_and_assignment
  • javascript.operators.bitwise_not
  • javascript.operators.bitwise_or
  • javascript.operators.bitwise_or_assignment
  • javascript.operators.bitwise_xor
  • javascript.operators.bitwise_xor_assignment
  • javascript.operators.comma
  • javascript.operators.conditional
  • javascript.operators.decrement
  • javascript.operators.delete
  • javascript.operators.division
  • javascript.operators.division_assignment
  • javascript.operators.equality
  • javascript.operators.function
  • javascript.operators.greater_than
  • javascript.operators.greater_than_or_equal
  • javascript.operators.grouping
  • javascript.operators.in
  • javascript.operators.increment
  • javascript.operators.inequality
  • javascript.operators.left_shift
  • javascript.operators.left_shift_assignment
  • javascript.operators.less_than
  • javascript.operators.less_than_or_equal
  • javascript.operators.logical_and
  • javascript.operators.logical_not
  • javascript.operators.logical_or
  • javascript.operators.multiplication
  • javascript.operators.multiplication_assignment
  • javascript.operators.new
  • javascript.operators.null
  • javascript.operators.property_accessors
  • javascript.operators.remainder
  • javascript.operators.remainder_assignment
  • javascript.operators.right_shift
  • javascript.operators.right_shift_assignment
  • javascript.operators.subtraction
  • javascript.operators.subtraction_assignment
  • javascript.operators.this
  • javascript.operators.typeof
  • javascript.operators.unary_negation
  • javascript.operators.unary_plus
  • javascript.operators.unsigned_right_shift
  • javascript.operators.unsigned_right_shift_assignment
  • javascript.operators.void
  • javascript.statements.block
  • javascript.statements.break
  • javascript.statements.continue
  • javascript.statements.empty
  • javascript.statements.for
  • javascript.statements.for_in
  • javascript.statements.function
  • javascript.statements.if_else
  • javascript.statements.return
  • javascript.statements.var
  • javascript.statements.while
  • javascript.statements.with

ECMAScript 3 (79 features)

javascript.builtins.Array.concat
javascript.builtins.Array.pop
javascript.builtins.Array.push
javascript.builtins.Array.shift
javascript.builtins.Array.slice
javascript.builtins.Array.toLocaleString
javascript.builtins.Array.unshift
javascript.builtins.Date.toDateString
javascript.builtins.Date.toLocaleDateString
javascript.builtins.Date.toLocaleTimeString
javascript.builtins.Date.toTimeString
javascript.builtins.Error
javascript.builtins.Error.Error
javascript.builtins.Error.message
javascript.builtins.Error.name
javascript.builtins.Error.toString
javascript.builtins.EvalError
javascript.builtins.EvalError.EvalError
javascript.builtins.Function.apply
javascript.builtins.Function.call
javascript.builtins.Number.toExponential
javascript.builtins.Number.toFixed
javascript.builtins.Number.toLocaleString
javascript.builtins.Number.toPrecision
javascript.builtins.Object.hasOwnProperty
javascript.builtins.Object.isPrototypeOf
javascript.builtins.Object.propertyIsEnumerable
javascript.builtins.Object.toLocaleString
javascript.builtins.RangeError
javascript.builtins.RangeError.RangeError
javascript.builtins.ReferenceError
javascript.builtins.ReferenceError.ReferenceError
javascript.builtins.RegExp
javascript.builtins.RegExp.RegExp
javascript.builtins.RegExp.exec
javascript.builtins.RegExp.global
javascript.builtins.RegExp.ignoreCase
javascript.builtins.RegExp.lastIndex
javascript.builtins.RegExp.multiline
javascript.builtins.RegExp.source
javascript.builtins.RegExp.test
javascript.builtins.RegExp.toString
javascript.builtins.String.concat
javascript.builtins.String.localeCompare
javascript.builtins.String.match
javascript.builtins.String.replace
javascript.builtins.String.search
javascript.builtins.String.slice
javascript.builtins.String.substr
javascript.builtins.String.toLocaleLowerCase
javascript.builtins.String.toLocaleUpperCase
javascript.builtins.SyntaxError
javascript.builtins.SyntaxError.SyntaxError
javascript.builtins.TypeError
javascript.builtins.TypeError.TypeError
javascript.builtins.URIError
javascript.builtins.URIError.URIError
javascript.builtins.decodeURI
javascript.builtins.decodeURIComponent
javascript.builtins.encodeURI
javascript.builtins.encodeURIComponent
javascript.grammar.regular_expression_literals
javascript.regular_expressions.backreference
javascript.regular_expressions.capturing_group
javascript.regular_expressions.character_class
javascript.regular_expressions.character_class_escape
javascript.regular_expressions.character_escape
javascript.regular_expressions.disjunction
javascript.regular_expressions.input_boundary_assertion
javascript.regular_expressions.literal_character
javascript.regular_expressions.lookahead_assertion
javascript.regular_expressions.non_capturing_group
javascript.regular_expressions.quantifier
javascript.regular_expressions.wildcard
javascript.regular_expressions.word_boundary_assertion
javascript.statements.do_while
javascript.statements.label
javascript.statements.throw
javascript.statements.try_catch

ECMAScript 5 (35 features)

  • javascript.builtins.Array.every
  • javascript.builtins.Array.filter
  • javascript.builtins.Array.forEach
  • javascript.builtins.Array.indexOf
  • javascript.builtins.Array.isArray
  • javascript.builtins.Array.lastIndexOf
  • javascript.builtins.Array.map
  • javascript.builtins.Array.reduce
  • javascript.builtins.Array.reduceRight
  • javascript.builtins.Array.some
  • javascript.builtins.Date.now
  • javascript.builtins.Date.parse.iso_8601
  • javascript.builtins.Date.toISOString
  • javascript.builtins.Date.toJSON
  • javascript.builtins.Function.apply.generic_arrays_as_arguments
  • javascript.builtins.Function.bind
  • javascript.builtins.JSON
  • javascript.builtins.JSON.parse
  • javascript.builtins.JSON.stringify
  • javascript.builtins.Object.create
  • javascript.builtins.Object.defineProperties
  • javascript.builtins.Object.defineProperty
  • javascript.builtins.Object.freeze
  • javascript.builtins.Object.getOwnPropertyDescriptor
  • javascript.builtins.Object.getOwnPropertyNames
  • javascript.builtins.Object.getPrototypeOf
  • javascript.builtins.Object.isExtensible
  • javascript.builtins.Object.isFrozen
  • javascript.builtins.Object.isSealed
  • javascript.builtins.Object.keys
  • javascript.builtins.Object.preventExtensions
  • javascript.builtins.Object.seal
  • javascript.builtins.String.trim
  • javascript.functions.get
  • javascript.functions.set

ECMAScript 2015 (355 features)

  • javascript.builtins.Array.copyWithin
  • javascript.builtins.Array.entries
  • javascript.builtins.Array.fill
  • javascript.builtins.Array.find
  • javascript.builtins.Array.findIndex
  • javascript.builtins.Array.from
  • javascript.builtins.Array.keys
  • javascript.builtins.Array.of
  • javascript.builtins.Array.splice
  • javascript.builtins.Array.values
  • javascript.builtins.Array.@@iterator
  • javascript.builtins.Array.@@species
  • javascript.builtins.Array.@@unscopables
  • javascript.builtins.ArrayBuffer
  • javascript.builtins.ArrayBuffer.ArrayBuffer
  • javascript.builtins.ArrayBuffer.ArrayBuffer.new_required
  • javascript.builtins.ArrayBuffer.byteLength
  • javascript.builtins.ArrayBuffer.isView
  • javascript.builtins.ArrayBuffer.slice
  • javascript.builtins.ArrayBuffer.@@species
  • javascript.builtins.DataView
  • javascript.builtins.DataView.DataView
  • javascript.builtins.DataView.DataView.new_required
  • javascript.builtins.DataView.buffer
  • javascript.builtins.DataView.byteLength
  • javascript.builtins.DataView.byteOffset
  • javascript.builtins.DataView.getFloat32
  • javascript.builtins.DataView.getFloat64
  • javascript.builtins.DataView.getInt16
  • javascript.builtins.DataView.getInt32
  • javascript.builtins.DataView.getInt8
  • javascript.builtins.DataView.getUint16
  • javascript.builtins.DataView.getUint32
  • javascript.builtins.DataView.getUint8
  • javascript.builtins.DataView.setFloat32
  • javascript.builtins.DataView.setFloat64
  • javascript.builtins.DataView.setInt16
  • javascript.builtins.DataView.setInt32
  • javascript.builtins.DataView.setInt8
  • javascript.builtins.DataView.setUint16
  • javascript.builtins.DataView.setUint32
  • javascript.builtins.DataView.setUint8
  • javascript.builtins.Date.@@toPrimitive
  • javascript.builtins.Float32Array
  • javascript.builtins.Float32Array.Float32Array
  • javascript.builtins.Float32Array.Float32Array.constructor_without_parameters
  • javascript.builtins.Float32Array.Float32Array.iterable_allowed
  • javascript.builtins.Float32Array.Float32Array.new_required
  • javascript.builtins.Float64Array
  • javascript.builtins.Float64Array.Float64Array
  • javascript.builtins.Float64Array.Float64Array.constructor_without_parameters
  • javascript.builtins.Float64Array.Float64Array.iterable_allowed
  • javascript.builtins.Float64Array.Float64Array.new_required
  • javascript.builtins.Function.length.configurable_true
  • javascript.builtins.Function.name
  • javascript.builtins.Function.name.configurable_true
  • javascript.builtins.Function.name.inferred_names
  • javascript.builtins.Function.@@hasInstance
  • javascript.builtins.Generator
  • javascript.builtins.Generator.next
  • javascript.builtins.Generator.return
  • javascript.builtins.Generator.throw
  • javascript.builtins.GeneratorFunction
  • javascript.builtins.GeneratorFunction.GeneratorFunction
  • javascript.builtins.Int16Array
  • javascript.builtins.Int16Array.Int16Array
  • javascript.builtins.Int16Array.Int16Array.constructor_without_parameters
  • javascript.builtins.Int16Array.Int16Array.iterable_allowed
  • javascript.builtins.Int16Array.Int16Array.new_required
  • javascript.builtins.Int32Array
  • javascript.builtins.Int32Array.Int32Array
  • javascript.builtins.Int32Array.Int32Array.constructor_without_parameters
  • javascript.builtins.Int32Array.Int32Array.iterable_allowed
  • javascript.builtins.Int32Array.Int32Array.new_required
  • javascript.builtins.Int8Array
  • javascript.builtins.Int8Array.Int8Array
  • javascript.builtins.Int8Array.Int8Array.constructor_without_parameters
  • javascript.builtins.Int8Array.Int8Array.iterable_allowed
  • javascript.builtins.Int8Array.Int8Array.new_required
  • javascript.builtins.Iterator
  • javascript.builtins.Iterator.@@iterator
  • javascript.builtins.Map
  • javascript.builtins.Map.Map
  • javascript.builtins.Map.Map.iterable_allowed
  • javascript.builtins.Map.Map.new_required
  • javascript.builtins.Map.Map.null_allowed
  • javascript.builtins.Map.clear
  • javascript.builtins.Map.delete
  • javascript.builtins.Map.entries
  • javascript.builtins.Map.forEach
  • javascript.builtins.Map.get
  • javascript.builtins.Map.has
  • javascript.builtins.Map.key_equality_for_zeros
  • javascript.builtins.Map.keys
  • javascript.builtins.Map.set
  • javascript.builtins.Map.size
  • javascript.builtins.Map.values
  • javascript.builtins.Map.@@iterator
  • javascript.builtins.Map.@@species
  • javascript.builtins.Math.acosh
  • javascript.builtins.Math.asinh
  • javascript.builtins.Math.atanh
  • javascript.builtins.Math.cbrt
  • javascript.builtins.Math.clz32
  • javascript.builtins.Math.cosh
  • javascript.builtins.Math.expm1
  • javascript.builtins.Math.fround
  • javascript.builtins.Math.hypot
  • javascript.builtins.Math.imul
  • javascript.builtins.Math.log10
  • javascript.builtins.Math.log1p
  • javascript.builtins.Math.log2
  • javascript.builtins.Math.sign
  • javascript.builtins.Math.sinh
  • javascript.builtins.Math.tanh
  • javascript.builtins.Math.trunc
  • javascript.builtins.Number.EPSILON
  • javascript.builtins.Number.MAX_SAFE_INTEGER
  • javascript.builtins.Number.MIN_SAFE_INTEGER
  • javascript.builtins.Number.isFinite
  • javascript.builtins.Number.isInteger
  • javascript.builtins.Number.isNaN
  • javascript.builtins.Number.isSafeInteger
  • javascript.builtins.Number.parseFloat
  • javascript.builtins.Number.parseInt
  • javascript.builtins.Object.assign
  • javascript.builtins.Object.getOwnPropertySymbols
  • javascript.builtins.Object.is
  • javascript.builtins.Object.preventExtensions.ES2015_behavior
  • javascript.builtins.Object.proto
  • javascript.builtins.Object.setPrototypeOf
  • javascript.builtins.Promise
  • javascript.builtins.Promise.Promise
  • javascript.builtins.Promise.all
  • javascript.builtins.Promise.catch
  • javascript.builtins.Promise.race
  • javascript.builtins.Promise.reject
  • javascript.builtins.Promise.resolve
  • javascript.builtins.Promise.then
  • javascript.builtins.Promise.@@species
  • javascript.builtins.Proxy
  • javascript.builtins.Proxy.Proxy
  • javascript.builtins.Proxy.handler.apply
  • javascript.builtins.Proxy.handler.construct
  • javascript.builtins.Proxy.handler.defineProperty
  • javascript.builtins.Proxy.handler.deleteProperty
  • javascript.builtins.Proxy.handler.get
  • javascript.builtins.Proxy.handler.getOwnPropertyDescriptor
  • javascript.builtins.Proxy.handler.getPrototypeOf
  • javascript.builtins.Proxy.handler.has
  • javascript.builtins.Proxy.handler.isExtensible
  • javascript.builtins.Proxy.handler.ownKeys
  • javascript.builtins.Proxy.handler.preventExtensions
  • javascript.builtins.Proxy.handler.set
  • javascript.builtins.Proxy.handler.setPrototypeOf
  • javascript.builtins.Proxy.revocable
  • javascript.builtins.Reflect
  • javascript.builtins.Reflect.apply
  • javascript.builtins.Reflect.construct
  • javascript.builtins.Reflect.defineProperty
  • javascript.builtins.Reflect.deleteProperty
  • javascript.builtins.Reflect.get
  • javascript.builtins.Reflect.getOwnPropertyDescriptor
  • javascript.builtins.Reflect.getPrototypeOf
  • javascript.builtins.Reflect.has
  • javascript.builtins.Reflect.isExtensible
  • javascript.builtins.Reflect.ownKeys
  • javascript.builtins.Reflect.preventExtensions
  • javascript.builtins.Reflect.set
  • javascript.builtins.Reflect.setPrototypeOf
  • javascript.builtins.RegExp.compile
  • javascript.builtins.RegExp.flags
  • javascript.builtins.RegExp.@@match
  • javascript.builtins.RegExp.@@replace
  • javascript.builtins.RegExp.@@search
  • javascript.builtins.RegExp.@@species
  • javascript.builtins.RegExp.@@split
  • javascript.builtins.Set
  • javascript.builtins.Set.Set
  • javascript.builtins.Set.Set.iterable_allowed
  • javascript.builtins.Set.Set.new_required
  • javascript.builtins.Set.Set.null_allowed
  • javascript.builtins.Set.add
  • javascript.builtins.Set.clear
  • javascript.builtins.Set.delete
  • javascript.builtins.Set.entries
  • javascript.builtins.Set.forEach
  • javascript.builtins.Set.has
  • javascript.builtins.Set.key_equality_for_zeros
  • javascript.builtins.Set.keys
  • javascript.builtins.Set.size
  • javascript.builtins.Set.values
  • javascript.builtins.Set.@@iterator
  • javascript.builtins.Set.@@species
  • javascript.builtins.String.anchor
  • javascript.builtins.String.big
  • javascript.builtins.String.blink
  • javascript.builtins.String.bold
  • javascript.builtins.String.codePointAt
  • javascript.builtins.String.endsWith
  • javascript.builtins.String.fixed
  • javascript.builtins.String.fontcolor
  • javascript.builtins.String.fontsize
  • javascript.builtins.String.fromCodePoint
  • javascript.builtins.String.includes
  • javascript.builtins.String.italics
  • javascript.builtins.String.link
  • javascript.builtins.String.normalize
  • javascript.builtins.String.raw
  • javascript.builtins.String.repeat
  • javascript.builtins.String.small
  • javascript.builtins.String.startsWith
  • javascript.builtins.String.strike
  • javascript.builtins.String.sub
  • javascript.builtins.String.sup
  • javascript.builtins.String.@@iterator
  • javascript.builtins.Symbol
  • javascript.builtins.Symbol.Symbol
  • javascript.builtins.Symbol.for
  • javascript.builtins.Symbol.hasInstance
  • javascript.builtins.Symbol.isConcatSpreadable
  • javascript.builtins.Symbol.iterator
  • javascript.builtins.Symbol.keyFor
  • javascript.builtins.Symbol.match
  • javascript.builtins.Symbol.replace
  • javascript.builtins.Symbol.search
  • javascript.builtins.Symbol.species
  • javascript.builtins.Symbol.split
  • javascript.builtins.Symbol.toPrimitive
  • javascript.builtins.Symbol.toString
  • javascript.builtins.Symbol.toStringTag
  • javascript.builtins.Symbol.toStringTag.dom_objects
  • javascript.builtins.Symbol.unscopables
  • javascript.builtins.Symbol.valueOf
  • javascript.builtins.Symbol.@@toPrimitive
  • javascript.builtins.TypedArray
  • javascript.builtins.TypedArray.BYTES_PER_ELEMENT
  • javascript.builtins.TypedArray.buffer
  • javascript.builtins.TypedArray.byteLength
  • javascript.builtins.TypedArray.byteOffset
  • javascript.builtins.TypedArray.constructor_without_parameters
  • javascript.builtins.TypedArray.copyWithin
  • javascript.builtins.TypedArray.entries
  • javascript.builtins.TypedArray.every
  • javascript.builtins.TypedArray.fill
  • javascript.builtins.TypedArray.filter
  • javascript.builtins.TypedArray.find
  • javascript.builtins.TypedArray.findIndex
  • javascript.builtins.TypedArray.findLast
  • javascript.builtins.TypedArray.findLastIndex
  • javascript.builtins.TypedArray.forEach
  • javascript.builtins.TypedArray.from
  • javascript.builtins.TypedArray.includes
  • javascript.builtins.TypedArray.index_properties_not_consulting_prototype
  • javascript.builtins.TypedArray.indexOf
  • javascript.builtins.TypedArray.iterable_in_constructor
  • javascript.builtins.TypedArray.join
  • javascript.builtins.TypedArray.keys
  • javascript.builtins.TypedArray.lastIndexOf
  • javascript.builtins.TypedArray.length
  • javascript.builtins.TypedArray.map
  • javascript.builtins.TypedArray.name
  • javascript.builtins.TypedArray.named_properties
  • javascript.builtins.TypedArray.new_required
  • javascript.builtins.TypedArray.of
  • javascript.builtins.TypedArray.reduce
  • javascript.builtins.TypedArray.reduceRight
  • javascript.builtins.TypedArray.reverse
  • javascript.builtins.TypedArray.set
  • javascript.builtins.TypedArray.slice
  • javascript.builtins.TypedArray.some
  • javascript.builtins.TypedArray.sort
  • javascript.builtins.TypedArray.subarray
  • javascript.builtins.TypedArray.toLocaleString
  • javascript.builtins.TypedArray.toString
  • javascript.builtins.TypedArray.values
  • javascript.builtins.TypedArray.@@iterator
  • javascript.builtins.TypedArray.@@species
  • javascript.builtins.Uint16Array
  • javascript.builtins.Uint16Array.Uint16Array
  • javascript.builtins.Uint16Array.Uint16Array.constructor_without_parameters
  • javascript.builtins.Uint16Array.Uint16Array.iterable_allowed
  • javascript.builtins.Uint16Array.Uint16Array.new_required
  • javascript.builtins.Uint32Array
  • javascript.builtins.Uint32Array.Uint32Array
  • javascript.builtins.Uint32Array.Uint32Array.constructor_without_parameters
  • javascript.builtins.Uint32Array.Uint32Array.iterable_allowed
  • javascript.builtins.Uint32Array.Uint32Array.new_required
  • javascript.builtins.Uint8Array
  • javascript.builtins.Uint8Array.Uint8Array
  • javascript.builtins.Uint8Array.Uint8Array.constructor_without_parameters
  • javascript.builtins.Uint8Array.Uint8Array.iterable_allowed
  • javascript.builtins.Uint8Array.Uint8Array.new_required
  • javascript.builtins.Uint8ClampedArray
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.constructor_without_parameters
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.iterable_allowed
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.new_required
  • javascript.builtins.WeakMap
  • javascript.builtins.WeakMap.WeakMap
  • javascript.builtins.WeakMap.WeakMap.iterable_allowed
  • javascript.builtins.WeakMap.WeakMap.new_required
  • javascript.builtins.WeakMap.WeakMap.null_allowed
  • javascript.builtins.WeakMap.delete
  • javascript.builtins.WeakMap.get
  • javascript.builtins.WeakMap.has
  • javascript.builtins.WeakMap.set
  • javascript.builtins.WeakSet
  • javascript.builtins.WeakSet.WeakSet
  • javascript.builtins.WeakSet.WeakSet.iterable_allowed
  • javascript.builtins.WeakSet.WeakSet.null_allowed
  • javascript.builtins.WeakSet.add
  • javascript.builtins.WeakSet.delete
  • javascript.builtins.WeakSet.has
  • javascript.classes
  • javascript.classes.constructor
  • javascript.classes.extends
  • javascript.classes.static
  • javascript.functions.arguments.@@iterator
  • javascript.functions.arrow_functions
  • javascript.functions.block_level_functions
  • javascript.functions.default_parameters
  • javascript.functions.default_parameters.destructured_parameter_with_default_value_assignment
  • javascript.functions.default_parameters.parameters_without_defaults_after_default_parameters
  • javascript.functions.get.computed_property_names
  • javascript.functions.method_definitions
  • javascript.functions.rest_parameters
  • javascript.functions.rest_parameters.destructuring
  • javascript.functions.set.computed_property_names
  • javascript.grammar.binary_numeric_literals
  • javascript.grammar.octal_numeric_literals
  • javascript.grammar.unicode_point_escapes
  • javascript.grammar.shorthand_object_literals
  • javascript.grammar.template_literals
  • javascript.operators.class
  • javascript.operators.destructuring
  • javascript.operators.destructuring.computed_property_names
  • javascript.operators.destructuring.rest_in_arrays
  • javascript.operators.destructuring.rest_in_objects
  • javascript.operators.generator_function
  • javascript.operators.new_target
  • javascript.operators.object_initializer.computed_property_names
  • javascript.operators.object_initializer.shorthand_method_names
  • javascript.operators.object_initializer.shorthand_property_names
  • javascript.operators.spread
  • javascript.operators.spread.spread_in_arrays
  • javascript.operators.spread.spread_in_function_calls
  • javascript.operators.super
  • javascript.operators.yield
  • javascript.operators.yield_star
  • javascript.statements.class
  • javascript.statements.const
  • javascript.statements.for_of
  • javascript.statements.generator_function
  • javascript.statements.let

ECMAScript 2016 (5 features)

  • javascript.builtins.Array.includes
  • javascript.operators.exponentiation
  • javascript.operators.exponentiation_assignment
  • javascript.statements.generator_function.IteratorResult_object
  • javascript.statements.generator_function.not_constructable_with_new

ECMAScript 2017 (35 features)

  • javascript.builtins.AsyncFunction
  • javascript.builtins.AsyncFunction.AsyncFunction
  • javascript.builtins.AsyncGenerator
  • javascript.builtins.AsyncGenerator.next
  • javascript.builtins.AsyncGenerator.return
  • javascript.builtins.AsyncGenerator.throw
  • javascript.builtins.AsyncGeneratorFunction
  • javascript.builtins.AsyncGeneratorFunction.AsyncGeneratorFunction
  • javascript.builtins.Atomics
  • javascript.builtins.Atomics.add
  • javascript.builtins.Atomics.and
  • javascript.builtins.Atomics.compareExchange
  • javascript.builtins.Atomics.exchange
  • javascript.builtins.Atomics.isLockFree
  • javascript.builtins.Atomics.load
  • javascript.builtins.Atomics.notify
  • javascript.builtins.Atomics.or
  • javascript.builtins.Atomics.store
  • javascript.builtins.Atomics.sub
  • javascript.builtins.Atomics.wait
  • javascript.builtins.Atomics.xor
  • javascript.builtins.DataView.DataView.sharedarraybuffer_support
  • javascript.builtins.DataView.buffer.sharedarraybuffer_support
  • javascript.builtins.Date.UTC.optional_monthIndex
  • javascript.builtins.Object.entries
  • javascript.builtins.Object.getOwnPropertyDescriptors
  • javascript.builtins.Object.values
  • javascript.builtins.SharedArrayBuffer
  • javascript.builtins.SharedArrayBuffer.SharedArrayBuffer
  • javascript.builtins.SharedArrayBuffer.byteLength
  • javascript.builtins.SharedArrayBuffer.slice
  • javascript.builtins.SharedArrayBuffer.@@species
  • javascript.builtins.String.padEnd
  • javascript.builtins.String.padStart
  • javascript.functions.arrow_functions.trailing_comma

ECMAScript 2018 (8 features)

  • javascript.builtins.AsyncIterator
  • javascript.builtins.AsyncIterator.@@asyncIterator
  • javascript.builtins.Promise.finally
  • javascript.builtins.RegExp.dotAll
  • javascript.builtins.Symbol.asyncIterator
  • javascript.grammar.template_literals.template_literal_revision
  • javascript.statements.for_await_of
  • javascript.statements.for_of.async_iterators

ECMAScript 2019 (10 features)

  • javascript.builtins.Array.flat
  • javascript.builtins.Array.flatMap
  • javascript.builtins.Array.sort.stable_sorting
  • javascript.builtins.Function.toString.toString_revision
  • javascript.builtins.JSON.json_superset
  • javascript.builtins.JSON.stringify.well_formed_stringify
  • javascript.builtins.Object.fromEntries
  • javascript.builtins.String.trimEnd
  • javascript.builtins.String.trimStart
  • javascript.builtins.Symbol.description

ECMAScript 2020 (22 features)

  • javascript.builtins.BigInt
  • javascript.builtins.BigInt.BigInt
  • javascript.builtins.BigInt.asIntN
  • javascript.builtins.BigInt.asUintN
  • javascript.builtins.BigInt.toLocaleString
  • javascript.builtins.BigInt.toString
  • javascript.builtins.BigInt.valueOf
  • javascript.builtins.BigInt64Array
  • javascript.builtins.BigInt64Array.BigInt64Array
  • javascript.builtins.BigUint64Array
  • javascript.builtins.BigUint64Array.BigUint64Array
  • javascript.builtins.DataView.getBigInt64
  • javascript.builtins.DataView.getBigUint64
  • javascript.builtins.DataView.setBigInt64
  • javascript.builtins.DataView.setBigUint64
  • javascript.builtins.Promise.allSettled
  • javascript.builtins.String.matchAll
  • javascript.builtins.Symbol.matchAll
  • javascript.builtins.globalThis
  • javascript.operators.nullish_coalescing
  • javascript.operators.nullish_coalescing_assignment
  • javascript.operators.optional_chaining

ECMAScript 2021 (13 features)

  • javascript.builtins.AggregateError
  • javascript.builtins.AggregateError.AggregateError
  • javascript.builtins.AggregateError.errors
  • javascript.builtins.Atomics.Atomic_operations_on_non_shared_buffers
  • javascript.builtins.FinalizationRegistry
  • javascript.builtins.FinalizationRegistry.FinalizationRegistry
  • javascript.builtins.FinalizationRegistry.register
  • javascript.builtins.FinalizationRegistry.unregister
  • javascript.builtins.Promise.any
  • javascript.builtins.String.replaceAll
  • javascript.builtins.WeakRef
  • javascript.builtins.WeakRef.WeakRef
  • javascript.builtins.WeakRef.deref

ECMAScript 2022 (7 features)

  • javascript.builtins.Array.at
  • javascript.builtins.Error.Error.options_cause_parameter
  • javascript.builtins.Error.cause
  • javascript.builtins.Object.hasOwn
  • javascript.builtins.RegExp.hasIndices
  • javascript.builtins.String.at
  • javascript.builtins.TypedArray.at

ECMAScript 2023 (14 features)

  • javascript.builtins.Array.findLast
  • javascript.builtins.Array.findLastIndex
  • javascript.builtins.Array.toReversed
  • javascript.builtins.Array.toSorted
  • javascript.builtins.Array.toSpliced
  • javascript.builtins.Array.with
  • javascript.builtins.FinalizationRegistry.symbol_as_target
  • javascript.builtins.TypedArray.toReversed
  • javascript.builtins.TypedArray.toSorted
  • javascript.builtins.TypedArray.with
  • javascript.builtins.WeakMap.symbol_as_keys
  • javascript.builtins.WeakRef.symbol_as_target
  • javascript.builtins.WeakSet.symbol_as_keys
  • javascript.grammar.hashbang_comments

ECMAScript 2024 (10 features)

  • javascript.builtins.ArrayBuffer.ArrayBuffer.maxByteLength_option
  • javascript.builtins.ArrayBuffer.maxByteLength
  • javascript.builtins.ArrayBuffer.resizable
  • javascript.builtins.ArrayBuffer.resize
  • javascript.builtins.Atomics.waitAsync
  • javascript.builtins.SharedArrayBuffer.SharedArrayBuffer.maxByteLength_option
  • javascript.builtins.SharedArrayBuffer.grow
  • javascript.builtins.SharedArrayBuffer.growable
  • javascript.builtins.SharedArrayBuffer.maxByteLength
  • javascript.builtins.String.toWellFormed


Second, I came up with some capability groups. Here I'm trying to be user-oriented as I believe we want to show what the web can do (and ignore its evolution for a moment). I guess we want to ask: ECMAScript, what do you offer? And here we need to figure out how detailed we want to be. I drafted some high-level capability groups for ECMAScript. Would love to hear thoughts on these.

  • Arrays
  • Promises
  • Typed Arrays
  • Functions
  • Async Functions
  • Generators
  • Async Generators
  • Shared Array Buffers
  • Big Integers
  • Date API
  • Weak References
  • Iterators
  • Maps
  • Sets
  • Math Functions
  • Number API
  • Object Reflection
  • Proxy/Reflection API
  • Regular Expressions
  • String API
  • Weak Maps
  • Weak Sets
  • Global functions
  • Classes
  • Various operators (bitwise, logical, mathematical)
  • Statements
  • Syntax
  • Import and Export

Third, we probably want to combine the high-level capability groups with the snapshots. One assumption we make is that the older/un-enhanced the capabilities are, the less interesting it is to break them down into sub groups. For example, the Date API has not seen substantial updates since ECMAScript 3 and so it is just the Date API as a whole without any meaningful iterations or new capabilities. For other high-level capabilities, like Arrays, this is very different. Here we probably want to break down what Arrays can do and since when; the snapshots help with that enormously. Compare Arrays and Date API:

Arrays

  • web-features:ecmascript-1: javascript.builtins.Array
  • web-features:ecmascript-1: javascript.builtins.Array.Array
  • web-features:ecmascript-1: javascript.builtins.Array.join
  • web-features:ecmascript-1: javascript.builtins.Array.length
  • web-features:ecmascript-1: javascript.builtins.Array.reverse
  • web-features:ecmascript-1: javascript.builtins.Array.sort
  • web-features:ecmascript-1: javascript.builtins.Array.toString
  • web-features:ecmascript-1: javascript.grammar.array_literals
  • web-features:ecmascript-3: javascript.builtins.Array.concat
  • web-features:ecmascript-3: javascript.builtins.Array.pop
  • web-features:ecmascript-3: javascript.builtins.Array.push
  • web-features:ecmascript-3: javascript.builtins.Array.shift
  • web-features:ecmascript-3: javascript.builtins.Array.slice
  • web-features:ecmascript-3: javascript.builtins.Array.toLocaleString
  • web-features:ecmascript-3: javascript.builtins.Array.unshift
  • web-features:ecmascript-5: javascript.builtins.Array.every
  • web-features:ecmascript-5: javascript.builtins.Array.filter
  • web-features:ecmascript-5: javascript.builtins.Array.forEach
  • web-features:ecmascript-5: javascript.builtins.Array.indexOf
  • web-features:ecmascript-5: javascript.builtins.Array.isArray
  • web-features:ecmascript-5: javascript.builtins.Array.lastIndexOf
  • web-features:ecmascript-5: javascript.builtins.Array.map
  • web-features:ecmascript-5: javascript.builtins.Array.reduce
  • web-features:ecmascript-5: javascript.builtins.Array.reduceRight
  • web-features:ecmascript-5: javascript.builtins.Array.some
  • web-features:ecmascript-2015: javascript.builtins.Array.copyWithin
  • web-features:ecmascript-2015: javascript.builtins.Array.entries
  • web-features:ecmascript-2015: javascript.builtins.Array.fill
  • web-features:ecmascript-2015: javascript.builtins.Array.find
  • web-features:ecmascript-2015: javascript.builtins.Array.findIndex
  • web-features:ecmascript-2015: javascript.builtins.Array.from
  • web-features:ecmascript-2015: javascript.builtins.Array.keys
  • web-features:ecmascript-2015: javascript.builtins.Array.of
  • web-features:ecmascript-2015: javascript.builtins.Array.splice
  • web-features:ecmascript-2015: javascript.builtins.Array.values
  • web-features:ecmascript-2015: javascript.builtins.Array.@@iterator
  • web-features:ecmascript-2015: javascript.builtins.Array.@@species
  • web-features:ecmascript-2015: javascript.builtins.Array.@@unscopables
  • web-features:ecmascript-2019: javascript.builtins.Array.flat
  • web-features:ecmascript-2019: javascript.builtins.Array.flatMap
  • web-features:ecmascript-2020: javascript.builtins.Array.includes
  • web-features:ecmascript-2022: javascript.builtins.Array.at
  • web-features:ecmascript-2023: javascript.builtins.Array.findLast
  • web-features:ecmascript-2023: javascript.builtins.Array.findLastIndex
  • web-features:ecmascript-2023: javascript.builtins.Array.toReversed
  • web-features:ecmascript-2023: javascript.builtins.Array.toSorted
  • web-features:ecmascript-2023: javascript.builtins.Array.toSpliced
  • web-features:ecmascript-2023: javascript.builtins.Array.with

Date API

  • web-features:ecmascript-1: javascript.builtins.Date
  • web-features:ecmascript-1: javascript.builtins.Date.Date
  • web-features:ecmascript-1: javascript.builtins.Date.UTC
  • web-features:ecmascript-1: javascript.builtins.Date.getDate
  • web-features:ecmascript-1: javascript.builtins.Date.getDay
  • web-features:ecmascript-1: javascript.builtins.Date.getFullYear
  • web-features:ecmascript-1: javascript.builtins.Date.getHours
  • web-features:ecmascript-1: javascript.builtins.Date.getMilliseconds
  • web-features:ecmascript-1: javascript.builtins.Date.getMinutes
  • web-features:ecmascript-1: javascript.builtins.Date.getMonth
  • web-features:ecmascript-1: javascript.builtins.Date.getSeconds
  • web-features:ecmascript-1: javascript.builtins.Date.getTime
  • web-features:ecmascript-1: javascript.builtins.Date.getTimezoneOffset
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCDate
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCDay
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCFullYear
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCHours
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCMilliseconds
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCMinutes
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCMonth
  • web-features:ecmascript-1: javascript.builtins.Date.getUTCSeconds
  • web-features:ecmascript-1: javascript.builtins.Date.getYear
  • web-features:ecmascript-1: javascript.builtins.Date.parse
  • web-features:ecmascript-1: javascript.builtins.Date.setDate
  • web-features:ecmascript-1: javascript.builtins.Date.setFullYear
  • web-features:ecmascript-1: javascript.builtins.Date.setHours
  • web-features:ecmascript-1: javascript.builtins.Date.setMilliseconds
  • web-features:ecmascript-1: javascript.builtins.Date.setMinutes
  • web-features:ecmascript-1: javascript.builtins.Date.setMonth
  • web-features:ecmascript-1: javascript.builtins.Date.setSeconds
  • web-features:ecmascript-1: javascript.builtins.Date.setTime
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCDate
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCFullYear
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCHours
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCMilliseconds
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCMinutes
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCMonth
  • web-features:ecmascript-1: javascript.builtins.Date.setUTCSeconds
  • web-features:ecmascript-1: javascript.builtins.Date.setYear
  • web-features:ecmascript-1: javascript.builtins.Date.toGMTString
  • web-features:ecmascript-1: javascript.builtins.Date.toLocaleString
  • web-features:ecmascript-1: javascript.builtins.Date.toString
  • web-features:ecmascript-1: javascript.builtins.Date.toUTCString
  • web-features:ecmascript-1: javascript.builtins.Date.valueOf
  • web-features:ecmascript-3: javascript.builtins.Date.toDateString
  • web-features:ecmascript-3: javascript.builtins.Date.toLocaleDateString
  • web-features:ecmascript-3: javascript.builtins.Date.toLocaleTimeString
  • web-features:ecmascript-3: javascript.builtins.Date.toTimeString
  • web-features:ecmascript-5: javascript.builtins.Date.now
  • web-features:ecmascript-5: javascript.builtins.Date.toISOString
  • web-features:ecmascript-5: javascript.builtins.Date.toJSON
  • web-features:ecmascript-2015: javascript.builtins.Date.@@toPrimitive
  • web-features:ecmascript-2017: javascript.builtins.Date.UTC.optional_monthIndex

(As you can see, I have just exercised this for Array and Date for the moment and not for all high-level capabilities listed above, but I can do that if y'all think this is useful for cataloging ECMAScript in web-features.)

One thing to say here is that the snapshot tags are useful, but maybe they aren't as meaningful as we want them to be. Instead of using the ECMAScript versions/years, we could also tag them with smaller capability groups and break Array down into some sub groups like these. This is a lot harder and more work, though. Example for Array:

  • Basic arrays (ES 1)
  • New Array mutation methods (ES 3)
  • New Array iteration methods (ES 5)
  • New Array methods (ES 2015)
  • Flattening Arrays (ES 2019)
  • Array.includes (ES 2020)
  • Array by copy (ES 2023)

Okay, that was a lot. Thanks for reading this far!
Now: How would you group/catalog 901 ECMAScript features?

@foolip
Copy link
Collaborator

foolip commented Feb 3, 2024

@Elchi3 thank you so much, I thought that would be a massive undertaking, and maybe it was, but you sure did it quickly!

Looking at this tells me that "Why not have both" from #558 is the right path here. We already have an entry for Flattening Arrays, and that's part of ECMAScript 2019 apparently.

My main question at this point is whether we should map at the level of BCD or in web-features. In other words, should we record that BCD's javascript.builtins.Array.flat + javascript.builtins.Array.flatMap are part of ECMAScript 2019, or the array-flat web-features entry?

When we have a high level feature that fits in a group like ECMAScript 2019, why not just associate those? But if there are ever cases where a feature straddles ECMAScript releases, and developers nonetheless think of it as one feature, then we'll need to deal with it some other way.

Building on #217 (comment), I'm inclined to suggest something like this. First, the tree of groups we'd define

web-features
├─ javascript
│  ├─ ecmascript-1
│  ├─ ecmascript-3
│  ├─ ecmascript-5
│  ├─ ecmascript-2015
│  ├─ ecmascript-...
│  ├─ ecmascript-2024

Then, the array-flat feature would have group: ecmascript-2019 in its YAML definition.

When needed, BCD could also use the tag "web-features:group:ecmascript-2019" to put individual BCD entries into a group.

@Elchi3 WDYT? Is it messy to split this across web-features and BCD like this?

@foolip
Copy link
Collaborator

foolip commented Feb 3, 2024

If we go with groups as distinct from features, we need to decide whether groups are a namespace or not. In other words, should consumers of web-features have to use "group:ecmascript-2019" or similar to point to a group? It comes down to whether it's good that it's obvious at the "call site" that it's a group and not a concrete feature, and I think it probably is.

@Elchi3
Copy link
Collaborator Author

Elchi3 commented Feb 5, 2024

@Elchi3 thank you so much, I thought that would be a massive undertaking, and maybe it was, but you sure did it quickly!

Yes, as always, 90% is easy and then the remaining 100 or so data points aren't as easy to sort. I ignored all non-standard features in the end as well. Still some more things to sort. Can be seen in this branch mdn/browser-compat-data@main...Elchi3:browser-compat-data:ecmascript-tags (I forgot the link in my initial comment above, added now and also updated the data above with the latest cataloging for ECMAScript version snapshots).

My main question at this point is whether we should map at the level of BCD or in web-features

I think, given BCD is a moving target and the source of all this cataloging, I find all this easier to do with BCD tags. The synchronization between the two will be work otherwise. But I could be convinced to do it in web-features. I think we are still at the phase where we explore what data model we need to have (more below).

When we have a high level feature that fits in a group like ECMAScript 2019, why not just associate those? But if there are ever cases where a feature straddles ECMAScript releases, and developers nonetheless think of it as one feature, then we'll need to deal with it some other way.

To me, so far, it was really useful to associate an ECMAScript snapshot version with individual BCD data points. See Array above. Just by looking at that, you can see how Array evolved and you can determine Array features from there (like I did in my step 3 above). And, yes, there are features that straddle ECMAScript releases, and so the snapshot tag is optional but useful in case we have it.

If we go with groups as distinct from features, we need to decide whether groups are a namespace or not. In other words, should consumers of web-features have to use "group:ecmascript-2019" or similar to point to a group?

To me, snapshots are different to groups. In fact, I think I found it useful to think about three things as my data model in my cataloging exercise:.

  1. "web-features-snapshot:<snapshot>"
  • where <snapshot> is an allow listed list of snapshots. For example: ecmascript-1, ecmascript-205, ... ecmascript-2022, html-1, css-4, indexed-db-1, indexed-db-2, ...
  1. "web-features-group:<group>"
  • where <group> is an allow listed list of high-level web platform capability groups. For example: typed-arrays, arrays, promises, iterators, ...
  1. "web-features-feature:<feature-name>"
  • where <feature-name> is an arbitrary name (not subject to allow-lists) that considers specific data points as a web feature. For example: basic-arrays, array-at, array-iterators, array-find-last

I played with this in BCD and it looks like this:
Array constructor:

"tags":[
  "web-features-snapshot:ecmascript-1",
  "web-features-group:arrays",
  "web-features-feature:basic-arrays"
],

Array.at:

"tags":[
  "web-features-snapshot:ecmascript-2022",
  "web-features-group:arrays",
  "web-features-feature:array-at"
],

Commit: mdn/browser-compat-data@89722af

Now you can do interesting queries against BCD:

npm run traverse -- -t web-features-snapshot:ecmascript-2023 (same as above but this branch has tags applied to smaller dataset)

  • javascript.builtins.Array.findLast
  • javascript.builtins.Array.findLastIndex
  • javascript.builtins.Array.toReversed
  • javascript.builtins.Array.toSorted
  • javascript.builtins.Array.toSpliced
  • javascript.builtins.Array.with
  • javascript.builtins.TypedArray.findLast
  • javascript.builtins.TypedArray.findLastIndex
  • javascript.builtins.TypedArray.toReversed
  • javascript.builtins.TypedArray.toSorted
  • javascript.builtins.TypedArray.with

npm run traverse -- -t web-features-group:arrays (All Array features)

  • javascript.builtins.Array
  • javascript.builtins.Array.Array
  • javascript.builtins.Array.at
  • javascript.builtins.Array.concat
  • javascript.builtins.Array.copyWithin
  • javascript.builtins.Array.entries
  • javascript.builtins.Array.every
  • javascript.builtins.Array.fill
  • javascript.builtins.Array.filter
  • javascript.builtins.Array.find
  • javascript.builtins.Array.findIndex
  • javascript.builtins.Array.findLast
  • javascript.builtins.Array.findLastIndex
  • javascript.builtins.Array.flat
  • javascript.builtins.Array.flatMap
  • javascript.builtins.Array.forEach
  • javascript.builtins.Array.from
  • javascript.builtins.Array.fromAsync
  • javascript.builtins.Array.includes
  • javascript.builtins.Array.indexOf
  • javascript.builtins.Array.isArray
  • javascript.builtins.Array.join
  • javascript.builtins.Array.keys
  • javascript.builtins.Array.lastIndexOf
  • javascript.builtins.Array.length
  • javascript.builtins.Array.map
  • javascript.builtins.Array.of
  • javascript.builtins.Array.pop
  • javascript.builtins.Array.push
  • javascript.builtins.Array.reduce
  • javascript.builtins.Array.reduceRight
  • javascript.builtins.Array.reverse
  • javascript.builtins.Array.shift
  • javascript.builtins.Array.slice
  • javascript.builtins.Array.some
  • javascript.builtins.Array.sort
  • javascript.builtins.Array.sort.stable_sorting
  • javascript.builtins.Array.splice
  • javascript.builtins.Array.toLocaleString
  • javascript.builtins.Array.toReversed
  • javascript.builtins.Array.toSorted
  • javascript.builtins.Array.toSpliced
  • javascript.builtins.Array.toString
  • javascript.builtins.Array.unshift
  • javascript.builtins.Array.values
  • javascript.builtins.Array.with
  • javascript.builtins.Array.@@iterator
  • javascript.builtins.Array.@@species
  • javascript.builtins.Array.@@unscopables
  • javascript.grammar.array_literals

npm run traverse -- -t web-features-group:typed-arrays (All Typed Array features)

  • javascript.builtins.Float32Array
  • javascript.builtins.Float32Array.Float32Array
  • javascript.builtins.Float32Array.Float32Array.constructor_without_parameters
  • javascript.builtins.Float32Array.Float32Array.iterable_allowed
  • javascript.builtins.Float32Array.Float32Array.new_required
  • javascript.builtins.Float64Array
  • javascript.builtins.Float64Array.Float64Array
  • javascript.builtins.Float64Array.Float64Array.constructor_without_parameters
  • javascript.builtins.Float64Array.Float64Array.iterable_allowed
  • javascript.builtins.Float64Array.Float64Array.new_required
  • javascript.builtins.Int16Array
  • javascript.builtins.Int16Array.Int16Array
  • javascript.builtins.Int16Array.Int16Array.constructor_without_parameters
  • javascript.builtins.Int16Array.Int16Array.new_required
  • javascript.builtins.Int32Array
  • javascript.builtins.Int32Array.Int32Array
  • javascript.builtins.Int32Array.Int32Array.constructor_without_parameters
  • javascript.builtins.Int32Array.Int32Array.iterable_allowed
  • javascript.builtins.Int32Array.Int32Array.new_required
  • javascript.builtins.Int8Array
  • javascript.builtins.Int8Array.Int8Array
  • javascript.builtins.Int8Array.Int8Array.constructor_without_parameters
  • javascript.builtins.Int8Array.Int8Array.iterable_allowed
  • javascript.builtins.Int8Array.Int8Array.new_required
  • javascript.builtins.TypedArray
  • javascript.builtins.TypedArray.BYTES_PER_ELEMENT
  • javascript.builtins.TypedArray.at
  • javascript.builtins.TypedArray.buffer
  • javascript.builtins.TypedArray.byteLength
  • javascript.builtins.TypedArray.byteOffset
  • javascript.builtins.TypedArray.constructor_without_parameters
  • javascript.builtins.TypedArray.copyWithin
  • javascript.builtins.TypedArray.entries
  • javascript.builtins.TypedArray.every
  • javascript.builtins.TypedArray.fill
  • javascript.builtins.TypedArray.filter
  • javascript.builtins.TypedArray.find
  • javascript.builtins.TypedArray.findIndex
  • javascript.builtins.TypedArray.findLast
  • javascript.builtins.TypedArray.findLastIndex
  • javascript.builtins.TypedArray.forEach
  • javascript.builtins.TypedArray.from
  • javascript.builtins.TypedArray.includes
  • javascript.builtins.TypedArray.indexOf
  • javascript.builtins.TypedArray.join
  • javascript.builtins.TypedArray.keys
  • javascript.builtins.TypedArray.lastIndexOf
  • javascript.builtins.TypedArray.length
  • javascript.builtins.TypedArray.map
  • javascript.builtins.TypedArray.name
  • javascript.builtins.TypedArray.named_properties
  • javascript.builtins.TypedArray.new_required
  • javascript.builtins.TypedArray.of
  • javascript.builtins.TypedArray.reduce
  • javascript.builtins.TypedArray.reduceRight
  • javascript.builtins.TypedArray.reverse
  • javascript.builtins.TypedArray.set
  • javascript.builtins.TypedArray.slice
  • javascript.builtins.TypedArray.some
  • javascript.builtins.TypedArray.sort
  • javascript.builtins.TypedArray.subarray
  • javascript.builtins.TypedArray.toLocaleString
  • javascript.builtins.TypedArray.toReversed
  • javascript.builtins.TypedArray.toSorted
  • javascript.builtins.TypedArray.toString
  • javascript.builtins.TypedArray.values
  • javascript.builtins.TypedArray.with
  • javascript.builtins.TypedArray.@@iterator
  • javascript.builtins.TypedArray.@@species
  • javascript.builtins.Uint16Array
  • javascript.builtins.Uint16Array.Uint16Array
  • javascript.builtins.Uint16Array.Uint16Array.constructor_without_parameters
  • javascript.builtins.Uint16Array.Uint16Array.iterable_allowed
  • javascript.builtins.Uint16Array.Uint16Array.new_required
  • javascript.builtins.Uint8Array
  • javascript.builtins.Uint8Array.Uint8Array
  • javascript.builtins.Uint8Array.Uint8Array.constructor_without_parameters
  • javascript.builtins.Uint8Array.Uint8Array.iterable_allowed
  • javascript.builtins.Uint8Array.Uint8Array.new_required
  • javascript.builtins.Uint8ClampedArray
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.iterable_allowed
  • javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.new_required

npm run traverse -- -t web-features-feature:array-by-copy (Array By Copy feature that impacts Arrays and Typed Arrays)

  • javascript.builtins.Array.toReversed
  • javascript.builtins.Array.toSorted
  • javascript.builtins.Array.toSpliced
  • javascript.builtins.Array.with
  • javascript.builtins.TypedArray.toReversed
  • javascript.builtins.TypedArray.toSorted
  • javascript.builtins.TypedArray.with

npm run traverse -- -t web-features-feature:array-find (Array Find that impacts Arrays and Typed Arrays

  • javascript.builtins.Array.find
  • javascript.builtins.Array.findIndex
  • javascript.builtins.TypedArray.find
  • javascript.builtins.TypedArray.findIndex

I didn't implement additional data querying, but I guess with this you could ask BCD for:

  • All features (a web-features-feature) in a group (a web-features-group):
    • For example: Features present in the "Arrays" group: basic-arrays, array-at, array-copywithin, array-iterators, array-fill, array-find, array-findlast, array-flattening, array-from, array-fromasync, array-includes, array-isarray, array-by-copy, ...
  • All features (a web-features-feature) in a snapshot (a web-features-snapshot):
    • For example: Features in ECMAScript 2015: basic-arrays, basic-typed-arrays, array-copywithin, array-find, array-from, ...

But sure, you could also record this data differently and say that there are parent-child relationships instead of "groups" and "features" like I did here. And maybe the snapshot data is just really useful data that helps to find specific features within a lot of data. 🤷

So, the data model consisting of "web-features-snapshot", "web-features-group", and "web-features-feature" is just a first idea. I'd love hear more and maybe others have a different mental model about these things. I think it would be good to sort this out, before trying to catalog all of ECMAScript which I'm setting as my personal goal here.

@foolip
Copy link
Collaborator

foolip commented Feb 5, 2024

I see, it does make sense to think of spec snapshots differently from groups. For example the HTML5 snapshot would certainly span multiple groups like "workers", "form controls", "media elements", and so on.

I wonder if web-specs might make more sense than web-features as the source of truth on snapshots. Have you checked if older spec snapshots are recorded there, or is it only current specs?

I also wonder about consumers, do you think BCD consumers would make use of snapshot data?

@Elchi3
Copy link
Collaborator Author

Elchi3 commented Feb 5, 2024

I wonder if web-specs might make more sense than web-features as the source of truth on snapshots. Have you checked if older spec snapshots are recorded there, or is it only current specs?

From what I can tell, it doesn't record snapshots. It would be an idea to get the list of allowable snapshots from web-specs indeed. I don't think we want to make up our own snapshots (I think indexed-db-1 and indexed-db-2 are real levels observed from the specs, and e.g. CSS4 is also officially defined as a kind of snapshot). So, yes, maybe we could propose this for web-specs and use it for validation for the web-features-snapshot tags.

I also wonder about consumers, do you think BCD consumers would make use of snapshot data?

Yes, I think tags are powerful to any BCD consumer because currently you only get lists of BCD features by tree (e.g. javascript.builtins.array.*). If we had the three tags that I described, you could already get much more nuanced feature lists as described in my comment above and without having to go through other data sources like web-features.

@captainbrosset
Copy link
Contributor

We discussed the feature vs. group vs. snapshot idea at yesterday's WebDX meeting: https://docs.google.com/document/d/1ree75ImLZjf60lTZ3BhCaLHygxgywr7SBXp-q0xPs8A/edit#heading=h.tm9h5efbalpr

A few highlights from the discussion:

  • It's re-assuring that someone with the right domain knowledge is able to do this kind of cataloging so quickly.
  • How do we exactly define the 3 levels? What's the boundary between them? The terminology has been a bit lose so far, and we would benefit from a glossary.
  • Who would benefit from this grouping. MDN has shown early interest in it. This could help with content organization.
  • When web features get implemented in browsers, they ship as little bundles or related things. Not just one method or property. These bundles that get implemented at the same time seem to correspond to what we call features here.

@foolip
Copy link
Collaborator

foolip commented Feb 9, 2024

When web features get implemented in browsers, they ship as little bundles or related things. Not just one method or property. These bundles that get implemented at the same time seem to correspond to what we call features here.

A lot of complexity comes different browsers shipping things in different order and bundles. I'm sure that all of the following happen for two granular APIs A and B that seem like they form a reasonable group at first:

  • One browser ships A, then B, and later other browsers only ship A+B together (extremely common early in a feature's life)
  • One browsers ships A+B together, and then another ships just A or B for a time before shipping the remaining one
  • One browser ships A, another ships B, and later both ship the remainder at different times

And so on.

A problem is that if we base groups on bundles of shipping, then when another browser ships only part of it, we need to split that feature group. Some amount of updating to match reality is reasonable, but I think trying to determine how and when to split manually and picking good names for the feature groups is going to be overwhelming.

Rather I think we'll need to find a way to handle small amounts of "skew" in a way that doesn't require minting new features for every unique combination of "initial support" versions.

This kind of thing has already been a problem with at least Clipboard API, custom elements, the input event, and scrollbar-* properties.

@ddbeck
Copy link
Collaborator

ddbeck commented Feb 9, 2024

I got to have lunch with @Elchi3 today and we had a very wide-ranging discussion, but we talked a lot about this issue specifically. I will not attempt to recap everything, but I thought I would share some things that I learned:

Terminology: We had a hard time talking about this because the terms are unclear. Specifically, "feature" is overloaded: everything's a feature, at different resolutions. For the purposes of our conversation, we settled on

  • snapshots for features given shape by a specification at a point in time1 (e.g., ECMAScript 2024),
  • capability or functional group for topical clusters of web platform features (e.g., Arrays) that accrete new behaviors over time, and
  • bundles2 to refer to narrower, directly authored groups (e.g., "Array flattening methods").

Bundling: Talking to Florian, I finally understood what he meant by "combin[ing] the high-level capability groups with the snapshots." Florian is concerned (rightly) that if we start authoring bundles we might very well compose groups that are ungrounded (e.g., "Daniel's favorite Array methods") or motivated (e.g., seeking specific Baseline statuses or mapping to browser engineering's incremental steps toward a genuine feature), instead of descriptive.

I originally misunderstood, thinking that Florian was suggesting (for example) "Array x ES2024" is a group that must exist, given the plausibility of the other two groups. Instead, the intersection might help us author the most meaningful bundles we might find in that intersection. This seems like a great way to unblock certain discussions about whether a feature is or is not in a given feature (e.g., whether to omit a given BCD key or to override a Baseline status and so on). This might help guide us in deciding whether to (as @foolip says above) skew or split a bundle.

Scaling: This struck me as especially important in the absence of developer salience. The bundles needed for the most visible features and proposals will be pretty transparent to developers (e.g. developers themselves will have a good sense of what is and is not "subgrid"). But when it comes to cataloguing the whole of the platform, drawing boxes around features becomes much more difficult: do we really expect developers to make clear distinctions between older cohorts of features? Using the intersection of snapshots and capabilities can give us a starting point other than vibes or recapitulating dubious legacies (e.g., wiki-era MDN information architecture choices).


  1. The emphasis here is on "point in time" not "specification." I suspect there are other possible origins of snapshots (e.g., implementation year), but they're all final. Some features get in or they don't and that's that.
  2. Credit to James for using this term in yesterday's WebDX meeting.

@tidoust
Copy link
Member

tidoust commented Feb 22, 2024

@Elchi3 The terminology shared by @ddbeck above mentions three levels (on top of the BCD key level of course). In the draft pull request you prepared, I see 4 types of tags:

  1. web-features-snapshot:xxx
  2. web-features-group:xxx
  3. web-features-bundle:xxx
  4. and a more generic web-features:xxx type of tag

What does the 4th type represent? Or is a leftover, to be replaced by web-features-bundle?

@Elchi3
Copy link
Collaborator Author

Elchi3 commented Feb 22, 2024

Or is a leftover, to be replaced by web-features-bundle?

Yeah, leftover. I didn't touch the generic web-features:xxx tags because I don't know if the terminology we are talking about here will be adapted. These would be bundles indeed, if adapted.

@foolip
Copy link
Collaborator

foolip commented Feb 22, 2024

Does someone have more context on bundles? If we adopt that terminology, would web-features not have anything called a "feature" any longer? Or are only some features bundles? (We have some entries which correspond to zero or one BCD key.)

@Elchi3
Copy link
Collaborator Author

Elchi3 commented Feb 22, 2024

I don't have a good definition yet and I'm not sure bundle is a good name for it but calling these things bundles was easier in this discussion because "feature" is already overloaded. We could also say web-features-feature:xxx or something else, too.

I guess the core of the problem is not really the name but missing guidelines about what goes into a bundle/feature-set and what doesn't.

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

To me,

  • a bundle is not "Daniel's favorite Array methods" (entirely subjective collection of things)
  • a bundle is not "First half of array-at because browser X decided to ship incrementally and incomplete". Example: When ECMAScript 2022 introduced Array.at and TypedArray.at then this is the "array-at" bundle, because both methods came at the same time (as indicated by the snapshot in this case) and we should require both methods to be in the bundle and not split this up into array-at and typedarray-at bundles even if a browser decided to ship these two at different times. The bundle is baseline if the all of its features are shipping.
  • looking at several bundles belonging to the same group helps to learn about the evolution of that higher level capability group (e.g. Array has many bundles, Date has not).

I'd love to hear how others approach bundling things together. Would definitely help me to catalog/bundle all of ECMAScript.

@captainbrosset
Copy link
Contributor

Agreed that the name isn't the issue here. In fact, if we manage to land on a clear definition for this, I'd love for this lower level to just be called "feature" again. Even if it's overloaded, as long as we define it clearly in the repo.

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

We need to think from a user's perspective which, I think, Can I Use does pretty well. For example, if "Can I use CSS Anchor Positioning yet?" is a question that a web developer is likely to ask themselves in an attempt to accomplish a particular task, then CSS Anchor Positioning is probably a feature/bundle. It's definitely a feature/bundle if CSS Anchor Positioning can't itself be broken down further into smaller features/bundles which we could ask similar questions about.

For example, "Can i use colors on the web?" is a valid developer question. Does that mean Colors is a feature/bundle? No, because you can break it down further into "Can I use relative color syntax?". This question makes sense from a web developer's perspective. They've heard of relative colors, have a need for it to accomplish a given task, and want to know if they can use it.
Can relative color be broken down further? Perhaps (the syntax is so complex that BCD might have multiple keys for it), but my hunch is that it's unlikely for a dev to ask "Can I use this specific way of writing relative colors?".

@ddbeck
Copy link
Collaborator

ddbeck commented Mar 7, 2024

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

I'm not sure I agree with this. I think bundles ought to be descriptive of web developers' view of the platform. I think it's very likely that most bundles are logical or evolutionary—and that's probably a safe default in the absence of other information about web developers' perspective—but I think it's possible for them to be arbitrary.

Imagine it's 2007 and some web developers are thinking about AJAX. Such a bundle would probably have something like XMLHttpRequest (and some methods), document.getElementById(), and Element.innerHTML. That looks pretty arbitrary, viewed from the bottom up. But it would be a bundle that would be very relevant to developers at the time.

It's not hard to imagine descriptive groups having meaning in 2024. For instance, we might want to map to historic caniuse features (approximately, "Alexis's best judgment at the time he created the feature on caniuse") or a blogger might coin a term relating to a development pattern that catches on (probably not me, but I bet there are certain versions of "<developer>'s favorite Array methods" that could matter).

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

No branches or pull requests

5 participants