javascriptBlockUtil.js 4.0 KB

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