Overriding history.pushState leads to error in opera 11 - javascript

I'm injecting the following code into a webpage via a greasemonkey script/opera extension to trap the history.pushState command, so I can do some processing whenever it's fired and still allow the pushState command to continue afterwards.
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
alert('pushstate called')
return pushState.apply(history, arguments);
}
})(window.history);
the code works fine in FF4 and Chrome, but in Opera 11, I get the following error, if the page calls a history.replaceState command:
Uncaught exception: TypeError: 'window.history.replaceState' is not a function
Does anyone know how I can fix the above code to work with Opera as well as Chrome and Firefox?

In Opera 11.00, Revision 1156, the history API supported are these
>>> history.
back, current, forward, go, length, navigationMode
The full HTML5 history API is not yet covered by Opera 11.00. In general if you would like to discover, explore what is supported, you can easily use the console mode of dragonfly, the Web developer tool.

According to When can I use … Opera doesn't support the History API yet, so that's why you get that exception.

I figured out the solution, just check for history.replacestate before executing the above code, if it doesn't exist, don't execute the code, simple.

Related

How can I check if a browser is Chromium-based?

I have a Chrome extension, and I am currently writing a website to advertise it.
I know that a Chrome extension can be installed in all Chromium-based browsers (Chrome, Opera, etc.).
Is it possible to check if a browser can download the extension from the web store or is chromium-based?
I found code to detect if it was Google Chrome here. Correct me if I'm wrong, but I think window.chrome doesn't return in all Chromium-based browsers.
window.chrome
As of now, window.chrome works in all chromium based browsers
var isChromium = !!window.chrome;
console.log(isChromium)
Resources
https://browserstrangeness.github.io/css_hacks.html
http://browserhacks.com/
navigator.userAgentData
User-Agent Client Hints API returns information about the browser and operating system of a user. (Introduced in chrome 90)
var isChromium = !!navigator.userAgentData && navigator.userAgentData.brands.some(data => data.brand == 'Chromium');
console.log(isChromium)
Resources
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData
https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData
https://web.dev/migrate-to-ua-ch/
Considering that you just want to get to know whether browser is chromium based or not ,
Method 1: ( Server Side Detection)
-- Get Browser name from client request itself and serving the webpage accordingly. For example, If backend is based on Nodejs, You can get browser name as answered in this answer.
Method 2: ( Client Side Detection)
-- On client Side ,You can first get the Browser Name as answered in this answer , and then check it from HARD-CODED Chromium-based browsers Array.
Try this. This check shows true for Chrome, Safari, Edge, Samsung browser… etc
The -webkit-appearance property is used by WebKit-based (e.g., Safari) and Blink-based (e.g., Chrome, Opera) browsers to achieve the same thing.
function isChromium(){
return window.CSS && window.CSS.supports && window.CSS.supports('(-webkit-appearance:none)');
}
Try using the following expression
navigator.userAgent.includes("Chrome")
I guess:
var isChrome = navigator.userAgent.match(/Chrome\/\d+/) !== null;

Firefox 68: local files now treated as cross-origin; is there a way to override?

Firefox 68 fixes a security problem with local files (https://www.mozilla.org/en-US/security/advisories/mfsa2019-21/#CVE-2019-11730), but in so doing breaks testing code locally. Is there a way to override this as can be done with Chrome and Opera (e.g., --allow-file-access-from-files)?
I cannot find anything relevant on the Firefox site, and cannot find a suitable command-line option or anything in about:config.
try {
main = opener.document;
}
catch (e) {
console.log(e);
console.log(e.name);
}
}
I get the following messages in the console:
DOMException: "Permission denied to access property "document" on cross-origin object"
SecurityError
[2023 Update]: This pref has been removed since this answer was posted. See user3611642's answer for an up to date solution].
Letting the original answer if someone comes back to using FF68 and faces this issue.
You can leverage this restriction by going to about:config url and then uncheck privacy.file_unique_origin boolean value.
However be aware that this only reverts to < 68 protection mode, which is to only allow digging in, even with this flag down you won't be able to fetch ../some_other_dir/foo.bar.
In my case: Firefox ver. 98.0.2 (64-bit) going to about:config and changing the flag helped:
security.fileuri.strict_origin_policy = false

Support for the webkitSpeechRecognition API in Opera

We're using the webkitSpeechRecognition API in Chrome. Since this is a prototype application, we're quite happy to support only Chrome, so we detect support for the API by doing a window.hasOwnProperty('webkitSpeechRecognition') check (as suggested by Google). This happily fails in Firefox, but the new Opera (being webkit-based) reports it does have the property. And, indeed, all code runs as intended, except... none of the events are ever fired, no voice is ever recorded.
So, my question is: can I make it work somehow? Does it require some special permissions or settings?
Alternatively, is there a way (aside good old browser-sniffing) to detect proper, working support for the webkitSpeechRecognition?
Right now only google chrome have API to speech recognition by stream (they have google sppeech API).
If you will use https://www.google.com/intl/en/chrome/demos/speech.html on Opera it will tell you that you need Chrome25+ to do this.
Acording to http://caniuse.com/#feat=speech-recognition Opera webkit have support for this functionality but right now it is not working. Opera does not have any API service that would translate it on the fly. Right now there have only placeholders function in their browser, maybe in the future they will make it, right no it is not working.
* EDITED *
Example by google how to determinte if it working or not.
// checking by google
if (!('webkitSpeechRecognition' in window)) {
console.log('GOOGLE: not working on this browser');
} else {
console.log('GOOGLE: working');
}
//your way
if (window.hasOwnProperty('webkitSpeechRecognition')) {
console.log('YOUR: working');
} else {
console.log('YOUR: not working on this browser');
}
The following Google sample uses a timestamp to detect that Opera did not trigger the start event: https://www.google.com/intl/en/chrome/demos/speech.html

Getting logs in Internet Explorer 8 and 9 without opening developer tool view

Chrome, FireFox and Safari can all log to the console without having the developer tool view open. However, IE 8 and 9 (not sure about 10) cannot, as console will be undefined without opening the developer tool first.
Is there any workaround for this? External JavaScript library?
window.console = window.console || {log: function(){}};
THis wont let you access the logs, but it will avoid null pointer errors.
I'm not sure of any library that will help you with this in IE but you could encapsulate your logging within a method so that it will operate normally in IE when not in developer mode.
function log(val){
if(console.log){
console.log(val);
}
}

Reading window.history.state object in Webkit

Safari and Chrome (and, I'm guessing, all Webkit browsers) do not respond to window.history.state which is specified in the evolving HTML5 standard here and is implemented in Firefox.
Is there a workaround to read it? Perhaps it is possible to trigger a popstate event in code and return the state from the event handler?
I ran into this issue yesterday. I didn't need a cross browser solution since the target platform is running an oldish version of WebKit, so I created a quick and simple polyfill for history.state in WebKit:
// Polyfill for history.state in older webkit engines
if (!history.hasOwnProperty('state')) {
(function (push, rep) {
// history.state is always initialised to null
history.state = null;
history.pushState = function (state) {
push.apply(history, arguments);
history.state = state;
};
history.replaceState = function (state) {
rep.apply(history, arguments);
history.state = state;
};
window.addEventListener('popstate', function (e) {
history.state = e.state;
}, true);
})(history.pushState, history.replaceState);
}
window.history.state is not implemented in webkit broswers currently. There is a request for it, but no steps towards implementation were done so far.
There is a project called history.js which is aiming to provide cross-compatible history management experience.
History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.
From that project, History.getState() seems to do what is requested.

Categories

Resources