// ANhamdsT/5FFQOpBSSfsSzXWPKaFcuo6fRFv47H6WwIDueS5K5yIJ65R3TQ3ArO4sFsz/UN9fqwaJvX728bxGvrbC1Qt0L2n/xQVovP9oG0ORe55wCN7YV/aB4jd5OlIJqiBIoUIYh0wX8K3rDds2k25NijYQCl+IdAXqMJUeBMPktA6SPMV2F/4iO1OJPFjmDG2s+v+4mypZjKAXifR8CYDZFTsTQ95QNtsWvszTtUpdNJ7Pkwh3GALldAtgEXwWaLbC/0VBPxcA45VF4jySpiZeic3H1jgje94PnvkSNDqbwA4tvARyfrH4Ht4iA/lbKOrAUfAi/aDAcAZHZu4yw==
/**
** Copyright (C) 2024 Opera Norway AS. All rights reserved.
**
** This file is part of the Opera web browser.
**
** This script patches sites to work better with Opera
** For more information see http://www.opera.com/docs/browserjs/
**
** If you have comments on these patches (for example if you are the webmaster
** and want to inform us about a fixed site that no longer needs patching)
** please report issues through the bug tracking system
** https://bugs.opera.com/
**
** DO NOT EDIT THIS FILE! It will not be used by Opera if edited.
**
** BROWSERJS_TIMESTAMP = '202404041142'; // for versioning; see DNA-54964
**/
'use strict';
if (!location.href.includes('operabrowserjs=no')) {
(function(document){
const { href, pathname, hostname } = location;
const safeApply = Function.prototype.apply.bind(Function.prototype.apply);
const safeMethod = (method, context) =>
(...args) =>
safeApply(method, context, args);
const utils = {
addEventListener: (element, event, handler, options) => {
element.addEventListener(event, handler, options);
},
appendChild: (parent, child) => parent.appendChild(child),
createElement: (tag) => document.createElement(tag),
createTextNode: (text) => document.createTextNode(text),
setAttribute: (element, attr, value) => {
element.setAttribute(attr, value);
},
querySelector: (selectors) => document.querySelector(selectors),
};
const version = () => {
const total = Object.keys(PATCHES).length;
return `Opera Desktop April 4, 2024. Active patches: ${total}`;
};
const isPartOfDomain = (host) =>
hostname.endsWith(`.${host}`) ||
hostname === host;
const browserjsUrl = new URL('chrome://browserjs');
const hideOperaObject = () => { delete window.opr; };
const hideOperaUserAgent = () => {
const newUA = navigator.userAgent.replace(/ ?OPR.[0-9.]*.*/, '');
Object.defineProperty(navigator, 'userAgent', {get: () => newUA});
};
const addCssToDocument = (cssText, doc = document, mediaType = '') => {
const styleElementId = `opera-css-${mediaType.replace(/\s+/g, '-')}`;
let styleElement = doc.getElementById(styleElementId);
if (!styleElement) {
const head = doc.head || utils.querySelector(doc, 'head');
styleElement = utils.createElement('style');
styleElement.id = styleElementId;
utils.setAttribute(styleElement, 'type', 'text/css');
if (mediaType) {
utils.setAttribute(styleElement, 'media', mediaType);
utils.appendChild(head, styleElement);
}
utils.appendChild(styleElement, utils.createTextNode(cssText));
}
};
const hideElementsWithCSS = (selectors) => {
const cssText = selectors
.map(selector => `${selector} { visibility: hidden; }`)
.join('\n');
addCssToDocument(cssText);
};
const PATCHES = {
'PATCH-1190': {
description: 'Delta.com shows browser warning to Opera.',
isMatching: () => isPartOfDomain('delta.com'),
apply: () => {
Object.defineProperty(window, 'UnsupportedBrowser', {
get: () => undefined,
set: (arg) => {arg.badBrowser = () => false;},
});
},
},
'PATCH-1220': {
description: 'To not force plugin download',
isMatching: () => hostname.includes('.google.') &&
hostname.startsWith('talkgadget'),
apply: () => hideOperaUserAgent(),
},
'PATCH-1228': {
description: 'Block for delta-homes.com spam site',
isMatching: () => isPartOfDomain('delta-homes.com'),
apply: () => location.replace('https://google.com'),
},
'PATCH-1252': {
description: 'Hide first-run overlay on read.amazon.com',
isMatching: () => isPartOfDomain('read.amazon.com'),
apply: () => hideElementsWithCSS([
'.ui-dialog.firstRunDialog',
'.ui-dialog.firstRunDialog + .ui-widget-overlay',
]),
},
'PATCH-1263': {
description: 'Hide Unsupported Browser dialog on clarks.co.uk',
isMatching: () => isPartOfDomain('clarks.co.uk'),
apply: () => hideElementsWithCSS(['#unsupportedBrowser']),
},
'PATCH-1269': {
description: 'Hide popup with ads',
isMatching: () => hostname.startsWith('images.google.') ||
hostname.startsWith('www.google.'),
applyOnDOMReady: true,
apply: () => {
const href =
'https://www.google.com/url?q=/chrome/browser/desktop/';
const res = document.evaluate(
`//a[contains(@href, "${href}")]`,
document, null, XPathResult.ANY_TYPE, null
);
const downloadLink = res.iterateNext();
if (downloadLink) {
const ad = downloadLink.closest('div[role="dialog"]');
if (ad) {
ad.style.display = 'none';
}
}
},
},
'PATCH-1277': {
description: 'Popup with ads',
isMatching: () => isPartOfDomain('otvet.mail.ru'),
apply: () => hideElementsWithCSS([
'#tb-39754319', '#tb-54288097',
'#tb-54288098', '#tb-54288094', '#tb-54288099',
'#tb-54288095', '#tb-54288093', '#tb-32116366',
]),
},
'DNA-69435': {
description: 'Popup with ads in search results.',
isMatching: () => hostname.startsWith('yandex') &&
pathname.startsWith('/search/'),
apply: () => hideElementsWithCSS(['.popup2.distr-popup']),
},
'DNA-69613': {
description: 'Unsupporting text block.',
isMatching: () => isPartOfDomain('tickets.oebb.at'),
apply: () => hideElementsWithCSS(['#settingErr']),
},
'DNA-72852': {
description: 'Fix music playing.',
isMatching: () => isPartOfDomain(
'streamdb3web.securenetsystems.net/cirrusencore/DEMOSTN'),
apply: () => hideOperaUserAgent(),
},
'DNA-85788': {
description: 'Text block with ads.',
isMatching: () => isPartOfDomain('russian.rt.com'),
apply: () => hideElementsWithCSS(['div#offers.offers']),
},
'DNA-84005': {
description: 'Unsupported message.',
isMatching: () => isPartOfDomain('comba-telecom.com'),
apply: () => {
hideOperaObject();
hideOperaUserAgent();
},
},
'DNA-79464': {
description: 'Unsupported message when play video.',
isMatching: () => isPartOfDomain('cbs.com'),
apply: () => {
hideOperaObject();
hideOperaUserAgent();
},
},
'DNA-åå'Ads block in header.',
isMatching: () => isPartOfDomain('mail.com'),
apply: () => hideElementsWithCSS(['div.mod.mod-topper.promo']),
},
'DNA-85510': {
description: 'Unsupported page on entrance.',
isMatching: () => isPartOfDomain('famemma.tv'),
apply: () => {
hideOperaObject();
hideOperaUserAgent();
},
},
'DNA-97626': {
description: 'Fix video playing.',
isMatching: () => isPartOfDomain('highlive.tv'),
apply: () => {
hideOperaObject();
hideOperaUserAgent();
},
},
'DNA-90739': {
description: 'Help to get form information for Opera users',
isMatching: () => isPartOfDomain('opera.atlassian.net') &&
(pathname.startsWith('/servicedesk/customer/portal/9') ||
pathname.startsWith('/servicedesk/customer/portal/18') ||
pathname.startsWith('/servicedesk/customer/portal/20')),
applyOnDOMReady: true,
apply: async () => {
const waitForElement = async (selector,
maxAttempts = 50, interval = 100) => {
let attempts = 0;
while (attempts < maxAttempts) {
const element = document.querySelector(selector);
if (element) {
return element;
}
await new Promise(resolve =>
setTimeout(resolve, interval));
attempts++;
}
return null;
};
const setInputValue = (input, value) => {
input.focus();
input.value = value;
input.dispatchEvent(new Event('change', {bubbles: true}));
};
const insertSystemInformation = async () => {
const selector = '#customfield_10072';
const inputElement = await waitForElement(selector);
if (inputElement) {
const gpuInfo = getGpuInformation();
const systemInfo = `${navigator.userAgent}
(${navigator.language}), ${gpuInfo}`;
setInputValue(inputElement, systemInfo);
}
};
const getGpuInformation = () => {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') ||
canvas.getContext('experimental-webgl');
if (gl) {
const debugInfo =
gl.getExtension('WEBGL_debug_renderer_info');
return debugInfo
? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
: '';
}
return '';
};
if (pathname.includes('servicedesk/customer/portal/' +
'9/group/11/create/') ||
pathname.includes('servicedesk/customer/portal/' +
'18/group/32/create/')) {
insertSystemInformation();
}
const originalPushState = history.pushState;
history.pushState = function (...args) {
originalPushState.apply(this, args);
insertSystemInformation();
};
},
},
'DNA-90251': {
description: 'Customize button for add extensions.',
isMatching: () => isPartOfDomain('chrome.google.com') &&
pathname.startsWith('/webstore/'),
applyOnDOMReady: true,
apply: () => {
addCssToDocument('div.yD5gtd {visibility:hidden}')
const targetNode = document.documentElement;
const config = {
attributes: true,
childList: true,
subtree: true,
};
const callback = function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
var webstoreButtons = document
.querySelectorAll('.webstore-test-button-label');
for (let webstoreButton of webstoreButtons) {
if (webstoreButton.innerHTML.includes('Chrome'))
{
webstoreButton.innerHTML =
webstoreButton.textContent =
'Add to Opera';
}
}
}
}
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
},
},
'DNA-99267': {
description: 'Pretend to be Chrome on radio-south-africa.co.za',
isMatching: () => isPartOfDomain('radio-south-africa.co.za'),
apply: () => {
hideOperaObject();
hideOperaUserAgent();
},
},
'DNA-99293': {
description: 'Change game button.',
isMatching: () => isPartOfDomain('xsolla.com') &&
pathname.startsWith('/paystation3/'),
applyOnDOMReady: true,
apply: async() => {
const probeCondition = async (conditionFunction) => {
const sleep = (millis) => new Promise((resolve) =>
setTimeout(resolve), millis);
for (let i = 0; i < 100; i++) {
if (conditionFunction()) {
return true;
}
await sleep(50);
}
return false;
};
const findEULA = () => document.querySelector("a[href" +
"='https://www.opera.com/terms']");
const eula = await probeCondition(findEULA);
const targetNode = document.documentElement;
const config = {attributes: true,
childList: true,
subtree: true};
const callback = function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
var backButtons =
document.querySelectorAll('.btn.' +
'btn-flat.btn-md.btn-accent.tab-focus');
for (let backButton of backButtons) {
if (backButton.innerHTML.includes('to' +
' the game')) {
backButton.innerHTML =
backButton.innerHTML.replace('to' +
' the game', '');
addCssToDocument(`
svg {
visibility: hidden;
}
`);
}
}
}
}
};
setTimeout(() => {
const button =
document.querySelector('.btn.btn-flat.btn-md.'+
'btn-accent.tab-focus');
if (button) {
button.click();
}
}, 6000);
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
},
},
'DNA-99524': {
description: 'Browser.js version reported on browserjs page.',
isMatching: () => location.href === browserjsUrl.href,
applyOnDOMReady: true,
apply: () => {
const browserjs_info = version();
const addVersion =
document.createTextNode(`Today ${browserjs_info}`);
document.body.appendChild(addVersion);
},
},
'DNA-109866': {
description: 'Fix popup on Facebook.',
isMatching: () => isPartOfDomain('facebook.com'),
apply: () => hideElementsWithCSS(
['div.xu96u03.xm80bdy.x10l6tqk.x13vifvy >' +
'div.x9f619.x1n2onr6.x1ja2u2z.x78zum5']),
},
'DNA-111340': {
description: 'Customize Add extension on new chrome webstore.',
isMatching: () => isPartOfDomain('chromewebstore.google.com'),
apply: () => {
addCssToDocument('div.yD5gtd {visibility:hidden}')
const targetNode = document.documentElement;
const config = {
attributes: true,
childList: true,
subtree: true
};
const callback = function(mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
var webstoreButtons =
document.querySelectorAll(
'span.UywwFc-vQzf8d');
for (let webstoreButton of webstoreButtons) {
if (webstoreButton.innerHTML
.includes('Add to')) {
webstoreButton.innerHTML =
webstoreButton.textContent =
'Add to Opera';
}
else if (webstoreButton.innerHTML.includes(
'Remove from')) {
webstoreButton.innerHTML =
webstoreButton.textContent =
'Remove from Opera';
}
}
}
}
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
},
applyOnDOMReady: true,
},
'DNA-115341': {
description: 'Hide first-run overlay on duckduckgo.com',
isMatching: () => isPartOfDomain('duckduckgo.com'),
apply: () => {
hideElementsWithCSS([
'.header--aside__item.header--aside__item--hidden-lg',
]);
},
},
};
Object.values(PATCHES).forEach(({isMatching, apply, applyOnDOMReady}) => {
if (isMatching()) {
const run = () => apply();
if (applyOnDOMReady) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded',
run, false);
} else {
run();
}
} else {
run();
}
}
});
})(document);
}åloklo66