Custom HTML Attributes Are Evil
HTML is itself a static content, and many developers have used the specification <!DOCTYPE >, which points out that it is merely a document.
The dynamic part is represented by JavaScript language. And here arose the problem.
Looking how various programming languages are used to build UI reveals that the language itself is a part of UI blocks. For example, Windows Presentation Framework uses XAML with C# controls:
<Grid Background="#555555" Width="400" Height="300"> <Button Click="OnButtonClick">Press me</Button></Grid>
Here will be created an instance of Grid class and an instance of Button class. Also it is possible to write logic whatever we like inside custom controls as they are just usual classes:
class Grid {
public Color Background {get; set;}
// methods and other UI logic
}
The same is true for Java with Android layouts, and many other languages and platforms.HTML initially does not provide such idea, it does not link <html-element> to a JavaScript instance. To enhance it we can simply declare HTML elements as objects of JavaScript types:
class div {
public string style {get;set;}
// methods and other UI logic
render: function(){
// return real html '<div>'+content+'</div>'
}
}
class MyWindowPopup {
public boolean fullScreen {get;set;}
public boolean visible {get;set;}
// methods and other UI logic
}
Then it becomes possible to build pages and components in a common way:
<MyWindowPopup visible="true" fullScreen="false">
<div>Popup text</div>
</MyWindowPopup>
Moreover we can advance some property types, e.g. use string[] array instead of string for class property <div class="typeof string[]">.
Then a browser or a server (NodeJS) is simply converts JavaScript to HTML and shows layout to a user. This approach took Facebook team with React and its JSX style.
---------------------------------------
Many other teams try to overcome HTML static nature by putting custom attributes, which seems very strange and inconvenient for me. Angular, Vue.js, Aurelia.js and many other JS frameworks use logic with custom marks (*ngIf, v-if, bind.click):
<div *ngIf="currentHero">Hello, {{currentHero.firstName}}</div>
<div *ngFor="let hero of heroes">{{hero.fullName}}</div>
JavaScript Monopoly
I think every team that works with Web tried to create a converter from their languages to JavaScript. However this approach produces massive bunch of problems due the nature of languages.
Google created GWT where Java is converter to JavaScript and developers can write kind of UI logic in Java. Also Google tried to apply usage of Dart language in modern browsers and again created conversion to JavaScript.
Microsoft uses aspx controls that can be written in .NET compatible language, Razor views, and TagHelpers in Asp Core, which all finally are converted to JavaScript and HTML. You can find same idea for Elm, Python, PHP and other languages.
The problem is that JavaScript and C#, JavaScript and Java, JavaScript and [your favourite language] are very different beasts.
Javascript is a prototype-based language with first-class functions. There is no even idea of an object instance of a class (class declaration leads again to a function). There are just six types in JavaScript: Object, Number, String, Boolean, Null, and Undefined, plus some object helpers like RegEx. There is no even notion of Integer or Decimal type because JavaScript Number only holds double-precision 64-bit format value. Run in a JS console "0.1 + 0.3" and see what you get, while with Decimal types in C# the result will be "0.4".
Thus, developers restrict their language of choice too much and loose the power of JavaScript. In addition to these points most of the time they loose highlighting and intellisense while producing JavaScript and HTML as a string, e.g. in Asp Core TagHelpers:
public class IconTextTagHelper : TagHelper
{
public string Glyph { get; set; }
[HtmlAttributeName("class")]
public string ClassName { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
string classnames = String.IsNullOrWhiteSpace(ClassName) ? "icontext" : "icontext " + ClassName;
output.TagName = "a";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.Add("class", classnames);
output.Content.SetHtmlContent(
// String, string, string
$@"<span>
<i class=""icon fa fa-{Glyph ?? ""} icontext__icon""></i>
<span class=""icontext__text"">{this.Text}</span>
</span>");
}
}
A way better solution is to work with JavaScript itself, or even better with TypeScript, which provides static type checking.
Breaking JavaScript Monopoly
The idea is very simple:
Browsers will support agnostic language (through ASTs) that will include many features from modern languages. It will be some kind of Intermediate Language that is used in Java and .NET virtual machines nowadays. It will be faster to parse, faster to transfer, faster to run, it will be in binary format instead of text format of current JavaScript.
Sadly web development progress is very slow.
The web community still tries to build some kind of XAML with its custom components, inline styles, namespaces and modules.
It is 2016 and only now we have Flexbox, which is analogue of StackPanel in WPF for arranging elements horizontally or vertically in a single line. And what about Grid, without a hack and whistles there is no way to do it in modern CSS, only recently W3C CSS Grid specification has passed from a Draft type to a Candidate Recommendation type.
There are so many bright minds in our realm but the overall picture is appalling.
P.S. JavaScript word is used for convenience, while ECMAScript is the proper notion in some places.