📜 ⬆️ ⬇️

Frills Opera

Immediately, I note that this post is not an attempt to add fuel to the fire of browser holivar This is a little story about my opening in Opera browser.
Many have probably heard that Opera “fixes” the work of some sites (and js libraries), so that in turn they work normally in this browser. I somehow ran across a page listing which sites and which problems were fixed on them. But then I did not think about how they "rule" this.

And today one of the users sent us a "bug report" that our service (ajax application) does not work in Opera 9.24, and sent an error message from the "Error console". The strangeness in this is that until recently everything worked in this and other (younger) versions of Opera, and we have not had new releases for more than a month and a half. He opened the Opera, went to url - it does not work for me either. And flies at the very beginning. Swears on a strange line, looking for in their scripts. No such. Then I remembered the “patches” of the Opera for websites - maybe there? After a brief search, I found a file with hacks - which is essentially a regular JS file (called browser.js), loads the very first one and does some work. There it turned out to be an ill-fated line. I looked around a bit: what is it, what is it. It turns out this file is updated by itself, and its last update was December 13th (for this version) and it is written in it, and it swayed to me on December 20th, when I ran the opera last time.
For the most part, all the crutches in this file are addressable, that is, they are designed for specific sites (yes! Location.hostname is checked). But part of the general. In particular, in my case, the problem was caused by the following code:
     Array.prototype.concat = function () {// working around incompatibility with prototype, bug 241832
         var array = [];
         for (var i = 0, length = this.length; i <length; i ++) array.push (this [i]);
         for (var i = 0, length = arguments.length; i <length; i ++) {
           if (arguments [i] .constructor == Array) {
         for (var j = 0, arrayLength = arguments [i] .length; j <arrayLength; j ++)
           array.push (arguments [i] [j]);
           } else {
         array.push (arguments [i]);
           }
         }
         return array;
     }

Alarmed. Somewhere I have already seen. I look at the commentary (because it’s not clear what this is for, they stuck here) - exactly: “working around incompatibility with prototype”. In prototype, I just saw it. I looked at prototype, the car turned out to be version 1.5 in which there is:
 if (window.opera) {
   // same code
 }

What kind of nonsense? At one time, I broke my head by interpreting these lines in prototype. I do not know what the implementation of the concat in Opera did not suit them, but then I did not find any differences from other implementations in other browsers. However, in Opera it was decided to do as in prototype, creating a stalemate for applications when arguments [i] is null or undefined (a test would not hurt to do it). And no matter what you write and what libraries you use, the concat opera works as in prototype.
I am wondering how to fix it (before that there were only small problems with the Array.splice method, but what / how is that ?!).
In general, I recommend everyone to study this browser.js, especially for those who are interested in studying the work of Opera from the inside. In addition, comments are very interesting, for example:
 // 194334, Y! Mail remove selectSingleNode and selectNodes
 / * because Yahoo Mail is better at emulating proprietary IE functions than we are .. * /
 Node.prototype.selectSingleNode = undefined;
 Node.prototype.selectNodes = undefined;

By the way, all these dances with a tambourine in Opera are called "magic fixes". Really "magic"!

Threat While I wrote in some miraculous way, the bug was fixed, but only with me. File browser.js is the same, but does not give errors. For the rest, nothing works and writes an error to the console.
UPDATE It turned out why I had a bug fixed. The fact is that at the beginning of the browser.js file contains the signature of the content. Accordingly, if you change the contents of the file (I just put the line break in one place), then the signature will already be different and Opera will stop using this file, as it considers broken and waits for the next update. The browser checks weekly updates for this file, downloads and uses them, unless of course it is disabled in the config file (for example, opera6.ini). The setting is called Browser Javascript. Thanks rsa2048 for the tip.

')

Source: https://habr.com/ru/post/18017/


All Articles