Good riddance, Internet Explorer!

As Internet Explorer enters end-of-life, Vivaldi browser co-founder and CEO Jon von Tetzchner remembers its controversial legacy and argues that its loss is not really a loss.

Hourglass indicates end of Internet Explorer.

Read this article in Español, Русский.

On the 17th of August, Microsoft decided to kill off its Internet Explorer browser. The browser lives on as Edge which first appeared with an engine also called Edge, but finally, the original Internet Explorer has been put to rest.

It is unfortunate that we now have one less browser engine on the Internet. Competition is good and fewer browser engines means less innovation in browser engines. It is quite simple really.

But that being said, the loss of Internet Explorer is not really a loss. The loss of the Presto browser engine was a much bigger loss. In fact, I would say that the Web is better off without Internet Explorer, something even Microsoft has understood.

Internet Explorer: Embrace, extend, extinguish

The first Internet Explorer was based off the original Mosaic code, licensed from Spyglass. Microsoft was late to the Web game. Their original goal was to build their own Internet, but like other proprietary attempts at building Internet, such as AOL and Compuserve, they failed.

Having seen the growth of Netscape, Microsoft understood that they needed to act and they did. After getting the license from Spyglass, they started on their road of the infamous Embrace, extend, extinguish tactic.

The principle there was to embrace web standards and get the standards community on board. After “cutting off the air supply” from Netscape, by bundling IE with Windows and stopping any ability to get browsers bundled on Windows computers, they quickly took the lead in the browser market.

They then started to expand on the web standards, with total disregard for the standards community. During this time they introduced technology such as ActiveX and Silverlight, making it impossible to use competing browsers when accessing services that used those technologies.

They also added various proprietary tags in their HTML/CSS/JS code, which made life difficult for web developers. In reality, many web developers made sites optimized for IE, instead of for web standards, making it really hard for competing browsers.

Microsoft close to taking over the Web

At the time, I was leading the Opera browser which I had co-founded with Geir Ivarsøy.

As a competitor of Microsoft, we noticed a lot of the things they did to kill off competition.

Getting distribution with any Windows-based computer was impossible. Projects we were involved with, such as with Compaq and Intel, got canceled due to threats from Microsoft. We had to deal with compatibility issues across the board. Some examples include:

  • Microsoft made their own server software and in an update (to version 4), they included a file that made sure we would not be sent cookies. It took us a really long time to figure that one out. Websites, such as the BBC, broke, and we got the blame. After we discovered the issue, Microsoft fixed it.
  • Microsoft barred Opera users from accessing their MSN service, claiming we did not support XHTML. We wrote a press release rebutting them, in XHTML. The reality was that we supported XHTML, but they did not.
  • Microsoft sent Opera users a broken CSS file, which meant that text overlapped. We had a bit of fun with this one and made a special Bork edition of Opera that changed all the text on the MSN site to something resembling the way the Swedish Cook spoke in the Muppet show. It worked and Microsoft fixed their site.

But there were a lot more websites with issues. Given that Microsoft deviated from the standards and they had the most used browser, so many sites demanded that you use Internet Explorer to access their content.

Microsoft was really close to taking over the Web fully.

Jon von Tetzchner on stage.
Jon von Tetzchner on stage.

Microsoft’s tactic backfires

Microsoft killed Netscape and although Netscape was replaced by Mozilla, Mozilla did not have a lot of clout in the early days.

Luckily Microsoft’s tactic backfired.

They stopped developing Internet Explorer after Internet Explorer 6, presumably because they wanted to move people over to Silverlight instead.

At the same time, Opera, Mozilla, and Apple, alongside the World Wide Web consortium, decided to work together on improving Web standards. Together we wrote HTML 4, which took the Web to another level.

Gradually our combined user base started to grow and Microsoft was forced to restart the development of Internet Explorer, but from this point onwards they were lagging behind. They still lead the market share, but they had lost momentum, and given that both the US government and the EU were watching Microsoft’s anti-competitive behavior, they were somewhat limited in their response.

Microsoft was pretty close to being split up over how they had used their domination in the browser market to kill off Netscape. With the government watching, they had to compete more on the merits and there they lost. Suddenly their incompatibility had moved from being an asset to being a liability.

Websites code for Web standards first, not Internet Explorer

Instead of sites coding for Internet Explorer first, more and more sites began coding for the standards first and then for Internet Explorer.

Microsoft was now dealing with the problem they had created. It became hard for them to both support the standards and their own deviations from those standards. Finally, they decided to drop their old code and embrace the standards. As doing that from scratch is hard and as there still is a lot of code there looking for their name in identification strings, they decided to use Chromium instead.

* * *

Microsoft can not be written off. Given that the focus of governments is now more on Google and Facebook, you can see how Microsoft is gradually trying to use their position to steal users in Windows, during updates and by making it hard for competing browsers to fully default.

At the same time, it is good to see that Internet Explorer is gone. As much as I want there to be choice on the Internet, Internet Explorer is not a choice we ever needed.

Photo by Aron Visuals on Unsplash.

Source: Good riddance, Internet Explorer!


Given a number n, for each integer i in the range from 1 to n inclusive, print one value per line as follows:

  • If i is a multiple of both 3 and 5, print FizzBuzz.
  • If i is a multiple of 3 (but not 5), print Fizz.
  • If i is a multiple of 5 (but not 3), print Buzz.
  • If i is not a multiple of 3 or 5, print the value of i.

Function Description

Complete the function fizzBuzz in the editor below.

fizzBuzz has the following parameter(s):

int n: upper limit of values to test (inclusive)

Returns: NONE


The function must print the appropriate response for each value i in the set {1, 2, … n} in ascending order, each on a separate line.


  • 0 < n < 2 × 105

Input Format for Custom Testing

Input from stdin will be processed as follows and passed to the function.

The single integer n, the limit of the range to test: [1, 2, …n].

Sample Case 0

Sample Input

STDIN    Function
-----    --------
15    →  n = 15

Sample Output



The numbers 3, 6, 9, and 12 are multiples of 3 (but not 5), so print Fizz on those lines.

The numbers 5 and 10 are multiples of 5 (but not 3), so print Buzz on those lines.

The number 15 is a multiple of both 3 and 5, so print FizzBuzz on that line.

None of the other values is a multiple of either 3 or 5, so print the value of i on those lines.

function fizzBuzz(n) {
	var i, res = '';
	for( i=1; i <= n; i++ ) {
		res = '';
		if( i % 3 == 0 ) {
			res += 'Fizz';
		if( i % 5 == 0 ) {
			res += 'Buzz';
		if( res == '' ) {
			res = i;

React Like button

import cx from 'classnames';
import { Component } from 'react';

export default class LikeButton extends Component {
    state = {
        count: 100,
        liked: false
    likeMe = () => {
        let newCount;
        if(this.state.liked) {
            newCount = this.state.count - 1;
        } else {
            newCount = this.state.count + 1;

          count: newCount,
          liked: !this.state.liked
    render() {
        return (
                    className={`like-button ${this.state.liked ? "liked" : ""}`}
                    >Like | <span className={`likes-counter`}>{this.state.count}</span></h1>
                    .like-button {
                        font-weight: normal;
                        cursor: pointer;
                        font-family: Helvetica, Arial, Sans-Serif;
                        font-size: 1rem;
                        padding: 5px 10px;
                        color: #585858;
                        border: 1px solid #585858;
                        display: inline-block;
                   .liked {
                        font-weight: bold;
                        color: #1565c0;
                        border-color: #1565c0;

Maximum words counter in the sentence

You would like to find the sentence containing the largest number of words in some given text. The text is specified as a string S consisting of N characters: letters, spaces, dots, question marks and exclamation marks.

The text can be divided into sentences by splitting it at dots, question marks and exclamation marks. A sentence can be divided into words by splitting it at spaces. A sentence without words is valid, but a valid word must contain at least one letter.

For example, given S = “We test coders. Give us a try?“, there are three sentences: “We test coders“, “ Give us a try” and ““. The first sentence contains three words: “We“, “test” and “coders“. The second sentence contains four words: “Give“, “us“, “a” and “try“. The third sentence is empty.

Write a function that, given a string S consisting of N characters, returns the maximum number of words in a sentence.

For example, given S = “We test coders. Give us a try?“, the function should return 4, as explained above.

Given S = “Forget CVs..Save time . x x“, the function should return 2, as there are four sentences: “Forget CVs” (2 words), “” (0 words), “Save time ” (2 words) and “ x x” (2 words).

Assume that:

  • the length of S is within the range [1..100];
  • string S consists only of letters (a-z, A-Z), spaces, dots (.), question marks (?) and exclamation marks (!).

In your solution, focus on correctness. The performance of your solution will not be the focus of the assessment.

function maxWordsCounter(S) {
    var sentencesList = [];
    var wordsList = [];
    var lenList = [];
    var i, j, wordCounter = 0;
    var updS = S;

    updS = updS.replace(/\.|\!|\?/g, '|'); // replace '.!?' with '|' (pipe symbol)
    sentencesList = updS.split('|');
    for (var i in sentencesList) {
        wordsList = [];
        wordsList = sentencesList[i].split(' ');
        for (var j in wordsList) {
            if(wordsList[j].trim() !== '') {
        wordCounter = 0;
    return Math.max(...lenList);

Unique integers that sum up to 0

Write a function that, given an integer N (1 ≤ N ≤ 100), returns an array containing N unique integers that sum up to 0. The function can return any such array.

For example, given N = 4, the function could return [1, 0, −3, 2] or [−2, 1, −4, 5]. The answer [1, −1, 1, 3] would be incorrect (because value 1 occurs twice). For N = 3 one of the possible answers is [−1, 0, 1] (but there are many more correct answers).

function uniqueIntegers(N) {
    result = [];
    var x = Math.floor(N / 2);
    var i = 0;
    if (N % 2 === 0) { // even
        i = 0;
    } else { // odd
        result[0] = 0;
        i = 1;
    while (i < N) {
        result[i] = x;
        result[i + 1] = -1 * x;
        i += 2;
    return result;

Maximum depth of nested ol/ul

You are given a DOM tree and have to analyze the ul and ol list tags within it. Your task is to find the maximum depth of nested ul/ol list tags. A single ul/ol list is nested one level deep. Each ul/ol list inside another ul/ol list is nested one level deeper. If there are no ul or ol lists at all in the DOM tree, the depth of nesting is 0.

Note that ul/ol lists can be nested directly or indirectly; that is, a ul list inside a table inside an ol list is nested two levels deep.

For example, given an HTML document with the following contents within the body tag:

  <li>simple list1</li>

there is a ul list nested three levels deep. Namely, “elem1” is in a ul list which is inside an ol list containing “Point”, while this ol list is inside another ul list containing “Item”.

Write a function that, given a DOM tree, returns the maximum depth of nested ul/ol lists. For example, given the DOM tree of the document shown above, the function should return 3, as explained above.

Given the following content:


the function should return 2.

Assume that:

  • the DOM tree represents a valid HTML5 document;
  • length of the HTML document does not exceed 4KB;
  • jQuery is supported.
function maxDepth() {
    var maxDepth = 0,
    targetSelector = 'ul, ol';

    $(targetSelector).each( function() {
        parents = $(this).parents(targetSelector);
        tempDepth = 1;
        if (parents) {
            tempDepth = parents.length + 1;
        if (tempDepth > maxDepth) {
            maxDepth = tempDepth;
    return maxDepth;

Difference between Promises vs Observables

Observable can provide a stream of data, also can filter the results and you can unsubscribe. It is not possible to do with Promises.
Observable can return a value synchronously or asynchronously. Promise is always asynchronous

const myPromise = new Promise(resolve => {
  setTimeout(() => {
  }, 100);

myPromise.then(result => {
  console.log('promise: ', result);

const myObservable = new Rx.Observable(observer => {
  setTimeout(() => {'dog');'cat');'bird');
  }, 100);

const subscription = myObservable
  // .filter(result => result === 'bird')
  .subscribe(result => {
    console.log('observable: ', result);

// subscription.unsubscribe();

Difference between Promises vs Observables

Alternating characters

Write a function that returns a string of length Num consisting of alternating characters: “a” and “b”, starting with an “a” character.
For example, giver Num=5, your function should return “ababa”.

function altChars(Num) {
    let result = '';
    for (i = 0; i < Num; i++) {
        if (i % 2 == 0) {
            result += 'a';
        } else {
            result += 'b';
    return result;