Why do sites that use lodash or underscore not work in Opera?

136 Views Asked by At

For whatever reason, some update in Opera has caused me to get frustrated for about a week now trying to figure out why Opera no longer works on my productivity sites - like StreamTime or Elementor (on any WordPress site).

I've narrowed it down to the fact that these sites all use underscore library (and possibly lodash). Because the error always seems to be with _.findWhere or _.pluck which are commonly used functions.

I've tried to monkey-patch it with Tamper Monkey, but whatever it is in Opera that's causing it is clearly happening before I get chance to fully inject my shims for those functions with native versions.

Here's what I've got in Tamper Monkey so far:

// ==UserScript==
// @name         Fix issues with Opera Compatibility.
// @namespace    https://www.hazrpg.co.uk
// @version      0.1
// @description  Trying to fix an opera issue that causes _.pluck and _.findWhere to not work.
// @author       hazrpg
// @match        https://*.app.streamtime.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=streamtime.net
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    console.log('Fixing opera issues...');

    let underscoreSrc_v1_13_6 = `
        if (typeof _ !== 'undefined' || typeof _ === 'function') {
            console.log('Looks like its already there jim, but lets shim shim shim!');

            // The '_' variable is already defined
            // You can now define your custom _.findWhere function
            _.findWhere = function (array, criteria) {
                //console.log('shimmed _.findWhere');
                return array.find(item => Object.keys(criteria).every(key => item[key] === criteria[key]))
            };
            _.pluck = function (collection, propertyName) {
                //console.log('shimmed _.pluck');
                return collection.map(item => item[propertyName]);
            };
        } else {
            console.log('Looks like we need to shimmy for Opera!');

            // The '_' variable is not defined
            // You can create your own namespace and define _.findWhere in it
            var _ = {
                findWhere: function (array, criteria) {
                    //console.log('shimmed _.findWhere');
                    return array.find(item => Object.keys(criteria).every(key => item[key] === criteria[key]))
                },
                pluck: function (collection, propertyName) {
                    //console.log('shimmed _.pluck');
                    return collection.map(item => item[propertyName]);
                },
            };
        }
    `;

    // Create a new script element for Underscore library
    var underscoreScript = document.createElement('script');
    //underscoreScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js';  // Adjust the URL as needed
    //underscoreScript.async = true;
    underscoreScript.textContent = underscoreSrc_v1_13_6;

    // Listen for the DOMContentLoaded event to inject the Underscore library
    document.addEventListener('DOMContentLoaded', function() {
        document.head.appendChild(underscoreScript);
    });

})();

I also toyed with the idea of using setTimeout and giving it a timeout of about 50 - which works to keep forcing my shims to be injected in, but whatever is overwriting it is doing it much faster and I'd hate to set it any lower than 50.

Anyone have any other ideas?

1

There are 1 best solutions below

0
hazrpg On

Turns out... its an extension that comes with Opera called "Opera Wallet" that is causing the issue. If you disable that, it instantly fixes the problem for everything!

So if anyone is having any issues - and you've been frustrated like I have been for quite a while. This might be your solution!

Next step is probably to start a ticket with Opera and get them to fix their user experience breaking extension!