javascriptBlockUtil.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. export function automaFetchClient(id, { type, resource }) {
  2. return new Promise((resolve, reject) => {
  3. const validType = ['text', 'json', 'base64'];
  4. if (!type || !validType.includes(type)) {
  5. reject(new Error('The "type" must be "text" or "json"'));
  6. return;
  7. }
  8. const eventName = `__autom-fetch-response-${id}__`;
  9. const eventListener = ({ detail }) => {
  10. if (detail.id !== id) return;
  11. window.removeEventListener(eventName, eventListener);
  12. if (detail.isError) {
  13. reject(new Error(detail.result));
  14. } else {
  15. resolve(detail.result);
  16. }
  17. };
  18. window.addEventListener(eventName, eventListener);
  19. window.dispatchEvent(
  20. new CustomEvent(`__automa-fetch__`, {
  21. detail: {
  22. id,
  23. type,
  24. resource,
  25. },
  26. })
  27. );
  28. });
  29. }
  30. export function jsContentHandler($blockData, $preloadScripts, $automaScript) {
  31. return new Promise((resolve, reject) => {
  32. try {
  33. let $documentCtx = document;
  34. if ($blockData.frameSelector) {
  35. const iframeCtx = document.querySelector(
  36. $blockData.frameSelector
  37. )?.contentDocument;
  38. if (!iframeCtx) {
  39. reject(new Error('iframe-not-found'));
  40. return;
  41. }
  42. $documentCtx = iframeCtx;
  43. }
  44. const scriptAttr = `block--${$blockData.id}`;
  45. const isScriptExists = $documentCtx.querySelector(
  46. `.automa-custom-js[${scriptAttr}]`
  47. );
  48. if (isScriptExists) {
  49. resolve('');
  50. return;
  51. }
  52. const script = document.createElement('script');
  53. script.setAttribute(scriptAttr, '');
  54. script.classList.add('automa-custom-js');
  55. script.textContent = `(() => {
  56. ${$automaScript}
  57. try {
  58. ${$blockData.data.code}
  59. ${
  60. $blockData.data.everyNewTab ||
  61. $blockData.data.code.includes('automaNextBlock')
  62. ? ''
  63. : 'automaNextBlock()'
  64. }
  65. } catch (error) {
  66. console.error(error);
  67. ${
  68. $blockData.data.everyNewTab
  69. ? ''
  70. : 'automaNextBlock({ $error: true, message: error.message })'
  71. }
  72. }
  73. })()`;
  74. const preloadScriptsEl = $preloadScripts.map((item) => {
  75. const scriptEl = document.createElement('script');
  76. scriptEl.id = item.id;
  77. scriptEl.textContent = item.script;
  78. $documentCtx.head.appendChild(scriptEl);
  79. return { element: scriptEl, removeAfterExec: item.removeAfterExec };
  80. });
  81. if (!$blockData.data.everyNewTab) {
  82. let timeout;
  83. let onNextBlock;
  84. let onResetTimeout;
  85. /* eslint-disable-next-line */
  86. function cleanUp() {
  87. script.remove();
  88. preloadScriptsEl.forEach((item) => {
  89. if (item.removeAfterExec) item.script.remove();
  90. });
  91. clearTimeout(timeout);
  92. $documentCtx.body.removeEventListener(
  93. '__automa-reset-timeout__',
  94. onResetTimeout
  95. );
  96. $documentCtx.body.removeEventListener(
  97. '__automa-next-block__',
  98. onNextBlock
  99. );
  100. }
  101. onNextBlock = ({ detail }) => {
  102. cleanUp(detail || {});
  103. resolve({
  104. columns: {
  105. data: detail?.data,
  106. insert: detail?.insert,
  107. },
  108. variables: detail?.refData?.variables,
  109. });
  110. };
  111. onResetTimeout = () => {
  112. clearTimeout(timeout);
  113. timeout = setTimeout(cleanUp, $blockData.data.timeout);
  114. };
  115. $documentCtx.body.addEventListener(
  116. '__automa-next-block__',
  117. onNextBlock
  118. );
  119. $documentCtx.body.addEventListener(
  120. '__automa-reset-timeout__',
  121. onResetTimeout
  122. );
  123. timeout = setTimeout(cleanUp, $blockData.data.timeout);
  124. } else {
  125. resolve();
  126. }
  127. $documentCtx.head.appendChild(script);
  128. } catch (error) {
  129. console.error(error);
  130. }
  131. });
  132. }