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!

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(() => {
    resolve('dog');
  }, 100);
});

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

const myObservable = new Rx.Observable(observer => {
  setTimeout(() => {
    observer.next('dog');
    observer.next('cat');
    observer.next('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;
}

Days of the week

Days of the week are represented as three-letter strings (“Mon”, “Tue”, “Wed”. “Thu”, “Fri”, “Sat”. “Sun”).
Write a function solution that, given a string S representing the day of the week and an integer K (between 0 and 500, inclusive), returns the day of the week that is K days later.
For example, given S = “Wed” and K = 2, the function should return “Fri”.
Given S = “Sat” and K = 23, the function should return “Mon”.

function weekDay(S, K) {
  var weekDays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
  
  // get the index of the day
  var dayIndex = weekDays.indexOf(S); 
  
  // get the offset index
  var moduloIndex = (dayIndex + K) % weekDays.length;
  return weekDays[moduloIndex];
}

Buildings and volume of water stuck

Given buildings of width 1 and variable height, write a function returning the volume of water which remains stuck between them when it rains. This function has to be written in JavaScript.
The program will receive the list of the building heights as input array. Your program should return volume of water stuck between the buildings.
For example input: [2,1,3] result should be: 1
For example input: [3,1,2,4] result should be: 3

function result(Arr) {
    var sum = 0;
    var lArr = [];
    var rArr = [];
    var leftMax = 0;
    var tmpMax = 0;
    var rightMax = 0;
    for (Ai = 0; Ai < Arr.length; Ai++) {
      // get maximum to the right of the current element
      lArr = Arr.slice(0, Ai);
      if(lArr.length > 0) {
        tmpMax = Math.max(...lArr);
      } else {
        tmpMax = 0;
      }
      leftMax = tmpMax;
      
      // get maximum to the right of the current element
      rArr = Arr.slice(Ai+1);
      if(rArr.length > 0) {
        tmpMax = Math.max(...rArr);
      } else {
        tmpMax = 0;
      }
      rightMax = tmpMax;
      
      // get amount of water based on the left and right max elements
      if(Arr[Ai] < leftMax && Arr[Ai] < rightMax) {
        sum += Math.min(leftMax, rightMax) - Arr[Ai];
      }
    }
    return sum;
}

Guard clause

A Guard Clause (one of the SmalltalkBestPracticePatterns, and equally applicable in a whole bunch of languages) is a chunk of code at the top of a function (or block) that serves a similar purpose to a Precondition.

It typically does one (or any or all) of the following:

  • checks the passed-in parameters, and returns with an error if they’re not suitable.
  • checks the state of the object, and bails out if the function call is inappropriate.
  • checks for trivial cases, and gets rid of them quickly.

For example:

draw() {
  if (! isVisible()) return;
  ...
}

// without Guard Clause
function getPayAmount() {
  let result;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}

// with Guard Clause
function getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  return normalPayAmount();
}