Some Web Technologies Enhancements — Proposals and Ideas

Génesis García Morilla
10 min readNov 27, 2018
Game of Frameworks by gengns on DeviantArt

Powerful enhancements that are coming to the standard and ideas that would make our lives even easier when dealing with web technologies.

[DOM] Print any element

Print any element of the document with its own style.

document.querySelector('div').print()

The standard only supports window.print() but it would be really interesting if it was possible to print anything we want to as it’s shown.

[JS] Flatten nested elements

There is already a proposal for arrays in the specification.

// current proposal solution
[1, 2, 3, [4, 5]].flat() // [1, 2, 3, 4, 5]

It would be really useful to extend the same approach for objects.

const obj = { 
name: 'mario',
work: {type: 'cto', salary: 80000, country: 'es'}
}
obj.flat() // infinite depth and low line separator by default
/*
{
name: 'mario',
work_type: 'cto',
work_salary: 80000,
work_country: 'es'
}
*/
obj.flat({depth: 2, separator: ''})
{
name: 'mario',
worktype: 'cto',
worksalary: 80000,
workcountry: 'es'
}

[CSS] Parent selector

It would be really nice to use a parent/ancestor selector similar to the child selector in CSS.

:first-ancestor

If you want to select a grandparent we would use nth-ancestor(2)

In this case, a second ancestor would be your grandparent and so on. :last-ancestor will be the html object.

[CSS] Extend sibling selectors

- for the immediate previous sibling selector (opposite of +)

img - p // paragraphs that come immediately before any image

¬ for any previous sibling selector (opposite of ~)

img ¬ p // all paragraphs that come before any image

If you want to select all siblings for example of #user you can just rely on previous ancestor selector as follow

#user:first-ancestor > *:not(#user)

[HTML] Datalist with CSS support

It would be great if we were able to change the style of an HTML <datalist> element completely as we do with other elements.

[JS] Standard support for local ISO dates

Inside the standard library, in the Date object, it would be nice to see the spread and useful function toLocalISOString()

[JS] Iterate over everything without destructuring or transforming to an array

Everything that could be represented as a list should not need to be transformed when using Higher-order Functions such as forEach, filter, map and reduce

Strings

'hi'.map(x => console.log(x))// current standard solution 
[...'hi'].map(x => console.log(x))

Objects

const obj = {name: 'maria', type: 'person'}obj.map(x => console.log(x))// current standard solution
Object.entries(obj).map(x => console.log(x))

DOM List

document.querySelector('div').classList.map(x => console.log(x))document.querySelectorAll('div').map(x => console.log(x))// current standard solution
[...document.querySelectorAll('div')].map(x => console.log(x))

Note: some browsers have added forEachsupport for DOM List

[HTML] Methods to simulate events

We already have one for click the HTMLElement.click() method that simulates a mouse click on an element. It would be nice to have the same for all the HTML events.

const $select = document.querySelector('select')$select.mousedown()// current standard solution
$select.dispatchEvent(new MouseEvent('mousedown'))

[HTML] Use src everywhere instead of href and avoid unnecessary attributes and closing tags

To avoid incompatibility we would support src and href attributes but in the future the second one would be deprecated. The same approach with the script tag, in the future it would be deprecated when nothing is inside.

<link src="index.css">
<a src="./page.html">page</a>
<script src="index.js">
// current support
<link rel=”stylesheet” href="index.css">
<a href="./page.html">page</a>
<script src=”index.js”></script>

[OBJECTS] Unified remove for storage, object properties and DOM elements

Storage, JS object properties and DOM elements have different ways of deletion, however, all of them are objects with some particularities. We could support all different method and advocate the use of delete.

delete localStorage.name ✓delete obj.property ✓delete document.querySelector(‘datalist’) ✕// equal tolocalStorage.name.remove() ✕obj.property.remove() ✕document.querySelector(‘datalist’).remove() ✓//equal tolocalStorage.removeItem(‘name’) ✓obj.removeItem(property) ✕document.querySelector(‘datalist’).removeItem() ✕

[JS] Avoid checking when looking for deep object values

There is already a proposal to reach a deep property value without making us check whether intermediate nodes exist.

// current standard support
const street = user.address && user.address.street
// current proposal solution
street = user.address?.street

[BROWSER] Asynchronous console.log properties without using JSON.parse(JSON.stringify(obj))

Examining objects via console.loghappens in an asynchronous manner. The console receives a reference to the object synchronously but does not display the properties of the object until it is expanded (in some cases, depending on the browser and whether you have DevTools open when the log happens). If the object has been modified before examining it in the console, the data shown will have the updated values.

console.show(obj) // we can propose this to be always synchronous// current standard solution
console.log(JSON.parse(JSON.stringify(obj)))

[JS] Immutable methods

New JS methods never change the existing object, however, there are many of the old ones where you will have to check the documentation to avoid confusion (slice vs splice)

So to fix this if we have doubts about which method use what, we can add an object as its second parameter with a mutable property.

array1.concat(array2, { mutable: false })

One of my peers came up with an even better solution. His idea is the addition of a 'use immutable' string at the beginning of the code to execute JavaScript on immutable mode, same as we do when we want to execute JavaScript on strict mode 'use strict'

Note: using an object as a second parameter allow us to extend it with more properties if it were necessary for the future.

[JS] Pipeline with multiple variables

There is already a proposal for the pipeline in the specification.

// current proposal solution
5 |> double |> double |> increment |> double; // 42

It would be really useful to extend the same approach with multiple variables using destructuring.

…[1, 2, 3] |> Math.min

[JS] Bits extension for type number

Increase Number.MAX_SAFE_INTEGER. Right now we can use libraries as bignum.js to achieve better arithmetical precision because with vanilla JS you can only safely represent numbers between - (2⁵³ - 1) and (2⁵³ - 1)

JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard. This format stores numbers in 64 bits, where the number (the fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and the sign in bit 63

We can wait to support 128 bits with new microprocessors or create a new type for integers.

Number.MAX_SAFE_INTEGER = Math.pow(2, 64) - 1// current standard support
Number.MAX_SAFE_INTEGER = Math.pow(2, 53) - 1

There is already a proposal for arbitrary precision integers in the specification.

// current proposal solution
BigInt(Number.MAX_SAFE_INTEGER) + 5n // 9007199254740996n

[HTML] Extend types in inputs

How an <input> works vary considerably depending on the value of its type attribute. It would be really helpful to extend those types.

// controls for entering different types of numbers
<input type="hexadecimal">
<input type="octal">
<input type="binary">
// and a new one that is growing rapidly especially in phones
<input type="footprint">

[BROWSER] Web SQL

Web SQL Database is a web page API for storing data in databases that can be queried using a variant of SQL. The API is supported by Google Chrome, Opera, Safari and the Android Browser.

Because Firefox and Edge do not have their own implementations it has been deprecated and people should consider replacing their Web SQL database with a modern alternative, such as IndexedDB. However, IndexedDB is really basic, I would like a SQL variant as Web SQL was with all its powerful structured queries and error handling.

[JS] Eradicate NULL, leave only undefined

Javascript has two Billon Dollar Mistakes one for nulland the other for undefined, at least we should aimed at eliminating the danger of one of them from code.

undefinedmeans variable declared but not defined with a value.

nullmeans no value and have to be set up programmatically.

Both use different types and almost represent the same (the lack of value) and you can set up a variable to undefinedas well. I cannot see any advantage over all errors derived of using another particular case of no value.

if (value) // do stuff

because

undefined || null || '' || false // false

[HTML] Mouse move

It is said that humans are a little bit annoying sometimes, the Internet is full of trolls and we are not all respectful programmers, therefore we are not allowed to have the chance of moving the mouse programmatically.

I see many advantages, from video games to guided tutorials, but I personally would like to have those moves for automatic beta testing my apps, I will love to simulate different random users interacting with mouse and touchscreens.

And to avoid the take away of your mouse control we could add an escape key or something impossible to be blocked.

[JS] Fetch with local support

There are plenty of scenarios where you will have to access and read your local files. With XMLHttpRequest(XHR) you can retrieve any type of data, not just XML, and it supports protocols other than HTTP (including file and FTP). The same can be done with Axios library, however, that aimed to be an easy way for XHRdo not support basic protocols like file for security reasons what is ridiculous because we already have the previous methods.

fetch('language.en.json').then(r => console.log(r))// current standard solution (axios is based on XHR)
axios.get('language.en.json').then(r => console.log(r))

I would also add file type detection by default.

[DOM] Display large data sets efficiently

The main idea is not to pollute DOM as Clusterize.js does.

In our apps when we work with big data sets we just request for the visible area in our local storage (IndexedDB). Imagine a scroll that goes up and down, what you see is what we are really representing nothing more.

It would be so comfortable to link big data representations directly with our storage using native HTML, a middle way between indexedDB and the DOM, able to render what is need it depending on the user interaction.

<ol render="visible-area">
<li>first item</li>
<li>second item</li>
<li>third item</li>
...
</ol>

[DOM] Chaining

If you have ever used jQuery (in the past) you know what chaining technique is like. It allows us to run multiple commands, one after the other, on the same element.

// jQuery
$('div')
.removeClass('box')
.addClass('pen')
.toggleClass('active')

It would be quite useful to have this kind of behavior working with DOM elements.

document.querySelector('div').classList
.remove('box')
.add('pen')
.toggle('active')
// current standard solution
const $div = document.querySelector('div')
$div.classList.remove('box')
$div.classList.add('pen')
$div.classList.toggle('active')

Thankfully, at least we can use chaining with high order functions like map, filter and reduce JavaScript.

['40', '5', '9', '10']
.map(Number)
.filter(n => n > 9)

[JS] Avoid the weird parts

If we want to avoid some unpredictable behavior we can set'use strict';tag at the beginning of the code.

However, this will not eradicate many core odd parts as follow:

[015, 016, 017, 018] // [13, 14, 15, 18] (018 should throw an error)0 <= null // true
0 < null // false
0 == null // false (it should be true)
{a: 1} <= {b: 2} // true
{a: 1} >= {b: 2} // true
{a: 1} == {b: 2} // false
let a= new Int32Array(10)
a['1'] = 5
a['1'] // 5
a['1.1'] = 5
a['1.1'] // undefined
a['1.0'] // 5
let x = 0 / 0 // NaN (it should throw an error)
x === x // false
var a = [x] // undefined
a.includes(x) // true
a.indexOf(x) // -1
let a = [0]
a == a // true
a != a // true
a == 0 // true
0 == [] // true
a == [] // false
[101, 920, 4].sort() // [101, 4, 920]['10', '10', '10', '10'].map(parseInt) // [10, NaN, 2, 3]

(Most of the examples above were presented in the funny speech of Benedikt Meure at You Gotta Love Frontend 2018)

Octal wrong behavior can be solved just using 0o18 instead of 018. Also, it’s easier to remember like in hexadecimal and binary: 0xAAand 0b10respectively.

Doble equal (equality) comparations can be solved using triple equal comparations (equality and type).

Mapping strings into numbers can be solved using Numberinstead of parseInt.

Sorting numbers can be solved defining a proper function inside.

About the rest of uncertainties, we usually don’t run into them but it would be nice to have a mode where weird behaviors are not allowed.

We mentioned earlier the immutabletag at the beginning of the code to execute JavaScript in that mode, so what if we just use one tag for everything, to make JS even more awesome, the use awesometag: use strict, immutable, just double consistent equal, better numeric precision, no nulls and inference types like Elm. After 2020 it would be the default mode, so you will not have to add it if the code is older and not tag were added it would be executed in old mode.

[BROWSER] Do not use external transpilers, rely on Browser

Sometimes we want to start using new things that will become part of the standard. Thanks to Babel, Webpack, Parcel and many other tools we can decide to transpile to a specific JavaScript version. However, you will struggle with a completely different JavaScript in your browser, so at the end, you need to use even more tools for debugging.

It would be wonderful if the browser were able to handle this checking their current implementation support and using tools like Babel internally, allowing the user to deal always with his code.

Would you like to change the future of the Web and contribute with the standard?

To contribute to the HTML and CSS specification, see https://www.w3.org/wiki/How_To_Contribute

To contribute to the ECMAScript specification, see https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md

Keep in touch

What things are you missing in HTML, CSS or JavaScript? Any proposal? Let us know in the comments below!

And if you want to fall asleep again next time I publish something, you can also follow me on Medium.

T-Shirts

★ Now you can have some of my coolest T-Shirts for programmers, check it out!

--

--

Génesis García Morilla

We humans are really bad at math and logic, so I don't know what the hell are we doing programming...