From dcd94813bf6ca8df191e623c67bfecc6d77ed8e4 Mon Sep 17 00:00:00 2001 From: patricksnape Date: Wed, 20 Feb 2013 10:16:50 +0000 Subject: [PATCH 1/5] Fixes #257 - User account switcher broken Adds new RESUtils function to delete cookies in a cross browser way. Includes deleting the reddit_session cookie which fixes the account switcher. Tested on Chome, Firefox, Opera and Safari. Could probably do with more testing before merging --- Chrome/background.js | 10 ++++++++-- Chrome/manifest.json | 1 + XPI/lib/main.js | 15 ++++++++------- lib/reddit_enhancement_suite.user.js | 26 +++++++++++++++++++++----- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Chrome/background.js b/Chrome/background.js index a5f580b597..8caa683516 100644 --- a/Chrome/background.js +++ b/Chrome/background.js @@ -90,6 +90,13 @@ XHRCache = { chrome.extension.onMessage.addListener( function(request, sender, sendResponse) { switch(request.requestType) { + case 'deleteCookie': + // Get chrome cookie handler + if (!chrome.cookies) { + chrome.cookies = chrome.experimental.cookies; + } + chrome.cookies.remove({'url': 'http://reddit.com', 'name': request.cname}); + break; case 'GM_xmlhttpRequest': if (request.aggressiveCache || XHRCache.forceCache) { var cachedResult = XHRCache.check(request.url); @@ -98,12 +105,11 @@ chrome.extension.onMessage.addListener( return; } } + var xhr = new XMLHttpRequest(); xhr.open(request.method, request.url, true); if (request.method == "POST") { xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - // xhr.setRequestHeader("Content-length", request.data.length); - // xhr.setRequestHeader("Connection", "close"); } xhr.onreadystatechange = function(a) { if (xhr.readyState == 4) { diff --git a/Chrome/manifest.json b/Chrome/manifest.json index 0e31e2dd3f..65bec649e4 100644 --- a/Chrome/manifest.json +++ b/Chrome/manifest.json @@ -36,6 +36,7 @@ "128": "icon128.png" }, "permissions": [ + "cookies", "tabs", "history", "http://redditenhancementsuite.com/", diff --git a/XPI/lib/main.js b/XPI/lib/main.js index 8ff6d336f4..62e8653c24 100644 --- a/XPI/lib/main.js +++ b/XPI/lib/main.js @@ -7,16 +7,14 @@ var tabs = require("tabs"); var ss = require("simple-storage"); // require chrome allows us to use XPCOM objects... -// var {Cc, Cu, Cr} = require("chrome"); -const {Cc,Ci} = require("chrome"); -// from XPCOM, use the NSIGlobalHistory2 service... -// var historyService = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsIGlobalHistory2); -var historyService = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIGlobalHistory2) +const {Cc,Ci,Cu} = require("chrome"); +var historyService = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIGlobalHistory2); +// Cookie manager for new API login +var cookieManager = Cc["@mozilla.org/cookiemanager;1"].getService().QueryInterface(Ci.nsICookieManager2); // this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI... function makeURI(aURL, aOriginCharset, aBaseURI) { - var ioService = Cc["@mozilla.org/network/io-service;1"] - .getService(Ci.nsIIOService); + var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); return ioService.newURI(aURL, aOriginCharset, aBaseURI); } @@ -129,6 +127,9 @@ pageMod.PageMod({ worker.on('message', function(data) { var request = data; switch(request.requestType) { + case 'deleteCookie': + cookieManager.remove('.reddit.com', request.cname, '/', false); + break; case 'GM_xmlhttpRequest': var responseObj = { XHRID: request.XHRID, diff --git a/lib/reddit_enhancement_suite.user.js b/lib/reddit_enhancement_suite.user.js index c430447adb..a554b62bee 100644 --- a/lib/reddit_enhancement_suite.user.js +++ b/lib/reddit_enhancement_suite.user.js @@ -1774,6 +1774,22 @@ var RESUtils = { } return true; }, + deleteCookie : function(cookieName) { + var requestJSON = { + requestType: 'deleteCookie', + cname: cookieName + }; + + if (typeof(chrome) != 'undefined') { + chrome.extension.sendMessage(requestJSON); + } else if (typeof(safari) != 'undefined') { + document.cookie = cookieName + '=null;expires=' + new Date() +'; path=/;domain=reddit.com'; + } else if (typeof(opera) != 'undefined') { + document.cookie = cookieName + '=null;expires=' + new Date() +'; path=/;domain=reddit.com'; + } else if (typeof(self.on) == 'function') { // Firefox + self.postMessage(requestJSON); + } + }, openLinkInNewTab: function(url, focus) { if (typeof(chrome) != 'undefined') { var thisJSON = { @@ -12225,7 +12241,6 @@ modules['accountSwitcher'] = { RESUtils.addCSS('#RESAccountSwitcherDropdown { min-width: 110px; width: auto; display: none; position: absolute; z-index: 999; }'); RESUtils.addCSS('#RESAccountSwitcherDropdown li.accountName { height: auto; line-height: 20px; padding-top: 2px; padding-bottom: 2px; }'); if (this.options.dropDownStyle.value == 'alien') { - // this.alienIMG = ''; RESUtils.addCSS('#RESAccountSwitcherIcon { cursor: pointer; margin-left: 3px; display: inline-block; width: 12px; vertical-align: middle; height: 16px; background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAPCAYAAAAyPTUwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkQ3NTExRkExOEYzNTExRTFBNjgzQzhEOUY2QzU2MUNFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkQ3NTExRkEyOEYzNTExRTFBNjgzQzhEOUY2QzU2MUNFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RDc1MTFGOUY4RjM1MTFFMUE2ODNDOEQ5RjZDNTYxQ0UiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RDc1MTFGQTA4RjM1MTFFMUE2ODNDOEQ5RjZDNTYxQ0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6W3fJJAAAB4ElEQVR42mJgwA4YgdgSiJUUFRXDW1tbL7Kzswsw4VDMBcRXgfgeMzPzJx4eHn4gG0MtSICPjY3NF0jLoCtglJWV1eDm5rZmZWX9k5ZbWGFmYqwhwM3B8Pn7T4bzl6/enzNlQsfrV68+srKxPWHMz89/ZmJiIunn58fA9+YKAwMHHwODlA4Dw4fHDAzPbzD8VLRhWLNuPcOzp0//MEhJSaU/f/HyPxhkyf//3xsEYa+s/f8/nOn//19f/n/98fO/jo5ONwMfH5/S27dvwfL/nt/5//8rhP3/z7f//55cgzD//PkPdK4F2N3x8fFLv3///v/d56//l69a83///v3/V65e8//+k+f///79+7+4uPgAUB0zIywUgNZEZmVlzRMTE2P78OEDA9DTDN++ffs3c+bMglOnTk0HqvkDC5p/L168+P7582cmaWlpBhUVFQZ5eXkGoPUMDx8+BMn/QQ5C1vb29r+HDx/+jwwuXLjwv7e39z8wWHkYkAOdk5OT4cePHygx9OXLF7BzgPpQo05NTS2mp6fnO7LJc+bM+a2np1eKNUFISEg0gEIFHIz//v3X1dWdDU1UYMAMYzg7O8eUlpYmXLly5dtfFm6h40cO3DU2NhYBphOea9euHQOpAQgwAKMW+Z5mJFvIAAAAAElFTkSuQmCC); }'); RESUtils.addCSS('#RESAccountSwitcherIconOverlay { cursor: pointer; position: absolute; display: none; width: 11px; height: 22px; background-position: 2px 3px; padding-left: 2px; padding-right: 2px; padding-top: 3px; border: 1px solid #336699; border-bottom: 1px solid #5f99cf; background-color: #5f99cf; border-radius: 3px 3px 0px 0px; z-index: 100; background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAPCAYAAAAyPTUwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkQ3NTExRkExOEYzNTExRTFBNjgzQzhEOUY2QzU2MUNFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkQ3NTExRkEyOEYzNTExRTFBNjgzQzhEOUY2QzU2MUNFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RDc1MTFGOUY4RjM1MTFFMUE2ODNDOEQ5RjZDNTYxQ0UiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RDc1MTFGQTA4RjM1MTFFMUE2ODNDOEQ5RjZDNTYxQ0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6W3fJJAAAB4ElEQVR42mJgwA4YgdgSiJUUFRXDW1tbL7Kzswsw4VDMBcRXgfgeMzPzJx4eHn4gG0MtSICPjY3NF0jLoCtglJWV1eDm5rZmZWX9k5ZbWGFmYqwhwM3B8Pn7T4bzl6/enzNlQsfrV68+srKxPWHMz89/ZmJiIunn58fA9+YKAwMHHwODlA4Dw4fHDAzPbzD8VLRhWLNuPcOzp0//MEhJSaU/f/HyPxhkyf//3xsEYa+s/f8/nOn//19f/n/98fO/jo5ONwMfH5/S27dvwfL/nt/5//8rhP3/z7f//55cgzD//PkPdK4F2N3x8fFLv3///v/d56//l69a83///v3/V65e8//+k+f///79+7+4uPgAUB0zIywUgNZEZmVlzRMTE2P78OEDA9DTDN++ffs3c+bMglOnTk0HqvkDC5p/L168+P7582cmaWlpBhUVFQZ5eXkGoPUMDx8+BMn/QQ5C1vb29r+HDx/+jwwuXLjwv7e39z8wWHkYkAOdk5OT4cePHygx9OXLF7BzgPpQo05NTS2mp6fnO7LJc+bM+a2np1eKNUFISEg0gEIFHIz//v3X1dWdDU1UYMAMYzg7O8eUlpYmXLly5dtfFm6h40cO3DU2NhYBphOea9euHQOpAQgwAKMW+Z5mJFvIAAAAAElFTkSuQmCC); }'); } else { @@ -12372,7 +12387,6 @@ modules['accountSwitcher'] = { break; } } - // console.log('request with user: ' +username+ ' -- passwd: ' + password); var loginUrl = 'https://ssl.reddit.com/api/login'; // unfortunately, due to 3rd party cookie issues, none of the below browsers work with ssl. if (typeof(opera) != 'undefined') { @@ -12382,6 +12396,10 @@ modules['accountSwitcher'] = { } else if (typeof(safari) != 'undefined') { loginUrl = 'http://'+location.hostname+'/api/login'; } + + // Remove old session cookie + RESUtils.deleteCookie('reddit_session'); + GM_xmlhttpRequest({ method: "POST", url: loginUrl, @@ -12390,8 +12408,6 @@ modules['accountSwitcher'] = { "Content-Type": "application/x-www-form-urlencoded" }, onload: function(response) { - // console.log(response.responseText); - // var data = JSON.parse(response.responseText); var badData = false; try { var data = JSON.parse(response.responseText); @@ -12399,7 +12415,7 @@ modules['accountSwitcher'] = { var data = {}; badData = true; } - // var errorCheck = data.jquery[10][3][0]; + var error = /WRONG_PASSWORD/; var rateLimit = /RATELIMIT/; if (badData) { From 9f9db80af5cc45200c4e69dd11a1508101e046f6 Mon Sep 17 00:00:00 2001 From: patricksnape Date: Wed, 20 Feb 2013 17:25:41 +0000 Subject: [PATCH 2/5] Currently we have a bug when a user isn't logged in which was added in commit 96f814e825713d7f4e6d8cd170a9e22391bc47fb --- lib/reddit_enhancement_suite.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/reddit_enhancement_suite.user.js b/lib/reddit_enhancement_suite.user.js index a554b62bee..6a0085b85d 100644 --- a/lib/reddit_enhancement_suite.user.js +++ b/lib/reddit_enhancement_suite.user.js @@ -12300,7 +12300,7 @@ modules['accountSwitcher'] = { var accountCount = 0; for (var i=0, len=accounts.length; i Date: Thu, 21 Feb 2013 13:38:25 +0000 Subject: [PATCH 3/5] Revert "Currently we have a bug when a user isn't logged in" This reverts commit a42c9cfda247457dca5d97caa7bad7bab9cc4071. --- lib/reddit_enhancement_suite.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/reddit_enhancement_suite.user.js b/lib/reddit_enhancement_suite.user.js index 6a0085b85d..a554b62bee 100644 --- a/lib/reddit_enhancement_suite.user.js +++ b/lib/reddit_enhancement_suite.user.js @@ -12300,7 +12300,7 @@ modules['accountSwitcher'] = { var accountCount = 0; for (var i=0, len=accounts.length; i Date: Thu, 21 Feb 2013 13:41:17 +0000 Subject: [PATCH 4/5] Proper fix for the toUpperCase error --- lib/reddit_enhancement_suite.user.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/reddit_enhancement_suite.user.js b/lib/reddit_enhancement_suite.user.js index a554b62bee..c313defd74 100644 --- a/lib/reddit_enhancement_suite.user.js +++ b/lib/reddit_enhancement_suite.user.js @@ -12300,7 +12300,7 @@ modules['accountSwitcher'] = { var accountCount = 0; for (var i=0, len=accounts.length; i Date: Sat, 23 Feb 2013 13:53:52 +0000 Subject: [PATCH 5/5] Fixes #260 as discussed - easier to merge this pull than two pull requests --- lib/reddit_enhancement_suite.user.js | 180 +++++++++++++-------------- 1 file changed, 85 insertions(+), 95 deletions(-) diff --git a/lib/reddit_enhancement_suite.user.js b/lib/reddit_enhancement_suite.user.js index c313defd74..3d0bd0cde4 100644 --- a/lib/reddit_enhancement_suite.user.js +++ b/lib/reddit_enhancement_suite.user.js @@ -169,6 +169,10 @@ var BrowserDetect = { if (index == -1) return; return parseFloat(dataString.substring(index+this.versionSearchString.length+1)); }, + isChrome: function() { return typeof(chrome) !== 'undefined'; }, + isFirefox: function() { return typeof(self.on) === 'function'; }, + isOpera: function() { return typeof(opera) !== 'undefined'; }, + isSafari: function() { return typeof(safari) !== 'undefined'; }, dataBrowser: [ { string: navigator.userAgent, @@ -267,7 +271,7 @@ var safeJSON = { // if silent is specified, it will fail silently... parse: function(data, localStorageSource, silent) { try { - if (typeof(safari) != 'undefined') { + if (BrowserDetect.isSafari()) { if (data.substring(0,2) == 's{') { data = data.substring(1,data.length); } @@ -345,7 +349,7 @@ xhrQueue = { count: 0, onloads: [] }; // if this is a jetpack addon, add an event listener like Safari's message handler... -if (typeof(self.on) == 'function') { +if (BrowserDetect.isFirefox()) { self.on('message', function(msgEvent) { switch (msgEvent.name) { case 'GM_xmlhttpRequest': @@ -512,7 +516,7 @@ function operaMessageHandler(msgEvent) { } // listen for messages from chrome background page -if (typeof(chrome) != 'undefined') { +if (BrowserDetect.isChrome()) { chrome.extension.onMessage.addListener( function(request, sender, sendResponse) { switch(request.requestType) { @@ -527,7 +531,7 @@ if (typeof(chrome) != 'undefined') { ); } -if (typeof(safari) != 'undefined') { +if (BrowserDetect.isSafari()) { // Safari has a ridiculous bug that causes it to lose access to safari.self.tab if you click the back button. // this stupid one liner fixes that. window.onunload = function(){}; @@ -536,7 +540,7 @@ if (typeof(safari) != 'undefined') { // we can't do this check for opera here because we need to wait until DOMContentLoaded is triggered, I think. Putting this in RESinit(); // opera compatibility -if (typeof(opera) != 'undefined') { +if (BrowserDetect.isOpera()) { // removing this line for new localStorage methodology (store in extension localstorage) sessionStorage = window.sessionStorage; localStorage = window.localStorage; @@ -546,7 +550,7 @@ if (typeof(opera) != 'undefined') { // Firebug stopped showing console.log for some reason. Need to use unsafeWindow if available. Not sure if this was due to a Firebug version update or what. if (typeof(unsafeWindow) != 'undefined') { - if ((typeof(unsafeWindow.console) != 'undefined') && (typeof(self.on) != 'function')) { + if ((typeof(unsafeWindow.console) != 'undefined') && (!BrowserDetect.isFirefox())) { console = unsafeWindow.console; } else if (typeof(console) == 'undefined') { console = { @@ -629,7 +633,7 @@ if ((typeof GM_deleteValue == 'undefined') || (typeof GM_addStyle == 'undefined' } } - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { GM_xmlhttpRequest = function(obj) { var crossDomain = (obj.url.indexOf(location.hostname) == -1); @@ -649,7 +653,7 @@ if ((typeof GM_deleteValue == 'undefined') || (typeof GM_addStyle == 'undefined' request.send(obj.data); return request; } } - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { GM_xmlhttpRequest = function(obj) { obj.requestType = 'GM_xmlhttpRequest'; // Since Safari doesn't provide legitimate callbacks, I have to store the onload function here in the main @@ -674,7 +678,7 @@ if ((typeof GM_deleteValue == 'undefined') || (typeof GM_addStyle == 'undefined' request.send(obj.data); return request; } } - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { GM_xmlhttpRequest = function(obj) { obj.requestType = 'GM_xmlhttpRequest'; // Turns out, Opera works this way too, but I'll forgive them since their extensions are so young and they're awesome people... @@ -696,7 +700,7 @@ if ((typeof GM_deleteValue == 'undefined') || (typeof GM_addStyle == 'undefined' request.send(obj.data); return request; } } - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { // we must be in a Firefox / jetpack addon... GM_xmlhttpRequest = function(obj) { obj.requestType = 'GM_xmlhttpRequest'; @@ -1175,7 +1179,7 @@ var RESUtils = { // mark off that we've checked for an update... RESStorage.setItem('RESLastUpdateCheck',now.getTime()); var outdated = false; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { // we've got chrome, so we need to hit up the background page to do cross domain XHR var thisJSON = { requestType: 'compareVersion', @@ -1185,7 +1189,7 @@ var RESUtils = { // send message to background.html to open new tabs... outdated = RESUtils.compareVersion(response, forceUpdate); }); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { // we've got safari, so we need to hit up the background page to do cross domain XHR thisJSON = { requestType: 'compareVersion', @@ -1193,7 +1197,7 @@ var RESUtils = { forceUpdate: forceUpdate } safari.self.tab.dispatchMessage("compareVersion", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { // we've got opera, so we need to hit up the background page to do cross domain XHR thisJSON = { requestType: 'compareVersion', @@ -1661,24 +1665,10 @@ var RESUtils = { $('#sr-autocomplete').val('RESIssues'); $('li a.text-button').click(); $('#submittingToEnhancement').fadeOut(); - var thisBrowser; - if (typeof(self.on) == 'function') { - thisBrowser = 'Firefox'; - } else if (typeof(chrome) != 'undefined') { - thisBrowser = 'Chrome'; - } else if (typeof(safari) != 'undefined') { - thisBrowser = 'Safari'; - } else if (typeof(opera) != 'undefined') { - thisBrowser = 'Opera'; - } else { - thisBrowser = 'Unknown'; - } + var txt = "- RES Version: " + RESVersion + "\n"; - // turns out this is pretty useless info, commenting it out. - // txt += "- Browser: " + navigator.appCodeName + " " + navigator.appName + "\n"; - // txt += "- Browser: " + thisBrowser + "\n"; txt += "- Browser: " + BrowserDetect.browser + "\n"; - if (typeof(navigator) == 'undefined') navigator = window.navigator; + if (typeof(navigator) === 'undefined') navigator = window.navigator; txt+= "- Browser Version: " + BrowserDetect.version + "\n"; txt+= "- Cookies Enabled: " + navigator.cookieEnabled + "\n"; txt+= "- Platform: " + BrowserDetect.OS + "\n"; @@ -1780,18 +1770,18 @@ var RESUtils = { cname: cookieName }; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { chrome.extension.sendMessage(requestJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { document.cookie = cookieName + '=null;expires=' + new Date() +'; path=/;domain=reddit.com'; - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { document.cookie = cookieName + '=null;expires=' + new Date() +'; path=/;domain=reddit.com'; - } else if (typeof(self.on) == 'function') { // Firefox + } else if (BrowserDetect.isFirefox()) { self.postMessage(requestJSON); } }, openLinkInNewTab: function(url, focus) { - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'openLinkInNewTab', linkURL: url, @@ -1799,21 +1789,21 @@ var RESUtils = { }; // send message to background.html to open new tabs... chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { thisJSON = { requestType: 'openLinkInNewTab', linkURL: url, button: focus } safari.self.tab.dispatchMessage("openLinkInNewTab", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { thisJSON = { requestType: 'openLinkInNewTab', linkURL: url, button: focus } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { thisJSON = { requestType: 'openLinkInNewTab', linkURL: url, @@ -1939,13 +1929,13 @@ var RESUtils = { requestType: 'XHRCache', operation: operation }; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { safari.self.tab.dispatchMessage('XHRCache', thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { self.postMessage(thisJSON); } }, @@ -4190,7 +4180,7 @@ modules['keyboardNav'] = { } var borderType = 'outline'; - if (typeof(opera) != 'undefined') borderType = 'border'; + if (BrowserDetect.isOpera()) borderType = 'border'; RESUtils.addCSS(' \ .keyHighlight { '+borderType+': '+focusBorder+'; background-color: '+focusBGColor+'; } \ .res-nightmode .keyHighlight, .res-nightmode .keyHighlight .usertext-body, .res-nightmode .keyHighlight .usertext-body .md, .res-nightmode .keyHighlight .usertext-body .md p, .res-nightmode .keyHighlight .noncollapsed, .res-nightmode .keyHighlight .noncollapsed .md, .res-nightmode .keyHighlight .noncollapsed .md p { background-color: '+focusBGColorNight+' !important; color: '+focusFGColorNight+' !important;} \ @@ -4793,28 +4783,28 @@ modules['keyboardNav'] = { var thisURL = link.getAttribute('href'); var isLocalToPage = (thisURL.indexOf('reddit') != -1) && (thisURL.indexOf('comments') != -1) && (thisURL.indexOf('#') != -1); if ((!isLocalToPage) && (button == 1)) { - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisURL, button: button }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisURL, button: button } safari.self.tab.dispatchMessage("keyboardNav", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisURL, button: button } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisURL, @@ -5179,28 +5169,28 @@ modules['keyboardNav'] = { var thisHREF = srLink.getAttribute('href'); if (newWindow) { var button = (this.options.followLinkNewTabFocus.value) ? 0 : 1; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button } safari.self.tab.dispatchMessage("keyboardNav", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, @@ -5445,28 +5435,28 @@ modules['keyboardNav'] = { // console.log(thisA); if (newWindow) { var button = (this.options.followLinkNewTabFocus.value) ? 0 : 1; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button } safari.self.tab.dispatchMessage("keyboardNav", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, button: button } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF, @@ -5484,25 +5474,25 @@ modules['keyboardNav'] = { var thisA = this.keyboardLinks[this.activeIndex].querySelector('a.comments'); var thisHREF = thisA.getAttribute('href'); if (newWindow) { - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF } safari.self.tab.dispatchMessage("keyboardNav", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF @@ -5581,19 +5571,19 @@ modules['keyboardNav'] = { inbox: function(newWindow) { var thisHREF = location.protocol + '//'+location.hostname+'/message/inbox/'; if (newWindow) { - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF } safari.self.tab.dispatchMessage("keyboardNav", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'keyboardNav', linkURL: thisHREF @@ -6850,7 +6840,7 @@ modules['betteReddit'] = { RESUtils.addCSS('#mail { top: 2px; min-width: 16px !important; width: auto !important; background-repeat: no-repeat !important; line-height: 8px !important; }'); // RESUtils.addCSS('#mail.havemail { top: 2px !important; margin-right: 1px; }'); RESUtils.addCSS('#mail.havemail { top: 2px !important; }'); - if ((typeof(chrome) != 'undefined') || (typeof(safari) != 'undefined')) { + if ((BrowserDetect.isChrome()) || (BrowserDetect.isSafari())) { // I hate that I have this conditional CSS in here but I can't figure out why it's needed for webkit and screws up firefox. RESUtils.addCSS('#mail.havemail { top: 0px; }'); } @@ -7576,7 +7566,7 @@ modules['singleClick'] = { if (!(thisLink.match(/^http/i))) { thisLink = 'http://' + document.domain + thisLink; } - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { var thisJSON = { requestType: 'singleClick', linkURL: thisLink, @@ -7586,7 +7576,7 @@ modules['singleClick'] = { ctrl: e.ctrlKey }; chrome.extension.sendMessage(thisJSON); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { var thisJSON = { requestType: 'singleClick', linkURL: thisLink, @@ -7596,7 +7586,7 @@ modules['singleClick'] = { ctrl: e.ctrlKey } safari.self.tab.dispatchMessage("singleClick", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { var thisJSON = { requestType: 'singleClick', linkURL: thisLink, @@ -7606,7 +7596,7 @@ modules['singleClick'] = { ctrl: e.ctrlKey } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { var thisJSON = { requestType: 'singleClick', linkURL: thisLink, @@ -8859,7 +8849,7 @@ modules['showImages'] = { if (this.options.markVisited.value) { // we only need this iFrame hack if we're unable to add to history directly, which Firefox addons and Chrome can do. - if ((typeof(chrome) == 'undefined') && (typeof(self.on) == 'undefined')) { + if (!BrowserDetect.isChrome() && !BrowserDetect.isFirefox()) { this.imageTrackFrame = document.createElement('iframe'); this.imageTrackFrame.addEventListener('load', function() { setTimeout(modules['showImages'].imageTrackShift, 300); @@ -9493,7 +9483,7 @@ modules['showImages'] = { var isNSFW = $(link).closest('.thing').is('.over18'); var sfwMode = modules['showImages'].options['sfwHistory'].value; - if ((typeof(chrome) != 'undefined') || (typeof(self.on) != 'undefined')) { + if ((BrowserDetect.isChrome()) || (BrowserDetect.isFirefox())) { var url = link.historyURL || link.href; if (!isNSFW || sfwMode != 'none') addClass(link, 'visited'); if (!isNSFW || sfwMode == 'add') { @@ -9522,7 +9512,7 @@ modules['showImages'] = { modules['showImages'].handleSidebarHiding(); return; } - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { if (!chrome.extension.inIncognitoContext) { chrome.extension.sendMessage({ requestType: 'addURLToHistory', @@ -9530,7 +9520,7 @@ modules['showImages'] = { }); } modules['showImages'].imageTrackShift(); - } else if (typeof(self.on) != 'undefined') { + } else if (BrowserDetect.isFirefox()) { // update: using XPCOM we may can add URLs to Firefox history without the iframe hack! var thisJSON = { requestType: 'addURLToHistory', @@ -11686,7 +11676,7 @@ modules['styleTweaks'] = { var match = twitterLink.match(/twitter.com\/[^\/]+\/(?:status|statuses)\/([\d]+)/i); if (match != null) { var jsonURL = 'http://api.twitter.com/1/statuses/show/'+match[1]+'.json'; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { // we've got chrome, so we need to hit up the background page to do cross domain XHR var thisJSON = { requestType: 'loadTweet', @@ -11699,7 +11689,7 @@ modules['styleTweaks'] = { thisExpando.style.display = 'block'; addClass(thisExpando,'twitterLoaded'); }); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { // we've got safari, so we need to hit up the background page to do cross domain XHR modules['styleTweaks'].tweetExpando = thisExpando; var thisJSON = { @@ -11707,7 +11697,7 @@ modules['styleTweaks'] = { url: jsonURL } safari.self.tab.dispatchMessage("loadTweet", thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { // we've got opera, so we need to hit up the background page to do cross domain XHR modules['styleTweaks'].tweetExpando = thisExpando; var thisJSON = { @@ -11715,7 +11705,7 @@ modules['styleTweaks'] = { url: jsonURL } opera.extension.postMessage(JSON.stringify(thisJSON)); - } else if (typeof(self.on) == 'function') { + } else if (BrowserDetect.isFirefox()) { // we've got a jetpack extension, hit up the background page... modules['styleTweaks'].tweetExpando = thisExpando; var thisJSON = { @@ -12388,11 +12378,11 @@ modules['accountSwitcher'] = { } var loginUrl = 'https://ssl.reddit.com/api/login'; // unfortunately, due to 3rd party cookie issues, none of the below browsers work with ssl. - if (typeof(opera) != 'undefined') { + if (BrowserDetect.isOpera()) { loginUrl = 'http://'+location.hostname+'/api/login'; - } else if ((typeof(chrome) != 'undefined') && (chrome.extension.inIncognitoContext)) { + } else if ((BrowserDetect.isChrome()) && (chrome.extension.inIncognitoContext)) { loginUrl = 'http://'+location.hostname+'/api/login'; - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { loginUrl = 'http://'+location.hostname+'/api/login'; } @@ -13768,7 +13758,7 @@ modules['subredditManager'] = { RESUtils.addCSS('#editShortcutDialog label { clear: both; float: left; width: 100px; margin-top: 12px; }'); RESUtils.addCSS('#editShortcutDialog input { float: left; width: 126px; margin-top: 10px; }'); RESUtils.addCSS('#editShortcutDialog input[type=button] { float: right; width: 45px; margin-left: 10px; cursor: pointer; padding-top: 3px; padding-bottom: 3px; padding-left: 5px; padding-right: 5px; font-size: 12px; color: #ffffff; border: 1px solid #636363; border-radius: 3px 3px 3px 3px; -moz-border-radius: 3px 3px 3px 3px; -webkit-border-radius: 3px 3px 3px 3px; background-color: #5cc410; }'); - if ((typeof(chrome) != 'undefined') || (typeof(safari) != 'undefined')) { + if ((BrowserDetect.isChrome()) || (BrowserDetect.isSafari())) { RESUtils.addCSS('#srLeftContainer { margin-right: 14px; }'); } else { RESUtils.addCSS('#srLeftContainer { margin-right: 6px; }'); @@ -13811,7 +13801,7 @@ modules['subredditManager'] = { RESUtils.addCSS('#srLeftContainer, #RESShortcutsViewport, #RESShortcutsEditContainer{max-height:18px;}'); // this shows the sr-header-area that we hid while rendering it (to curb opera's glitchy "jumping")... - if (typeof(opera) != 'undefined') { + if (BrowserDetect.isOpera()) { RESUtils.addCSS('#sr-header-area { display: block !important; }'); } } @@ -14171,7 +14161,7 @@ modules['subredditManager'] = { }, 200); }, followSubredditShortcut: function() { - if (typeof(self.on) == 'function') { + if (BrowserDetect.isFirefox()) { // stupid firefox... sigh... location.href = location.protocol + '//' + location.hostname + modules['subredditManager'].clickedShortcut; } else { @@ -14274,7 +14264,7 @@ modules['subredditManager'] = { this.headerContents = document.querySelector('#sr-header-area'); if (this.headerContents) { // for opera, because it renders progressively and makes it look "glitchy", hide the header bar, then show it all at once with CSS. - // if (typeof(opera) != 'undefined') this.headerContents.style.display = 'none'; + // if (BrowserDetect.isOpera()) this.headerContents.style.display = 'none'; // Clear out the existing stuff in the top bar first, we'll replace it with our own stuff. $(this.headerContents).html(''); this.srLeftContainer = createElementWithID('div','srLeftContainer'); @@ -17456,7 +17446,7 @@ function RESInit() { // if this is a firefox addon, check for the old lsTest to see if they used to use the Greasemonkey script... // if so, present them with a notification explaining that they should download a new script so they can // copy their old settings... - if (typeof(self.on) == 'function') { + if (BrowserDetect.isFirefox()) { if ((localStorage.getItem('RES.lsTest') == 'test') && (localStorage.getItem('copyComplete') != 'true')) { RESUtils.notification('

Important Alert for Greasemonkey Users!

Hey! It looks like you have upgraded to RES 4.0, but used to use the Greasemonkey version of RES. You\'re going to see double until you uninstall the Greasemonkey script. However, you should first copy your settings by clicking the blue button. After installing, refresh this page! GM->FF Import Tool', 15000); localStorage.removeItem('RES.lsTest'); @@ -17484,11 +17474,11 @@ function RESInit() { if (localStorageFail) { RESFail = "Sorry, but localStorage seems inaccessible. Reddit Enhancement Suite can't work without it. \n\n"; - if (typeof(safari) != 'undefined') { + if (BrowserDetect.isSafari()) { RESFail += 'Since you\'re using Safari, it might be that you\'re in private browsing mode, which unfortunately is incompatible with RES until Safari provides a way to allow extensions localStorage access.'; - } else if (typeof(chrome) != 'undefined') { + } else if (BrowserDetect.isChrome()) { RESFail += 'Since you\'re using Chrome, you might just need to go to your extensions settings and check the "Allow in Incognito" box.'; - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { RESFail += 'Since you\'re using Opera, you might just need to go to your extensions settings and click the gear icon, then click "privacy" and check the box that says "allow interaction with private tabs".'; } else { RESFail += 'Since it looks like you\'re using Firefox, you probably need to go to about:config and ensure that dom.storage.enabled is set to true, and that dom.storage.default_quota is set to a number above zero (i.e. 5120, the normal default)".'; @@ -17558,7 +17548,7 @@ function RESInit() { RESStorage = {}; function setUpRESStorage (response) { - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { RESStorage = response; // we'll set up a method for getItem, but it's not adviseable to use since it's asynchronous... RESStorage.getItem = function(key) { @@ -17596,7 +17586,7 @@ function setUpRESStorage (response) { } window.localStorage = RESStorage; //RESInit(); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { RESStorage = response; RESStorage.getItem = function(key) { if (typeof(RESStorage[key]) != 'undefined') return RESStorage[key]; @@ -17631,7 +17621,7 @@ function setUpRESStorage (response) { safari.self.tab.dispatchMessage("localStorage", thisJSON); } window.localStorage = RESStorage; - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { RESStorage = response; RESStorage.getItem = function(key) { if (typeof(RESStorage[key]) != 'undefined') return RESStorage[key]; @@ -17666,7 +17656,7 @@ function setUpRESStorage (response) { opera.extension.postMessage(JSON.stringify(thisJSON)); } window.localStorage = RESStorage; - } else if (typeof(self.on) != 'undefined') { + } else if (BrowserDetect.isFirefox()) { RESStorage = response; RESStorage.getItem = function(key) { if (typeof(RESStorage[key]) != 'undefined') return RESStorage[key]; @@ -17749,7 +17739,7 @@ function setUpRESStorage (response) { return false; } RESRunOnce = true; - if (typeof(chrome) != 'undefined') { + if (BrowserDetect.isChrome()) { // we've got chrome, get a copy of the background page's localStorage first, so don't init until after. var thisJSON = { requestType: 'getLocalStorage' @@ -17770,19 +17760,19 @@ function setUpRESStorage (response) { setUpRESStorage(response); } }); - } else if (typeof(safari) != 'undefined') { + } else if (BrowserDetect.isSafari()) { // we've got safari, get localStorage from background process thisJSON = { requestType: 'getLocalStorage' } safari.self.tab.dispatchMessage("getLocalStorage", thisJSON); - } else if (typeof(self.on) != 'undefined') { + } else if (BrowserDetect.isFirefox()) { // we've got firefox jetpack, get localStorage from background process thisJSON = { requestType: 'getLocalStorage' } self.postMessage(thisJSON); - } else if (typeof(opera) != 'undefined') { + } else if (BrowserDetect.isOpera()) { // I freaking hate having to use different code that won't run in other browsers to log debugs, so I'm overriding console.log with opera.postError here // so I don't have to litter my code with different statements for different browsers when debugging. console.log = opera.postError; @@ -17823,7 +17813,7 @@ function RESInitReadyCheck() { if ((typeof(RESStorage.getItem) != 'function') || (document.body == null)) { setTimeout(RESInitReadyCheck, 50); } else { - if (typeof(self.on) == 'function') { + if (BrowserDetect.isFirefox()) { // firefox addon sdk... we've included jQuery... // also, for efficiency, we're going to try using unsafeWindow for "less secure" (but we're not going 2 ways here, so that's OK) but faster DOM node access... // console.log('faster?'); @@ -17850,7 +17840,7 @@ function RESInitReadyCheck() { console.log('Uh oh, something has gone wrong loading jQuery...'); } } - if (typeof(opera) != 'undefined') { + if (BrowserDetect.isOpera()) { // require.js-like modular injected scripts, code via: // http://my.opera.com/BS-Harou/blog/2012/08/08/modular-injcted-scripts-in-extensions // Note: This code requires Opera 12.50 to run!