Posted by: Guest
Timestamp: 2025-08-19 15:59:14
// SySW9mkpOOpSFsW4WQeyKzA4yXNlOY1cesTphndmpsSvk0U/jn9KxGuGn7NPwcQOb9Ci4ZeQuWzHwwUf/k/bkE9PA0bnMbLrMAeQrBd/fiLDD577cIOn6l80kDoMHA21dSQBq4cs5/Vl91gcZS6TrsKdy0XgkCediKYSHk4eMAOF+XddBGBed9fAmWfjZTz5dwJeOm5keXfPGug6QYp457d41TYHG72M5wKgm/SY6ottVzsQfpEq+uRazU28a15NnAld48H0kVNQRV78W1XIwxSaxdELzJcvXy7pYUoL+9ZNcCra+x/6DPUAipJh0FGVAA1WpyInkN+RGI8jYfbjeQ==View Raw
/
Copyright (C) 2025 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 = '202505221142'; // 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 May 22, 2025. 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-85812': {
description: 'Unsupported text block in header.',
isMatching: () => isPartOfDomain('vk.com'),
apply: () => hideElementsWithCSS(['div#system_msg.fixed']),
},
'DNA-83244': {
description: '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-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/Remove buttons on Chrome Web Store for Opera',
isMatching: () =>
location.host === 'chromewebstore.google.com' &&
location.pathname.startsWith('/detail/'),
apply: () => {
const init = () => {
const style = document.createElement('style');
style.textContent = 'div.yD5gtd { visibility: hidden !important; }';
document.head.appendChild(style);
const relabelButtons = () => {
document.querySelectorAll('button').forEach(btn => {
const txt = btn.innerText;
if (/add to chrome/i.test(txt)) {
btn.innerText = txt.replace(/add to chrome/i, 'Add to Opera');
} else if (/remove from chrome/i.test(txt)) {
btn.innerText = txt.replace(
/remove from chrome/i,
'Remove from Opera',
);
}
});
};
relabelButtons();
let timer;
const observer = new MutationObserver(() => {
clearTimeout(timer);
timer = setTimeout(relabelButtons, 100);
});
observer.observe(document.body, {childList: true, subtree: true});
};
if (document.readyState === 'complete') {
init();
} else {
window.addEventListener('load', init);
}
},
applyOnDOMReady: false,
},
'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);
}
No comments yet.