🏠 返回首頁 

Greasy Fork is available in English.

Protect Textarea

Protect from closing or navigating away from a web page with changed textareas.


安装此脚本?
  1. // ==UserScript==
  2. // @name Protect Textarea
  3. // @namespace https://arantius.com/misc/greasemonkey/
  4. // @description Protect from closing or navigating away from a web page with changed textareas.
  5. // @include http*
  6. // @version 1.3
  7. // ==/UserScript==
  8. // Version History:
  9. //
  10. // 1.3 (2011-06-06): Use pagehide/pageshow events for cache friendliness.
  11. // https://developer.mozilla.org/en-US/Firefox/Releases/1.5/Using_Firefox_1.5_caching#Page_caching_despite_unload_and_beforeunload_handlers
  12. // 1.2.1 (2010-02-16): Reduce false-positive warning rate.
  13. // 1.2 (2009-09-15): Complete rewrite, less false positives for hidden
  14. // fields controlled by scripts, better handling of
  15. // dynamic/ajax sites.
  16. // 1.1 (2006-09-18): Add the "noprotect" class detection
  17. //
  18. var CHANGED_MARK=String(Math.random()).substr(2);
  19. window.addEventListener('keypress', handleKeypress, true);
  20. window.addEventListener('submit', handl###bmit, true);
  21. window.addEventListener('beforeunload', handleUnload, true);
  22. window.addEventListener('pageshow', function() {
  23. window.addEventListener('beforeunload', handleUnload, true);
  24. }, true);
  25. function handleKeypress(event) {
  26. if (
  27. // Ignore events not in a textarea.
  28. !event.target
  29. || !event.target.tagName
  30. || 'TEXTAREA'!=event.target.tagName
  31. // Ignore non-character keypresses.
  32. || 0==event.charCode
  33. // Ignore "noprotect" textareas.
  34. || event.target.className.match(/\bnoprotect\b/)
  35. ) {
  36. return;
  37. }
  38. if (0 /* debug? */) {
  39. console.log('saw keypress in', event.target);
  40. console.dir(event);
  41. }
  42. // At this point we have noticed a keypress to a textarea. Record it.
  43. var textarea = event.target;
  44. textarea.setAttribute('changed_mark', CHANGED_MARK);
  45. if (!textarea.hasAttribute('orig_value')) {
  46. textarea.setAttribute('orig_value', textarea.value);
  47. }
  48. }
  49. function handl###bmit(event) {
  50. var textareas = event.target.getElementsByTagName('textarea');
  51. for (var i=0, textarea=null; textarea=textareas[i]; i++) {
  52. textarea.removeAttribute('changed_mark');
  53. }
  54. }
  55. function handleUnload(event) {
  56. // Re-add later via pageshow. See https://developer.mozilla.org/en-US/Firefox/Releases/1.5/Using_Firefox_1.5_caching#Page_caching_despite_unload_and_beforeunload_handlers
  57. window.removeEventListener('beforeunload', handleUnload, true);
  58. var textareas = event.target.getElementsByTagName('textarea');
  59. textarealoop:
  60. for (var i=0, textarea=null; textarea=textareas[i]; i++) {
  61. // Check for presence in the document.
  62. var parent=textarea.parentNode;
  63. while (true) {
  64. if ('BODY'==parent.tagName) break;
  65. // Skip if we climbed the parent tree and fell out before getting to the
  66. // <body>; this textarea was removed from the document, probably by the
  67. // script that submitted it via AJAX (or some such).
  68. if (!parent || !parent.tagName) continue textarealoop;
  69. parent=parent.parentNode;
  70. }
  71. // Skip if we haven't marked this as changed.
  72. if (!textarea.hasAttribute('changed_mark')) continue;
  73. if (textarea.getAttribute('changed_mark') != CHANGED_MARK) continue;
  74. // Skip if the value is the same as the first we observed. (I.E. only
  75. // arrow or Ctrl-C keypresses.)
  76. if (textarea.value == textarea.getAttribute('orig_value')) continue;
  77. // Skip if the value is empty. (Nothing to lose!)
  78. if ('' == textarea.value) continue;
  79. // Didn't skip, so do interrupt leaving the page.
  80. return event.returnValue='You have modified a textarea, and ' +
  81. 'have not submitted the form.';
  82. }
  83. }