├── .project └── WebContent ├── _locales ├── en │ └── messages.json └── fr │ └── messages.json ├── accountStorage.js ├── background.html ├── background.js ├── config.js ├── content.js ├── iconBlocked.png ├── iconFeedback.png ├── iconPlus.png ├── icon_128.png ├── icon_48.png ├── icon_bg.png ├── icon_more.gif ├── manifest.json ├── options.css ├── options.html ├── options.js ├── popup.html ├── popup.js ├── popupCommon.js ├── popupDef.html └── popupDef.js /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BugMeNot 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.jsdt.core.javascriptValidator 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.wst.common.project.facet.core.nature 26 | org.eclipse.wst.common.modulecore.ModuleCoreNature 27 | org.eclipse.wst.jsdt.core.jsNature 28 | 29 | 30 | -------------------------------------------------------------------------------- /WebContent/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "bugmenot_name" : { 3 | "message": "BugMeNot Lite" 4 | }, 5 | "bugmenot_description": { 6 | "message": "Bypass compulsory web registration via www.bugmenot.com." 7 | }, 8 | "optionsTitle": { 9 | "message": "BugMeNot Lite Options" 10 | }, 11 | "maxSize": { 12 | "message": "maximum account list size" 13 | }, 14 | "minRating": { 15 | "message": "minimum account rating" 16 | }, 17 | "autoHideDelay": { 18 | "message": "auto-hide icon" 19 | }, 20 | "autoFeedbackDelay": { 21 | "message": "show feedback icon" 22 | }, 23 | "alwaysAutoSubmit": { 24 | "message": "always auto-submit form" 25 | }, 26 | "neverVoteTwice": { 27 | "message": "never vote twice for an account" 28 | }, 29 | "dontStoreVote": { 30 | "message": "don't store votes into local database" 31 | }, 32 | "deleteDatabase": { 33 | "message": "delete votes from local database" 34 | }, 35 | "deleteDatabaseInput": { 36 | "message": "delete" 37 | }, 38 | "maxSizeShowAll": { 39 | "message": "show all" 40 | }, 41 | "autoHideDelayNever": { 42 | "message": "never" 43 | }, 44 | "autoHideDelay5s": { 45 | "message": "after 5s" 46 | }, 47 | "autoHideDelay10s": { 48 | "message": "after 10s" 49 | }, 50 | "autoHideDelay20s": { 51 | "message": "after 20s" 52 | }, 53 | "autoFeedbackDelayNever": { 54 | "message":"never" 55 | }, 56 | "autoFeedbackDelayAfterSubmit": { 57 | "message":"after submit" 58 | }, 59 | "autoFeedbackDelay0s": { 60 | "message":"instantly" 61 | }, 62 | "autoFeedbackDelay5s": { 63 | "message":"after 5s" 64 | }, 65 | "autoFeedbackDelay10s": { 66 | "message":"after 10s" 67 | }, 68 | "autoFeedbackDelay20s": { 69 | "message":"after 20s" 70 | }, 71 | "questionPart1": { 72 | "message":"Did" 73 | }, 74 | "questionPart2": { 75 | "message":"work out for you ?" 76 | }, 77 | "yes":{ 78 | "message":"Yes" 79 | }, 80 | "no": { 81 | "message":"No" 82 | }, 83 | "autoSubmit": { 84 | "message":"auto-submit form" 85 | }, 86 | "noFeedback": { 87 | "message":"no feedback" 88 | }, 89 | "tabNoFeedback": { 90 | "message":"no feedback in this tab" 91 | }, 92 | "siteNoFeedback": { 93 | "message":"no feedback for this site" 94 | }, 95 | "addAccount": { 96 | "message":"add account on bugmenot.com" 97 | }, 98 | "password": { 99 | "message":"password" 100 | }, 101 | "noAvailableAccounts": { 102 | "message":"no accounts available !" 103 | }, 104 | "blockedSite" : { 105 | "message":"site blocked" 106 | }, 107 | "accounts" : { 108 | "message":"accounts" 109 | }, 110 | "account" : { 111 | "message":"account" 112 | }, 113 | "manualLogin" : { 114 | "message":"manual login" 115 | } 116 | } -------------------------------------------------------------------------------- /WebContent/_locales/fr/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "bugmenot_name" : { 3 | "message": "BugMeNot Lite" 4 | }, 5 | "bugmenot_description": { 6 | "message": "Contournez les formulaires de login via www.bugmenot.com." 7 | }, 8 | "optionsTitle": { 9 | "message": "Options de BugMeNot Lite" 10 | }, 11 | "maxSize": { 12 | "message": "taille maximum de la liste de comptes" 13 | }, 14 | "minRating": { 15 | "message": "note minimum des comptes" 16 | }, 17 | "autoHideDelay": { 18 | "message": "cacher automatiquement l'icone" 19 | }, 20 | "autoFeedbackDelay": { 21 | "message": "afficher l'icone de feedback" 22 | }, 23 | "alwaysAutoSubmit": { 24 | "message": "toujours envoyer le formulaire automatiquement" 25 | }, 26 | "neverVoteTwice": { 27 | "message": "ne jamais voter deux fois pour un compte" 28 | }, 29 | "dontStoreVote": { 30 | "message": "ne pas enregistrer les votes en base de données" 31 | }, 32 | "deleteDatabase": { 33 | "message": "supprimer les votes de la base de données" 34 | }, 35 | "deleteDatabaseInput": { 36 | "message": "supprimer" 37 | }, 38 | "maxSizeShowAll": { 39 | "message": "tout afficher" 40 | }, 41 | "autoHideDelayNever": { 42 | "message": "jamais" 43 | }, 44 | "autoHideDelay5s": { 45 | "message": "après 5s" 46 | }, 47 | "autoHideDelay10s": { 48 | "message": "après 10s" 49 | }, 50 | "autoHideDelay20s": { 51 | "message": "après 20s" 52 | }, 53 | "autoFeedbackDelayNever": { 54 | "message":"jamais" 55 | }, 56 | "autoFeedbackDelayAfterSubmit": { 57 | "message":"après envoi" 58 | }, 59 | "autoFeedbackDelay0s": { 60 | "message":"sans délai" 61 | }, 62 | "autoFeedbackDelay5s": { 63 | "message":"après 5s" 64 | }, 65 | "autoFeedbackDelay10s": { 66 | "message":"après 10s" 67 | }, 68 | "autoFeedbackDelay20s": { 69 | "message":"après 20s" 70 | }, 71 | "questionPart1": { 72 | "message":"Le login" 73 | }, 74 | "questionPart2": { 75 | "message":"est valide ?" 76 | }, 77 | "yes": { 78 | "message":"Oui" 79 | }, 80 | "no": { 81 | "message":"Non" 82 | }, 83 | "autoSubmit": { 84 | "message":"envoi auto du formulaire" 85 | }, 86 | "noFeedback": { 87 | "message":"pas de vote" 88 | }, 89 | "tabNoFeedback": { 90 | "message":"pas de vote dans l'onglet" 91 | }, 92 | "siteNoFeedback": { 93 | "message":"pas de vote sur le site" 94 | }, 95 | "addAccount": { 96 | "message":"ajouter un compte sur bugmenot.com" 97 | }, 98 | "password": { 99 | "message":"mot de passe" 100 | }, 101 | "noAvailableAccounts": { 102 | "message":"pas de compte disponible !" 103 | }, 104 | "blockedSite" : { 105 | "message":"site bloqué" 106 | }, 107 | "accounts" : { 108 | "message":"comptes" 109 | }, 110 | "account" : { 111 | "message":"compte" 112 | }, 113 | "manualLogin" : { 114 | "message":"login manuel" 115 | } 116 | } -------------------------------------------------------------------------------- /WebContent/accountStorage.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var accountStorage = {}; 22 | (function() { 23 | var db; 24 | 25 | function init() { 26 | db = openDatabase("BugMeNot", "1.0", "Accounts", 200000); 27 | db.transaction(function(tx) { 28 | tx.executeSql( 29 | "create table if not exists accounts (loginId integer primary key, hostId integer, vote varchar(1))" 30 | ); 31 | }); 32 | } 33 | 34 | accountStorage.get = function(accounts, callback) { 35 | db.transaction(function(tx) { 36 | var i, query, params = []; 37 | if (accounts.length) { 38 | query = "select loginId, hostId, vote from accounts where"; 39 | for (i = 0;i < accounts.length;i++) { 40 | query += " (loginId=? and hostId=?)"; 41 | params.push(accounts[i].loginId); 42 | params.push(accounts[i].hostId); 43 | if (i < accounts.length - 1) 44 | query += " or"; 45 | } 46 | ret = tx.executeSql(query, params, function(cbTx, result) { 47 | callback(result.rows); 48 | }); 49 | } else 50 | callback([]); 51 | }); 52 | }; 53 | 54 | accountStorage.add = function(loginId, hostId, vote) { 55 | db.transaction(function(tx) { 56 | tx.executeSql("insert or replace into accounts (loginId, hostId, vote) values (?, ?, ?)", [loginId, hostId, vote]); 57 | }); 58 | }; 59 | 60 | accountStorage.reset = function() { 61 | db.transaction(function(tx) { 62 | tx.executeSql("delete from accounts"); 63 | }); 64 | }; 65 | 66 | init(); 67 | })(); -------------------------------------------------------------------------------- /WebContent/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WebContent/background.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var tabs = {}; 22 | 23 | /** 24 | * TabData constructor. 25 | * 26 | * @param tabId 27 | */ 28 | function TabData(tabId) { 29 | this.accounts = []; 30 | this.hosts = []; 31 | this.ports = {}; 32 | this.currentIndex = 0; 33 | this.autoSubmit = false; 34 | this.displayPopup = false; 35 | this.noFeedback = false; 36 | this.noSiteFeedback = false; 37 | this.timerHide = {}; 38 | this.timerLastActivity = {}; 39 | this.notBlocked = false; 40 | this.forceSetAccount = false; 41 | this.tabIndex = 0; 42 | this.index = 0; 43 | this.submit = false; 44 | this.id = tabId; 45 | } 46 | 47 | TabData.prototype = new Object(); 48 | 49 | /** 50 | * Clear the auto hide timer. 51 | */ 52 | TabData.prototype._clearAutoHideTimer = function() { 53 | if (this.timerHide) { 54 | clearTimeout(this.timerHide); 55 | this.timerHide = null; 56 | } 57 | }; 58 | 59 | /** 60 | * Set the auto hide timer. 61 | */ 62 | TabData.prototype._setAutoHideTimer = function() { 63 | var that = this; 64 | if (config.autoHideDelay() != -1) { 65 | this._clearAutoHideTimer(); 66 | this.timerHide = setTimeout(function() { 67 | if (!that.displayPopup) 68 | that._hideIcon(); 69 | that.timerHide = null; 70 | }, config.autoHideDelay() * 1000); 71 | } 72 | }; 73 | 74 | /** 75 | * Set the auto feedback timer. 76 | */ 77 | TabData.prototype._setAutoFeedbackTimer = function() { 78 | var that = this; 79 | if (config.autoFeedbackDelay() > -1 && !config.dynPopupUnvailable && !this.noFeedback && !this.noSiteFeedback) { 80 | if (this.timerLastActivity) { 81 | clearTimeout(this.timerLastActivity); 82 | this.timerLastActivity = null; 83 | } 84 | this.timerLastActivity = setTimeout(function() { 85 | that.displayPopup = true; 86 | that._showFeedbackIcon(); 87 | that.timerLastActivity = null; 88 | }, config.autoFeedbackDelay() * 1000); 89 | } 90 | }; 91 | 92 | /** 93 | * Show BugMeNot icon. 94 | */ 95 | TabData.prototype._showIcon = function() { 96 | if (!this.displayPopup) { 97 | this._hideIcon(); 98 | if (!config.dynPopupUnvailable) 99 | chrome.pageAction.setPopup( { 100 | tabId : this.id, 101 | popup : "" 102 | }); 103 | chrome.pageAction.show(this.id); 104 | this._setAutoHideTimer(); 105 | if (this.notBlocked) { 106 | if (this.accounts.length) 107 | chrome.pageAction.setIcon( { 108 | tabId : this.id, 109 | path : chrome.extension.getURL("icon_48.png") 110 | }); 111 | else 112 | chrome.pageAction.setIcon( { 113 | tabId : this.id, 114 | path : chrome.extension.getURL("iconPlus.png") 115 | }); 116 | chrome.pageAction.setTitle( { 117 | tabId : this.id, 118 | title : this.accounts.length + " " 119 | + (this.accounts.length > 1 ? chrome.i18n.getMessage("accounts") : chrome.i18n.getMessage("account")) 120 | }); 121 | } else { 122 | chrome.pageAction.setIcon( { 123 | tabId : this.id, 124 | path : chrome.extension.getURL("iconBlocked.png") 125 | }); 126 | chrome.pageAction.setTitle( { 127 | tabId : this.id, 128 | title : chrome.i18n.getMessage("blockedSite") 129 | }); 130 | } 131 | if (this.accounts.length == 0 && this.notBlocked && !config.dynPopupUnvailable) { 132 | chrome.pageAction.setPopup( { 133 | tabId : this.id, 134 | popup : "popupDef.html?tabId=" + this.id 135 | }); 136 | } 137 | if (this.forceSetAccount) 138 | this._setAccount(this.id); 139 | } 140 | }; 141 | 142 | /** 143 | * Show BugMeNot feedback icon. 144 | */ 145 | TabData.prototype._showFeedbackIcon = function() { 146 | var that = this; 147 | if (this.displayPopup) { 148 | accountStorage.get( [ this.accounts[this.currentIndex] ], function(accounts) { 149 | if ((!accounts.length && config.neverVoteTwice()) || !config.neverVoteTwice()) { 150 | that._hideIcon(); 151 | chrome.pageAction.setIcon( { 152 | tabId : that.id, 153 | path : chrome.extension.getURL("iconFeedback.png") 154 | }); 155 | chrome.pageAction.show(that.id); 156 | that._setAutoHideTimer(); 157 | chrome.pageAction.setPopup( { 158 | tabId : that.id, 159 | popup : "popup.html?tabId=" + that.id + "&login=" + encodeURI(that.accounts[that.currentIndex].login) + "&password=" 160 | + encodeURI(that.accounts[that.currentIndex].password) + "&autoSubmit=" 161 | + (that.autoSubmit || config.alwaysAutoSubmit() ? "yes" : "no") 162 | }); 163 | } else 164 | that.displayPopup = false; 165 | }); 166 | } 167 | }; 168 | 169 | /** 170 | * Hide BugMeNot icon. 171 | */ 172 | TabData.prototype._hideIcon = function() { 173 | chrome.pageAction.hide(this.id); 174 | this._clearAutoHideTimer(); 175 | }; 176 | 177 | /** 178 | * Parse accounts data from HTML. 179 | * 180 | * @param {String} htmlText 181 | */ 182 | TabData.prototype._parseAccounts = function(htmlText) { 183 | var range, parsedHTML, loginNodes, passwordNodes, statsNodes, loginIds, hostIds, i; 184 | range = document.createRange(); 185 | range.selectNode(document.body); 186 | parsedHTML = range.createContextualFragment(htmlText); 187 | loginNodes = parsedHTML.querySelectorAll(".account tr:nth-child(1) td"); 188 | if (loginNodes.length) { 189 | hostIds = parsedHTML.querySelectorAll(".account input:nth-child(2)"); 190 | loginIds = parsedHTML.querySelectorAll(".account input:nth-child(1)"); 191 | passwordNodes = parsedHTML.querySelectorAll(".account tr:nth-child(2) td"); 192 | statsNodes = parsedHTML.querySelectorAll(".account tr:nth-child(4) td"); 193 | for (i = 0; i < loginNodes.length; i++) 194 | if (loginNodes[i].textContent && passwordNodes[i].textContent && !this.accounts.some(function(element, index, array) { 195 | return element.login == loginNodes[i].textContent; 196 | })) { 197 | this.accounts.push( { 198 | login : loginNodes[i].textContent, 199 | password : passwordNodes[i].textContent, 200 | rating : parseInt(statsNodes[i].textContent.split("%")[0], 10), 201 | loginId : loginIds[i].value, 202 | hostId : hostIds[i].value 203 | }); 204 | } 205 | } 206 | }; 207 | 208 | /** 209 | * Request accounts data on bugmenot.com. 210 | * 211 | * @param {String} host 212 | * @return 213 | */ 214 | TabData.prototype._requestAccounts = function(host) { 215 | var request = new XMLHttpRequest(), blocked, that = this; 216 | request.onreadystatechange = function() { 217 | var hosts; 218 | if (request.readyState == 4) { 219 | if (request.status == 200 || request.status == 404) { 220 | blocked = request.status == 404 && request.responseText.toLowerCase().indexOf("blocked") != -1; 221 | if (request.status != 404) 222 | that._parseAccounts(request.responseText); 223 | if (request.status == 200 || !blocked) 224 | that.hosts.push(host); 225 | that.notBlocked = !blocked; 226 | hosts = host.split("."); 227 | if (hosts[0] == "www") 228 | hosts.shift(); 229 | if (hosts.length > 2) 230 | that._requestAccounts(host.substr(host.indexOf('.') + 1)); 231 | else 232 | accountStorage.get(that.accounts, function(trustedAccounts) { 233 | var trustedYes = []; 234 | that.accounts = that.accounts 235 | .filter(function(account) { 236 | var foundYes = false, i = 0; 237 | while (i < trustedAccounts.length && !foundYes) { 238 | if (trustedAccounts.item(i).hostId == account.hostId 239 | && trustedAccounts.item(i).loginId == account.loginId) { 240 | if (trustedAccounts.item(i).vote == "Y") { 241 | account.trustedYes = true; 242 | foundYes = true; 243 | } else 244 | account.trustedNo = true; 245 | } 246 | i++; 247 | } 248 | if (foundYes) 249 | trustedYes.unshift(account); 250 | return !foundYes; 251 | }); 252 | that.accounts.sort(function(a, b) { 253 | return !a.trustedNo && b.trustedNo ? -1 : a.trustedNo && !b.trustedNo ? 1 : a.rating > b.rating ? -1 254 | : a.rating < b.rating ? 1 : a.login < b.login ? -1 : a.login > b.login ? 1 : 0; 255 | }); 256 | if (config.maxSize() != -1 && that.accounts.length > config.maxSize()) 257 | that.accounts.length = config.maxSize(); 258 | if (config.minRating()) 259 | that.accounts = that.accounts.filter(function(account) { 260 | return account.rating >= config.minRating(); 261 | }); 262 | trustedYes.forEach(function(account) { 263 | that.accounts.unshift(account); 264 | }); 265 | if (config.maxSize() != -1 && that.accounts.length > config.maxSize()) 266 | that.accounts.length = config.maxSize(); 267 | that._showIcon(); 268 | }); 269 | } 270 | } 271 | }; 272 | request.open('GET', 'http://www.bugmenot.com/view/' + host + '?utm_source=extension&utm_medium=firefox', true); 273 | request.send(null); 274 | }; 275 | 276 | /** 277 | * Notify content script to set accounts data. 278 | */ 279 | TabData.prototype._setAccount = function() { 280 | var portId; 281 | if (this.accounts.length) { 282 | for (portId in this.ports) 283 | this.ports[portId].postMessage( { 284 | setAccount : true, 285 | account : this.accounts[this.index], 286 | accounts : this.accounts, 287 | autoSubmit : this.autoSubmit 288 | }); 289 | this.currentIndex = this.index; 290 | this.index = (this.index + 1) % this.accounts.length; 291 | } 292 | }; 293 | 294 | /** 295 | * Set host and port. 296 | * 297 | * @param {String} host 298 | * @param {Port} port 299 | * @param {Boolean} forceSetAccount 300 | */ 301 | TabData.prototype.onSearchAccounts = function(host, port, forceSetAccount) { 302 | if (this.hosts.indexOf(host) == -1) { 303 | this.hosts = []; 304 | this.noSiteFeedback = false; 305 | this.accounts = []; 306 | this.index = 0; 307 | this.currentIndex = 0; 308 | this.ports = {}; 309 | this.ports[port.portId_] = port; 310 | this.tabIndex = port.sender.tab.index; 311 | this.forceSetAccount = false; 312 | this.notBlocked = false; 313 | this._requestAccounts(host); 314 | } else { 315 | this.forceSetAccount = forceSetAccount; 316 | if (forceSetAccount && this.currentIndex == this.index) 317 | this.index = (this.index + 1) % this.accounts.length; 318 | this.ports[port.portId_] = port; 319 | this._showIcon(); 320 | } 321 | }; 322 | 323 | /** 324 | * Set current account index. 325 | * 326 | * @param {Number} index 327 | */ 328 | TabData.prototype.onSelectIndex = function(index) { 329 | this.submit = false; 330 | this.index = index; 331 | this.currentIndex = index; 332 | this._setAutoFeedbackTimer(); 333 | this._setAutoHideTimer(); 334 | }; 335 | 336 | /** 337 | * Update tab state and show the feedback icon. 338 | * 339 | * @param {Number} index 340 | */ 341 | TabData.prototype.onSubmitForm = function(index) { 342 | if (!this.submit) { 343 | this.index = index; 344 | this.currentIndex = index; 345 | this.submit = true; 346 | if (!config.dynPopupUnvailable && !this.noFeedback && !this.noSiteFeedback && config.autoFeedbackDelay() == -1) { 347 | this.displayPopup = true; 348 | this._showFeedbackIcon(); 349 | } 350 | } 351 | }; 352 | 353 | /** 354 | * Launch action asked by popup. 355 | * 356 | * @param {Number} tabIndex 357 | * @param {Message} msg 358 | */ 359 | TabData.prototype.onSubmitFeedback = function(tabIndex, msg) { 360 | var portId, request; 361 | this.tabIndex = tabIndex; 362 | if (msg.vote) { 363 | this._hideIcon(); 364 | this.displayPopup = false; 365 | this.autoSubmit = msg.autoSubmit; 366 | request = new XMLHttpRequest(); 367 | request.open('GET', 'http://www.bugmenot.com/vote_ajax.php?id=' + this.accounts[this.currentIndex].loginId + '&site=' 368 | + this.accounts[this.currentIndex].hostId + '&vote=' + msg.vote, true); 369 | request.send(null); 370 | if (!config.dontStoreVote()) 371 | accountStorage.add(this.accounts[this.currentIndex].loginId, this.accounts[this.currentIndex].hostId, msg.vote); 372 | this.accounts[this.currentIndex].trustedYes = msg.vote == "Y"; 373 | this.accounts[this.currentIndex].trustedNo = msg.vote == "N"; 374 | if (msg.vote == "N") { 375 | this._setAutoFeedbackTimer(); 376 | this._setAutoHideTimer(); 377 | this.submit = false; 378 | for (portId in this.ports) 379 | this.ports[portId].postMessage( { 380 | init : true, 381 | forceSetAccount : true 382 | }); 383 | } 384 | } else if (msg.openAccount) 385 | chrome.tabs.create( { 386 | index : this.tabIndex + 1, 387 | url : 'http://www.bugmenot.com/view/' + encodeURI(this.hosts[0]), 388 | selected : false 389 | }); 390 | else if (msg.addAccount) 391 | chrome.tabs.create( { 392 | index : this.tabIndex + 1, 393 | url : "http://www.bugmenot.com/submit.php?" + encodeURI(this.hosts[0]), 394 | selected : false 395 | }); 396 | else { 397 | if (msg.noFeedback || msg.noSiteFeedback || msg.cancel) { 398 | this.displayPopup = false; 399 | this.submit = false; 400 | this._showIcon(); 401 | } 402 | if (msg.noFeedback) 403 | this.noFeedback = true; 404 | else if (msg.noSiteFeedback) 405 | this.noSiteFeedback = true; 406 | } 407 | }; 408 | 409 | /** 410 | * Show feedback icon if needed and send "init" action message to content 411 | * script. 412 | * 413 | * @param {Port} port 414 | * @param {Boolean} topWindow 415 | */ 416 | TabData.prototype.onInit = function(port, topWindow) { 417 | if (topWindow && config.autoFeedbackDelay() == -1) 418 | this._showFeedbackIcon(); 419 | port.postMessage( { 420 | init : true, 421 | forceSetAccount : this.submit 422 | }); 423 | this.submit = false; 424 | }; 425 | 426 | /** 427 | * Show optional contextual popup or fill account. 428 | */ 429 | TabData.prototype.onClick = function() { 430 | if (this.accounts.length == 0) { 431 | if (this.notBlocked) { 432 | if (!config.dynPopupUnvailable) { 433 | chrome.pageAction.setPopup( { 434 | tabId : this.id, 435 | popup : "popupDef.html?tabId=" + this.id 436 | }); 437 | } else { 438 | chrome.tabs.create( { 439 | index : this.tabIndex + 1, 440 | url : 'http://www.bugmenot.com/view/' + encodeURI(this.hosts[0]), 441 | selected : false 442 | }); 443 | } 444 | } 445 | } else { 446 | this.submit = false; 447 | this._setAccount(); 448 | this._clearAutoHideTimer(); 449 | this._setAutoFeedbackTimer(); 450 | this._setAutoHideTimer(); 451 | } 452 | }; 453 | 454 | /** 455 | * Call TabData.onSubmitFeedback for the right tab. 456 | * 457 | * @param {Object} msg 458 | */ 459 | function submitFeeedBack(msg) { 460 | chrome.tabs.get(msg.tabId, function(tab) { 461 | tabs[msg.tabId].onSubmitFeedback(tab.index, msg); 462 | }); 463 | } 464 | 465 | chrome.pageAction.onClicked.addListener(function(tab) { 466 | tabs[tab.id].onClick(); 467 | }); 468 | 469 | chrome.extension.onConnect.addListener(function(port) { 470 | port.onDisconnect.addListener(function(msg) { 471 | if (port.sender.tab && tabs[port.sender.tab.id]) 472 | delete tabs[port.sender.tab.id].ports[port.portId_]; 473 | }); 474 | 475 | port.onMessage.addListener(function(msg) { 476 | var tabId = port.sender.tab.id, tabData = tabs[tabId]; 477 | if (msg.init) { 478 | if (tabData) 479 | tabData.onInit(port, msg.topWindow); 480 | else 481 | port.postMessage( { 482 | init : true 483 | }); 484 | } else if (msg.searchAccounts) { 485 | if (!tabData) { 486 | tabData = new TabData(tabId); 487 | tabs[tabId] = tabData; 488 | } 489 | tabData.onSearchAccounts(msg.host, port, msg.forceSetAccount); 490 | } else if (msg.selectIndex) 491 | tabData.onSelectIndex(msg.index); 492 | else if (msg.submitForm) 493 | tabData.onSubmitForm(msg.index); 494 | }); 495 | }); -------------------------------------------------------------------------------- /WebContent/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var config = { 22 | dynPopupUnvailable : !chrome.pageAction.setPopup, 23 | autoHideDelay : function() { 24 | return parseInt(window.localStorage["autoHideDelay"], 10) || -1; 25 | }, 26 | alwaysAutoSubmit : function() { 27 | return window.localStorage["alwaysAutoSubmit"] || ""; 28 | }, 29 | autoFeedbackDelay : function() { 30 | return parseInt(window.localStorage["autoFeedbackDelay"], 10) || (config.dynPopupUnvailable ? -2 : -1); 31 | }, 32 | maxSize : function() { 33 | return parseInt(window.localStorage["maxSize"], 10) || -1; 34 | }, 35 | minRating : function() { 36 | return parseInt(window.localStorage["minRating"], 10) || 0; 37 | }, 38 | dontStoreVote : function() { 39 | return window.localStorage["dontStoreVote"]; 40 | }, 41 | neverVoteTwice : function() { 42 | return window.localStorage["neverVoteTwice"]; 43 | } 44 | }; -------------------------------------------------------------------------------- /WebContent/content.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var port = chrome.extension.connect(), formsData = new FormsData(); 22 | 23 | /** 24 | * Hack to fire a fake submit event when HTMLFormElement.submit method is used. 25 | */ 26 | function _injectSubmitScript() { 27 | var functionScript = document.getElementById("__bmn_injectSubmitHookFn__"); 28 | function __bmn_injectSubmitHook__() { 29 | Array.prototype.forEach.call(arguments, function(i) { 30 | var form = document.forms[i], submitFunction = form.submit; 31 | if (!submitFunction || (typeof (submitFunction) == "function" && submitFunction.name != "__bmn_submitHook__")) { 32 | form.submit = function __bmn_submitHook__() { 33 | var submitEvent = document.createEvent('Event'); 34 | submitEvent.initEvent('submit', true, true); 35 | form.dispatchEvent(submitEvent); 36 | return submitFunction ? submitFunction.call(form) : true; 37 | }; 38 | } 39 | }); 40 | } 41 | if (formsData.getFormsIndex().length) { 42 | if (!functionScript) { 43 | functionScript = document.createElement("script"); 44 | functionScript.setAttribute("type", "text/javascript"); 45 | functionScript.id = "__bmn_injectSubmitHookFn__"; 46 | functionScript.innerHTML = __bmn_injectSubmitHook__.toString(); 47 | document.head.appendChild(functionScript); 48 | } 49 | } 50 | } 51 | 52 | /** 53 | * FormData constructor. 54 | * 55 | * @param {HTMLFormElement} form 56 | * @param {HTMLInputElement} loginInput 57 | * @param {HTMLInputElement} passwordInput 58 | * @param {HTMLInputElement} submitInput 59 | */ 60 | function FormData(form, index, loginInput, passwordInput, submitInput) { 61 | this.form = form; 62 | this.index = index; 63 | this.loginInput = loginInput; 64 | this.passwordInput = passwordInput; 65 | this.submitInput = submitInput; 66 | } 67 | 68 | /** 69 | * Notify form submit to background page 70 | * 71 | * @param {HTMLSelectElement} loginSelect 72 | */ 73 | FormData.prototype._notifySubmitForm = function() { 74 | port.postMessage( { 75 | submitForm : true, 76 | index : this.loginSelect.selectedIndex, 77 | login : this.loginSelect.value 78 | }); 79 | formsData.submit = true; 80 | }; 81 | 82 | /** 83 | * Initialize the login HTMLSelectElement element. 84 | * 85 | * @param {Array} accounts 86 | */ 87 | FormData.prototype._initLoginSelect = function(accounts) { 88 | var option, that = this, style, property, value; 89 | function selectOnchange() { 90 | if (that.loginSelect.value) { 91 | that.loginInput.value = that.loginSelect.value; 92 | that.passwordInput.value = that.loginSelect.options[that.loginSelect.selectedIndex].password; 93 | port.postMessage( { 94 | selectIndex : true, 95 | index : that.loginSelect.selectedIndex 96 | }); 97 | } else { 98 | that.loginSelect.parentElement.removeChild(this); 99 | that.loginInput.style.display = "inline-block"; 100 | that.loginInput.value = ""; 101 | that.passwordInput.value = ""; 102 | that.loginInput.focus(); 103 | } 104 | } 105 | Array.prototype.forEach.call(this.loginInput.attributes, function(attribute) { 106 | if (attribute.name != "name" && attribute.name != "id") 107 | that.loginSelect.setAttribute(attribute.name, attribute.value); 108 | }); 109 | style = getComputedStyle(that.loginInput); 110 | for (property in style) { 111 | if (style[property] != "-webkit-appearance" && style[property] != "white-space") { 112 | value = style.getPropertyCSSValue(style[property]); 113 | if (value) 114 | that.loginSelect.style[style[property]] = value.cssText; 115 | } 116 | } 117 | accounts.forEach(function(account) { 118 | option = new Option("(" + account.rating + "%) - " + account.login, account.login, true); 119 | that.loginSelect.options[that.loginSelect.options.length] = option; 120 | option = that.loginSelect.options[that.loginSelect.options.length - 1]; 121 | option.password = account.password; 122 | if (account.trustedYes) 123 | option.style.backgroundColor = "#a9dea2"; 124 | else if (account.trustedNo) 125 | option.style.backgroundColor = "#dea2ad"; 126 | }); 127 | option = new Option("", ""); 128 | option.disabled = true; 129 | this.loginSelect.options[this.loginSelect.options.length] = option; 130 | option = new Option(">> " + chrome.i18n.getMessage("manualLogin"), ""); 131 | option.style.backgroundColor = "#dddddd"; 132 | this.loginSelect.options[this.loginSelect.options.length] = option; 133 | this.loginSelect.onchange = selectOnchange; 134 | this.loginSelect.onfocus = null; 135 | this.loginSelect.size = 1; 136 | }; 137 | 138 | /** 139 | * Put select element and hide login element in all login forms. 140 | * 141 | * @param {Object} account 142 | * @param {Array} accounts 143 | */ 144 | FormData.prototype.init = function(account, accounts) { 145 | var that = this; 146 | location.href= "javascript:__bmn_injectSubmitHook__(" + formsData.getFormsIndex().join(",") + ");"; 147 | if (!this.loginSelect) { 148 | this.loginSelect = document.createElement("select"); 149 | this._initLoginSelect(accounts); 150 | this.form.addEventListener("submit", function() { 151 | if (that.loginSelect.offsetWidth) 152 | that._notifySubmitForm(); 153 | }); 154 | if (this.submitInput) 155 | this.submitInput.addEventListener("click", function() { 156 | if (that.loginSelect.offsetWidth) 157 | that._notifySubmitForm(); 158 | }, false); 159 | } 160 | if (!this.loginSelect.offsetWidth) { 161 | this.loginInput.parentNode.insertBefore(this.loginSelect, this.loginInput); 162 | this.loginInput.style.display = "none"; 163 | } 164 | this.loginSelect.value = account.login; 165 | this.loginInput.value = account.login; 166 | this.passwordInput.value = account.password; 167 | this.loginSelect.focus(); 168 | }; 169 | 170 | /** 171 | * Submit login form. 172 | */ 173 | FormData.prototype.submit = function() { 174 | var fakeSubmitInput; 175 | this._notifySubmitForm(); 176 | this.loginInput.value = this.loginSelect.value; 177 | this.passwordInput.value = this.loginSelect.options[this.loginSelect.selectedIndex].password; 178 | if (this.submitInput != null && this.submitInput.name == "submit") { 179 | fakeSubmitInput = document.createElement("input"); 180 | Array.prototype.forEach.call(this.submitInput.attributes, function(attribute) { 181 | fakeSubmitInput.setAttribute(attribute.name, attribute.value); 182 | }); 183 | fakeSubmitInput.type = "hidden"; 184 | this.submitInput.parentNode.appendChild(fakeSubmitInput); 185 | this.submitInput.setAttribute("name", ""); 186 | } 187 | HTMLFormElement.prototype.submit.call(this.form); 188 | }; 189 | 190 | /** 191 | * FormsData constructor. 192 | */ 193 | function FormsData() { 194 | this.forms = []; 195 | this.submit = false; 196 | this.deferredPrepare = null; 197 | }; 198 | 199 | /** 200 | * Find login form elements (i.e. login, password and and optional submit). 201 | * 202 | * @param {NodeList} forms 203 | */ 204 | FormsData.prototype._findFormElements = function(forms) { 205 | var passwordInput, loginInput, submitInput, elements, element, i, j, passwordIndex, visibleElementIndex; 206 | for (i = 0; i < forms.length; i++) { 207 | elements = forms[i].elements; 208 | passwordInput = null; 209 | loginInput = null; 210 | submitInput = null; 211 | visibleElementIndex = 0; 212 | passwordIndex = 0; 213 | for (j = elements.length - 1; j >= 0 && !(passwordInput && loginInput); j--) { 214 | element = elements[j]; 215 | if (!passwordInput && !loginInput && !submitInput && element.type == "submit") 216 | submitInput = element; 217 | if (!passwordInput) { 218 | if (element.type == "password") { 219 | passwordIndex = visibleElementIndex; 220 | passwordInput = element; 221 | } 222 | } else if (element.type == "password" && (passwordIndex + 1 == visibleElementIndex)) 223 | passwordInput = null; 224 | else if (passwordInput && (!element.type || element.type == "text" || element.type == "email")) 225 | loginInput = element; 226 | if (element.type != "hidden") 227 | visibleElementIndex++; 228 | } 229 | if (passwordInput && loginInput) { 230 | if (!submitInput) { 231 | elements = forms[i].querySelectorAll("input, button"); 232 | for (j = elements.length - 1; j >= 0 && !submitInput; j--) { 233 | element = elements[j]; 234 | if (element.outerHTML.toLowerCase().indexOf("submit") != -1 && element.type != "hidden") 235 | submitInput = element; 236 | } 237 | } 238 | if (!submitInput) { 239 | elements = forms[i].querySelectorAll("input, button, a"); 240 | for (j = elements.length - 1; j >= 0 && !submitInput; j--) { 241 | element = elements[j]; 242 | if (element.outerHTML.toLowerCase().match(/log|submit|sign/i)) 243 | submitInput = element; 244 | } 245 | } 246 | j = 0; 247 | while (j < this.forms.length && this.forms[j].loginInput != loginInput && this.forms[j].passwordInput != passwordInput 248 | && this.forms[j].submitInput != submitInput) 249 | j++; 250 | if (j == this.forms.length) 251 | this.forms.push(new FormData(forms[i], i, loginInput, passwordInput, submitInput)); 252 | } 253 | } 254 | _injectSubmitScript(); 255 | }; 256 | 257 | /** 258 | * Set account data into login and password elements. 259 | * 260 | * @param {Object} account 261 | * @param {Array} accounts 262 | * @param {Boolean} autoSubmit 263 | */ 264 | FormsData.prototype.init = function(account, accounts, autoSubmit) { 265 | this.submit = false; 266 | if (account) { 267 | this._findFormElements(document.forms); 268 | this.forms.forEach(function(form) { 269 | form.init(account, accounts); 270 | }); 271 | if (this.forms[0] && autoSubmit) 272 | this.forms[0].submit(); 273 | } 274 | }; 275 | 276 | /** 277 | * Initialize content script. 278 | * 279 | * @param {Boolean} forceSetAccount 280 | */ 281 | FormsData.prototype.prepare = function(forceSetAccount) { 282 | this._findFormElements(document.forms); 283 | if (this.forms.length) 284 | port.postMessage( { 285 | searchAccounts : true, 286 | host : encodeURIComponent(location.host), 287 | forceSetAccount : forceSetAccount 288 | }); 289 | }; 290 | 291 | /** 292 | * Return submit forms index. 293 | * 294 | * @return {Array} array of index 295 | */ 296 | FormsData.prototype.getFormsIndex = function() { 297 | return this.forms.map(function(form) { 298 | return form.index; 299 | }); 300 | }; 301 | 302 | port.onMessage.addListener(function(msg) { 303 | if (msg.setAccount) 304 | formsData.init(msg.account, msg.accounts, msg.autoSubmit); 305 | else if (msg.init) 306 | formsData.prepare(msg.forceSetAccount, msg.autoSubmit); 307 | }); 308 | 309 | document.addEventListener('keypress', function(event) { 310 | if (event.ctrlKey && event.charCode == 9) 311 | formsData.prepare(true); 312 | }, true); 313 | 314 | document.addEventListener("DOMNodeInsertedIntoDocument", function(event) { 315 | if (!formsData.deferredPrepare && event.target && event.target.tagName 316 | && (event.target.tagName.toLowerCase() == "form" || event.target.tagName.toLowerCase() == "input")) 317 | formsData.deferredPrepare = setTimeout(function() { 318 | formsData.prepare(formsData.submit); 319 | formsData.submit = false; 320 | formsData.deferredPrepare = null; 321 | }, 200); 322 | }, true); 323 | 324 | // START 325 | if (document.location.href.indexOf("http://www.bugmenot.com/submit.php?") == 0) { 326 | document.getElementById("host").value = decodeURI(document.location.search.substr(1)); 327 | document.getElementById("f_username").focus(); 328 | } else 329 | port.postMessage( { 330 | init : true, 331 | topWindow : window == top, 332 | host : encodeURIComponent(location.host) 333 | }); -------------------------------------------------------------------------------- /WebContent/iconBlocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/iconBlocked.png -------------------------------------------------------------------------------- /WebContent/iconFeedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/iconFeedback.png -------------------------------------------------------------------------------- /WebContent/iconPlus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/iconPlus.png -------------------------------------------------------------------------------- /WebContent/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/icon_128.png -------------------------------------------------------------------------------- /WebContent/icon_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/icon_48.png -------------------------------------------------------------------------------- /WebContent/icon_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/icon_bg.png -------------------------------------------------------------------------------- /WebContent/icon_more.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/BugMeNot-Lite/caa3659a4335a32f3befb849f211e78f3497b575/WebContent/icon_more.gif -------------------------------------------------------------------------------- /WebContent/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "default_locale" : "en", 3 | "name" : "__MSG_bugmenot_name__", 4 | "icons" : { 5 | "48" : "icon_48.png", 6 | "128" : "icon_128.png" 7 | }, 8 | "version" : "0.3.10", 9 | "description" : "__MSG_bugmenot_description__", 10 | "content_scripts" : [ { 11 | "matches" : [ "http://*/*", "https://*/*" ], 12 | "js" : [ "content.js" ], 13 | "run_at" : "document_end", 14 | "all_frames" : true 15 | } ], 16 | "background" : { 17 | "scripts": [ 18 | "accountStorage.js", 19 | "config.js", 20 | "background.js" 21 | ] 22 | }, 23 | "options_page": "options.html", 24 | "page_action" : { 25 | "default_icon" : "icon_48.png" 26 | }, 27 | "permissions" : [ "tabs", "http://www.bugmenot.com/" ], 28 | "manifest_version": 2 29 | } -------------------------------------------------------------------------------- /WebContent/options.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | body>div { 22 | position: relative; 23 | margin: 0px auto; 24 | width: 450px; 25 | font-family: sans-serif; 26 | background-color: #F3F7FC; 27 | border: 1px solid #D2DBED; 28 | font-family: Arial, sans-serif; 29 | font-size: 13px; 30 | } 31 | 32 | body>div>div { 33 | padding-left: 10px; 34 | padding-right: 10px; 35 | } 36 | 37 | .optionBlock { 38 | overflow: hidden; 39 | height: 35px; 40 | } 41 | 42 | h2 { 43 | font-size: 17px; 44 | font-weight: bold; 45 | margin-bottom: 30px; 46 | } 47 | 48 | label { 49 | display: inline-block; 50 | width: 325px; 51 | } 52 | 53 | img + label { 54 | width: 303px; 55 | } 56 | 57 | 58 | select,button { 59 | width: 100px; 60 | } 61 | 62 | select { 63 | margin-top: 0px; 64 | } 65 | 66 | button { 67 | background: -webkit-gradient(linear, left bottom, left top, color-stop(0.12, rgb(191 68 | , 191, 191) ), color-stop(0.79, rgb(247, 247, 247) ) ); 69 | border-color: rgb(191, 191, 191); 70 | border-style: solid; 71 | } 72 | 73 | button:active { 74 | border-color: rgb(247, 247, 247); 75 | } 76 | 77 | .open, .close { 78 | -webkit-transition-duration: 250ms; 79 | -webkit-transition-delay: 0, 250ms; 80 | } 81 | 82 | .open { 83 | -webkit-transition-property: height, opacity; 84 | } 85 | 86 | .close { 87 | -webkit-transition-property: opacity, height; 88 | } 89 | 90 | input[type="checkbox"] { 91 | width: auto; 92 | margin-left: 85px; 93 | margin-bottom: 5px; 94 | margin-top: 5px; 95 | } 96 | 97 | #main { 98 | display: none; 99 | border-radius: 5px; 100 | } 101 | 102 | .more { 103 | padding-right: 5px; 104 | padding-left: 2px; 105 | } 106 | 107 | #icon { 108 | width: 25px; 109 | padding-right: 10px; 110 | vertical-align: bottom; 111 | } -------------------------------------------------------------------------------- /WebContent/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BugMeNot Lite Options 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |

icon

13 |
14 | 15 | 17 |
18 |
19 | 20 | 26 |
27 |
28 | 29 | 31 |
32 |
33 | 34 | 36 |
37 |
38 |
39 | more 40 | 41 | 42 |
43 |
44 | more 45 | 46 | 47 |
48 |
49 | more 50 | 51 | 52 |
53 |
54 | more 55 | 56 | 57 |
58 |
59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /WebContent/options.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var autoHideDelayInput, neverAskFeedbackBlock, alwaysAutoSubmitInput, autoFeedbackDelayInput, maxSizeInput, minRatingInput, dontStoreVoteInput, neverVoteTwiceInput, deleteDatabaseInput; 22 | 23 | function changeAutoFeedbackDelay(fast) { 24 | if (autoFeedbackDelayInput.value >= -1) { 25 | neverAskFeedbackBlock.style.pixelHeight = 140; 26 | neverAskFeedbackBlock.style.opacity = 1; 27 | if (!fast) 28 | neverAskFeedbackBlock.className = "open"; 29 | } else { 30 | neverAskFeedbackBlock.style.pixelHeight = 0; 31 | neverAskFeedbackBlock.style.opacity = 0; 32 | if (!fast) 33 | neverAskFeedbackBlock.className = "close"; 34 | } 35 | }; 36 | 37 | neverAskFeedbackBlock = document.getElementById("neverAskFeedbackBlock"); 38 | autoHideDelayInput = document.getElementById("autoHideDelayInput"); 39 | alwaysAutoSubmitInput = document.getElementById("alwaysAutoSubmitInput"); 40 | autoFeedbackDelayInput = document.getElementById("autoFeedbackDelayInput"); 41 | maxSizeInput = document.getElementById("maxSizeInput"); 42 | minRatingInput = document.getElementById("minRatingInput"); 43 | dontStoreVoteInput = document.getElementById("dontStoreVoteInput"); 44 | neverVoteTwiceInput = document.getElementById("neverVoteTwiceInput"); 45 | deleteDatabaseInput = document.getElementById("deleteDatabaseInput"); 46 | 47 | document.getElementById("title").innerHTML = chrome.i18n.getMessage("optionsTitle"); 48 | document.getElementById("maxSizeLabel").innerHTML = chrome.i18n.getMessage("maxSize"); 49 | document.getElementById("minRatingLabel").innerHTML = chrome.i18n.getMessage("minRating"); 50 | document.getElementById("autoHideDelayLabel").innerHTML = chrome.i18n.getMessage("autoHideDelay"); 51 | document.getElementById("autoFeedbackDelayLabel").innerHTML = chrome.i18n.getMessage("autoFeedbackDelay"); 52 | document.getElementById("alwaysAutoSubmitLabel").innerHTML = chrome.i18n.getMessage("alwaysAutoSubmit"); 53 | document.getElementById("neverVoteTwiceLabel").innerHTML = chrome.i18n.getMessage("neverVoteTwice"); 54 | document.getElementById("dontStoreVoteLabel").innerHTML = chrome.i18n.getMessage("dontStoreVote"); 55 | document.getElementById("deleteDatabaseLabel").innerHTML = chrome.i18n.getMessage("deleteDatabase"); 56 | document.getElementById("deleteDatabaseInput").innerHTML = chrome.i18n.getMessage("deleteDatabaseInput"); 57 | maxSizeInput.options[0] = new Option(chrome.i18n.getMessage("maxSizeShowAll"), -1); 58 | maxSizeInput.options[1] = new Option("50", 50); 59 | maxSizeInput.options[2] = new Option("20", 20); 60 | maxSizeInput.options[3] = new Option("10", 10); 61 | maxSizeInput.options[4] = new Option("5", 5); 62 | autoHideDelayInput.options[0] = new Option(chrome.i18n.getMessage("autoHideDelayNever"), -1); 63 | autoHideDelayInput.options[1] = new Option(chrome.i18n.getMessage("autoHideDelay5s"), 5); 64 | autoHideDelayInput.options[2] = new Option(chrome.i18n.getMessage("autoHideDelay10s"), 10); 65 | autoHideDelayInput.options[3] = new Option(chrome.i18n.getMessage("autoHideDelay20s"), 20); 66 | autoFeedbackDelayInput.options[0] = new Option(chrome.i18n.getMessage("autoFeedbackDelayNever"), -2); 67 | autoFeedbackDelayInput.options[1] = new Option(chrome.i18n.getMessage("autoFeedbackDelayAfterSubmit"), -1); 68 | autoFeedbackDelayInput.options[2] = new Option(chrome.i18n.getMessage("autoFeedbackDelay0s"), 0); 69 | autoFeedbackDelayInput.options[3] = new Option(chrome.i18n.getMessage("autoFeedbackDelay5s"), 5); 70 | autoFeedbackDelayInput.options[4] = new Option(chrome.i18n.getMessage("autoFeedbackDelay10s"), 10); 71 | autoFeedbackDelayInput.options[5] = new Option(chrome.i18n.getMessage("autoFeedbackDelay20s"), 20); 72 | 73 | autoHideDelayInput.value = config.autoHideDelay(); 74 | alwaysAutoSubmitInput.checked = config.alwaysAutoSubmit() == "alwaysAutoSubmit"; 75 | dontStoreVoteInput.checked = config.dontStoreVote() == "dontStoreVote"; 76 | neverVoteTwiceInput.checked = config.neverVoteTwice() == "neverVoteTwice"; 77 | autoFeedbackDelayInput.value = config.autoFeedbackDelay(); 78 | maxSizeInput.value = config.maxSize(); 79 | minRatingInput.value = config.minRating(); 80 | if (config.dynPopupUnvailable) 81 | document.getElementById("autoFeedbackDelayBlock").style.display = "none"; 82 | autoFeedbackDelayInput.onchange = function() { 83 | changeAutoFeedbackDelay(); 84 | }; 85 | changeAutoFeedbackDelay(true); 86 | 87 | autoHideDelayInput.addEventListener("change", function() { 88 | localStorage["autoHideDelay"] = autoHideDelayInput.value; 89 | }, false); 90 | alwaysAutoSubmitInput.addEventListener("change", function() { 91 | localStorage["alwaysAutoSubmit"] = alwaysAutoSubmitInput.checked ? "alwaysAutoSubmit" : ""; 92 | }, false); 93 | autoFeedbackDelayInput.addEventListener("change", function() { 94 | localStorage["autoFeedbackDelay"] = autoFeedbackDelayInput.value; 95 | }, false); 96 | maxSizeInput.addEventListener("change", function() { 97 | localStorage["maxSize"] = maxSizeInput.value; 98 | }, false); 99 | minRatingInput.addEventListener("change", function() { 100 | localStorage["minRating"] = minRatingInput.value; 101 | }, false); 102 | dontStoreVoteInput.addEventListener("change", function() { 103 | localStorage["dontStoreVote"] = dontStoreVoteInput.checked ? "dontStoreVote" : ""; 104 | }, false); 105 | neverVoteTwiceInput.addEventListener("change", function() { 106 | localStorage["neverVoteTwice"] = neverVoteTwiceInput.checked ? "neverVoteTwice" : ""; 107 | }, false); 108 | deleteDatabaseInput.addEventListener("click", function() { 109 | accountStorage.reset(); 110 | }, false); 111 | document.getElementById('main').style.display = 'block'; 112 | -------------------------------------------------------------------------------- /WebContent/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 78 | 79 | 80 |
81 |
82 | 83 | 84 | 85 |
86 |
87 | 88 | 89 |
90 |
91 |  
92 |
93 | 94 |
95 |
96 | 97 |
98 |
99 | 100 |
101 |
102 | 103 | 104 | 107 | 108 |
105 | 106 |
109 |
110 | 111 | 112 |
113 | 114 | -------------------------------------------------------------------------------- /WebContent/popup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var loginInput = document.getElementById("login"); 22 | var yesInput = document.getElementById("yes"); 23 | var noInput = document.getElementById("no"); 24 | var noFeedbackInput = document.getElementById("noFeedbackInput"); 25 | var tabNoFeedbackInput = document.getElementById("tabNoFeedbackInput"); 26 | var siteNoFeedbackInput = document.getElementById("siteNoFeedbackInput"); 27 | 28 | function answerNo() { 29 | chrome.extension.getBackgroundPage().submitFeeedBack({ 30 | autoSubmit : document.getElementById("autoSubmit").checked, 31 | vote : "N", 32 | tabId : parseInt(params.tabId, 10) 33 | }); 34 | close(); 35 | } 36 | function answerYes() { 37 | chrome.extension.getBackgroundPage().submitFeeedBack({ 38 | vote : "Y", 39 | tabId : parseInt(params.tabId, 10) 40 | }); 41 | close(); 42 | } 43 | function answerNoFeedback() { 44 | chrome.extension.getBackgroundPage().submitFeeedBack({ 45 | tabId : parseInt(params.tabId, 10), 46 | noFeedback : true 47 | }); 48 | close(); 49 | } 50 | function answerCancel() { 51 | chrome.extension.getBackgroundPage().submitFeeedBack({ 52 | tabId : parseInt(params.tabId, 10), 53 | cancel : true 54 | }); 55 | close(); 56 | } 57 | function answerNoSiteFeedback() { 58 | chrome.extension.getBackgroundPage().submitFeeedBack({ 59 | tabId : parseInt(params.tabId, 10), 60 | noSiteFeedback : true 61 | }); 62 | close(); 63 | } 64 | function openAccount(closePopup) { 65 | chrome.extension.getBackgroundPage().submitFeeedBack({ 66 | tabId : parseInt(params.tabId, 10), 67 | openAccount : true 68 | }); 69 | if (closePopup) 70 | close(); 71 | } 72 | 73 | loginInput.addEventListener("click", openAccount, false); 74 | yesInput.addEventListener("click", answerYes, false); 75 | noInput.addEventListener("click", answerNo, false); 76 | noFeedbackInput.addEventListener("click", answerCancel, false); 77 | tabNoFeedbackInput.addEventListener("click", answerNoFeedback, false); 78 | siteNoFeedbackInput.addEventListener("click", answerNoSiteFeedback, false); 79 | loginInput.innerHTML = decodeURI(params.login); 80 | document.getElementById("login").title = chrome.i18n.getMessage("password") + ' : "' + decodeURI(params.password) + '"'; 81 | document.getElementById("autoSubmit").checked = params.autoSubmit == "yes"; 82 | document.getElementById("questionPart1").innerHTML = chrome.i18n.getMessage("questionPart1"); 83 | document.getElementById("questionPart2").innerHTML = chrome.i18n.getMessage("questionPart2"); 84 | yesInput.innerHTML = chrome.i18n.getMessage("yes"); 85 | noInput.innerHTML = chrome.i18n.getMessage("no"); 86 | document.getElementById("autoSubmitLabel").innerHTML = chrome.i18n.getMessage("autoSubmit"); 87 | noFeedbackInput.innerHTML = chrome.i18n.getMessage("noFeedback"); 88 | tabNoFeedbackInput.innerHTML = chrome.i18n.getMessage("tabNoFeedback"); 89 | siteNoFeedbackInput.innerHTML = chrome.i18n.getMessage("siteNoFeedback"); -------------------------------------------------------------------------------- /WebContent/popupCommon.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of BugMeNot Lite. 6 | * 7 | * BugMeNot Lite is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * BugMeNot Lite is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with BugMeNot Lite. If not, see . 19 | */ 20 | 21 | var params = getUrlParams(); 22 | var addAccountLink = document.getElementById("addAccountLink"); 23 | 24 | function getUrlParams() { 25 | var i, ret = {}, urlParams = window.location.search.substr(1).split('&'), value; 26 | for (i = 0; i < urlParams.length; i++) { 27 | value = urlParams[i].split('='); 28 | ret[value[0]] = value[1]; 29 | } 30 | return ret; 31 | } 32 | 33 | function addAccount() { 34 | chrome.extension.getBackgroundPage().submitFeeedBack({ 35 | tabId : parseInt(params.tabId, 10), 36 | addAccount : true 37 | }); 38 | close(); 39 | } 40 | 41 | addAccountLink.addEventListener("click", addAccount, false); 42 | addAccountLink.innerHTML = chrome.i18n.getMessage("addAccount"); -------------------------------------------------------------------------------- /WebContent/popupDef.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 |
17 |

18 | 19 | 20 | 23 | 24 |
21 | 22 |
25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /WebContent/popupDef.js: -------------------------------------------------------------------------------- 1 | document.getElementById("noAvailableAccounts").innerHTML = chrome.i18n.getMessage("noAvailableAccounts"); 2 | document.getElementById("addAccountLink").innerHTML = chrome.i18n.getMessage("addAccount"); --------------------------------------------------------------------------------