BugMeNot

Integrates BugMeNot into any login form (it retrieves all matching logins from bugmenot.com and autofills the login form)

  1. // ==UserScript==
  2. // @name BugMeNot
  3. // @namespace darkred
  4. // @version 2017.12.15
  5. // @description Integrates BugMeNot into any login form (it retrieves all matching logins from bugmenot.com and autofills the login form)
  6. // @authors hosts, Matt McCarthy, darkred
  7. // @license MIT
  8. // @include http://*
  9. // @include https://*
  10. // @exclude http://bugmenot.com/*
  11. // @grant GM.getValue
  12. // @grant GM_getValue
  13. // @grant GM.setValue
  14. // @grant GM_setValue
  15. // @grant GM.openInTab
  16. // @grant GM_openInTab
  17. // @grant GM.xmlHttpRequest
  18. // @grant GM_xmlhttpRequest
  19. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  20. // @noframes
  21. // @run-at document-idle
  22. // @supportURL https://github.com/darkred/Userscripts/issues
  23. // ==/UserScript==
  24.  
  25. // // @grant GM.listValues
  26.  
  27. // latest version by hosts: 01.03.09
  28. // based on code found at http://www.oreillynet.com/pub/h/4171
  29. // ----------------------------
  30. // based on code by Matt McCarthy
  31. // and included here with his gracious permission
  32.  
  33. /* global GM */
  34.  
  35.  
  36.  
  37. function copyProperties(to, from) {
  38. for (var i in from) {
  39. to[i] = from[i];
  40. }
  41. }
  42.  
  43. function main() {
  44. processPasswordFields();
  45. }
  46.  
  47. function getBmnWrapper(pwFieldIndex) {
  48. return document.getElementById('reify-bugmenot-bmnWrapper' + pwFieldIndex);
  49. }
  50.  
  51.  
  52. function processPasswordFields() {
  53. (async function() {
  54. var allInputs = document.getElementsByTagName('input');
  55. //allInputslength = allInputs.length;
  56. var bmnContainer = document.createElement('div');
  57. bmnContainer.id = 'reify-bugmenot-container';
  58. var bodyEl = document.getElementsByTagName('body')[0];
  59. if (!bodyEl) return;
  60. for (var i = 0; i < allInputs.length; i++) {
  61. var pwField = allInputs[i];
  62. // console.log(allInputs[i].type.toLowerCase());
  63. if (!(pwField.type && pwField.type.toLowerCase() == 'password')) {
  64. continue;
  65. }
  66. var previousTextFieldInd = getPreviousTextField(i, allInputs);
  67. if (previousTextFieldInd == - 1) {
  68. if (DEBUG) {
  69. console.log('Couldn\'t find text field before password input ' + i + '.');
  70. continue;
  71. }
  72. }
  73. var usernameField = allInputs[previousTextFieldInd];
  74. usernameField.blur(); // Workaround for when the Username textbox has focus by default on page load
  75. usernameField.setAttribute('usernameInputIndex', previousTextFieldInd);
  76. usernameField.setAttribute('passwordInputIndex', i);
  77. Utility.addEventHandler(usernameField, 'focus', usernameField_onfocus);
  78. Utility.addEventHandler(usernameField, 'blur', usernameField_onblur);
  79. Utility.addEventHandler(pwField, 'focus', pwField_onfocus);
  80. Utility.addEventHandler(pwField, 'blur', pwField_onblur);
  81. pwField.setAttribute('usernameInputIndex', previousTextFieldInd);
  82. pwField.setAttribute('passwordInputIndex', i);
  83.  
  84. // var getLoginLink = menuLink(bmnUri, 'Get login from BugMeNot', 'Get a login from BugMeNot', getLoginLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
  85.  
  86. // console.log('counter2: ' + counter);
  87. if (counter === 0) {
  88. // counter = 0;
  89. var myprompt = 'Get login from BugMeNot' + ' (' + (counter + 1) + '/-)';
  90. var myprompt2 = 'Get a login from BugMeNot';
  91. } else {
  92. // var total = JSON.parse(await GM.getValue('allUsernames')).length
  93. var total;
  94. total = JSON.parse(await GM.getValue('allUsernames')).length ;
  95. // console.log('total: ' + total + ' | ' + ' counter: ' + counter);
  96. // console.log(counter <= total);
  97.  
  98.  
  99. if (counter + 1 <= total) {
  100. myprompt = 'Try next login from BugMeNot' + ' (' + (counter + 1) + '/' + total + ')';
  101. myprompt2 = 'Try next login';
  102. } else {
  103. myprompt = 'No other logins';
  104. myprompt2 = 'No other logins available';
  105. }
  106. // })();
  107.  
  108. }
  109.  
  110. var getLoginLink = menuLink(bmnUri, myprompt, myprompt2, getLoginLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
  111. var getLoginLinkWrapper = menuEntry(getLoginLink, Style.menuLinkWrapper);
  112.  
  113. if (counter > 0) {
  114. var resetCounterLink = menuLink('', 'Reset login attempt counter', 'Resets the login attempt counter (reloads the page)', resetCounterLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
  115. var resetCounterLinkWrapper = menuEntry(resetCounterLink, Style.menuLinkWrapper);
  116. }
  117.  
  118. var fullFormLink = menuLink(bmnUri, 'More options', 'See more options for getting logins from BugMeNot.com ' + '(opens a new window)', openMenuLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
  119. var fullFormLinkWrapper = menuEntry(fullFormLink, Style.menuLinkWrapper);
  120.  
  121. var visitBmnLink = menuLink(bmnHomeUri, 'Visit BugMeNot', 'Go to the BugMeNot home page (opens a new window)', openMenuLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
  122. var visitBmnLinkWrapper = menuEntry(visitBmnLink, Style.menuLinkWrapper);
  123.  
  124.  
  125. var bmnWrapper = document.createElement('div');
  126. bmnWrapper.id = 'reify-bugmenot-bmnWrapper' + i;
  127. bmnWrapper.className = 'reify-bugmenot-bmnWrapper';
  128.  
  129. bmnWrapper.appendChild(getLoginLinkWrapper);
  130. if (counter > 0) {
  131. bmnWrapper.appendChild(resetCounterLinkWrapper);
  132. }
  133. bmnWrapper.appendChild(fullFormLinkWrapper);
  134. bmnWrapper.appendChild(visitBmnLinkWrapper);
  135.  
  136. copyProperties(bmnWrapper.style, Style.bmnWrapper);
  137. bmnContainer.appendChild(bmnWrapper);
  138. }
  139. if (bmnContainer.hasChildNodes()) {
  140. bodyEl.appendChild(bmnContainer);
  141. }
  142. })();
  143. }
  144.  
  145. function menuEntry(linkEl, styleObj) {
  146. var p = document.createElement('p');
  147. copyProperties(p.style, styleObj);
  148. p.appendChild(linkEl);
  149. return p;
  150. }
  151.  
  152. function menuLink(href, text, title, onclick, styleObj, usernameInputIndex, passwordInputIndex, onmouseover, onmouseout) {
  153. var newMenuLink = document.createElement('a');
  154. newMenuLink.href = href;
  155. newMenuLink.appendChild(document.createTextNode(text));
  156. newMenuLink.title = title;
  157. newMenuLink.setAttribute('usernameInputIndex', usernameInputIndex);
  158. newMenuLink.setAttribute('passwordInputIndex', passwordInputIndex);
  159. Utility.addEventHandler(newMenuLink, 'click', onclick);
  160. Utility.addEventHandler(newMenuLink, 'mouseover', onmouseover);
  161. Utility.addEventHandler(newMenuLink, 'mouseout', onmouseout);
  162. copyProperties(newMenuLink.style, styleObj);
  163. return newMenuLink;
  164. }
  165.  
  166. function menuLink_onmouseover(event) {
  167. event = event || window.event;
  168. var target = event.currentTarget || event.srcElement;
  169. copyProperties(target.style, Style.menuLinkHover);
  170. }
  171.  
  172. function menuLink_onmouseout(event) {
  173. event = event || window.event;
  174. var target = event.currentTarget || event.srcElement;
  175. copyProperties(target.style, Style.menuLink);
  176. }
  177.  
  178. function getLoginLink_onclick(event) {
  179. var allInputs = document.getElementsByTagName('input');
  180. if ((!allInputs[this.getAttribute('passwordInputIndex')].value.length && !allInputs[this.getAttribute('usernameInputIndex')].value.length) || confirm('Overwrite the current login entry?')) {
  181. getLogin(bmnUri, this.getAttribute('usernameInputIndex'), this.getAttribute('passwordInputIndex'));
  182. }
  183. menuLink_onmouseout({
  184. currentTarget: this
  185. });
  186. event.preventDefault && event.preventDefault();
  187. return false;
  188. }
  189.  
  190. function openMenuLink_onclick(event) {
  191. if (typeof GM.openInTab !== 'undefined') {
  192. GM.openInTab(this.href);
  193. } else {
  194. window.open(this.href);
  195. }
  196. menuLink_onmouseout({
  197. currentTarget: this
  198. });
  199. event.preventDefault && event.preventDefault();
  200. return false;
  201. }
  202.  
  203. function resetCounterLink_onclick(){
  204. (async function() {
  205. GM.setValue('counter', 0);
  206. })();
  207.  
  208. window.location.reload();
  209. }
  210.  
  211.  
  212. function usernameField_onfocus(event) {
  213. var allInputs = document.getElementsByTagName('input');
  214. event = event || window.event;
  215. var target = event.currentTarget || event.srcElement;
  216. target.setAttribute('hasFocus', true);
  217. showHideBmnWrapper(target, allInputs[target.getAttribute('passwordInputIndex')], true);
  218. }
  219.  
  220. function usernameField_onblur(event) {
  221. var allInputs = document.getElementsByTagName('input');
  222. event = event || window.event || this;
  223. var target = event.currentTarget || event.srcElement;
  224. target.setAttribute('hasFocus', false);
  225. var fRef = hideIfNoFocus(allInputs[target.getAttribute('usernameInputIndex')], allInputs[target.getAttribute('passwordInputIndex')]);
  226. // race condition: wait for other element's onfocus
  227. setTimeout(fRef, BLUR_TIMEOUT);
  228. }
  229.  
  230. function pwField_onfocus(event) {
  231. var allInputs = document.getElementsByTagName('input');
  232. event = event || window.event;
  233. var target = event.currentTarget || event.srcElement;
  234. target.setAttribute('hasFocus', true);
  235. showHideBmnWrapper(allInputs[target.getAttribute('usernameInputIndex')], target, true);
  236. }
  237.  
  238. function pwField_onblur(event) {
  239. var allInputs = document.getElementsByTagName('input');
  240. event = event || window.event;
  241. var target = event.currentTarget || event.srcElement;
  242. target.setAttribute('hasFocus', false);
  243. var fRef = hideIfNoFocus(allInputs[target.getAttribute('usernameInputIndex')], allInputs[target.getAttribute('passwordInputIndex')]);
  244. // race condition: wait for other element's onfocus
  245. setTimeout(fRef, BLUR_TIMEOUT);
  246. }
  247.  
  248. function hideIfNoFocus(usernameField, pwField) {
  249. return (function () {
  250. var bUsernameFocus = usernameField.getAttribute('hasFocus');
  251. if (typeof bUsernameFocus === 'string') {
  252. bUsernameFocus = (bUsernameFocus && bUsernameFocus != 'false');
  253. }
  254. var bPasswordFocus = pwField.getAttribute('hasFocus');
  255. if (typeof bPasswordFocus === 'string') {
  256. bPasswordFocus = (bPasswordFocus && bPasswordFocus != 'false');
  257. }
  258. if ((!bUsernameFocus) && (!bPasswordFocus)) {
  259. showHideBmnWrapper(usernameField, pwField, false);
  260. }
  261. });
  262. }
  263.  
  264. function showHideBmnWrapper(usernameField, pwField, show) {
  265. var bmnWrapper = getBmnWrapper(pwField.getAttribute('passwordInputIndex'));
  266. if (show) {
  267. bmnWrapper.style.display = 'block';
  268. positionBmnWrapper(bmnWrapper, usernameField, pwField);
  269. } else {
  270. // console.log('hiding bugmenot wrapper');
  271. bmnWrapper.style.display = 'none';
  272. // Menu links may not get onmouseout event, so they get
  273. // stuck with the hover style unless we do this.
  274. var menuLinks = bmnWrapper.getElementsByTagName('div');
  275. for (var i = 0; i < menuLinks.length; i++) {
  276. copyProperties(menuLinks[i].style, Style.menuLink);
  277. }
  278. }
  279. }
  280.  
  281. function positionBmnWrapper(bmnWrapper, usernameField, pwField) {
  282. var pwLeft = Utility.elementLeft(pwField);
  283. if (pwLeft + pwField.offsetWidth + bmnWrapper.offsetWidth +
  284. Utility.scrollLeft() + 10 < Utility.viewportWidth()) {
  285. bmnWrapper.style.left = (pwLeft + pwField.offsetWidth + 2) + 'px';
  286. bmnWrapper.style.top = Utility.elementTop(pwField) + 'px';
  287. } else {
  288. bmnWrapper.style.left = (Utility.elementLeft(usernameField) -
  289. bmnWrapper.offsetWidth - 2) + 'px';
  290. bmnWrapper.style.top = Utility.elementTop(usernameField) + 'px';
  291. }
  292. }
  293.  
  294.  
  295. // We have a uri param rather than assuming it's for the current
  296. // page so this function can be modular and potentially used
  297. // for pages other than the current one.
  298. function getLogin(uri, usernameInputIndex, passwordInputIndex) {
  299.  
  300. (async function() {
  301.  
  302. var allInputs = document.getElementsByTagName('input');
  303. var usernameField = allInputs[usernameInputIndex];
  304. var pwField = allInputs[passwordInputIndex];
  305. waitOrRestoreFields(usernameField, pwField, false);
  306. // var hostUri = location.hostname;
  307. var firstAttempt = retrievals == 0;
  308. var submitData = 'submit=This+login+didn%27t+work&num=' + retrievals +
  309. '&site=' + encodeURI(location.hostname);
  310.  
  311.  
  312.  
  313. // console.log(uri + ' ' + usernameInputIndex + ' ' + passwordInputIndex);
  314. if (counter === 0){
  315. console.log('( retrieving logins from bugmenot.com via XHR... )');
  316. // (async function(){
  317. GM.xmlHttpRequest({
  318. method: firstAttempt ? 'get' : 'post',
  319. headers: firstAttempt ? null :
  320. {
  321. 'Content-type': 'application/x-www-form-urlencoded'
  322. },
  323. data: firstAttempt ? null : submitData,
  324. url: firstAttempt ? uri : bmnView,
  325. // synchronous: true,
  326. onload: function (responseDetails) {
  327. if (responseDetails.status == 200) {
  328. waitOrRestoreFields(usernameField, pwField, true);
  329. // decoded = decodeit(responseDetails.responseText);
  330. var decoded = responseDetails.responseText;
  331. var doc = textToXml(decoded);
  332. if (!(doc && doc.documentElement)) {
  333. return Errors.say(Errors.malformedResponse);
  334. }
  335.  
  336.  
  337.  
  338. var allUsernames = doc.documentElement.querySelectorAll('dd:nth-child(2) > kbd');
  339. var allPasswords = doc.documentElement.querySelectorAll('dd:nth-child(4) > kbd');
  340. var allUsernamesArray = [];
  341. var allPasswordsArray = [];
  342. for (var i = 0; i < allUsernames.length; i++) {
  343. allUsernamesArray.push(allUsernames[i].innerHTML);
  344. allPasswordsArray.push(allPasswords[i].innerHTML);
  345. }
  346.  
  347. var temp = '';
  348. for (var j = 0; j < allUsernamesArray.length; j++){
  349. temp += (j + 1) + ': ' + allUsernamesArray[j] + ', ' + allPasswordsArray[j] + '\n';
  350. }
  351. console.log('Found logins (' + allUsernamesArray.length + '):\n' + temp);
  352.  
  353. (async function() {
  354. GM.setValue('allUsernames', JSON.stringify(allUsernamesArray));
  355. GM.setValue('allPasswords', JSON.stringify(allPasswordsArray));
  356. })();
  357. //
  358. // var accountInfo = doc.documentElement.getElementsByTagName('td') [0];
  359. var accountInfo = doc.documentElement.getElementsByTagName('kbd') [0];
  360. if (!(accountInfo)) {
  361. return Errors.say(Errors.noLoginAvailable);
  362. }
  363. usernameField.value = accountInfo.childNodes[0].nodeValue;
  364. // var pwsField = doc.documentElement.getElementsByTagName('td') [1];
  365. var pwsField = doc.documentElement.getElementsByTagName('kbd') [1];
  366. pwField.value = pwsField.childNodes[0].nodeValue;
  367. retrievals++;
  368. } else {
  369. return Errors.say(Errors.xmlHttpFailure);
  370. }
  371. },
  372. onerror: function (responseDetails) {
  373. waitOrRestoreFields(usernameField, pwField, true);
  374. Errors.say(Errors.xmlHttpFailure);
  375. }
  376. });
  377. // })();
  378.  
  379. } else {
  380.  
  381.  
  382. var retrievedUsernames = [];
  383. var retrievedPasswords = [];
  384. // (async function() {
  385. retrievedUsernames = JSON.parse(await GM.getValue('allUsernames'));
  386. retrievedPasswords = JSON.parse(await GM.getValue('allPasswords'));
  387. var temp = '';
  388. for (var j = 0; j < retrievedUsernames.length; j++){
  389. temp += (j + 1) + ': ' + retrievedUsernames[j] + ', ' + retrievedPasswords[j] + '\n';
  390. }
  391. console.log('Found logins (' + retrievedUsernames.length + '):\n' + temp);
  392. usernameField.value = retrievedUsernames[counter];
  393. pwField.value = retrievedPasswords[counter];
  394. // })();
  395.  
  396.  
  397.  
  398. }
  399.  
  400.  
  401.  
  402.  
  403. counter = parseInt(counter);
  404. counter++; // (after all is done..)
  405. GM.setValue('counter', counter); // .. store just increased counter and..
  406. GM.setValue('lastURL', String(window.location)); // .. store current location as lastURL
  407.  
  408.  
  409.  
  410. })();
  411.  
  412. }
  413.  
  414. function waitOrRestoreFields(usernameField, pwField, restore) {
  415. document.documentElement.style.cursor = restore ? 'default' : 'progress';
  416. usernameField.value = restore ? '' : 'Loading...';
  417. //usernameField.disabled = !restore;
  418. //pwField.disabled = !restore;
  419. }
  420.  
  421. function getPreviousTextField(pwFieldIndex, allInputs) {
  422. //var allInputs = document.getElementsByTagName("input");
  423. for (var i = pwFieldIndex; i >= 0 && i < allInputs.length; i--)
  424. if (allInputs[i].type && (allInputs[i].type.toLowerCase() == 'text' || allInputs[i].type.toLowerCase() == 'email'))
  425. return i;
  426. return - 1;
  427. }
  428.  
  429. /*
  430. function decodeit(codedtext) {
  431. var regexkey = /var key = (.*?)\;/;
  432. var match = regexkey.exec(codedtext);
  433. if (match != null) {
  434. var key = parseInt(match[1]);
  435. } else {
  436. alert('decoded key cannot be found\nbugmenot site has changed');
  437. }
  438. var codedtext = codedtext.replace(/<script>d\('(.*?)'\)\;<\/script>/gi, aaa);
  439. //alert (codedtext);
  440. return codedtext;
  441. function aaa(str, strInput, offset, s) {
  442. return d(strInput);
  443. }
  444. function decoder(data) {
  445. var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  446. var o1,
  447. o2,
  448. o3,
  449. h1,
  450. h2,
  451. h3,
  452. h4,
  453. bits,
  454. i = 0,
  455. enc = '';
  456. do {
  457. h1 = b64.indexOf(data.charAt(i++));
  458. h2 = b64.indexOf(data.charAt(i++));
  459. h3 = b64.indexOf(data.charAt(i++));
  460. h4 = b64.indexOf(data.charAt(i++));
  461. bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
  462. o1 = bits >> 16 & 255;
  463. o2 = bits >> 8 & 255;
  464. o3 = bits & 255;
  465. if (h3 == 64) enc += String.fromCharCode(o1);
  466. else if (h4 == 64) enc += String.fromCharCode(o1, o2);
  467. else enc += String.fromCharCode(o1, o2, o3);
  468. } while (i < data.length);
  469. return enc;
  470. }
  471. function d(strInput) {
  472. strInput = decoder(strInput);
  473. var strOutput = '';
  474. var intOffset = (key + 112) / 12;
  475. for (i = 4; i < strInput.length; i++) {
  476. thisLetter = strInput.charAt(i);
  477. thisCharCode = strInput.charCodeAt(i);
  478. newCharCode = thisCharCode - intOffset;
  479. strOutput += String.fromCharCode(newCharCode);
  480. }
  481. return strOutput;
  482. }
  483. }
  484. */
  485.  
  486. function textToXml(t) {
  487. try {
  488. if (typeof DOMParser !== 'undefined') {
  489. //t = toString(t);
  490. // var dp = new DOMParser( );
  491. // return dp.parseFromString(t, "text/xml");
  492. var parser = new DOMParser();
  493. //var t = t.replace(/<\?xml.*?\?>/g, ""); // strip <?xml ?> tag
  494. //t = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<rando>" + t + "</rando>";
  495. //t = t.replace(/&(?!\w*;)/g, "&");
  496. //alert(t);
  497. //alert(parser.parseFromString(t, "application/xml"));
  498. // return parser.parseFromString(t, 'application/xml'); // <--- the previous value
  499. return parser.parseFromString(t, 'text/html');
  500. }
  501. else {
  502. return null;
  503. }
  504. }
  505. catch (e) {
  506. return null;
  507. }
  508. }
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546. var Style = {
  547. menuLink: {
  548. border: 'none',
  549. backgroundColor: '#fff',
  550. color: '#000',
  551. display: 'block',
  552. padding: '2px',
  553. margin: '0',
  554. // width: '12em',
  555. width: '17em',
  556. fontSize: '8pt',
  557. fontWeight: 'normal',
  558. textDecoration: 'none'
  559. },
  560. menuLinkHover: {
  561. backgroundColor: '#316AC5',
  562. color: '#fff'
  563. },
  564. menuLinkWrapper: {
  565. textAlign: 'left',
  566. padding: '1px',
  567. margin: 0
  568. },
  569. bmnWrapper: {
  570. display: 'none',
  571. fontFamily: 'tahoma, verdana, arial, sans-serif',
  572. whiteSpace: 'nowrap',
  573. position: 'absolute',
  574. zIndex: 1000,
  575. padding: '2px',
  576. border: '1px solid #ACA899',
  577. backgroundColor: '#fff',
  578. opacity: '0.9',
  579. filter: 'alpha(opacity=90)'
  580. }
  581. };
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600. var Errors = {
  601. noLoginAvailable: 'Sorry, but BugMeNot.com had no login available ' +
  602. 'for this site.\nIf you\'re feeling helpful, you can click "More ' +
  603. 'options" to provide a login for future visitors.',
  604. malformedResponse: 'Sorry, but I couldn\'t understand the response ' +
  605. 'from BugMeNot.com.\nThe service might be unavailable.',
  606. siteBlocked: 'Sorry, but I couldn\'t understand the response ' +
  607. 'from BugMeNot.com.\nThe service might be unavailable.',
  608. xmlHttpFailure: 'There was an error in contacting BugMeNot.com.\n' +
  609. 'The server may be unavailable or having internal errors.',
  610. say: function (msg) {
  611. alert(msg);
  612. return false;
  613. }
  614. };
  615.  
  616. var Utility = {
  617. elementTop: function (el) {
  618. return Utility.recursiveOffset(el, 'offsetTop');
  619. },
  620. elementLeft: function (el) {
  621. return Utility.recursiveOffset(el, 'offsetLeft');
  622. },
  623. recursiveOffset: function (el, prop) {
  624. var dist = 0;
  625. while (el.offsetParent)
  626. {
  627. dist += el[prop];
  628. el = el.offsetParent;
  629. }
  630. return dist;
  631. },
  632. viewportWidth: function () {
  633. return Utility.detectAndUseAppropriateObj('clientWidth');
  634. },
  635. viewportHeight: function () {
  636. return Utility.detectAndUseAppropriateObj('clientHeight');
  637. },
  638. scrollLeft: function () {
  639. return Utility.detectAndUseAppropriateObj('scrollLeft');
  640. },
  641. scrollTop: function () {
  642. return Utility.detectAndUseAppropriateObj('scrollTop');
  643. },
  644. detectAndUseAppropriateObj: function (prop) {
  645. if (document.documentElement && document.documentElement[prop]) {
  646. return document.documentElement[prop];
  647. }
  648. else if (document.body && document.body[prop]) {
  649. return document.body[prop];
  650. } else {
  651. return - 1;
  652. }
  653. },
  654. addEventHandler: function (target, eventName, eventHandler) {
  655. if (target.addEventListener) {
  656. target.addEventListener(eventName, eventHandler, false);
  657. } else if (target.attachEvent) {
  658. target.attachEvent('on' + eventName, eventHandler);
  659. }
  660. }
  661. };
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686. // new logins gotten from the current page (reset on every page load)
  687. var retrievals = 0;
  688. // millisecond delay between a field losing focus and checking to see
  689. // if any other of our fields has focus. If this is too low, the menu
  690. // won't work because it will get "display: none" and its onclick
  691. // won't fire.
  692. // var BLUR_TIMEOUT = 150;
  693. const BLUR_TIMEOUT = 250;
  694.  
  695. //http://www.bugmenot.com/view/orasisx.net
  696. //phoneRegex = /(?:http://)(.*)/.*?/;
  697. //doma= location.href.match( phoneRegex );
  698.  
  699. // myString = location.href;
  700. // domainnameRE = new RegExp('(?:https?://)(.*?)/.*?', 'i');
  701. // domainname = myString.match(domainnameRE)
  702. // domainname = domainname[1];
  703. //alert (domainname);
  704. const myString = location.href;
  705. const domainnameRE = new RegExp('(?:https?://)(www\\.)?(.*?)/.*?', 'i');
  706. const domainname = myString.match(domainnameRE)[2];
  707.  
  708. // var allInputs = null;
  709. const bmnView = 'http://bugmenot.com/view';
  710. const bmnUri = bmnView + '/' + domainname;
  711. const bmnHomeUri = 'http://bugmenot.com/';
  712. const DEBUG = false;
  713. // var bmnWrappers = new Object();
  714.  
  715.  
  716. var counter ;
  717.  
  718.  
  719. // If the current domain name doesn't match the stored lastURL, then reset the counter
  720. var lastURL;
  721. (async function() {
  722. lastURL = await GM.getValue('lastURL', '');
  723. // console.log('lastURL: ' + lastURL);
  724. if (lastURL.indexOf(domainname) === -1){
  725. counter = 0;
  726. GM.setValue('counter', 0);
  727. // console.log('CASE 0');
  728. } else {
  729. counter = parseInt(await GM.getValue('counter', 0));
  730. // console.log('counter1: ' + counter);
  731. }
  732. // console.log(await GM.listValues());
  733.  
  734. main();
  735. })();
  736.  
  737.  
  738.  
  739.  
  740. // main();
  741.  
  742.  
  743.  
  744. // to do
  745. // http://www.bugmenot.com/view/thecavernforum.com Site Blocked

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址