I'm working on a snippet for check the Firefox OS version used.
Now i'm using the gecko version in the user agent string (is different in every version of Firefox OS) but it's not a professional solution often is simple.
The gist:
https://gist.github.com/Mte90/11087561
Any suggestion?
The gist is updated with the better solution for check the Firefox OS version
Not very nice way to do this but you could parse the user agent
function convertVersionNumber(ver) {
var hashVersion = {
'18.0': '1.0.1',
'18.1': '1.1',
'26.0': '1.2',
'28.0': '1.3',
'30.0': '1.4',
'32.0': '1.5'
}
var rver = ver;
var sStr = ver.substring(0, 4);
if (hashVersion[sStr]) {
rver = hashVersion[sStr];
}
return (rver);
} function getVersion() {
if (navigator.userAgent.match(/(mobile|tablet)/i)) {
var ffVersionArray = (navigator.userAgent.match(/Firefox\/([\d]+\.[\w]?\.?[\w]+)/));
if (ffVersionArray.length === 2) {
return (convertVersionNumber(ffVersionArray[1]));
}
}
return (null);
}
This is the only way I know to detect the version of Firefox OS right now. If it's also to see if a feature exists, I would, again, use feature detection instead of version detection.
if (navigator.connection) //Network Information API
if (navigator.battery) // Battery Status API
If these if return true, it's because those features are available on the version the user run your application on.
In /gaia/profile/settings.json can you read the version?
Or use the settings api to read and compare:
deviceinfo.platform_version
Firefox OS Settings List
Related
We have a testcase to test indexeddb with different browsers and OS.
It is just simple test:
open database, add some data, retrieve some data
That is it. It is working perfectly in Chrome (39), Firefox (new versions), MacBook Pro with OSX 9.5, Android based Browsers.
When we try with Ipad3 with iOS 8, the page is not doing anything. And we can not see any errors too.
Any ideas, how to fix the problem?
We used indexeddb.shim.js file that suppose to help, but still does not work.
if (!window.indexedDB) {
window.alert("Your browser doesn't support a stable version of IndexedDB.")
}
var request = indexedDB.open("kitta db1");
request.onupgradeneeded = function() {
//create Store and etc
};
request.onsuccess = function() {
db = request.result;
};
The error in iOS 8:
Type Error: null is not an Object on the line:
var request = indexedDB.open("kitta db1");
Any idea how can I fix it?
It looks like the variable indexedDB is null. The polyfill does this:
e.indexedDB=e.indexedDB||e.webkitIndexedDB||e.mozIndexedDB||e.oIndexedDB||e.msIndexedDB
So it is setting the variable to one of those values. If those values are all undefined/null, then the indexedDB variable remains null.
A simple way to test whether any of these variations have values (less Microsoft, Opera, and Mozilla) would be something like the following:
console.log('indexedDB: ', indexedDB);
console.log('webkitIndexedDB: ', webkitIndexedDB);
If webkitIndexedDB is undefined and indexedDB is undefined, then iOS apparently does not support indexedDB.
A simple search on caniuse.com says that indexedDB on iOS8 and iOS8.1 is supported but buggy.
I'm trying to use Javascript to detect if a web browser supports websockets, but using only feature-based detection, I'm getting false positives, so I added a user agent test to throw out Android devices instead, which I'm not happy about. I have a Samsung Galaxy Tab 2, and here's my detection code:
var isSupported = (("WebSocket" in window && window.WebSocket != undefined) ||
("MozWebSocket" in window));
/* This line exists because my Galaxy Tab 2 would otherwise appear to have support. */
if (isSupported && navigator.userAgent.indexOf("Android") > 0)
isSupported = false;
if (isSupported)
document.write("Your browser supports websockets");
else
document.write("Your browser does not support websockets");
This code seems to work with IE, Firefox, Safari (including iPhone/iPad), and Chrome. However, the feature-based check is returning true when I use the default browser of my Samsung Galaxy Tab 2, which is incorrect because that browser does not actually support websockets. Furthermore, I don't know how many other Android devices have this same issue, so at the moment, this is the best solution I'm aware of for detection.
Is there a better way to detect websocket support other than what I'm doing? I do realize that workarounds exist for Android, such as using a different browser, which means my user agent detection code as-is would not be a good thing. My goal is to not have to rely on the user agent in the first place.
Any suggestions?
This is the shortest solution and is used by Modernizr. Simply add this to your code
supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in window;
then you can use it by running
if (supportsWebSockets) {
// run web socket code
}
I think the Modernizr library is what you are looking for: http://modernizr.com/
Once you include the library on your page, you can use a simple check like:
if(Modernizr.websockets){
// socket to me baby
}
This page comes on top in google search.
In year 2016 cutting the mustard for modern WebSockets implementation (no prefixes such as MozWebSocket) would be
if (
'WebSocket' in window && window.WebSocket.CLOSING === 2
) {
// supported
}
http://www.w3.org/TR/websockets/#the-websocket-interface
after reading #gzost's response.. I started tinkering.. since nothing else can properly detect WS's on my android phone... even websocket.org says i have it, but then fails to connect.
Anyways, try this workaround.. seems to properly detect it on/off with chrome, FF, safari and the default android browser.
var has_ws=0;
function checkWebSocket(){
try{
websocket = new WebSocket("ws:websocket.org");
websocket.close('');
}catch(e){ //throws code 15 if has socket to me babies
has_ws=1;
}
}
$(document).ready(function(){
checkWebSocket();
});
None of the above answers by itself was sufficient in my tests. The following code seems to be working fine:
function nll( o ) { return CS.undefined === typeof o || null === o; }
// ...
function check_ws_object() {
try {
var websocket = new WebSocket( "wss://echo.websocket.org" );
return true;
} catch ( e ) { ; }
return false;
}
//
function check_support() {
if ( !( WebSocket in window ) ) {
if ( nll( window.WebSocket) ) {
if ( !this.check_ws_object() ) {
alert( "This browser doesn't support HTML5 Web Sockets!" );
return false;
}
}
}
return true;
},
The above tests are sorted, so that the faster ones come first.
I need to create the database in blackberry os 5.0 using javascript for phonegap application.
var mydb=false;
function onLoad() {
try {
if (!window.openDatabase) {
alert('not supported');
}
else {
var shortName = 'phonegap';
var version = '0.9.4';
var displayName = 'PhoneGap Test Database';
var maxSize = 65536; // in bytes
mydb = openDatabase(shortName, version, displayName, maxSize);
}
}
}
It is moving to if condition and only the alert is displayed.But the database is not getting created.Please tell me what's wrong in this code.
Thanks in advance!
You have your answer, no? If it's moving to the if and only the alert is being displayed, it's never going to go to the else and create the database, but there's a good reason for that. The if tests for support. Apparently, BlackBerry OS 5.0 doesn't support databases. You can check this page for a list of polyfills to support HTML5 features in less capable browsers.
BlackBerry 5 is not supported by PhoneGap's openDatabase API.
http://docs.phonegap.com/phonegap_storage_storage.md.html
Supported Platforms
Android
BlackBerry WebWorks (OS 6.0 and higher)
iPhone
HI Recently I had the same problem and I found a cool solution :D
BB5 have a "Google Gear" Iternaly in the browser to do that
if (window.openDatabase){
//HTML5
}else{
//try google GEARS
if (window.google || google.gears){
_DB = google.gears.factory.create('beta.database', '1.0');
_DB.open('MyLocalDB');
}
}
We are using software that registers its own protocol. We can run application from browser then by link like:
customprotocol://do_this.
but is there a way to check is such custom protocol supported by user`s system? If not we would like to ask user to install software first.
E.g:
if (canHandle ('customprotocol')) {
// run software
}
else {
// ask to install
}
Edit
I know about protocolLong property but it works only in IE.
Unfortunately, there's no easy way of achieving this. There's certainly no method of pre-determining whether or not the protocol handler is installed.
Internet Explorer, as you mentioned, has the protocolLong property but I'm having trouble getting it to return anything other than "Unknown Protocol" for all custom protocol handlers -- if anyone knows how to get IE to return the correct value please let me know so I can update this section. The best solution I've found with IE is to append to the user agent string or install a browser extension along with your app that exposes a Javascript accessible property.
Firefox is by far the easiest of the major browsers, as it will allow you to try and catch a navigation attempt that fails. The error object returned contains a name property whose value is NS_ERROR_UNKNOWN_PROTOCOL:
try {
iframe.contentWindow.location.href = "randomprotocolstring://test/";
} catch(e) {
if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL")
window.location = "/download/";
}
Firefox will pop up with its own alert box:
Firefox doesn't know how to open this address, because the protocol (randomprotocolstring) isn't associated with any program.
Once you close this box, the catch block will execute and you have a working fallback.
Second is Opera, which allows you to employ the laws of predictability to detect success of a custom protocol link clicked. If a custom protocol click works, the page will remain the same location. If there is no handler installed, Opera will navigate to an error page. This makes it rather easy to detect with an iframe:
iframe.contentWindow.location = "randomprotocolstring://test/";
window.setTimeout(function () {
try {
alert(ifr.contentWindow.location);
} catch (e) { window.location = "/download/"; }
}, 0);
The setTimeout here is to make sure we check the location after navigation. It's important to note that if you try and access the page, Opera throws a ReferenceException (cross-domain security error). That doesn't matter, because all we need to know is that the location changed from about:blank, so a try...catch works just fine.
Chrome officially sucks with this regard. If a custom protocol handler fails, it does absolutely zip. If the handler works... you guessed it... it does absolutely zip. No way of differentiating between the two, I'm afraid.
I haven't tested Safari but I fear it would be the same as Chrome.
You're welcome to try the test code I wrote whilst investigating this (I had a vested interest in it myself). It's Opera and Firefox cross compatible but currently does nothing in IE and Chrome.
Here's an off-the-wall answer: Install an unusual font at the time you register your custom protocol. Then use javascript to check whether that font exists, using something like this.
Sure it's a hack, but unlike the other answers it would work across browsers and operating systems.
Just to chime in with our own experience, we used FireBreath to create a simple cross-platform plugin. Once installed this plugin registers a mime type which can be detected from the browser javascript after a page refresh. Detection of the mime type indicates that the protocol handler is installed.
if(IE) { //This bastard always needs special treatment
try {
var flash = new ActiveXObject("Plugin.Name");
} catch (e) {
//not installed
}
else { //firefox,chrome,opera
navigator.plugins.refresh(true);
var mimeTypes = navigator.mimeTypes;
var mime = navigator.mimeTypes['application/x-plugin-name'];
if(mime) {
//installed
} else {
//not installed
}
}
Internet Explorer 10 on Windows 8 introduced the very useful navigator.msLaunchUri method for launching a custom protocol URL and detecting the success or failure. For example:
if (typeof (navigator.msLaunchUri) == typeof (Function)) {
navigator.msLaunchUri(witchUrl,
function () { /* Success */ },
function () { /* Failure */ showError(); });
return;
}
Windows 7 / IE 9 and below support conditional comments as suggested by #mark-kahn.
For Internet Explorer, the best solution I've found is to use Conditionl comments & Version Vector (application must write something to registry while installing protocol, see http://msdn.microsoft.com/en-us/library/ms537512.aspx#Version_Vectors). protocolLong doesn't work for custom protocol.
On mobile you can use an embedded iframe to auto switch between the custom protocol and a known one (web or app store), see https://gist.github.com/2662899
I just want to explain more previous Mark's answer (some people did not understand for example user7892745).
1) When you launch you web-page or web-application it checks for an unusual font (something like Chinese Konfuciuz font http://www.fontspace.com/apostrophic-lab/konfuciuz).
Below is the code of sample web-page with function which checks the font (called isFontAvailable):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
/**
* Checks if a font is available to be used on a web page.
*
* #param {String} fontName The name of the font to check
* #return {Boolean}
* #license MIT
* #copyright Sam Clarke 2013
* #author Sam Clarke <sam#samclarke.com>
*/
(function (document) {
var width;
var body = document.body;
var container = document.createElement('span');
container.innerHTML = Array(100).join('wi');
container.style.cssText = [
'position:absolute',
'width:auto',
'font-size:128px',
'left:-99999px'
].join(' !important;');
var getWidth = function (fontFamily) {
container.style.fontFamily = fontFamily;
body.appendChild(container);
width = container.clientWidth;
body.removeChild(container);
return width;
};
// Pre compute the widths of monospace, serif & sans-serif
// to improve performance.
var monoWidth = getWidth('monospace');
var serifWidth = getWidth('serif');
var sansWidth = getWidth('sans-serif');
window.isFontAvailable = function (font) {
return monoWidth !== getWidth(font + ',monospace') ||
sansWidth !== getWidth(font + ',sans-serif') ||
serifWidth !== getWidth(font + ',serif');
};
})(document);
function isProtocolAvailable()
{
if (isFontAvailable('Konfuciuz'))
{
return true;
}
else
{
return false;
}
}
function checkProtocolAvail()
{
if (isProtocolAvailable())
{
alert('Custom protocol is available!');
}
else
{
alert('Please run executable to install protocol!');
}
}
</script>
<h3>Check if custom protocol was installed or not</h3>
<pre>
<input type="button" value="Check if custom protocol was installed!" onclick="checkProtocolAvail()">
</body>
</html>
2) First time when user opens this page, font will not be installed so he will get a message saying "Please run executable to install custom protocol...".
3) He will run executable which will install the font. Your exe can just copy the font file (in my case it is KONFUC__.ttf) into C:\Windows directory or using a code like this (example on Delphi):
// Adding the font ..
AddFontResource(PChar('XXXFont.TTF'));
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
4) After that, when user runs web app again, he gets "Custom protocol is available!" message because font was installed this time.
Tested on Google Chrome, Internet Explorer and Firefox - working great!
For Firefox, most of articles I googled, including Andy E 's answer here, and this gist Cross-browser implementation of navigator.msLaunchUri or https://github.com/ismailhabib/custom-protocol-detection using
iframe.contentWindow.location.href = uri
But it has stopped working since Firefox 64, e.g here https://github.com/ismailhabib/custom-protocol-detection/issues/37 also confirmed that.
So FF 64+ I found I can either using Chrome's method, blurHandler or using the post there https://github.com/ismailhabib/custom-protocol-detection/issues/37#issuecomment-617962659
try {
iframe.contentWindow.location.href = uri;
setTimeout(function () {
try {
if (iframe.contentWindow.location.protocol === "about:") {
successCb();
} else {
failCb();
}
} catch (e) {
if (e.name === "NS_ERROR_UNKNOWN_PROTOCOL" ||
e.name === "NS_ERROR_FAILURE" || e.name === "SecurityError") {
failCb();
}
}
}, 500);
} catch (e) {
if (e.name === "NS_ERROR_UNKNOWN_PROTOCOL" || e.name === "NS_ERROR_FAILURE"
|| e.name === "SecurityError") {
failCb();
}
}
For Chrome 86+ it also fails to work, check my answer for details Detect Custom Protocol handler in chrome 86
BTW, I find most of answers/articles are outdated in some cases.
Basically, I'm wanting to figure out the best way to check the user's JRE version on a web page. I have a link to a JNLP file that I only want to display if the user's JRE version is 1.6 or greater. I've been playing around with the deployJava JavaScript code (http://java.sun.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html) and have gotten it to work in every browser but Safari (by using deployJava.versionCheck). For whatever reason, Safari doesn't give the most updated JRE version number - I found this out by displaying the value of the getJREs() function. I have 1.6.0_20 installed, which is displayed in every other browser, but Safari keeps saying that only 1.5.0 is currently installed.
I've also tried using the createWebStartLaunchButtonEx() function and specifying '1.6.0' as the minimum version, but when I click the button nothing happens (in any browser).
Any suggestions?
FYI: Here's my code --
if (deployJava.versionCheck('1.6+')) {
var dir = location.href.substring(0,location.href.lastIndexOf('/')+1);
var url = dir + "tmaj.jnlp";
deployJava.createWebStartLaunchButton(url, '1.6.0');
} else {
var noticeText = document.createTextNode("In order to use TMAJ, you must visit the following link to download the latest version of Java:");
document.getElementById('jreNotice').appendChild(noticeText);
var link = document.createElement('a');
link.setAttribute('href', 'http://www.java.com/en/download/index.jsp');
var linkText = document.createTextNode("Download Latest Version of Java");
link.appendChild(linkText);
document.getElementById('jreDownloadLink').appendChild(link);
}
Probably the best bet would be to check the navigator.plugins array.
Here is a quick example that works in Chrome/Firefox. As far as I know, Internet Explorer does not provide access to the plugins array.
function getJavaVersion() {
var j, matches;
for (j = 0;j < navigator.plugins.length;j += 1) {
matches = navigator.plugins[j].description.match(/Java [^\d]+(\d+\.?\d*\.?\d*_?\d*)/i);
if (matches !== null) {
return matches[1];
}
}
return null;
};
console.log(getJavaVersion()); // => 1.6.0_16
Not sure if it helps you but you can specify the minimum jre version as a clause in the jnlp file. Webstart will not launch your app if the requirement is not met.
See the tag.
Also, have a look at
How to check JRE version prior to launch?