JSON paste on textarea

Paste JSON on textarea

当前为 2021-06-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name JSON paste on textarea
  3. // @version 0.4
  4. // @description Paste JSON on textarea
  5. // @match https://*/*
  6. // @grant none
  7. // @namespace https://gf.qytechs.cn/users/371179
  8. // ==/UserScript==
  9. (function() {
  10. 'use strict';
  11.  
  12. /*
  13.  
  14. -- Example --
  15. https://jsonformatter.curiousconcept.com/
  16. "{\"a\":1,\"b\":2,\"c\":3,\"d\":\"A\",\"e\":\"B\",\"f\":\"C\"}"
  17.  
  18. */
  19.  
  20. function getClipText(evt) {
  21.  
  22. var text;
  23. var clp = (evt.originalEvent || evt).clipboardData;
  24. if (clp === undefined || clp === null) {
  25. text = window.clipboardData.getData("text") || null;
  26. } else {
  27. text = clp.getData('text/plain') || null;
  28. }
  29. return text;
  30.  
  31. }
  32.  
  33. function changeText(evt, callback) {
  34.  
  35.  
  36. var text, newText;
  37. var clp = (evt.originalEvent || evt).clipboardData;
  38. if (clp === undefined || clp === null) {
  39. text = window.clipboardData.getData("text") || "";
  40. if (text !== "") {
  41. newText = callback(text);
  42.  
  43. if (typeof newText == 'string' && newText != text) {
  44. evt.preventDefault();
  45. if (window.getSelection) {
  46. var newNode = document.createElement("span");
  47. newNode.innerHTML = newText;
  48. window.getSelection().getRangeAt(0).insertNode(newNode);
  49. } else {
  50. document.selection.createRange().pasteHTML(newText);
  51. }
  52. }
  53. }
  54. } else {
  55. text = clp.getData('text/plain') || "";
  56. if (text !== "") {
  57. newText = callback(text);
  58. if (typeof newText == 'string' && newText != text) {
  59. evt.preventDefault();
  60. document.execCommand('insertText', false, newText);
  61. }
  62. }
  63. }
  64.  
  65.  
  66. }
  67.  
  68. // =========================================================================================
  69. // https://stackoverflow.com/questions/7464282/javascript-scroll-to-selection-after-using-textarea-setselectionrange-in-chrome
  70.  
  71. function setSelectionRange(textarea, selectionStart, selectionEnd) {
  72. // First scroll selection region to view
  73. const fullText = textarea.value;
  74. textarea.value = fullText.substring(0, selectionEnd);
  75. // For some unknown reason, you must store the scollHeight to a variable
  76. // before setting the textarea value. Otherwise it won't work for long strings
  77. const scrollHeight = textarea.scrollHeight
  78. textarea.value = fullText;
  79. let scrollTop = scrollHeight;
  80. const textareaHeight = textarea.clientHeight;
  81. if (scrollTop > textareaHeight) {
  82. // scroll selection to center of textarea
  83. scrollTop -= textareaHeight / 2;
  84. } else {
  85. scrollTop = 0;
  86. }
  87. textarea.scrollTop = scrollTop;
  88.  
  89. // Continue to set selection range
  90. textarea.setSelectionRange(selectionStart, selectionEnd);
  91. }
  92. // =========================================================================================
  93.  
  94.  
  95. if (document.queryCommandSupported("insertText")) {
  96.  
  97. var object = {
  98.  
  99. callback: function(str) {
  100.  
  101. var targetElm = this.targetElm;
  102. var clipText = this.clipText;
  103.  
  104. var newClipText = typeof str == 'string' ? str : clipText;
  105. if (newClipText != "") {
  106.  
  107.  
  108. var oldText = targetElm.value
  109. document.execCommand("insertText", false, newClipText);
  110.  
  111. if ('selectionStart' in targetElm) {
  112. var afterChange = () => {
  113. var newText = targetElm.value;
  114. if (oldText == newText) return window.requestAnimationFrame(afterChange);
  115. setSelectionRange(targetElm, targetElm.selectionStart, targetElm.selectionEnd);
  116. };
  117.  
  118. window.requestAnimationFrame(afterChange);
  119.  
  120. }
  121. }
  122.  
  123. }
  124. };
  125.  
  126. var JF_safeObjects=[];
  127.  
  128. var makeJFunction = (() => {
  129. var a = document.createElement('iframe');
  130. a.style.position = 'absolute';
  131. a.style.left = '-99px';
  132. a.style.top = '-99px';
  133. a.src = "about:blank"; //userscript can access "about:blank"
  134. a.width = "1";
  135. a.height = "1";
  136. document.documentElement.appendChild(a)
  137. // it is assumed that the "contentWindow" is immediately available after appendChild
  138. var JFunction;
  139. try {
  140. JFunction = (a.contentWindow || window).Function;
  141. } catch (e) {
  142. JFunction = window.Function
  143. }
  144.  
  145. document.documentElement.removeChild(a)
  146.  
  147. var res = null;
  148. try {
  149. res = new JFunction('return Object.keys(window);')(); // avoid no access to JFunction
  150. } catch (e) {}
  151.  
  152. if (res && 'forEach' in res) {
  153. JF_safeObjects=res;
  154. }else{
  155. JFunction = window.Function;
  156. JF_safeObjects=[];
  157. }
  158.  
  159. return JFunction
  160. });
  161.  
  162.  
  163. var JFunction = null;
  164. document.addEventListener('paste', function(evt) {
  165.  
  166. var clipText = getClipText(evt)
  167. if (clipText === null || typeof clipText != 'string') return;
  168.  
  169.  
  170. var targetElm = evt.target;
  171.  
  172. if (!targetElm) return;
  173.  
  174. switch (targetElm.tagName) {
  175. case 'TEXTAREA':
  176. break;
  177. default:
  178. return;
  179. }
  180.  
  181. var testP = clipText.replace(/[0-9a-zA-Z\u4E00-\u9FFF\/\%\-\+\_\.\;\$\#]+/g, '').trim();
  182. var testR = /^[\:\[\]\{\}\,\s\n\"\'\\\/]+$/
  183. if (!testP) {
  184. return;
  185. }
  186. if (!testR.test(testP)) return;
  187.  
  188.  
  189. object.targetElm = targetElm;
  190. object.clipText = clipText;
  191.  
  192. // JS-safe Function
  193. JFunction = JFunction || makeJFunction();
  194.  
  195. //window.JF = JFunction
  196.  
  197.  
  198.  
  199. var res = null;
  200. try {
  201. res = new JFunction(...JF_safeObjects,'return (' + clipText + ');')(); //backbracket to avoid return newline -> undefined
  202. } catch (e) {}
  203.  
  204. //console.log(res)
  205.  
  206. if (typeof res == 'string') {
  207. console.log('userscript - there is a text convertion to your pasted content');
  208. evt.preventDefault();
  209. object.callback(res);
  210. }
  211.  
  212.  
  213. });
  214. }
  215.  
  216. // Your code here...
  217. })();

QingJ © 2025

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