gitea源码

repo-issue-pull.ts 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import {createApp} from 'vue';
  2. import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
  3. import {GET, POST} from '../modules/fetch.ts';
  4. import {fomanticQuery} from '../modules/fomantic/base.ts';
  5. import {createElementFromHTML} from '../utils/dom.ts';
  6. function initRepoPullRequestUpdate(el: HTMLElement) {
  7. const prUpdateButtonContainer = el.querySelector('#update-pr-branch-with-base');
  8. if (!prUpdateButtonContainer) return;
  9. const prUpdateButton = prUpdateButtonContainer.querySelector<HTMLButtonElement>(':scope > button');
  10. const prUpdateDropdown = prUpdateButtonContainer.querySelector(':scope > .ui.dropdown');
  11. prUpdateButton.addEventListener('click', async function (e) {
  12. e.preventDefault();
  13. const redirect = this.getAttribute('data-redirect');
  14. this.classList.add('is-loading');
  15. let response: Response;
  16. try {
  17. response = await POST(this.getAttribute('data-do'));
  18. } catch (error) {
  19. console.error(error);
  20. } finally {
  21. this.classList.remove('is-loading');
  22. }
  23. let data: Record<string, any>;
  24. try {
  25. data = await response?.json(); // the response is probably not a JSON
  26. } catch (error) {
  27. console.error(error);
  28. }
  29. if (data?.redirect) {
  30. window.location.href = data.redirect;
  31. } else if (redirect) {
  32. window.location.href = redirect;
  33. } else {
  34. window.location.reload();
  35. }
  36. });
  37. fomanticQuery(prUpdateDropdown).dropdown({
  38. onChange(_text: string, _value: string, $choice: any) {
  39. const choiceEl = $choice[0];
  40. const url = choiceEl.getAttribute('data-do');
  41. if (url) {
  42. const buttonText = prUpdateButton.querySelector('.button-text');
  43. if (buttonText) {
  44. buttonText.textContent = choiceEl.textContent;
  45. }
  46. prUpdateButton.setAttribute('data-do', url);
  47. }
  48. },
  49. });
  50. }
  51. function initRepoPullRequestCommitStatus(el: HTMLElement) {
  52. for (const btn of el.querySelectorAll('.commit-status-hide-checks')) {
  53. const panel = btn.closest('.commit-status-panel');
  54. const list = panel.querySelector<HTMLElement>('.commit-status-list');
  55. btn.addEventListener('click', () => {
  56. list.style.maxHeight = list.style.maxHeight ? '' : '0px'; // toggle
  57. btn.textContent = btn.getAttribute(list.style.maxHeight ? 'data-show-all' : 'data-hide-all');
  58. });
  59. }
  60. }
  61. function initRepoPullRequestMergeForm(box: HTMLElement) {
  62. const el = box.querySelector('#pull-request-merge-form');
  63. if (!el) return;
  64. const view = createApp(PullRequestMergeForm);
  65. view.mount(el);
  66. }
  67. function executeScripts(elem: HTMLElement) {
  68. for (const oldScript of elem.querySelectorAll('script')) {
  69. // TODO: that's the only way to load the data for the merge form. In the future
  70. // we need to completely decouple the page data and embedded script
  71. // eslint-disable-next-line github/no-dynamic-script-tag
  72. const newScript = document.createElement('script');
  73. for (const attr of oldScript.attributes) {
  74. if (attr.name === 'type' && attr.value === 'module') continue;
  75. newScript.setAttribute(attr.name, attr.value);
  76. }
  77. newScript.text = oldScript.text;
  78. document.body.append(newScript);
  79. }
  80. }
  81. export function initRepoPullMergeBox(el: HTMLElement) {
  82. initRepoPullRequestCommitStatus(el);
  83. initRepoPullRequestUpdate(el);
  84. initRepoPullRequestMergeForm(el);
  85. const reloadingIntervalValue = el.getAttribute('data-pull-merge-box-reloading-interval');
  86. if (!reloadingIntervalValue) return;
  87. const reloadingInterval = parseInt(reloadingIntervalValue);
  88. const pullLink = el.getAttribute('data-pull-link');
  89. let timerId: number;
  90. let reloadMergeBox: () => Promise<void>;
  91. const stopReloading = () => {
  92. if (!timerId) return;
  93. clearTimeout(timerId);
  94. timerId = null;
  95. };
  96. const startReloading = () => {
  97. if (timerId) return;
  98. setTimeout(reloadMergeBox, reloadingInterval);
  99. };
  100. const onVisibilityChange = () => {
  101. if (document.hidden) {
  102. stopReloading();
  103. } else {
  104. startReloading();
  105. }
  106. };
  107. reloadMergeBox = async () => {
  108. const resp = await GET(`${pullLink}/merge_box`);
  109. stopReloading();
  110. if (!resp.ok) {
  111. startReloading();
  112. return;
  113. }
  114. document.removeEventListener('visibilitychange', onVisibilityChange);
  115. const newElem = createElementFromHTML(await resp.text());
  116. executeScripts(newElem);
  117. el.replaceWith(newElem);
  118. };
  119. document.addEventListener('visibilitychange', onVisibilityChange);
  120. startReloading();
  121. }