diff --git a/DetectRTC.js b/DetectRTC.js
index a4735de..d48a0f4 100644
--- a/DetectRTC.js
+++ b/DetectRTC.js
@@ -1,4 +1,4 @@
-// Last time updated at Friday, January 1st, 2016, 5:04:28 PM
+// Last time updated at Saturday, January 2nd, 2016, 2:59:43 PM
// Latest file can be found here: https://cdn.webrtc-experiment.com/DetectRTC.js
@@ -36,6 +36,12 @@
var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i);
var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob);
+ var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
+ var isFirefox = typeof window.InstallTrigger !== 'undefined';
+ var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
+ var isChrome = !!window.chrome && !isOpera;
+ var isIE = !!document.documentMode && !isEdge;
+
// this one can also be used:
// https://www.websocket.org/js/stuff.js (DetectBrowser.js)
@@ -48,26 +54,31 @@
var nameOffset, verOffset, ix;
// In Opera, the true version is after 'Opera' or after 'Version'
- if ((verOffset = nAgt.indexOf('Opera')) !== -1) {
+ if (isOpera) {
browserName = 'Opera';
- fullVersion = nAgt.substring(verOffset + 6);
-
- if ((verOffset = nAgt.indexOf('Version')) !== -1) {
- fullVersion = nAgt.substring(verOffset + 8);
+ try {
+ fullVersion = navigator.userAgent.split('OPR/')[1].split(' ')[0];
+ majorVersion = fullVersion.split('.')[0];
+ } catch (e) {
+ fullVersion = '0.0.0.0';
+ majorVersion = 0;
}
}
// In MSIE, the true version is after 'MSIE' in userAgent
- else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) {
+ else if (isIE) {
+ verOffset = nAgt.indexOf('MSIE');
browserName = 'IE';
fullVersion = nAgt.substring(verOffset + 5);
}
// In Chrome, the true version is after 'Chrome'
- else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) {
+ else if (isChrome) {
+ verOffset = nAgt.indexOf('Chrome');
browserName = 'Chrome';
fullVersion = nAgt.substring(verOffset + 7);
}
// In Safari, the true version is after 'Safari' or after 'Version'
- else if ((verOffset = nAgt.indexOf('Safari')) !== -1) {
+ else if (isSafari) {
+ verOffset = nAgt.indexOf('Safari');
browserName = 'Safari';
fullVersion = nAgt.substring(verOffset + 7);
@@ -76,7 +87,8 @@
}
}
// In Firefox, the true version is after 'Firefox'
- else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) {
+ else if (isFirefox) {
+ verOffset = nAgt.indexOf('Firefox');
browserName = 'Firefox';
fullVersion = nAgt.substring(verOffset + 8);
}
@@ -116,10 +128,112 @@
return {
fullVersion: fullVersion,
version: majorVersion,
- name: browserName
+ name: browserName,
+ isPrivateBrowsing: false
};
}
+ // via: https://gist.github.com/cou929/7973956
+
+ function retry(isDone, next) {
+ var currentTrial = 0,
+ maxRetry = 50,
+ interval = 10,
+ isTimeout = false;
+ var id = window.setInterval(
+ function() {
+ if (isDone()) {
+ window.clearInterval(id);
+ next(isTimeout);
+ }
+ if (currentTrial++ > maxRetry) {
+ window.clearInterval(id);
+ isTimeout = true;
+ next(isTimeout);
+ }
+ },
+ 10
+ );
+ }
+
+ function isIE10OrLater(userAgent) {
+ var ua = userAgent.toLowerCase();
+ if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
+ return false;
+ }
+ var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
+ if (match && parseInt(match[1], 10) >= 10) {
+ return true;
+ }
+ return false;
+ }
+
+ function detectPrivateMode(callback) {
+ var isPrivate;
+
+ if (window.webkitRequestFileSystem) {
+ window.webkitRequestFileSystem(
+ window.TEMPORARY, 1,
+ function() {
+ isPrivate = false;
+ },
+ function(e) {
+ console.log(e);
+ isPrivate = true;
+ }
+ );
+ } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
+ var db;
+ try {
+ db = window.indexedDB.open('test');
+ } catch (e) {
+ isPrivate = true;
+ }
+
+ if (typeof isPrivate === 'undefined') {
+ retry(
+ function isDone() {
+ return db.readyState === 'done' ? true : false;
+ },
+ function next(isTimeout) {
+ if (!isTimeout) {
+ isPrivate = db.result ? false : true;
+ }
+ }
+ );
+ }
+ } else if (isIE10OrLater(window.navigator.userAgent)) {
+ isPrivate = false;
+ try {
+ if (!window.indexedDB) {
+ isPrivate = true;
+ }
+ } catch (e) {
+ isPrivate = true;
+ }
+ } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
+ try {
+ window.localStorage.setItem('test', 1);
+ } catch (e) {
+ isPrivate = true;
+ }
+
+ if (typeof isPrivate === 'undefined') {
+ isPrivate = false;
+ window.localStorage.removeItem('test');
+ }
+ }
+
+ retry(
+ function isDone() {
+ return typeof isPrivate !== 'undefined' ? true : false;
+ },
+ function next(isTimeout) {
+ callback(isPrivate);
+ }
+ );
+ }
+
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
@@ -165,28 +279,139 @@
}
};
- var osName = 'Unknown OS';
+ // via: http://jsfiddle.net/ChristianL/AVyND/
+ function detectDesktopOS() {
+ var unknown = '-';
- if (isMobile.any()) {
- osName = isMobile.getOsName();
- } else {
- if (navigator.appVersion.indexOf('Win') !== -1) {
- osName = 'Windows';
- }
+ var nVer = navigator.appVersion;
+ var nAgt = navigator.userAgent;
- if (navigator.appVersion.indexOf('Mac') !== -1) {
- osName = 'MacOS';
+ var os = unknown;
+ var clientStrings = [{
+ s: 'Windows 10',
+ r: /(Windows 10.0|Windows NT 10.0)/
+ }, {
+ s: 'Windows 8.1',
+ r: /(Windows 8.1|Windows NT 6.3)/
+ }, {
+ s: 'Windows 8',
+ r: /(Windows 8|Windows NT 6.2)/
+ }, {
+ s: 'Windows 7',
+ r: /(Windows 7|Windows NT 6.1)/
+ }, {
+ s: 'Windows Vista',
+ r: /Windows NT 6.0/
+ }, {
+ s: 'Windows Server 2003',
+ r: /Windows NT 5.2/
+ }, {
+ s: 'Windows XP',
+ r: /(Windows NT 5.1|Windows XP)/
+ }, {
+ s: 'Windows 2000',
+ r: /(Windows NT 5.0|Windows 2000)/
+ }, {
+ s: 'Windows ME',
+ r: /(Win 9x 4.90|Windows ME)/
+ }, {
+ s: 'Windows 98',
+ r: /(Windows 98|Win98)/
+ }, {
+ s: 'Windows 95',
+ r: /(Windows 95|Win95|Windows_95)/
+ }, {
+ s: 'Windows NT 4.0',
+ r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/
+ }, {
+ s: 'Windows CE',
+ r: /Windows CE/
+ }, {
+ s: 'Windows 3.11',
+ r: /Win16/
+ }, {
+ s: 'Android',
+ r: /Android/
+ }, {
+ s: 'Open BSD',
+ r: /OpenBSD/
+ }, {
+ s: 'Sun OS',
+ r: /SunOS/
+ }, {
+ s: 'Linux',
+ r: /(Linux|X11)/
+ }, {
+ s: 'iOS',
+ r: /(iPhone|iPad|iPod)/
+ }, {
+ s: 'Mac OS X',
+ r: /Mac OS X/
+ }, {
+ s: 'Mac OS',
+ r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/
+ }, {
+ s: 'QNX',
+ r: /QNX/
+ }, {
+ s: 'UNIX',
+ r: /UNIX/
+ }, {
+ s: 'BeOS',
+ r: /BeOS/
+ }, {
+ s: 'OS/2',
+ r: /OS\/2/
+ }, {
+ s: 'Search Bot',
+ r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/
+ }];
+ for (var id in clientStrings) {
+ var cs = clientStrings[id];
+ if (cs.r.test(nAgt)) {
+ os = cs.s;
+ break;
+ }
}
- if (navigator.appVersion.indexOf('X11') !== -1) {
- osName = 'UNIX';
+ var osVersion = unknown;
+
+ if (/Windows/.test(os)) {
+ osVersion = /Windows (.*)/.exec(os)[1];
+ os = 'Windows';
}
- if (navigator.appVersion.indexOf('Linux') !== -1) {
- osName = 'Linux';
+ switch (os) {
+ case 'Mac OS X':
+ osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1];
+ break;
+
+ case 'Android':
+ osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1];
+ break;
+
+ case 'iOS':
+ osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer);
+ osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0);
+ break;
}
+
+ return {
+ osName: os,
+ osVersion: osVersion
+ };
}
+ var osName = 'Unknown OS';
+ var osVersion = 'Unknown OS Version';
+
+ if (isMobile.any()) {
+ osName = isMobile.getOsName();
+ } else {
+ var osInfo = detectDesktopOS();
+ osName = osInfo.osName;
+ osVersion = osInfo.osVersion;
+ }
var isCanvasSupportsStreamCapturing = false;
var isVideoSupportsStreamCapturing = false;
@@ -489,6 +714,10 @@
// DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion
DetectRTC.browser = getBrowserInfo();
+ detectPrivateMode(function(isPrivateBrowsing) {
+ DetectRTC.browser.isPrivateBrowsing = !!isPrivateBrowsing;
+ });
+
// DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge
DetectRTC.browser['is' + DetectRTC.browser.name] = true;
@@ -605,7 +834,16 @@
DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported;
// -----------
- DetectRTC.osName = osName; // "osName" is defined in "detectOSName.js"
+ DetectRTC.osName = osName;
+ DetectRTC.osVersion = osVersion;
+
+ var displayResolution = '';
+ if (screen.width) {
+ var width = (screen.width) ? screen.width : '';
+ var height = (screen.height) ? screen.height : '';
+ displayResolution += '' + width + ' x ' + height;
+ }
+ DetectRTC.displayResolution = displayResolution;
// ----------
DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing;
diff --git a/DetectRTC.min.js b/DetectRTC.min.js
index ccfa4fc..00e69e3 100644
--- a/DetectRTC.min.js
+++ b/DetectRTC.min.js
@@ -1,3 +1,3 @@
-// Last time updated at Friday, January 1st, 2016, 5:04:28 PM
+// Last time updated at Saturday, January 2nd, 2016, 2:59:44 PM
-!function(){"use strict";function getBrowserInfo(){var nameOffset,verOffset,ix,nAgt=(navigator.appVersion,navigator.userAgent),browserName=navigator.appName,fullVersion=""+parseFloat(navigator.appVersion),majorVersion=parseInt(navigator.appVersion,10);return-1!==(verOffset=nAgt.indexOf("Opera"))?(browserName="Opera",fullVersion=nAgt.substring(verOffset+6),-1!==(verOffset=nAgt.indexOf("Version"))&&(fullVersion=nAgt.substring(verOffset+8))):-1!==(verOffset=nAgt.indexOf("MSIE"))?(browserName="IE",fullVersion=nAgt.substring(verOffset+5)):-1!==(verOffset=nAgt.indexOf("Chrome"))?(browserName="Chrome",fullVersion=nAgt.substring(verOffset+7)):-1!==(verOffset=nAgt.indexOf("Safari"))?(browserName="Safari",fullVersion=nAgt.substring(verOffset+7),-1!==(verOffset=nAgt.indexOf("Version"))&&(fullVersion=nAgt.substring(verOffset+8))):-1!==(verOffset=nAgt.indexOf("Firefox"))?(browserName="Firefox",fullVersion=nAgt.substring(verOffset+8)):(nameOffset=nAgt.lastIndexOf(" ")+1)<(verOffset=nAgt.lastIndexOf("/"))&&(browserName=nAgt.substring(nameOffset,verOffset),fullVersion=nAgt.substring(verOffset+1),browserName.toLowerCase()===browserName.toUpperCase()&&(browserName=navigator.appName)),isEdge&&(browserName="Edge",fullVersion=parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2],10).toString()),-1!==(ix=fullVersion.indexOf(";"))&&(fullVersion=fullVersion.substring(0,ix)),-1!==(ix=fullVersion.indexOf(" "))&&(fullVersion=fullVersion.substring(0,ix)),majorVersion=parseInt(""+fullVersion,10),isNaN(majorVersion)&&(fullVersion=""+parseFloat(navigator.appVersion),majorVersion=parseInt(navigator.appVersion,10)),{fullVersion:fullVersion,version:majorVersion,name:browserName}}function DetectLocalIPAddress(callback){DetectRTC.isWebRTCSupported&&(DetectRTC.isORTCSupported||getIPs(function(ip){callback(ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)?"Local: "+ip:"Public: "+ip)}))}function getIPs(callback){function handleCandidate(candidate){var ipRegex=/([0-9]{1,3}(\.[0-9]{1,3}){3})/,match=ipRegex.exec(candidate);if(!match)return void console.warn("Could not match IP address in",candidate);var ipAddress=match[1];void 0===ipDuplicates[ipAddress]&&callback(ipAddress),ipDuplicates[ipAddress]=!0}var ipDuplicates={},RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection,useWebKit=!!window.webkitRTCPeerConnection;if(!RTCPeerConnection){var iframe=document.getElementById("iframe");if(!iframe)throw"NOTE: you need to have an iframe in the page right above the script tag.";var win=iframe.contentWindow;RTCPeerConnection=win.RTCPeerConnection||win.mozRTCPeerConnection||win.webkitRTCPeerConnection,useWebKit=!!win.webkitRTCPeerConnection}if(RTCPeerConnection){var servers,mediaConstraints={optional:[{RtpDataChannels:!0}]};useWebKit&&(servers={iceServers:[{urls:"stun:stun.services.mozilla.com"}]},"undefined"!=typeof DetectRTC&&DetectRTC.browser.isFirefox&&DetectRTC.browser.version<=38&&(servers[0]={url:servers[0].urls}));var pc=new RTCPeerConnection(servers,mediaConstraints);pc.onicecandidate=function(ice){ice.candidate&&handleCandidate(ice.candidate.candidate)},pc.createDataChannel(""),pc.createOffer(function(result){pc.setLocalDescription(result,function(){},function(){})},function(){}),setTimeout(function(){var lines=pc.localDescription.sdp.split("\n");lines.forEach(function(line){0===line.indexOf("a=candidate:")&&handleCandidate(line)})},1e3)}}function checkDeviceSupport(callback){if(canEnumerate){if(!navigator.enumerateDevices&&window.MediaStreamTrack&&window.MediaStreamTrack.getSources&&(navigator.enumerateDevices=window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack)),!navigator.enumerateDevices&&navigator.enumerateDevices&&(navigator.enumerateDevices=navigator.enumerateDevices.bind(navigator)),!navigator.enumerateDevices)return void(callback&&callback());MediaDevices=[],audioInputDevices=[],audioOutputDevices=[],videoInputDevices=[],navigator.enumerateDevices(function(devices){devices.forEach(function(_device){var device={};for(var d in _device)device[d]=_device[d];"audio"===device.kind&&(device.kind="audioinput"),"video"===device.kind&&(device.kind="videoinput");var skip;MediaDevices.forEach(function(d){d.id===device.id&&d.kind===device.kind&&(skip=!0)}),skip||(device.deviceId||(device.deviceId=device.id),device.id||(device.id=device.deviceId),device.label?("videoinput"!==device.kind||isWebsiteHasWebcamPermissions||(isWebsiteHasWebcamPermissions=!0),"audioinput"!==device.kind||isWebsiteHasMicrophonePermissions||(isWebsiteHasMicrophonePermissions=!0)):(device.label="Please invoke getUserMedia once.","https:"!==location.protocol&&(device.label="HTTPs is required to get label of this "+device.kind+" device.")),"audioinput"===device.kind&&(hasMicrophone=!0,audioInputDevices.push(device)),"audiooutput"===device.kind&&(hasSpeakers=!0,audioOutputDevices.push(device)),"videoinput"===device.kind&&(hasWebcam=!0,videoInputDevices.push(device)),MediaDevices.push(device))}),"undefined"!=typeof DetectRTC&&(DetectRTC.MediaDevices=MediaDevices,DetectRTC.hasMicrophone=hasMicrophone,DetectRTC.hasSpeakers=hasSpeakers,DetectRTC.hasWebcam=hasWebcam,DetectRTC.isWebsiteHasWebcamPermissions=isWebsiteHasWebcamPermissions,DetectRTC.isWebsiteHasMicrophonePermissions=isWebsiteHasMicrophonePermissions,DetectRTC.audioInputDevices=audioInputDevices,DetectRTC.audioOutputDevices=audioOutputDevices,DetectRTC.videoInputDevices=videoInputDevices),callback&&callback()})}}var navigator=window.navigator;"undefined"!=typeof navigator?("undefined"!=typeof navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),"undefined"!=typeof navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia)):navigator={getUserMedia:function(){},userAgent:"Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45"};var isMobileDevice=!!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i),isEdge=!(-1===navigator.userAgent.indexOf("Edge")||!navigator.msSaveOrOpenBlob&&!navigator.msSaveBlob),isMobile={Android:function(){return navigator.userAgent.match(/Android/i)},BlackBerry:function(){return navigator.userAgent.match(/BlackBerry/i)},iOS:function(){return navigator.userAgent.match(/iPhone|iPad|iPod/i)},Opera:function(){return navigator.userAgent.match(/Opera Mini/i)},Windows:function(){return navigator.userAgent.match(/IEMobile/i)},any:function(){return isMobile.Android()||isMobile.BlackBerry()||isMobile.iOS()||isMobile.Opera()||isMobile.Windows()},getOsName:function(){var osName="Unknown OS";return isMobile.Android()&&(osName="Android"),isMobile.BlackBerry()&&(osName="BlackBerry"),isMobile.iOS()&&(osName="iOS"),isMobile.Opera()&&(osName="Opera Mini"),isMobile.Windows()&&(osName="Windows"),osName}},osName="Unknown OS";isMobile.any()?osName=isMobile.getOsName():(-1!==navigator.appVersion.indexOf("Win")&&(osName="Windows"),-1!==navigator.appVersion.indexOf("Mac")&&(osName="MacOS"),-1!==navigator.appVersion.indexOf("X11")&&(osName="UNIX"),-1!==navigator.appVersion.indexOf("Linux")&&(osName="Linux"));var isCanvasSupportsStreamCapturing=!1,isVideoSupportsStreamCapturing=!1;["captureStream","mozCaptureStream","webkitCaptureStream"].forEach(function(item){!isCanvasSupportsStreamCapturing&&item in document.createElement("canvas")&&(isCanvasSupportsStreamCapturing=!0),!isVideoSupportsStreamCapturing&&item in document.createElement("video")&&(isVideoSupportsStreamCapturing=!0)});var MediaDevices=[],audioInputDevices=[],audioOutputDevices=[],videoInputDevices=[];navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&(navigator.enumerateDevices=function(callback){navigator.mediaDevices.enumerateDevices().then(callback)});var canEnumerate=!1;"undefined"!=typeof MediaStreamTrack&&"getSources"in MediaStreamTrack?canEnumerate=!0:navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&(canEnumerate=!0);var hasMicrophone=!1,hasSpeakers=!1,hasWebcam=!1,isWebsiteHasMicrophonePermissions=!1,isWebsiteHasWebcamPermissions=!1;checkDeviceSupport();var DetectRTC=window.DetectRTC||{};DetectRTC.browser=getBrowserInfo(),DetectRTC.browser["is"+DetectRTC.browser.name]=!0;var isWebRTCSupported=(!!(window.process&&"object"==typeof window.process&&window.process.versions&&window.process.versions["node-webkit"]),!1);["RTCPeerConnection","webkitRTCPeerConnection","mozRTCPeerConnection","RTCIceGatherer"].forEach(function(item){isWebRTCSupported||item in window&&(isWebRTCSupported=!0)}),DetectRTC.isWebRTCSupported=isWebRTCSupported,DetectRTC.isORTCSupported="undefined"!=typeof RTCIceGatherer;var isScreenCapturingSupported=!1;DetectRTC.browser.isChrome&&DetectRTC.browser.version>=35?isScreenCapturingSupported=!0:DetectRTC.browser.isFirefox&&DetectRTC.browser.version>=34&&(isScreenCapturingSupported=!0),"https:"!==location.protocol&&(isScreenCapturingSupported=!1),DetectRTC.isScreenCapturingSupported=isScreenCapturingSupported;var webAudio={isSupported:!1,isCreateMediaStreamSourceSupported:!1};["AudioContext","webkitAudioContext","mozAudioContext","msAudioContext"].forEach(function(item){webAudio.isSupported||item in window&&(webAudio.isSupported=!0,"createMediaStreamSource"in window[item].prototype&&(webAudio.isCreateMediaStreamSourceSupported=!0))}),DetectRTC.isAudioContextSupported=webAudio.isSupported,DetectRTC.isCreateMediaStreamSourceSupported=webAudio.isCreateMediaStreamSourceSupported;var isRtpDataChannelsSupported=!1;DetectRTC.browser.isChrome&&DetectRTC.browser.version>31&&(isRtpDataChannelsSupported=!0),DetectRTC.isRtpDataChannelsSupported=isRtpDataChannelsSupported;var isSCTPSupportd=!1;if(DetectRTC.browser.isFirefox&&DetectRTC.browser.version>28?isSCTPSupportd=!0:DetectRTC.browser.isChrome&&DetectRTC.browser.version>25?isSCTPSupportd=!0:DetectRTC.browser.isOpera&&DetectRTC.browser.version>=11&&(isSCTPSupportd=!0),DetectRTC.isSctpDataChannelsSupported=isSCTPSupportd,DetectRTC.isMobileDevice=isMobileDevice,DetectRTC.isWebSocketsSupported="WebSocket"in window&&2===window.WebSocket.CLOSING,DetectRTC.isWebSocketsBlocked="Checking",DetectRTC.isWebSocketsSupported){var websocket=new WebSocket("wss://echo.websocket.org:443/");websocket.onopen=function(){DetectRTC.isWebSocketsBlocked=!1,DetectRTC.loadCallback&&DetectRTC.loadCallback(),websocket.close(),websocket=null},websocket.onerror=function(){DetectRTC.isWebSocketsBlocked=!0,DetectRTC.loadCallback&&DetectRTC.loadCallback()}}var isGetUserMediaSupported=!1;navigator.getUserMedia?isGetUserMediaSupported=!0:navigator.mediaDevices&&navigator.mediaDevices.getUserMedia&&(isGetUserMediaSupported=!0),DetectRTC.browser.isChrome&&DetectRTC.browser.version>=46&&"https:"!==location.protocol&&(DetectRTC.isGetUserMediaSupported="Requires HTTPs"),DetectRTC.isGetUserMediaSupported=isGetUserMediaSupported,DetectRTC.osName=osName,DetectRTC.isCanvasSupportsStreamCapturing=isCanvasSupportsStreamCapturing,DetectRTC.isVideoSupportsStreamCapturing=isVideoSupportsStreamCapturing,DetectRTC.DetectLocalIPAddress=DetectLocalIPAddress,DetectRTC.load=function(callback){this.loadCallback=callback,checkDeviceSupport(callback)},DetectRTC.MediaDevices=MediaDevices,DetectRTC.hasMicrophone=hasMicrophone,DetectRTC.hasSpeakers=hasSpeakers,DetectRTC.hasWebcam=hasWebcam,DetectRTC.isWebsiteHasWebcamPermissions=isWebsiteHasWebcamPermissions,DetectRTC.isWebsiteHasMicrophonePermissions=isWebsiteHasMicrophonePermissions,DetectRTC.audioInputDevices=audioInputDevices,DetectRTC.audioOutputDevices=audioOutputDevices,DetectRTC.videoInputDevices=videoInputDevices;var isSetSinkIdSupported=!1;"setSinkId"in document.createElement("video")&&(isSetSinkIdSupported=!0),DetectRTC.isSetSinkIdSupported=isSetSinkIdSupported;var isRTPSenderReplaceTracksSupported=!1;DetectRTC.browser.isFirefox?"getSenders"in mozRTCPeerConnection.prototype&&(isRTPSenderReplaceTracksSupported=!0):DetectRTC.browser.isChrome&&"getSenders"in webkitRTCPeerConnection.prototype&&(isRTPSenderReplaceTracksSupported=!0),DetectRTC.isRTPSenderReplaceTracksSupported=isRTPSenderReplaceTracksSupported;var isRemoteStreamProcessingSupported=!1;DetectRTC.browser.isFirefox&&DetectRTC.browser.version>38&&(isRemoteStreamProcessingSupported=!0),DetectRTC.isRemoteStreamProcessingSupported=isRemoteStreamProcessingSupported;var isApplyConstraintsSupported=!1;"undefined"!=typeof MediaStreamTrack&&"applyConstraints"in MediaStreamTrack.prototype&&(isApplyConstraintsSupported=!0),DetectRTC.isApplyConstraintsSupported=isApplyConstraintsSupported;var isMultiMonitorScreenCapturingSupported=!1;DetectRTC.browser.isFirefox&&DetectRTC.browser.version>=43&&(isMultiMonitorScreenCapturingSupported=!0),DetectRTC.isMultiMonitorScreenCapturingSupported=isMultiMonitorScreenCapturingSupported,window.DetectRTC=DetectRTC}();
\ No newline at end of file
+!function(){"use strict";function getBrowserInfo(){var nameOffset,verOffset,ix,nAgt=(navigator.appVersion,navigator.userAgent),browserName=navigator.appName,fullVersion=""+parseFloat(navigator.appVersion),majorVersion=parseInt(navigator.appVersion,10);if(isOpera){browserName="Opera";try{fullVersion=navigator.userAgent.split("OPR/")[1].split(" ")[0],majorVersion=fullVersion.split(".")[0]}catch(e){fullVersion="0.0.0.0",majorVersion=0}}else isIE?(verOffset=nAgt.indexOf("MSIE"),browserName="IE",fullVersion=nAgt.substring(verOffset+5)):isChrome?(verOffset=nAgt.indexOf("Chrome"),browserName="Chrome",fullVersion=nAgt.substring(verOffset+7)):isSafari?(verOffset=nAgt.indexOf("Safari"),browserName="Safari",fullVersion=nAgt.substring(verOffset+7),-1!==(verOffset=nAgt.indexOf("Version"))&&(fullVersion=nAgt.substring(verOffset+8))):isFirefox?(verOffset=nAgt.indexOf("Firefox"),browserName="Firefox",fullVersion=nAgt.substring(verOffset+8)):(nameOffset=nAgt.lastIndexOf(" ")+1)<(verOffset=nAgt.lastIndexOf("/"))&&(browserName=nAgt.substring(nameOffset,verOffset),fullVersion=nAgt.substring(verOffset+1),browserName.toLowerCase()===browserName.toUpperCase()&&(browserName=navigator.appName));return isEdge&&(browserName="Edge",fullVersion=parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2],10).toString()),-1!==(ix=fullVersion.indexOf(";"))&&(fullVersion=fullVersion.substring(0,ix)),-1!==(ix=fullVersion.indexOf(" "))&&(fullVersion=fullVersion.substring(0,ix)),majorVersion=parseInt(""+fullVersion,10),isNaN(majorVersion)&&(fullVersion=""+parseFloat(navigator.appVersion),majorVersion=parseInt(navigator.appVersion,10)),{fullVersion:fullVersion,version:majorVersion,name:browserName,isPrivateBrowsing:!1}}function retry(isDone,next){var currentTrial=0,maxRetry=50,isTimeout=!1,id=window.setInterval(function(){isDone()&&(window.clearInterval(id),next(isTimeout)),currentTrial++>maxRetry&&(window.clearInterval(id),isTimeout=!0,next(isTimeout))},10)}function isIE10OrLater(userAgent){var ua=userAgent.toLowerCase();if(0===ua.indexOf("msie")&&0===ua.indexOf("trident"))return!1;var match=/(?:msie|rv:)\s?([\d\.]+)/.exec(ua);return match&&parseInt(match[1],10)>=10?!0:!1}function detectPrivateMode(callback){var isPrivate;if(window.webkitRequestFileSystem)window.webkitRequestFileSystem(window.TEMPORARY,1,function(){isPrivate=!1},function(e){console.log(e),isPrivate=!0});else if(window.indexedDB&&/Firefox/.test(window.navigator.userAgent)){var db;try{db=window.indexedDB.open("test")}catch(e){isPrivate=!0}"undefined"==typeof isPrivate&&retry(function(){return"done"===db.readyState?!0:!1},function(isTimeout){isTimeout||(isPrivate=db.result?!1:!0)})}else if(isIE10OrLater(window.navigator.userAgent)){isPrivate=!1;try{window.indexedDB||(isPrivate=!0)}catch(e){isPrivate=!0}}else if(window.localStorage&&/Safari/.test(window.navigator.userAgent)){try{window.localStorage.setItem("test",1)}catch(e){isPrivate=!0}"undefined"==typeof isPrivate&&(isPrivate=!1,window.localStorage.removeItem("test"))}retry(function(){return"undefined"!=typeof isPrivate?!0:!1},function(isTimeout){callback(isPrivate)})}function detectDesktopOS(){var unknown="-",nVer=navigator.appVersion,nAgt=navigator.userAgent,os=unknown,clientStrings=[{s:"Windows 10",r:/(Windows 10.0|Windows NT 10.0)/},{s:"Windows 8.1",r:/(Windows 8.1|Windows NT 6.3)/},{s:"Windows 8",r:/(Windows 8|Windows NT 6.2)/},{s:"Windows 7",r:/(Windows 7|Windows NT 6.1)/},{s:"Windows Vista",r:/Windows NT 6.0/},{s:"Windows Server 2003",r:/Windows NT 5.2/},{s:"Windows XP",r:/(Windows NT 5.1|Windows XP)/},{s:"Windows 2000",r:/(Windows NT 5.0|Windows 2000)/},{s:"Windows ME",r:/(Win 9x 4.90|Windows ME)/},{s:"Windows 98",r:/(Windows 98|Win98)/},{s:"Windows 95",r:/(Windows 95|Win95|Windows_95)/},{s:"Windows NT 4.0",r:/(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/},{s:"Windows CE",r:/Windows CE/},{s:"Windows 3.11",r:/Win16/},{s:"Android",r:/Android/},{s:"Open BSD",r:/OpenBSD/},{s:"Sun OS",r:/SunOS/},{s:"Linux",r:/(Linux|X11)/},{s:"iOS",r:/(iPhone|iPad|iPod)/},{s:"Mac OS X",r:/Mac OS X/},{s:"Mac OS",r:/(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/},{s:"QNX",r:/QNX/},{s:"UNIX",r:/UNIX/},{s:"BeOS",r:/BeOS/},{s:"OS/2",r:/OS\/2/},{s:"Search Bot",r:/(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/}];for(var id in clientStrings){var cs=clientStrings[id];if(cs.r.test(nAgt)){os=cs.s;break}}var osVersion=unknown;switch(/Windows/.test(os)&&(osVersion=/Windows (.*)/.exec(os)[1],os="Windows"),os){case"Mac OS X":osVersion=/Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1];break;case"Android":osVersion=/Android ([\.\_\d]+)/.exec(nAgt)[1];break;case"iOS":osVersion=/OS (\d+)_(\d+)_?(\d+)?/.exec(nVer),osVersion=osVersion[1]+"."+osVersion[2]+"."+(0|osVersion[3])}return{osName:os,osVersion:osVersion}}function DetectLocalIPAddress(callback){DetectRTC.isWebRTCSupported&&(DetectRTC.isORTCSupported||getIPs(function(ip){callback(ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)?"Local: "+ip:"Public: "+ip)}))}function getIPs(callback){function handleCandidate(candidate){var ipRegex=/([0-9]{1,3}(\.[0-9]{1,3}){3})/,match=ipRegex.exec(candidate);if(!match)return void console.warn("Could not match IP address in",candidate);var ipAddress=match[1];void 0===ipDuplicates[ipAddress]&&callback(ipAddress),ipDuplicates[ipAddress]=!0}var ipDuplicates={},RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection,useWebKit=!!window.webkitRTCPeerConnection;if(!RTCPeerConnection){var iframe=document.getElementById("iframe");if(!iframe)throw"NOTE: you need to have an iframe in the page right above the script tag.";var win=iframe.contentWindow;RTCPeerConnection=win.RTCPeerConnection||win.mozRTCPeerConnection||win.webkitRTCPeerConnection,useWebKit=!!win.webkitRTCPeerConnection}if(RTCPeerConnection){var servers,mediaConstraints={optional:[{RtpDataChannels:!0}]};useWebKit&&(servers={iceServers:[{urls:"stun:stun.services.mozilla.com"}]},"undefined"!=typeof DetectRTC&&DetectRTC.browser.isFirefox&&DetectRTC.browser.version<=38&&(servers[0]={url:servers[0].urls}));var pc=new RTCPeerConnection(servers,mediaConstraints);pc.onicecandidate=function(ice){ice.candidate&&handleCandidate(ice.candidate.candidate)},pc.createDataChannel(""),pc.createOffer(function(result){pc.setLocalDescription(result,function(){},function(){})},function(){}),setTimeout(function(){var lines=pc.localDescription.sdp.split("\n");lines.forEach(function(line){0===line.indexOf("a=candidate:")&&handleCandidate(line)})},1e3)}}function checkDeviceSupport(callback){if(canEnumerate){if(!navigator.enumerateDevices&&window.MediaStreamTrack&&window.MediaStreamTrack.getSources&&(navigator.enumerateDevices=window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack)),!navigator.enumerateDevices&&navigator.enumerateDevices&&(navigator.enumerateDevices=navigator.enumerateDevices.bind(navigator)),!navigator.enumerateDevices)return void(callback&&callback());MediaDevices=[],audioInputDevices=[],audioOutputDevices=[],videoInputDevices=[],navigator.enumerateDevices(function(devices){devices.forEach(function(_device){var device={};for(var d in _device)device[d]=_device[d];"audio"===device.kind&&(device.kind="audioinput"),"video"===device.kind&&(device.kind="videoinput");var skip;MediaDevices.forEach(function(d){d.id===device.id&&d.kind===device.kind&&(skip=!0)}),skip||(device.deviceId||(device.deviceId=device.id),device.id||(device.id=device.deviceId),device.label?("videoinput"!==device.kind||isWebsiteHasWebcamPermissions||(isWebsiteHasWebcamPermissions=!0),"audioinput"!==device.kind||isWebsiteHasMicrophonePermissions||(isWebsiteHasMicrophonePermissions=!0)):(device.label="Please invoke getUserMedia once.","https:"!==location.protocol&&(device.label="HTTPs is required to get label of this "+device.kind+" device.")),"audioinput"===device.kind&&(hasMicrophone=!0,audioInputDevices.push(device)),"audiooutput"===device.kind&&(hasSpeakers=!0,audioOutputDevices.push(device)),"videoinput"===device.kind&&(hasWebcam=!0,videoInputDevices.push(device)),MediaDevices.push(device))}),"undefined"!=typeof DetectRTC&&(DetectRTC.MediaDevices=MediaDevices,DetectRTC.hasMicrophone=hasMicrophone,DetectRTC.hasSpeakers=hasSpeakers,DetectRTC.hasWebcam=hasWebcam,DetectRTC.isWebsiteHasWebcamPermissions=isWebsiteHasWebcamPermissions,DetectRTC.isWebsiteHasMicrophonePermissions=isWebsiteHasMicrophonePermissions,DetectRTC.audioInputDevices=audioInputDevices,DetectRTC.audioOutputDevices=audioOutputDevices,DetectRTC.videoInputDevices=videoInputDevices),callback&&callback()})}}var navigator=window.navigator;"undefined"!=typeof navigator?("undefined"!=typeof navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),"undefined"!=typeof navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia)):navigator={getUserMedia:function(){},userAgent:"Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45"};var isMobileDevice=!!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i),isEdge=!(-1===navigator.userAgent.indexOf("Edge")||!navigator.msSaveOrOpenBlob&&!navigator.msSaveBlob),isOpera=!!window.opera||navigator.userAgent.indexOf(" OPR/")>=0,isFirefox="undefined"!=typeof window.InstallTrigger,isSafari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,isChrome=!!window.chrome&&!isOpera,isIE=!!document.documentMode&&!isEdge,isMobile={Android:function(){return navigator.userAgent.match(/Android/i)},BlackBerry:function(){return navigator.userAgent.match(/BlackBerry/i)},iOS:function(){return navigator.userAgent.match(/iPhone|iPad|iPod/i)},Opera:function(){return navigator.userAgent.match(/Opera Mini/i)},Windows:function(){return navigator.userAgent.match(/IEMobile/i)},any:function(){return isMobile.Android()||isMobile.BlackBerry()||isMobile.iOS()||isMobile.Opera()||isMobile.Windows()},getOsName:function(){var osName="Unknown OS";return isMobile.Android()&&(osName="Android"),isMobile.BlackBerry()&&(osName="BlackBerry"),isMobile.iOS()&&(osName="iOS"),isMobile.Opera()&&(osName="Opera Mini"),isMobile.Windows()&&(osName="Windows"),osName}},osName="Unknown OS",osVersion="Unknown OS Version";if(isMobile.any())osName=isMobile.getOsName();else{var osInfo=detectDesktopOS();osName=osInfo.osName,osVersion=osInfo.osVersion}var isCanvasSupportsStreamCapturing=!1,isVideoSupportsStreamCapturing=!1;["captureStream","mozCaptureStream","webkitCaptureStream"].forEach(function(item){!isCanvasSupportsStreamCapturing&&item in document.createElement("canvas")&&(isCanvasSupportsStreamCapturing=!0),!isVideoSupportsStreamCapturing&&item in document.createElement("video")&&(isVideoSupportsStreamCapturing=!0)});var MediaDevices=[],audioInputDevices=[],audioOutputDevices=[],videoInputDevices=[];navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&(navigator.enumerateDevices=function(callback){navigator.mediaDevices.enumerateDevices().then(callback)});var canEnumerate=!1;"undefined"!=typeof MediaStreamTrack&&"getSources"in MediaStreamTrack?canEnumerate=!0:navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices&&(canEnumerate=!0);var hasMicrophone=!1,hasSpeakers=!1,hasWebcam=!1,isWebsiteHasMicrophonePermissions=!1,isWebsiteHasWebcamPermissions=!1;checkDeviceSupport();var DetectRTC=window.DetectRTC||{};DetectRTC.browser=getBrowserInfo(),detectPrivateMode(function(isPrivateBrowsing){DetectRTC.browser.isPrivateBrowsing=!!isPrivateBrowsing}),DetectRTC.browser["is"+DetectRTC.browser.name]=!0;var isWebRTCSupported=(!!(window.process&&"object"==typeof window.process&&window.process.versions&&window.process.versions["node-webkit"]),!1);["RTCPeerConnection","webkitRTCPeerConnection","mozRTCPeerConnection","RTCIceGatherer"].forEach(function(item){isWebRTCSupported||item in window&&(isWebRTCSupported=!0)}),DetectRTC.isWebRTCSupported=isWebRTCSupported,DetectRTC.isORTCSupported="undefined"!=typeof RTCIceGatherer;var isScreenCapturingSupported=!1;DetectRTC.browser.isChrome&&DetectRTC.browser.version>=35?isScreenCapturingSupported=!0:DetectRTC.browser.isFirefox&&DetectRTC.browser.version>=34&&(isScreenCapturingSupported=!0),"https:"!==location.protocol&&(isScreenCapturingSupported=!1),DetectRTC.isScreenCapturingSupported=isScreenCapturingSupported;var webAudio={isSupported:!1,isCreateMediaStreamSourceSupported:!1};["AudioContext","webkitAudioContext","mozAudioContext","msAudioContext"].forEach(function(item){webAudio.isSupported||item in window&&(webAudio.isSupported=!0,"createMediaStreamSource"in window[item].prototype&&(webAudio.isCreateMediaStreamSourceSupported=!0))}),DetectRTC.isAudioContextSupported=webAudio.isSupported,DetectRTC.isCreateMediaStreamSourceSupported=webAudio.isCreateMediaStreamSourceSupported;var isRtpDataChannelsSupported=!1;DetectRTC.browser.isChrome&&DetectRTC.browser.version>31&&(isRtpDataChannelsSupported=!0),DetectRTC.isRtpDataChannelsSupported=isRtpDataChannelsSupported;var isSCTPSupportd=!1;if(DetectRTC.browser.isFirefox&&DetectRTC.browser.version>28?isSCTPSupportd=!0:DetectRTC.browser.isChrome&&DetectRTC.browser.version>25?isSCTPSupportd=!0:DetectRTC.browser.isOpera&&DetectRTC.browser.version>=11&&(isSCTPSupportd=!0),DetectRTC.isSctpDataChannelsSupported=isSCTPSupportd,DetectRTC.isMobileDevice=isMobileDevice,DetectRTC.isWebSocketsSupported="WebSocket"in window&&2===window.WebSocket.CLOSING,DetectRTC.isWebSocketsBlocked="Checking",DetectRTC.isWebSocketsSupported){var websocket=new WebSocket("wss://echo.websocket.org:443/");websocket.onopen=function(){DetectRTC.isWebSocketsBlocked=!1,DetectRTC.loadCallback&&DetectRTC.loadCallback(),websocket.close(),websocket=null},websocket.onerror=function(){DetectRTC.isWebSocketsBlocked=!0,DetectRTC.loadCallback&&DetectRTC.loadCallback()}}var isGetUserMediaSupported=!1;navigator.getUserMedia?isGetUserMediaSupported=!0:navigator.mediaDevices&&navigator.mediaDevices.getUserMedia&&(isGetUserMediaSupported=!0),DetectRTC.browser.isChrome&&DetectRTC.browser.version>=46&&"https:"!==location.protocol&&(DetectRTC.isGetUserMediaSupported="Requires HTTPs"),DetectRTC.isGetUserMediaSupported=isGetUserMediaSupported,DetectRTC.osName=osName,DetectRTC.osVersion=osVersion;var displayResolution="";if(screen.width){var width=screen.width?screen.width:"",height=screen.height?screen.height:"";displayResolution+=""+width+" x "+height}DetectRTC.displayResolution=displayResolution,DetectRTC.isCanvasSupportsStreamCapturing=isCanvasSupportsStreamCapturing,DetectRTC.isVideoSupportsStreamCapturing=isVideoSupportsStreamCapturing,DetectRTC.DetectLocalIPAddress=DetectLocalIPAddress,DetectRTC.load=function(callback){this.loadCallback=callback,checkDeviceSupport(callback)},DetectRTC.MediaDevices=MediaDevices,DetectRTC.hasMicrophone=hasMicrophone,DetectRTC.hasSpeakers=hasSpeakers,DetectRTC.hasWebcam=hasWebcam,DetectRTC.isWebsiteHasWebcamPermissions=isWebsiteHasWebcamPermissions,DetectRTC.isWebsiteHasMicrophonePermissions=isWebsiteHasMicrophonePermissions,DetectRTC.audioInputDevices=audioInputDevices,DetectRTC.audioOutputDevices=audioOutputDevices,DetectRTC.videoInputDevices=videoInputDevices;var isSetSinkIdSupported=!1;"setSinkId"in document.createElement("video")&&(isSetSinkIdSupported=!0),DetectRTC.isSetSinkIdSupported=isSetSinkIdSupported;var isRTPSenderReplaceTracksSupported=!1;DetectRTC.browser.isFirefox?"getSenders"in mozRTCPeerConnection.prototype&&(isRTPSenderReplaceTracksSupported=!0):DetectRTC.browser.isChrome&&"getSenders"in webkitRTCPeerConnection.prototype&&(isRTPSenderReplaceTracksSupported=!0),DetectRTC.isRTPSenderReplaceTracksSupported=isRTPSenderReplaceTracksSupported;var isRemoteStreamProcessingSupported=!1;DetectRTC.browser.isFirefox&&DetectRTC.browser.version>38&&(isRemoteStreamProcessingSupported=!0),DetectRTC.isRemoteStreamProcessingSupported=isRemoteStreamProcessingSupported;var isApplyConstraintsSupported=!1;"undefined"!=typeof MediaStreamTrack&&"applyConstraints"in MediaStreamTrack.prototype&&(isApplyConstraintsSupported=!0),DetectRTC.isApplyConstraintsSupported=isApplyConstraintsSupported;var isMultiMonitorScreenCapturingSupported=!1;DetectRTC.browser.isFirefox&&DetectRTC.browser.version>=43&&(isMultiMonitorScreenCapturingSupported=!0),DetectRTC.isMultiMonitorScreenCapturingSupported=isMultiMonitorScreenCapturingSupported,window.DetectRTC=DetectRTC}();
\ No newline at end of file
diff --git a/Gruntfile.js b/Gruntfile.js
index b9f0aec..27e2aaa 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -22,7 +22,9 @@ module.exports = function(grunt) {
'dev/head.js',
'dev/common.js',
'dev/getBrowserInfo.js',
+ 'dev/detectPrivateBrowsing.js',
'dev/isMobile.js',
+ 'dev/detectDesktopOS.js',
'dev/detectOSName.js',
'dev/detectCaptureStream.js',
'dev/DetectLocalIPAddress.js',
@@ -54,6 +56,7 @@ module.exports = function(grunt) {
},
jsbeautifier: {
files: [
+ 'dev/*.js',
'DetectRTC.js',
'Gruntfile.js'
],
diff --git a/README.md b/README.md
index 60745ec..c4fbcb0 100644
--- a/README.md
+++ b/README.md
@@ -69,17 +69,17 @@ http://localhost:9001
```javascript
DetectRTC.load(function() {
- // DetectRTC.hasWebcam (has webcam device!)
- // DetectRTC.hasMicrophone (has microphone device!)
- // DetectRTC.hasSpeakers (has speakers!)
- // DetectRTC.isScreenCapturingSupported
- // DetectRTC.isSctpDataChannelsSupported
- // DetectRTC.isRtpDataChannelsSupported
- // DetectRTC.isAudioContextSupported
- // DetectRTC.isWebRTCSupported
- // DetectRTC.isDesktopCapturingSupported
- // DetectRTC.isMobileDevice
- // DetectRTC.isWebSocketsSupported
+ DetectRTC.hasWebcam (has webcam device!)
+ DetectRTC.hasMicrophone (has microphone device!)
+ DetectRTC.hasSpeakers (has speakers!)
+ DetectRTC.isScreenCapturingSupported
+ DetectRTC.isSctpDataChannelsSupported
+ DetectRTC.isRtpDataChannelsSupported
+ DetectRTC.isAudioContextSupported
+ DetectRTC.isWebRTCSupported
+ DetectRTC.isDesktopCapturingSupported
+ DetectRTC.isMobileDevice
+ DetectRTC.isWebSocketsSupported
DetectRTC.isWebsiteHasWebcamPermissions // getUserMedia allowed for HTTPs domain in Chrome?
DetectRTC.isWebsiteHasMicrophonePermissions // getUserMedia allowed for HTTPs domain in Chrome?
@@ -88,21 +88,24 @@ DetectRTC.load(function() {
DetectRTC.audioOutputDevices // speakers
DetectRTC.videoInputDevices // cameras
- // DetectRTC.osName
+ DetectRTC.osName
+ DetectRTC.osVersion
- // DetectRTC.browser.name === 'Edge' || 'Chrome' || 'Firefox'
- // DetectRTC.browser.version
- // DetectRTC.browser.isChrome
- // DetectRTC.browser.isFirefox
- // DetectRTC.browser.isOpera
- // DetectRTC.browser.isIE
- // DetectRTC.browser.isSafari
- // DetectRTC.browser.isEdge
-
- // DetectRTC.isCanvasSupportsStreamCapturing
- // DetectRTC.isVideoSupportsStreamCapturing
-
- // DetectRTC.DetectLocalIPAddress(callback)
+ DetectRTC.browser.name === 'Edge' || 'Chrome' || 'Firefox'
+ DetectRTC.browser.version
+ DetectRTC.browser.isChrome
+ DetectRTC.browser.isFirefox
+ DetectRTC.browser.isOpera
+ DetectRTC.browser.isIE
+ DetectRTC.browser.isSafari
+ DetectRTC.browser.isEdge
+
+ DetectRTC.browser.isPrivateBrowsing // incognito or private modes
+
+ DetectRTC.isCanvasSupportsStreamCapturing
+ DetectRTC.isVideoSupportsStreamCapturing
+
+ DetectRTC.DetectLocalIPAddress(callback)
});
```
diff --git a/bower.json b/bower.json
index c34c24f..315dec0 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "detectrtc",
- "version": "1.2.4",
+ "version": "1.2.5",
"authors": [
{
"name": "Muaz Khan",
diff --git a/dev/CheckDeviceSupport.js b/dev/CheckDeviceSupport.js
index 5c826a9..c3a0cf7 100644
--- a/dev/CheckDeviceSupport.js
+++ b/dev/CheckDeviceSupport.js
@@ -16,11 +16,9 @@ if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
var canEnumerate = false;
/*global MediaStreamTrack:true */
-if(typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) {
+if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) {
canEnumerate = true;
-}
-
-else if(navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) {
+} else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) {
canEnumerate = true;
}
@@ -34,7 +32,7 @@ var isWebsiteHasWebcamPermissions = false;
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices
// todo: switch to enumerateDevices when landed in canary.
function checkDeviceSupport(callback) {
- if(!canEnumerate) {
+ if (!canEnumerate) {
return;
}
@@ -98,7 +96,7 @@ function checkDeviceSupport(callback) {
if (!device.label) {
device.label = 'Please invoke getUserMedia once.';
- if(location.protocol !== 'https:') {
+ if (location.protocol !== 'https:') {
device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.';
}
} else {
@@ -131,7 +129,7 @@ function checkDeviceSupport(callback) {
MediaDevices.push(device);
});
- if(typeof DetectRTC !== 'undefined') {
+ if (typeof DetectRTC !== 'undefined') {
// to sync latest outputs
DetectRTC.MediaDevices = MediaDevices;
DetectRTC.hasMicrophone = hasMicrophone;
diff --git a/dev/DetectLocalIPAddress.js b/dev/DetectLocalIPAddress.js
index 91149bc..6e2ab10 100644
--- a/dev/DetectLocalIPAddress.js
+++ b/dev/DetectLocalIPAddress.js
@@ -1,10 +1,10 @@
// via: https://github.com/diafygi/webrtc-ips
function DetectLocalIPAddress(callback) {
- if(!DetectRTC.isWebRTCSupported) {
+ if (!DetectRTC.isWebRTCSupported) {
return;
}
-
- if(DetectRTC.isORTCSupported) {
+
+ if (DetectRTC.isORTCSupported) {
return;
}
@@ -45,7 +45,7 @@ function getIPs(callback) {
if (!RTCPeerConnection) {
return;
}
-
+
//minimal requirements for data connection
var mediaConstraints = {
optional: [{
@@ -66,7 +66,7 @@ function getIPs(callback) {
}]
};
- if(typeof DetectRTC !== 'undefined' && DetectRTC.browser.isFirefox && DetectRTC.browser.version <= 38) {
+ if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isFirefox && DetectRTC.browser.version <= 38) {
servers[0] = {
url: servers[0].urls
};
@@ -80,12 +80,12 @@ function getIPs(callback) {
//match just the IP address
var ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
var match = ipRegex.exec(candidate);
- if (!match) {
+ if (!match) {
console.warn('Could not match IP address in', candidate);
return;
}
var ipAddress = match[1];
-
+
//remove duplicates
if (ipDuplicates[ipAddress] === undefined) {
callback(ipAddress);
diff --git a/dev/DetectRTC.js b/dev/DetectRTC.js
index 8f788ec..a0ce507 100644
--- a/dev/DetectRTC.js
+++ b/dev/DetectRTC.js
@@ -4,6 +4,10 @@ var DetectRTC = window.DetectRTC || {};
// DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion
DetectRTC.browser = getBrowserInfo();
+detectPrivateMode(function(isPrivateBrowsing) {
+ DetectRTC.browser.isPrivateBrowsing = !!isPrivateBrowsing;
+});
+
// DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge
DetectRTC.browser['is' + DetectRTC.browser.name] = true;
@@ -12,13 +16,13 @@ var isNodeWebkit = !!(window.process && (typeof window.process === 'object') &&
// --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1.
var isWebRTCSupported = false;
['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function(item) {
- if(isWebRTCSupported) {
- return;
- }
+ if (isWebRTCSupported) {
+ return;
+ }
- if(item in window) {
- isWebRTCSupported = true;
- }
+ if (item in window) {
+ isWebRTCSupported = true;
+ }
});
DetectRTC.isWebRTCSupported = isWebRTCSupported;
@@ -27,36 +31,35 @@ DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined';
// --------- Detect if system supports screen capturing API
var isScreenCapturingSupported = false;
-if(DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) {
- isScreenCapturingSupported = true;
-}
-else if(DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) {
- isScreenCapturingSupported = true;
+if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) {
+ isScreenCapturingSupported = true;
+} else if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) {
+ isScreenCapturingSupported = true;
}
-if(location.protocol !== 'https:') {
- isScreenCapturingSupported = false;
+if (location.protocol !== 'https:') {
+ isScreenCapturingSupported = false;
}
DetectRTC.isScreenCapturingSupported = isScreenCapturingSupported;
// --------- Detect if WebAudio API are supported
var webAudio = {
- isSupported: false,
- isCreateMediaStreamSourceSupported: false
+ isSupported: false,
+ isCreateMediaStreamSourceSupported: false
};
['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function(item) {
- if (webAudio.isSupported) {
+ if (webAudio.isSupported) {
return;
}
- if(item in window) {
- webAudio.isSupported = true;
+ if (item in window) {
+ webAudio.isSupported = true;
- if('createMediaStreamSource' in window[item].prototype) {
- webAudio.isCreateMediaStreamSourceSupported = true;
- }
- }
+ if ('createMediaStreamSource' in window[item].prototype) {
+ webAudio.isCreateMediaStreamSourceSupported = true;
+ }
+ }
});
DetectRTC.isAudioContextSupported = webAudio.isSupported;
DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported;
@@ -64,20 +67,18 @@ DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourc
// ---------- Detect if SCTP/RTP channels are supported.
var isRtpDataChannelsSupported = false;
-if(DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) {
- isRtpDataChannelsSupported = true;
+if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) {
+ isRtpDataChannelsSupported = true;
}
DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported;
var isSCTPSupportd = false;
-if(DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) {
- isSCTPSupportd = true;
-}
-else if(DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) {
- isSCTPSupportd = true;
-}
-else if(DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) {
- isSCTPSupportd = true;
+if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) {
+ isSCTPSupportd = true;
+} else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) {
+ isSCTPSupportd = true;
+} else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) {
+ isSCTPSupportd = true;
}
DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd;
@@ -90,41 +91,49 @@ DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is define
DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING;
DetectRTC.isWebSocketsBlocked = 'Checking';
-if(DetectRTC.isWebSocketsSupported) {
- var websocket = new WebSocket('wss://echo.websocket.org:443/');
- websocket.onopen = function() {
- DetectRTC.isWebSocketsBlocked = false;
-
- if(DetectRTC.loadCallback) {
- DetectRTC.loadCallback();
- }
- websocket.close();
- websocket = null;
- };
- websocket.onerror = function() {
- DetectRTC.isWebSocketsBlocked = true;
-
- if(DetectRTC.loadCallback) {
- DetectRTC.loadCallback();
- }
- };
+if (DetectRTC.isWebSocketsSupported) {
+ var websocket = new WebSocket('wss://echo.websocket.org:443/');
+ websocket.onopen = function() {
+ DetectRTC.isWebSocketsBlocked = false;
+
+ if (DetectRTC.loadCallback) {
+ DetectRTC.loadCallback();
+ }
+ websocket.close();
+ websocket = null;
+ };
+ websocket.onerror = function() {
+ DetectRTC.isWebSocketsBlocked = true;
+
+ if (DetectRTC.loadCallback) {
+ DetectRTC.loadCallback();
+ }
+ };
}
// ------
var isGetUserMediaSupported = false;
-if(navigator.getUserMedia) {
- isGetUserMediaSupported = true;
+if (navigator.getUserMedia) {
+ isGetUserMediaSupported = true;
+} else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
+ isGetUserMediaSupported = true;
}
-else if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia){
- isGetUserMediaSupported = true;
-}
-if(DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && location.protocol !== 'https:') {
- DetectRTC.isGetUserMediaSupported = 'Requires HTTPs';
+if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && location.protocol !== 'https:') {
+ DetectRTC.isGetUserMediaSupported = 'Requires HTTPs';
}
DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported;
// -----------
-DetectRTC.osName = osName; // "osName" is defined in "detectOSName.js"
+DetectRTC.osName = osName;
+DetectRTC.osVersion = osVersion;
+
+var displayResolution = '';
+if (screen.width) {
+ var width = (screen.width) ? screen.width : '';
+ var height = (screen.height) ? screen.height : '';
+ displayResolution += '' + width + ' x ' + height;
+}
+DetectRTC.displayResolution = displayResolution;
// ----------
DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing;
@@ -154,31 +163,30 @@ DetectRTC.videoInputDevices = videoInputDevices;
// ------
var isSetSinkIdSupported = false;
-if('setSinkId' in document.createElement('video')) {
- isSetSinkIdSupported = true;
+if ('setSinkId' in document.createElement('video')) {
+ isSetSinkIdSupported = true;
}
DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported;
// -----
var isRTPSenderReplaceTracksSupported = false;
-if(DetectRTC.browser.isFirefox/*&& DetectRTC.browser.version > 39*/) {
- /*global mozRTCPeerConnection:true */
- if('getSenders' in mozRTCPeerConnection.prototype) {
- isRTPSenderReplaceTracksSupported = true;
- }
-}
-else if(DetectRTC.browser.isChrome) {
- /*global webkitRTCPeerConnection:true */
- if('getSenders' in webkitRTCPeerConnection.prototype) {
- isRTPSenderReplaceTracksSupported = true;
- }
+if (DetectRTC.browser.isFirefox /*&& DetectRTC.browser.version > 39*/ ) {
+ /*global mozRTCPeerConnection:true */
+ if ('getSenders' in mozRTCPeerConnection.prototype) {
+ isRTPSenderReplaceTracksSupported = true;
+ }
+} else if (DetectRTC.browser.isChrome) {
+ /*global webkitRTCPeerConnection:true */
+ if ('getSenders' in webkitRTCPeerConnection.prototype) {
+ isRTPSenderReplaceTracksSupported = true;
+ }
}
DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported;
//------
var isRemoteStreamProcessingSupported = false;
-if(DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) {
- isRemoteStreamProcessingSupported = true;
+if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) {
+ isRemoteStreamProcessingSupported = true;
}
DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported;
@@ -186,16 +194,16 @@ DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported;
var isApplyConstraintsSupported = false;
/*global MediaStreamTrack:true */
-if(typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) {
- isApplyConstraintsSupported = true;
+if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) {
+ isApplyConstraintsSupported = true;
}
DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported;
//-------
var isMultiMonitorScreenCapturingSupported = false;
-if(DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) {
- // version 43 merely supports platforms for multi-monitors
- // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing.
- isMultiMonitorScreenCapturingSupported = true;
+if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) {
+ // version 43 merely supports platforms for multi-monitors
+ // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing.
+ isMultiMonitorScreenCapturingSupported = true;
}
DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported;
diff --git a/dev/common.js b/dev/common.js
index 89eb46e..a37ed45 100644
--- a/dev/common.js
+++ b/dev/common.js
@@ -11,7 +11,7 @@ if (typeof navigator !== 'undefined') {
}
} else {
navigator = {
- getUserMedia: function() { },
+ getUserMedia: function() {},
userAgent: 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45'
};
}
diff --git a/dev/detectCaptureStream.js b/dev/detectCaptureStream.js
index 71b7ede..e727365 100644
--- a/dev/detectCaptureStream.js
+++ b/dev/detectCaptureStream.js
@@ -1,12 +1,11 @@
-
var isCanvasSupportsStreamCapturing = false;
var isVideoSupportsStreamCapturing = false;
['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function(item) {
- if(!isCanvasSupportsStreamCapturing && item in document.createElement('canvas')) {
+ if (!isCanvasSupportsStreamCapturing && item in document.createElement('canvas')) {
isCanvasSupportsStreamCapturing = true;
}
- if(!isVideoSupportsStreamCapturing && item in document.createElement('video')) {
+ if (!isVideoSupportsStreamCapturing && item in document.createElement('video')) {
isVideoSupportsStreamCapturing = true;
}
});
diff --git a/dev/detectDesktopOS.js b/dev/detectDesktopOS.js
new file mode 100644
index 0000000..84ce71d
--- /dev/null
+++ b/dev/detectDesktopOS.js
@@ -0,0 +1,122 @@
+// via: http://jsfiddle.net/ChristianL/AVyND/
+function detectDesktopOS() {
+ var unknown = '-';
+
+ var nVer = navigator.appVersion;
+ var nAgt = navigator.userAgent;
+
+ var os = unknown;
+ var clientStrings = [{
+ s: 'Windows 10',
+ r: /(Windows 10.0|Windows NT 10.0)/
+ }, {
+ s: 'Windows 8.1',
+ r: /(Windows 8.1|Windows NT 6.3)/
+ }, {
+ s: 'Windows 8',
+ r: /(Windows 8|Windows NT 6.2)/
+ }, {
+ s: 'Windows 7',
+ r: /(Windows 7|Windows NT 6.1)/
+ }, {
+ s: 'Windows Vista',
+ r: /Windows NT 6.0/
+ }, {
+ s: 'Windows Server 2003',
+ r: /Windows NT 5.2/
+ }, {
+ s: 'Windows XP',
+ r: /(Windows NT 5.1|Windows XP)/
+ }, {
+ s: 'Windows 2000',
+ r: /(Windows NT 5.0|Windows 2000)/
+ }, {
+ s: 'Windows ME',
+ r: /(Win 9x 4.90|Windows ME)/
+ }, {
+ s: 'Windows 98',
+ r: /(Windows 98|Win98)/
+ }, {
+ s: 'Windows 95',
+ r: /(Windows 95|Win95|Windows_95)/
+ }, {
+ s: 'Windows NT 4.0',
+ r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/
+ }, {
+ s: 'Windows CE',
+ r: /Windows CE/
+ }, {
+ s: 'Windows 3.11',
+ r: /Win16/
+ }, {
+ s: 'Android',
+ r: /Android/
+ }, {
+ s: 'Open BSD',
+ r: /OpenBSD/
+ }, {
+ s: 'Sun OS',
+ r: /SunOS/
+ }, {
+ s: 'Linux',
+ r: /(Linux|X11)/
+ }, {
+ s: 'iOS',
+ r: /(iPhone|iPad|iPod)/
+ }, {
+ s: 'Mac OS X',
+ r: /Mac OS X/
+ }, {
+ s: 'Mac OS',
+ r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/
+ }, {
+ s: 'QNX',
+ r: /QNX/
+ }, {
+ s: 'UNIX',
+ r: /UNIX/
+ }, {
+ s: 'BeOS',
+ r: /BeOS/
+ }, {
+ s: 'OS/2',
+ r: /OS\/2/
+ }, {
+ s: 'Search Bot',
+ r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/
+ }];
+ for (var id in clientStrings) {
+ var cs = clientStrings[id];
+ if (cs.r.test(nAgt)) {
+ os = cs.s;
+ break;
+ }
+ }
+
+ var osVersion = unknown;
+
+ if (/Windows/.test(os)) {
+ osVersion = /Windows (.*)/.exec(os)[1];
+ os = 'Windows';
+ }
+
+ switch (os) {
+ case 'Mac OS X':
+ osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1];
+ break;
+
+ case 'Android':
+ osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1];
+ break;
+
+ case 'iOS':
+ osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer);
+ osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0);
+ break;
+ }
+
+ return {
+ osName: os,
+ osVersion: osVersion
+ };
+}
diff --git a/dev/detectOSName.js b/dev/detectOSName.js
index 97a3a95..94ec9fd 100644
--- a/dev/detectOSName.js
+++ b/dev/detectOSName.js
@@ -1,21 +1,10 @@
var osName = 'Unknown OS';
-
-if(isMobile.any()) {
- osName = isMobile.getOsName();}
-else {
- if (navigator.appVersion.indexOf('Win') !== -1) {
- osName = 'Windows';
- }
-
- if (navigator.appVersion.indexOf('Mac') !== -1) {
- osName = 'MacOS';
- }
-
- if (navigator.appVersion.indexOf('X11') !== -1) {
- osName = 'UNIX';
- }
-
- if (navigator.appVersion.indexOf('Linux') !== -1) {
- osName = 'Linux';
- }
+var osVersion = 'Unknown OS Version';
+
+if (isMobile.any()) {
+ osName = isMobile.getOsName();
+} else {
+ var osInfo = detectDesktopOS();
+ osName = osInfo.osName;
+ osVersion = osInfo.osVersion;
}
diff --git a/dev/detectPrivateBrowsing.js b/dev/detectPrivateBrowsing.js
new file mode 100644
index 0000000..7af7dce
--- /dev/null
+++ b/dev/detectPrivateBrowsing.js
@@ -0,0 +1,100 @@
+// via: https://gist.github.com/cou929/7973956
+
+function retry(isDone, next) {
+ var currentTrial = 0,
+ maxRetry = 50,
+ interval = 10,
+ isTimeout = false;
+ var id = window.setInterval(
+ function() {
+ if (isDone()) {
+ window.clearInterval(id);
+ next(isTimeout);
+ }
+ if (currentTrial++ > maxRetry) {
+ window.clearInterval(id);
+ isTimeout = true;
+ next(isTimeout);
+ }
+ },
+ 10
+ );
+}
+
+function isIE10OrLater(userAgent) {
+ var ua = userAgent.toLowerCase();
+ if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
+ return false;
+ }
+ var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
+ if (match && parseInt(match[1], 10) >= 10) {
+ return true;
+ }
+ return false;
+}
+
+function detectPrivateMode(callback) {
+ var isPrivate;
+
+ if (window.webkitRequestFileSystem) {
+ window.webkitRequestFileSystem(
+ window.TEMPORARY, 1,
+ function() {
+ isPrivate = false;
+ },
+ function(e) {
+ console.log(e);
+ isPrivate = true;
+ }
+ );
+ } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
+ var db;
+ try {
+ db = window.indexedDB.open('test');
+ } catch (e) {
+ isPrivate = true;
+ }
+
+ if (typeof isPrivate === 'undefined') {
+ retry(
+ function isDone() {
+ return db.readyState === 'done' ? true : false;
+ },
+ function next(isTimeout) {
+ if (!isTimeout) {
+ isPrivate = db.result ? false : true;
+ }
+ }
+ );
+ }
+ } else if (isIE10OrLater(window.navigator.userAgent)) {
+ isPrivate = false;
+ try {
+ if (!window.indexedDB) {
+ isPrivate = true;
+ }
+ } catch (e) {
+ isPrivate = true;
+ }
+ } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
+ try {
+ window.localStorage.setItem('test', 1);
+ } catch (e) {
+ isPrivate = true;
+ }
+
+ if (typeof isPrivate === 'undefined') {
+ isPrivate = false;
+ window.localStorage.removeItem('test');
+ }
+ }
+
+ retry(
+ function isDone() {
+ return typeof isPrivate !== 'undefined' ? true : false;
+ },
+ function next(isTimeout) {
+ callback(isPrivate);
+ }
+ );
+}
diff --git a/dev/getBrowserInfo.js b/dev/getBrowserInfo.js
index c96c1dd..c95b5a5 100644
--- a/dev/getBrowserInfo.js
+++ b/dev/getBrowserInfo.js
@@ -1,6 +1,12 @@
var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i);
var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob);
+var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
+var isFirefox = typeof window.InstallTrigger !== 'undefined';
+var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
+var isChrome = !!window.chrome && !isOpera;
+var isIE = !!document.documentMode && !isEdge;
+
// this one can also be used:
// https://www.websocket.org/js/stuff.js (DetectBrowser.js)
@@ -13,26 +19,31 @@ function getBrowserInfo() {
var nameOffset, verOffset, ix;
// In Opera, the true version is after 'Opera' or after 'Version'
- if ((verOffset = nAgt.indexOf('Opera')) !== -1) {
+ if (isOpera) {
browserName = 'Opera';
- fullVersion = nAgt.substring(verOffset + 6);
-
- if ((verOffset = nAgt.indexOf('Version')) !== -1) {
- fullVersion = nAgt.substring(verOffset + 8);
+ try {
+ fullVersion = navigator.userAgent.split('OPR/')[1].split(' ')[0];
+ majorVersion = fullVersion.split('.')[0];
+ } catch (e) {
+ fullVersion = '0.0.0.0';
+ majorVersion = 0;
}
}
// In MSIE, the true version is after 'MSIE' in userAgent
- else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) {
+ else if (isIE) {
+ verOffset = nAgt.indexOf('MSIE');
browserName = 'IE';
fullVersion = nAgt.substring(verOffset + 5);
}
// In Chrome, the true version is after 'Chrome'
- else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) {
+ else if (isChrome) {
+ verOffset = nAgt.indexOf('Chrome');
browserName = 'Chrome';
fullVersion = nAgt.substring(verOffset + 7);
}
// In Safari, the true version is after 'Safari' or after 'Version'
- else if ((verOffset = nAgt.indexOf('Safari')) !== -1) {
+ else if (isSafari) {
+ verOffset = nAgt.indexOf('Safari');
browserName = 'Safari';
fullVersion = nAgt.substring(verOffset + 7);
@@ -41,7 +52,8 @@ function getBrowserInfo() {
}
}
// In Firefox, the true version is after 'Firefox'
- else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) {
+ else if (isFirefox) {
+ verOffset = nAgt.indexOf('Firefox');
browserName = 'Firefox';
fullVersion = nAgt.substring(verOffset + 8);
}
@@ -81,6 +93,7 @@ function getBrowserInfo() {
return {
fullVersion: fullVersion,
version: majorVersion,
- name: browserName
+ name: browserName,
+ isPrivateBrowsing: false
};
}
diff --git a/dev/head.js b/dev/head.js
index 3962a79..b42875e 100644
--- a/dev/head.js
+++ b/dev/head.js
@@ -12,4 +12,4 @@
(function() {
-'use strict';
+ 'use strict';
diff --git a/dev/isMobile.js b/dev/isMobile.js
index 1fd05a3..d61a233 100644
--- a/dev/isMobile.js
+++ b/dev/isMobile.js
@@ -19,23 +19,23 @@ var isMobile = {
},
getOsName: function() {
var osName = 'Unknown OS';
- if(isMobile.Android()) {
+ if (isMobile.Android()) {
osName = 'Android';
}
- if(isMobile.BlackBerry()) {
+ if (isMobile.BlackBerry()) {
osName = 'BlackBerry';
}
- if(isMobile.iOS()) {
+ if (isMobile.iOS()) {
osName = 'iOS';
}
- if(isMobile.Opera()) {
+ if (isMobile.Opera()) {
osName = 'Opera Mini';
}
- if(isMobile.Windows()) {
+ if (isMobile.Windows()) {
osName = 'Windows';
}
diff --git a/index.html b/index.html
index 6e0a98c..20645af 100755
--- a/index.html
+++ b/index.html
@@ -49,6 +49,22 @@
display: inline-block;
width: 8em;
}
+
+ .info-div {
+ display: inline-block;
+ vertical-align: middle;
+ background-repeat: no-repeat;
+ background-image: url(https://i.imgur.com/tnMN9tG.png?1);
+ background-position: center center;
+ width: 32px;
+ height: 32px;
+ }
+
+ .inline-pre {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ }
+
+
+
+
+
+
-
+
@@ -99,11 +121,15 @@
+
+
+
+
Print & Save As Image
- Detect WebRTC!
+ DetectRTC!
@@ -115,7 +141,7 @@ Detect WebRTC!
function appendTR(firstValue, secondValue) {
var tr = document.createElement('tr');
- tr.innerHTML = '' + firstValue + ' ' + secondValue + ' ';
+ tr.innerHTML = '' + firstValue + ' ' + secondValue + ' ';
browserFeaturesTable.appendChild(tr);
}
@@ -123,26 +149,72 @@ Detect WebRTC!
return value == true ? 'Yep' : value == false ? 'Nope' : value;
}
+ function getInfoDiv(id) {
+ return '
';
+ }
+
+ var output = '';
+
DetectRTC.load(function() {
browserFeaturesTable.innerHTML = '';
- appendTR('System has Speakers?', printVal(DetectRTC.hasSpeakers));
- appendTR('System has Microphone?', printVal(DetectRTC.hasMicrophone));
- appendTR('System has Webcam?', printVal(DetectRTC.hasWebcam));
+ appendTR('Operating System', printVal(DetectRTC.osName) + ' ' + printVal(DetectRTC.osVersion));
+ appendTR('Browser', printVal(DetectRTC.browser.name) + ' ' + printVal(DetectRTC.browser.fullVersion) + ' Private browsing? ' + printVal(DetectRTC.browser.isPrivateBrowsing));
+
+ appendTR('Display resolutions', printVal(DetectRTC.displayResolution));
+
+ output = printVal(DetectRTC.hasSpeakers);
+ if(DetectRTC.audioOutputDevices.length) {
+ output += ' Found speaker devices: ' + DetectRTC.audioOutputDevices.length;
+
+ var labels = [];
+ DetectRTC.audioOutputDevices.forEach(function(device) {
+ labels.push(device.label);
+ });
+
+ output += '' + labels.join(' ') + '
';
+ }
+ appendTR('System has Speakers?', output);
+
+ output = printVal(DetectRTC.hasMicrophone);
+ if(DetectRTC.audioInputDevices.length) {
+ output += ' Found microphone devices: ' + DetectRTC.audioInputDevices.length;
+
+ var labels = [];
+ DetectRTC.audioInputDevices.forEach(function(device) {
+ labels.push(device.label);
+ });
+
+ output += '' + labels.join(' ') + '
';
+ }
+ appendTR('System has Microphone?', output);
+
+ output = printVal(DetectRTC.hasWebcam);
+ if(DetectRTC.videoInputDevices.length) {
+ output += ' Found webcam devices: ' + DetectRTC.videoInputDevices.length;
+
+ var labels = [];
+ DetectRTC.videoInputDevices.forEach(function(device) {
+ labels.push(device.label);
+ });
+
+ output += '' + labels.join(' ') + '
';
+ }
+ appendTR('System has Webcam?', output);
appendTR('Website has webcam permissions?', printVal(DetectRTC.isWebsiteHasWebcamPermissions));
appendTR('Website has mcirophone permissions?', printVal(DetectRTC.isWebsiteHasMicrophonePermissions));
appendTR('Browser allows getUserMedia on this page?', printVal(DetectRTC.isGetUserMediaSupported));
- appendTR('Can you change output audio devices?', printVal(DetectRTC.isSetSinkIdSupported));
+ appendTR('Can you change output audio devices?' + getInfoDiv('infoIcon-set-sink-id'), printVal(DetectRTC.isSetSinkIdSupported));
- appendTR('Can you change camera resolutions without making new getUserMedia request?', printVal(DetectRTC.isApplyConstraintsSupported));
+ appendTR('Can you change camera resolutions without making new getUserMedia request?' + getInfoDiv('infoIcon-apply-constraints'), printVal(DetectRTC.isApplyConstraintsSupported));
appendTR('Browser Supports WebRTC (Either 1.0 or 1.1)?', printVal(DetectRTC.isWebRTCSupported));
appendTR('Browser Supports ORTC (WebRTC 1.1)?', printVal(DetectRTC.isORTCSupported));
- appendTR('Can you replace tracks without renegotiating peers?', printVal(DetectRTC.isRTPSenderReplaceTracksSupported));
+ appendTR('Can you replace tracks without renegotiating peers?' + getInfoDiv('infoIcon-replace-tracks'), printVal(DetectRTC.isRTPSenderReplaceTracksSupported));
appendTR('Can your browser record remote audio or process remote audio stream in WebAudio API?', printVal(DetectRTC.isRemoteStreamProcessingSupported));
@@ -159,9 +231,7 @@ Detect WebRTC!
appendTR('Is it a mobile device?', printVal(DetectRTC.isMobileDevice));
appendTR('Browser Supports WebSockets?', printVal(DetectRTC.isWebSocketsSupported));
-
- document.getElementById('welcome').innerHTML = DetectRTC.osName + ': ' + DetectRTC.browser.name + ' (version: ' + DetectRTC.browser.version + ')';
-
+
var rightSide = '';
// you can even use "DetectRTC.audioInputDevices", "audioOutputDevices" and "videoInputDevices"
@@ -184,6 +254,7 @@ Detect WebRTC!
appendTR('Is Browser Supports Video Capturing from Canvas?', printVal(DetectRTC.isVideoSupportsStreamCapturing));
appendTR('Is Browser Supports Stream Capturing from Video?', printVal(DetectRTC.isVideoSupportsStreamCapturing));
+ /*
DetectRTC.DetectLocalIPAddress(function(ipAddress) {
if (ipAddress.indexOf('Local') !== -1) {
appendTR('Your Local IP Address', ipAddress);
@@ -191,6 +262,69 @@ Detect WebRTC!
appendTR('Your Public IP Address', ipAddress);
}
});
+ */
+
+ document.getElementById('infoIcon-set-sink-id').onclick = function() {
+ var pre = this.parentNode.querySelector('pre');
+ if(pre) {
+ pre.parentNode.removeChild(pre);
+ return;
+ }
+
+ pre = document.createElement('pre');
+ pre.className = 'sh_javascript inline-pre';
+ pre.innerHTML += '\
+var secondarySpeakers = DetectRTC.audioInputDevices[1]; \
+if(secondarySpeakers) { \
+ videoElement.setSinkId(secondarySpeakers.deviceId); \
+}';
+ this.parentNode.appendChild(pre);
+ pre.focus();
+ sh_highlightDocument();
+ };
+
+ document.getElementById('infoIcon-apply-constraints').onclick = function() {
+ var pre = this.parentNode.querySelector('pre');
+ if(pre) {
+ pre.parentNode.removeChild(pre);
+ return;
+ }
+
+ pre = document.createElement('pre');
+ pre.className = 'sh_javascript inline-pre';
+ pre.innerHTML += '\
+var secondaryCamera = DetectRTC.videoInputDevices[1]; \
+if(secondaryCamera) { \
+ var videoConstraints = { \
+ deviceId: secondaryCamera.deviceId \
+ }; \
+ \
+ oldMediaStream.getVideoTracks().forEach(function(track) { \
+ track.applyConstraints(videoConstraints); \
+ }); \
+}';
+ this.parentNode.appendChild(pre);
+ pre.focus();
+ sh_highlightDocument();
+ };
+
+ document.getElementById('infoIcon-replace-tracks').onclick = function() {
+ var pre = this.parentNode.querySelector('pre');
+ if(pre) {
+ pre.parentNode.removeChild(pre);
+ return;
+ }
+
+ pre = document.createElement('pre');
+ pre.className = 'sh_javascript inline-pre';
+ pre.innerHTML += '\
+var newTrack = newMediaStream.getVideoTracks()[0]; \
+var rtpSenders = rtcPeerConnection.getSenders()[0]; \
+rtpSenders.replaceTrack(newTrack);';
+ this.parentNode.appendChild(pre);
+ pre.focus();
+ sh_highlightDocument();
+ };
});
document.getElementById('save').onclick = function() {
@@ -289,43 +423,50 @@
-
+
<script src="https://cdn.WebRTC-Experiment.com/DetectRTC.js"></script>
-
+
DetectRTC.load(function() {
- // DetectRTC.hasWebcam (has webcam device!)
- // DetectRTC.hasMicrophone (has microphone device!)
- // DetectRTC.isWebsiteHasWebcamPermissions
- // DetectRTC.isWebsiteHasMicrophonePermissions
- // DetectRTC.hasSpeakers (has speakers!)
- // DetectRTC.isScreenCapturingSupported
- // DetectRTC.isSctpDataChannelsSupported
- // DetectRTC.isRtpDataChannelsSupported
- // DetectRTC.isAudioContextSupported
- // DetectRTC.isWebRTCSupported
- // DetectRTC.isDesktopCapturingSupported
- // DetectRTC.isMobileDevice
- // DetectRTC.isWebSocketsSupported
-
- // DetectRTC.audioInputDevices --- microphones
- // DetectRTC.audioOutputDevices --- speakers
- // DetectRTC.videoInputDevices --- cameras
- // DetectRTC.MediaDevices --- all devices
+ DetectRTC.hasWebcam (has webcam device!)
+ DetectRTC.hasMicrophone (has microphone device!)
+ DetectRTC.hasSpeakers (has speakers!)
+ DetectRTC.isScreenCapturingSupported
+ DetectRTC.isSctpDataChannelsSupported
+ DetectRTC.isRtpDataChannelsSupported
+ DetectRTC.isAudioContextSupported
+ DetectRTC.isWebRTCSupported
+ DetectRTC.isDesktopCapturingSupported
+ DetectRTC.isMobileDevice
+ DetectRTC.isWebSocketsSupported
+
+ DetectRTC.isWebsiteHasWebcamPermissions // getUserMedia allowed for HTTPs domain in Chrome?
+ DetectRTC.isWebsiteHasMicrophonePermissions // getUserMedia allowed for HTTPs domain in Chrome?
+
+ DetectRTC.audioInputDevices // microphones
+ DetectRTC.audioOutputDevices // speakers
+ DetectRTC.videoInputDevices // cameras
- // DetectRTC.osName
+ DetectRTC.osName
+ DetectRTC.osVersion
- // DetectRTC.browser.name
- // DetectRTC.browser.version
- // DetectRTC.browser.isChrome
- // DetectRTC.browser.isFirefox
- // DetectRTC.browser.isOpera
- // DetectRTC.browser.isIE
- // DetectRTC.browser.isSafari
-
- // DetectRTC.DetectLocalIPAddress(callback)
+ DetectRTC.browser.name === 'Edge' || 'Chrome' || 'Firefox'
+ DetectRTC.browser.version
+ DetectRTC.browser.isChrome
+ DetectRTC.browser.isFirefox
+ DetectRTC.browser.isOpera
+ DetectRTC.browser.isIE
+ DetectRTC.browser.isSafari
+ DetectRTC.browser.isEdge
+
+ DetectRTC.browser.isPrivateBrowsing // incognito or private modes
+
+ DetectRTC.isCanvasSupportsStreamCapturing
+ DetectRTC.isVideoSupportsStreamCapturing
+
+ DetectRTC.DetectLocalIPAddress(callback)
});
diff --git a/package.json b/package.json
index 21b5ed1..6a86e91 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "detectrtc",
"preferGlobal": true,
- "version": "1.2.4",
+ "version": "1.2.5",
"author": {
"name": "Muaz Khan",
"email": "muazkh@gmail.com",