mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	
							
								
								
									
										771
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										771
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							@@ -10,6 +10,7 @@
 | 
				
			|||||||
    "@claviska/jquery-minicolors": "2.3.6",
 | 
					    "@claviska/jquery-minicolors": "2.3.6",
 | 
				
			||||||
    "@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
 | 
					    "@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
 | 
				
			||||||
    "@primer/octicons": "17.5.0",
 | 
					    "@primer/octicons": "17.5.0",
 | 
				
			||||||
 | 
					    "@vue/compiler-sfc": "3.2.37",
 | 
				
			||||||
    "add-asset-webpack-plugin": "2.0.1",
 | 
					    "add-asset-webpack-plugin": "2.0.1",
 | 
				
			||||||
    "css-loader": "6.7.1",
 | 
					    "css-loader": "6.7.1",
 | 
				
			||||||
    "dropzone": "6.0.0-beta.2",
 | 
					    "dropzone": "6.0.0-beta.2",
 | 
				
			||||||
@@ -34,11 +35,10 @@
 | 
				
			|||||||
    "tippy.js": "6.3.7",
 | 
					    "tippy.js": "6.3.7",
 | 
				
			||||||
    "tributejs": "5.1.3",
 | 
					    "tributejs": "5.1.3",
 | 
				
			||||||
    "uint8-to-base64": "0.2.0",
 | 
					    "uint8-to-base64": "0.2.0",
 | 
				
			||||||
    "vue": "2.6.14",
 | 
					    "vue": "3.2.37",
 | 
				
			||||||
    "vue-bar-graph": "1.3.1",
 | 
					    "vue-bar-graph": "2.0.0",
 | 
				
			||||||
    "vue-calendar-heatmap": "0.8.4",
 | 
					    "vue-loader": "17.0.0",
 | 
				
			||||||
    "vue-loader": "15.9.8",
 | 
					    "vue3-calendar-heatmap": "2.0.0",
 | 
				
			||||||
    "vue-template-compiler": "2.6.14",
 | 
					 | 
				
			||||||
    "webpack": "5.74.0",
 | 
					    "webpack": "5.74.0",
 | 
				
			||||||
    "webpack-cli": "4.10.0",
 | 
					    "webpack-cli": "4.10.0",
 | 
				
			||||||
    "workbox-routing": "6.5.4",
 | 
					    "workbox-routing": "6.5.4",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,9 +63,9 @@
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				})();
 | 
									})();
 | 
				
			||||||
				</script>
 | 
									</script>
 | 
				
			||||||
		<div id="diff-file-list-container"></div>
 | 
							<div id="diff-file-list"></div>
 | 
				
			||||||
		<div id="diff-container">
 | 
							<div id="diff-container">
 | 
				
			||||||
				<div id="diff-file-tree-container"></div>
 | 
									<div id="diff-file-tree"></div>
 | 
				
			||||||
				<div id="diff-file-boxes" class="sixteen wide column">
 | 
									<div id="diff-file-boxes" class="sixteen wide column">
 | 
				
			||||||
					{{range $i, $file := .Diff.Files}}
 | 
										{{range $i, $file := .Diff.Files}}
 | 
				
			||||||
						{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
 | 
											{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,10 @@
 | 
				
			|||||||
	{{end}}
 | 
						{{end}}
 | 
				
			||||||
	inline-template
 | 
						inline-template
 | 
				
			||||||
	v-cloak
 | 
						v-cloak
 | 
				
			||||||
	>
 | 
						></repo-search>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template id="dashboard-repo-list-template">
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		<div v-if="!isOrganization" class="ui two item tabable menu">
 | 
							<div v-if="!isOrganization" class="ui two item tabable menu">
 | 
				
			||||||
			<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.locale.Tr "repository"}}</a>
 | 
								<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.locale.Tr "repository"}}</a>
 | 
				
			||||||
@@ -193,5 +196,4 @@
 | 
				
			|||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</repo-search>
 | 
					</template>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import {CalendarHeatmap} from 'vue-calendar-heatmap';
 | 
					import {CalendarHeatmap} from 'vue3-calendar-heatmap';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: 'ActivityHeatmap',
 | 
					  name: 'ActivityHeatmap',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div>
 | 
					  <div ref="root">
 | 
				
			||||||
    <div v-if="loading" class="ui active centered inline loader"/>
 | 
					    <div v-if="loading" class="ui active centered inline loader"/>
 | 
				
			||||||
    <div v-if="!loading && issue !== null">
 | 
					    <div v-if="!loading && issue !== null">
 | 
				
			||||||
      <p><small>{{ issue.repository.full_name }} on {{ createdAt }}</small></p>
 | 
					      <p><small>{{ issue.repository.full_name }} on {{ createdAt }}</small></p>
 | 
				
			||||||
@@ -109,15 +109,16 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    this.$root.$on('load-context-popup', (data, callback) => {
 | 
					    this.$refs.root.addEventListener('us-load-context-popup', (e) => {
 | 
				
			||||||
 | 
					      const data = e.detail;
 | 
				
			||||||
      if (!this.loading && this.issue === null) {
 | 
					      if (!this.loading && this.issue === null) {
 | 
				
			||||||
        this.load(data, callback);
 | 
					        this.load(data);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    load(data, callback) {
 | 
					    load(data) {
 | 
				
			||||||
      this.loading = true;
 | 
					      this.loading = true;
 | 
				
			||||||
      this.i18nErrorMessage = null;
 | 
					      this.i18nErrorMessage = null;
 | 
				
			||||||
      $.get(`${appSubUrl}/${data.owner}/${data.repo}/issues/${data.index}/info`).done((issue) => {
 | 
					      $.get(`${appSubUrl}/${data.owner}/${data.repo}/issues/${data.index}/info`).done((issue) => {
 | 
				
			||||||
@@ -130,9 +131,6 @@ export default {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }).always(() => {
 | 
					      }).always(() => {
 | 
				
			||||||
        this.loading = false;
 | 
					        this.loading = false;
 | 
				
			||||||
        if (callback) {
 | 
					 | 
				
			||||||
          this.$nextTick(callback);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp, nextTick} from 'vue';
 | 
				
			||||||
import $ from 'jquery';
 | 
					import $ from 'jquery';
 | 
				
			||||||
import {initVueSvg, vueDelimiters} from './VueComponentLoader.js';
 | 
					import {initVueSvg, vueDelimiters} from './VueComponentLoader.js';
 | 
				
			||||||
import {initTooltip} from '../modules/tippy.js';
 | 
					import {initTooltip} from '../modules/tippy.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const {appSubUrl, assetUrlPrefix, pageData} = window.config;
 | 
					const {appSubUrl, assetUrlPrefix, pageData} = window.config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function initVueComponents() {
 | 
					function initVueComponents(app) {
 | 
				
			||||||
  Vue.component('repo-search', {
 | 
					  app.component('repo-search', {
 | 
				
			||||||
    delimiters: vueDelimiters,
 | 
					    delimiters: vueDelimiters,
 | 
				
			||||||
    props: {
 | 
					    props: {
 | 
				
			||||||
      searchLimit: {
 | 
					      searchLimit: {
 | 
				
			||||||
@@ -138,13 +138,14 @@ function initVueComponents() {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mounted() {
 | 
					    mounted() {
 | 
				
			||||||
 | 
					      const el = document.getElementById('dashboard-repo-list');
 | 
				
			||||||
      this.changeReposFilter(this.reposFilter);
 | 
					      this.changeReposFilter(this.reposFilter);
 | 
				
			||||||
      for (const el of this.$el.querySelectorAll('.tooltip')) {
 | 
					      for (const elTooltip of el.querySelectorAll('.tooltip')) {
 | 
				
			||||||
        initTooltip(el);
 | 
					        initTooltip(elTooltip);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      $(this.$el).find('.dropdown').dropdown();
 | 
					      $(el).find('.dropdown').dropdown();
 | 
				
			||||||
      this.setCheckboxes();
 | 
					      this.setCheckboxes();
 | 
				
			||||||
      Vue.nextTick(() => {
 | 
					      nextTick(() => {
 | 
				
			||||||
        this.$refs.search.focus();
 | 
					        this.$refs.search.focus();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -192,7 +193,7 @@ function initVueComponents() {
 | 
				
			|||||||
        this.reposFilter = filter;
 | 
					        this.reposFilter = filter;
 | 
				
			||||||
        this.repos = [];
 | 
					        this.repos = [];
 | 
				
			||||||
        this.page = 1;
 | 
					        this.page = 1;
 | 
				
			||||||
        Vue.set(this.counts, `${filter}:${this.archivedFilter}:${this.privateFilter}`, 0);
 | 
					        this.counts[`${filter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
 | 
				
			||||||
        this.searchRepos();
 | 
					        this.searchRepos();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -261,7 +262,7 @@ function initVueComponents() {
 | 
				
			|||||||
        this.page = 1;
 | 
					        this.page = 1;
 | 
				
			||||||
        this.repos = [];
 | 
					        this.repos = [];
 | 
				
			||||||
        this.setCheckboxes();
 | 
					        this.setCheckboxes();
 | 
				
			||||||
        Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
 | 
					        this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
 | 
				
			||||||
        this.searchRepos();
 | 
					        this.searchRepos();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -283,7 +284,7 @@ function initVueComponents() {
 | 
				
			|||||||
        this.page = 1;
 | 
					        this.page = 1;
 | 
				
			||||||
        this.repos = [];
 | 
					        this.repos = [];
 | 
				
			||||||
        this.setCheckboxes();
 | 
					        this.setCheckboxes();
 | 
				
			||||||
        Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
 | 
					        this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
 | 
				
			||||||
        this.searchRepos();
 | 
					        this.searchRepos();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -297,7 +298,7 @@ function initVueComponents() {
 | 
				
			|||||||
          this.page = 1;
 | 
					          this.page = 1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.repos = [];
 | 
					        this.repos = [];
 | 
				
			||||||
        Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0);
 | 
					        this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
 | 
				
			||||||
        this.searchRepos();
 | 
					        this.searchRepos();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -331,7 +332,7 @@ function initVueComponents() {
 | 
				
			|||||||
          if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
 | 
					          if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
 | 
				
			||||||
            this.reposTotalCount = count;
 | 
					            this.reposTotalCount = count;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          Vue.set(this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, count);
 | 
					          this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = count;
 | 
				
			||||||
          this.finalPage = Math.ceil(count / this.searchLimit);
 | 
					          this.finalPage = Math.ceil(count / this.searchLimit);
 | 
				
			||||||
          this.updateHistory();
 | 
					          this.updateHistory();
 | 
				
			||||||
          this.isLoading = false;
 | 
					          this.isLoading = false;
 | 
				
			||||||
@@ -352,22 +353,20 @@ function initVueComponents() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return 'octicon-repo';
 | 
					        return 'octicon-repo';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template: document.getElementById('dashboard-repo-list-template'),
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
export function initDashboardRepoList() {
 | 
					export function initDashboardRepoList() {
 | 
				
			||||||
  const el = document.getElementById('dashboard-repo-list');
 | 
					  const el = document.getElementById('dashboard-repo-list');
 | 
				
			||||||
  const dashboardRepoListData = pageData.dashboardRepoList || null;
 | 
					  const dashboardRepoListData = pageData.dashboardRepoList || null;
 | 
				
			||||||
  if (!el || !dashboardRepoListData) return;
 | 
					  if (!el || !dashboardRepoListData) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initVueSvg();
 | 
					  const app = createApp({
 | 
				
			||||||
  initVueComponents();
 | 
					 | 
				
			||||||
  new Vue({
 | 
					 | 
				
			||||||
    el,
 | 
					 | 
				
			||||||
    delimiters: vueDelimiters,
 | 
					    delimiters: vueDelimiters,
 | 
				
			||||||
    data: () => {
 | 
					    data() {
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        searchLimit: dashboardRepoListData.searchLimit || 0,
 | 
					        searchLimit: dashboardRepoListData.searchLimit || 0,
 | 
				
			||||||
        subUrl: appSubUrl,
 | 
					        subUrl: appSubUrl,
 | 
				
			||||||
@@ -375,4 +374,7 @@ export function initDashboardRepoList() {
 | 
				
			|||||||
      };
 | 
					      };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					  initVueSvg(app);
 | 
				
			||||||
 | 
					  initVueComponents(app);
 | 
				
			||||||
 | 
					  app.mount(el);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <ol class="diff-detail-box diff-stats m-0" id="diff-files" v-if="fileListIsVisible">
 | 
					  <ol class="diff-detail-box diff-stats m-0" ref="root" v-if="fileListIsVisible">
 | 
				
			||||||
    <li v-for="file in files" :key="file.NameHash">
 | 
					    <li v-for="file in files" :key="file.NameHash">
 | 
				
			||||||
      <div class="bold df ac pull-right">
 | 
					      <div class="bold df ac pull-right">
 | 
				
			||||||
        <span v-if="file.IsBin" class="ml-1 mr-3">{{ binaryFileMessage }}</span>
 | 
					        <span v-if="file.IsBin" class="ml-1 mr-3">{{ binaryFileMessage }}</span>
 | 
				
			||||||
@@ -37,7 +37,7 @@ export default {
 | 
				
			|||||||
    fileListIsVisible(newValue) {
 | 
					    fileListIsVisible(newValue) {
 | 
				
			||||||
      if (newValue === true) {
 | 
					      if (newValue === true) {
 | 
				
			||||||
        this.$nextTick(() => {
 | 
					        this.$nextTick(() => {
 | 
				
			||||||
          for (const el of this.$el.querySelectorAll('.tooltip')) {
 | 
					          for (const el of this.$refs.root.querySelectorAll('.tooltip')) {
 | 
				
			||||||
            initTooltip(el);
 | 
					            initTooltip(el);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,10 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div
 | 
					  <div
 | 
				
			||||||
    v-show="fileTreeIsVisible"
 | 
					    v-if="fileTreeIsVisible"
 | 
				
			||||||
    id="diff-file-tree"
 | 
					 | 
				
			||||||
    class="mr-3 mt-3 diff-detail-box"
 | 
					    class="mr-3 mt-3 diff-detail-box"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <!-- only render the tree if we're visible. in many cases this is something that doesn't change very often -->
 | 
					    <!-- only render the tree if we're visible. in many cases this is something that doesn't change very often -->
 | 
				
			||||||
    <div class="ui list" v-if="fileTreeIsVisible">
 | 
					    <div class="ui list">
 | 
				
			||||||
      <DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
 | 
					      <DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
 | 
					    <div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
 | 
				
			||||||
@@ -117,6 +116,9 @@ export default {
 | 
				
			|||||||
      const [toShow, toHide] = document.querySelectorAll('.diff-toggle-file-tree-button .icon');
 | 
					      const [toShow, toHide] = document.querySelectorAll('.diff-toggle-file-tree-button .icon');
 | 
				
			||||||
      toShow.classList.toggle('hide', visible);  // hide the toShow icon if the tree is visible
 | 
					      toShow.classList.toggle('hide', visible);  // hide the toShow icon if the tree is visible
 | 
				
			||||||
      toHide.classList.toggle('hide', !visible); // similarly
 | 
					      toHide.classList.toggle('hide', !visible); // similarly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const diffTree = document.getElementById('diff-file-tree');
 | 
				
			||||||
 | 
					      diffTree.classList.toggle('hide', !visible);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    loadMoreData() {
 | 
					    loadMoreData() {
 | 
				
			||||||
      this.isLoadingNewData = true;
 | 
					      this.isLoadingNewData = true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp, nextTick} from 'vue';
 | 
				
			||||||
import $ from 'jquery';
 | 
					import $ from 'jquery';
 | 
				
			||||||
import {vueDelimiters} from './VueComponentLoader.js';
 | 
					import {vueDelimiters} from './VueComponentLoader.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,10 +37,14 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    $data.remove();
 | 
					    $data.remove();
 | 
				
			||||||
    new Vue({
 | 
					
 | 
				
			||||||
      el: this,
 | 
					    // eslint-disable-next-line unicorn/no-this-assignment
 | 
				
			||||||
 | 
					    const elRoot = this;
 | 
				
			||||||
 | 
					    const view = createApp({
 | 
				
			||||||
      delimiters: vueDelimiters,
 | 
					      delimiters: vueDelimiters,
 | 
				
			||||||
      data,
 | 
					      data() {
 | 
				
			||||||
 | 
					        return data;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      computed: {
 | 
					      computed: {
 | 
				
			||||||
        filteredItems() {
 | 
					        filteredItems() {
 | 
				
			||||||
          const items = this.items.filter((item) => {
 | 
					          const items = this.items.filter((item) => {
 | 
				
			||||||
@@ -73,10 +77,10 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      beforeMount() {
 | 
					      beforeMount() {
 | 
				
			||||||
        this.noResults = this.$el.getAttribute('data-no-results');
 | 
					        this.noResults = elRoot.getAttribute('data-no-results');
 | 
				
			||||||
        this.canCreateBranch = this.$el.getAttribute('data-can-create-branch') === 'true';
 | 
					        this.canCreateBranch = elRoot.getAttribute('data-can-create-branch') === 'true';
 | 
				
			||||||
        this.branchForm = this.$el.getAttribute('data-branch-form');
 | 
					        this.branchForm = elRoot.getAttribute('data-branch-form');
 | 
				
			||||||
        switch (this.$el.getAttribute('data-view-type')) {
 | 
					        switch (elRoot.getAttribute('data-view-type')) {
 | 
				
			||||||
          case 'tree':
 | 
					          case 'tree':
 | 
				
			||||||
            this.isViewTree = true;
 | 
					            this.isViewTree = true;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@@ -87,19 +91,19 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
            this.isViewBranch = true;
 | 
					            this.isViewBranch = true;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.refName = this.$el.getAttribute('data-ref-name');
 | 
					        this.refName = elRoot.getAttribute('data-ref-name');
 | 
				
			||||||
        this.branchURLPrefix = this.$el.getAttribute('data-branch-url-prefix');
 | 
					        this.branchURLPrefix = elRoot.getAttribute('data-branch-url-prefix');
 | 
				
			||||||
        this.branchURLSuffix = this.$el.getAttribute('data-branch-url-suffix');
 | 
					        this.branchURLSuffix = elRoot.getAttribute('data-branch-url-suffix');
 | 
				
			||||||
        this.tagURLPrefix = this.$el.getAttribute('data-tag-url-prefix');
 | 
					        this.tagURLPrefix = elRoot.getAttribute('data-tag-url-prefix');
 | 
				
			||||||
        this.tagURLSuffix = this.$el.getAttribute('data-tag-url-suffix');
 | 
					        this.tagURLSuffix = elRoot.getAttribute('data-tag-url-suffix');
 | 
				
			||||||
        this.setAction = this.$el.getAttribute('data-set-action') === 'true';
 | 
					        this.setAction = elRoot.getAttribute('data-set-action') === 'true';
 | 
				
			||||||
        this.submitForm = this.$el.getAttribute('data-submit-form') === 'true';
 | 
					        this.submitForm = elRoot.getAttribute('data-submit-form') === 'true';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        document.body.addEventListener('click', (event) => {
 | 
					        document.body.addEventListener('click', (event) => {
 | 
				
			||||||
          if (this.$el.contains(event.target)) return;
 | 
					          if (elRoot.contains(event.target)) return;
 | 
				
			||||||
          if (this.menuVisible) {
 | 
					          if (this.menuVisible) {
 | 
				
			||||||
            Vue.set(this, 'menuVisible', false);
 | 
					            this.menuVisible = false;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -135,7 +139,7 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
            if (this.submitForm) {
 | 
					            if (this.submitForm) {
 | 
				
			||||||
              $(`#${this.branchForm}`).trigger('submit');
 | 
					              $(`#${this.branchForm}`).trigger('submit');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Vue.set(this, 'menuVisible', false);
 | 
					            this.menuVisible = false;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        createNewBranch() {
 | 
					        createNewBranch() {
 | 
				
			||||||
@@ -143,7 +147,7 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
          $(this.$refs.newBranchForm).trigger('submit');
 | 
					          $(this.$refs.newBranchForm).trigger('submit');
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        focusSearchField() {
 | 
					        focusSearchField() {
 | 
				
			||||||
          Vue.nextTick(() => {
 | 
					          nextTick(() => {
 | 
				
			||||||
            this.$refs.searchField.focus();
 | 
					            this.$refs.searchField.focus();
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -213,5 +217,6 @@ export function initRepoBranchTagDropdown(selector) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    view.mount(this);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp} from 'vue';
 | 
				
			||||||
import {svgs} from '../svg.js';
 | 
					import {svgs} from '../svg.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const vueDelimiters = ['${', '}'];
 | 
					export const vueDelimiters = ['${', '}'];
 | 
				
			||||||
@@ -8,13 +8,14 @@ export function initVueEnv() {
 | 
				
			|||||||
  if (vueEnvInited) return;
 | 
					  if (vueEnvInited) return;
 | 
				
			||||||
  vueEnvInited = true;
 | 
					  vueEnvInited = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const isProd = window.config.runModeIsProd;
 | 
					  // As far as I could tell, this is no longer possible.
 | 
				
			||||||
  Vue.config.productionTip = false;
 | 
					  // But there seem not to be a guide what to do instead.
 | 
				
			||||||
  Vue.config.devtools = !isProd;
 | 
					  // const isProd = window.config.runModeIsProd;
 | 
				
			||||||
 | 
					  // Vue.config.devtools = !isProd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let vueSvgInited = false;
 | 
					let vueSvgInited = false;
 | 
				
			||||||
export function initVueSvg() {
 | 
					export function initVueSvg(app) {
 | 
				
			||||||
  if (vueSvgInited) return;
 | 
					  if (vueSvgInited) return;
 | 
				
			||||||
  vueSvgInited = true;
 | 
					  vueSvgInited = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,7 +25,7 @@ export function initVueSvg() {
 | 
				
			|||||||
      .replace(/height="[0-9]+"/, 'v-bind:height="size"')
 | 
					      .replace(/height="[0-9]+"/, 'v-bind:height="size"')
 | 
				
			||||||
      .replace(/width="[0-9]+"/, 'v-bind:width="size"');
 | 
					      .replace(/width="[0-9]+"/, 'v-bind:width="size"');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Vue.component(name, {
 | 
					    app.component(name, {
 | 
				
			||||||
      props: {
 | 
					      props: {
 | 
				
			||||||
        size: {
 | 
					        size: {
 | 
				
			||||||
          type: String,
 | 
					          type: String,
 | 
				
			||||||
@@ -42,8 +43,7 @@ export function initVueApp(el, opts = {}) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  if (!el) return null;
 | 
					  if (!el) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return new Vue(Object.assign({
 | 
					  return createApp(
 | 
				
			||||||
    el,
 | 
					    Object.assign({delimiters: vueDelimiters}, opts)
 | 
				
			||||||
    delimiters: vueDelimiters,
 | 
					  ).mount(el);
 | 
				
			||||||
  }, opts));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import $ from 'jquery';
 | 
					import $ from 'jquery';
 | 
				
			||||||
import Vue from 'vue';
 | 
					import {createApp} from 'vue';
 | 
				
			||||||
import ContextPopup from '../components/ContextPopup.vue';
 | 
					import ContextPopup from '../components/ContextPopup.vue';
 | 
				
			||||||
import {parseIssueHref} from '../utils.js';
 | 
					import {parseIssueHref} from '../utils.js';
 | 
				
			||||||
import {createTippy} from '../modules/tippy.js';
 | 
					import {createTippy} from '../modules/tippy.js';
 | 
				
			||||||
@@ -17,17 +17,12 @@ export default function initContextPopups() {
 | 
				
			|||||||
    if (!owner) return;
 | 
					    if (!owner) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const el = document.createElement('div');
 | 
					    const el = document.createElement('div');
 | 
				
			||||||
    el.innerHTML = '<div></div>';
 | 
					 | 
				
			||||||
    this.parentNode.insertBefore(el, this.nextSibling);
 | 
					    this.parentNode.insertBefore(el, this.nextSibling);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const View = Vue.extend({
 | 
					    const view = createApp(ContextPopup);
 | 
				
			||||||
      render: (createElement) => createElement(ContextPopup),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const view = new View();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      view.$mount(el.firstChild);
 | 
					      view.mount(el);
 | 
				
			||||||
    } catch (err) {
 | 
					    } catch (err) {
 | 
				
			||||||
      console.error(err);
 | 
					      console.error(err);
 | 
				
			||||||
      el.textContent = 'ContextPopup failed to load';
 | 
					      el.textContent = 'ContextPopup failed to load';
 | 
				
			||||||
@@ -37,7 +32,7 @@ export default function initContextPopups() {
 | 
				
			|||||||
      content: el,
 | 
					      content: el,
 | 
				
			||||||
      interactive: true,
 | 
					      interactive: true,
 | 
				
			||||||
      onShow: () => {
 | 
					      onShow: () => {
 | 
				
			||||||
        view.$emit('load-context-popup', {owner, repo, index});
 | 
					        el.firstChild.dispatchEvent(new CustomEvent('us-load-context-popup', {detail: {owner, repo, index}}));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp} from 'vue';
 | 
				
			||||||
import ActivityHeatmap from '../components/ActivityHeatmap.vue';
 | 
					import ActivityHeatmap from '../components/ActivityHeatmap.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function initHeatmap() {
 | 
					export default function initHeatmap() {
 | 
				
			||||||
@@ -17,11 +17,9 @@ export default function initHeatmap() {
 | 
				
			|||||||
      return {date: new Date(v), count: heatmap[v]};
 | 
					      return {date: new Date(v), count: heatmap[v]};
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const View = Vue.extend({
 | 
					    const View = createApp(ActivityHeatmap, {values});
 | 
				
			||||||
      render: (createElement) => createElement(ActivityHeatmap, {props: {values}}),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new View().$mount(el);
 | 
					    View.mount(el);
 | 
				
			||||||
  } catch (err) {
 | 
					  } catch (err) {
 | 
				
			||||||
    console.error('Heatmap failed to load', err);
 | 
					    console.error('Heatmap failed to load', err);
 | 
				
			||||||
    el.textContent = 'Heatmap failed to load';
 | 
					    el.textContent = 'Heatmap failed to load';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,17 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp} from 'vue';
 | 
				
			||||||
import DiffFileTree from '../components/DiffFileTree.vue';
 | 
					import DiffFileTree from '../components/DiffFileTree.vue';
 | 
				
			||||||
import DiffFileList from '../components/DiffFileList.vue';
 | 
					import DiffFileList from '../components/DiffFileList.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function initDiffFileTree() {
 | 
					export default function initDiffFileTree() {
 | 
				
			||||||
  const el = document.getElementById('diff-file-tree-container');
 | 
					  const el = document.getElementById('diff-file-tree');
 | 
				
			||||||
  if (!el) return;
 | 
					  if (!el) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const View = Vue.extend({
 | 
					  const fileTreeView = createApp(DiffFileTree);
 | 
				
			||||||
    render: (createElement) => createElement(DiffFileTree),
 | 
					  fileTreeView.mount(el);
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  new View().$mount(el);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const fileListElement = document.getElementById('diff-file-list-container');
 | 
					  const fileListElement = document.getElementById('diff-file-list');
 | 
				
			||||||
  if (!fileListElement) return;
 | 
					  if (!fileListElement) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const fileListView = Vue.extend({
 | 
					  const fileListView = createApp(DiffFileList);
 | 
				
			||||||
    render: (createElement) => createElement(DiffFileList),
 | 
					  fileListView.mount(fileListElement);
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  new fileListView().$mount(fileListElement);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,10 @@
 | 
				
			|||||||
import Vue from 'vue';
 | 
					import {createApp} from 'vue';
 | 
				
			||||||
import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
 | 
					import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function initPullRequestMergeForm() {
 | 
					export default function initPullRequestMergeForm() {
 | 
				
			||||||
  const el = document.getElementById('pull-request-merge-form');
 | 
					  const el = document.getElementById('pull-request-merge-form');
 | 
				
			||||||
  if (!el) return;
 | 
					  if (!el) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const View = Vue.extend({
 | 
					  const view = createApp(PullRequestMergeForm);
 | 
				
			||||||
    render: (createElement) => createElement(PullRequestMergeForm),
 | 
					  view.mount(el);
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  new View().$mount(el);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,6 @@ import octiconSidebarExpand from '../../public/img/svg/octicon-sidebar-expand.sv
 | 
				
			|||||||
import octiconSidebarCollapse from '../../public/img/svg/octicon-sidebar-collapse.svg';
 | 
					import octiconSidebarCollapse from '../../public/img/svg/octicon-sidebar-collapse.svg';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Vue from 'vue';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const svgs = {
 | 
					export const svgs = {
 | 
				
			||||||
  'octicon-chevron-down': octiconChevronDown,
 | 
					  'octicon-chevron-down': octiconChevronDown,
 | 
				
			||||||
  'octicon-chevron-right': octiconChevronRight,
 | 
					  'octicon-chevron-right': octiconChevronRight,
 | 
				
			||||||
@@ -74,7 +72,8 @@ export function svg(name, size = 16, className = '') {
 | 
				
			|||||||
  return serializer.serializeToString(svgNode);
 | 
					  return serializer.serializeToString(svgNode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SvgIcon = Vue.component('SvgIcon', {
 | 
					export const SvgIcon = {
 | 
				
			||||||
 | 
					  name: 'SvgIcon',
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    name: {type: String, required: true},
 | 
					    name: {type: String, required: true},
 | 
				
			||||||
    size: {type: Number, default: 16},
 | 
					    size: {type: Number, default: 16},
 | 
				
			||||||
@@ -88,4 +87,4 @@ export const SvgIcon = Vue.component('SvgIcon', {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template: `<span v-html="svg" />`
 | 
					  template: `<span v-html="svg" />`
 | 
				
			||||||
});
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,16 @@
 | 
				
			|||||||
  text-align: center;
 | 
					  text-align: center;
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  min-height: 125px;
 | 
					  min-height: 125px;
 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  justify-content: center;
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // for the "Less" and "More" legend
 | 
				
			||||||
 | 
					  .vch__legend .vch__legend div:first-child,
 | 
				
			||||||
 | 
					  .vch__legend .vch__legend div:last-child {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    padding: 0 5px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  > svg {
 | 
					  > svg {
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,13 @@ import AddAssetPlugin from 'add-asset-webpack-plugin';
 | 
				
			|||||||
import LicenseCheckerWebpackPlugin from 'license-checker-webpack-plugin';
 | 
					import LicenseCheckerWebpackPlugin from 'license-checker-webpack-plugin';
 | 
				
			||||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
 | 
					import MiniCssExtractPlugin from 'mini-css-extract-plugin';
 | 
				
			||||||
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
 | 
					import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
 | 
				
			||||||
import VueLoader from 'vue-loader';
 | 
					import {VueLoaderPlugin} from 'vue-loader';
 | 
				
			||||||
import EsBuildLoader from 'esbuild-loader';
 | 
					import EsBuildLoader from 'esbuild-loader';
 | 
				
			||||||
import {parse, dirname} from 'path';
 | 
					import {parse, dirname} from 'path';
 | 
				
			||||||
import webpack from 'webpack';
 | 
					import webpack from 'webpack';
 | 
				
			||||||
import {fileURLToPath} from 'url';
 | 
					import {fileURLToPath} from 'url';
 | 
				
			||||||
import {readFileSync} from 'fs';
 | 
					import {readFileSync} from 'fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const {VueLoaderPlugin} = VueLoader;
 | 
					 | 
				
			||||||
const {ESBuildMinifyPlugin} = EsBuildLoader;
 | 
					const {ESBuildMinifyPlugin} = EsBuildLoader;
 | 
				
			||||||
const {SourceMapDevToolPlugin} = webpack;
 | 
					const {SourceMapDevToolPlugin} = webpack;
 | 
				
			||||||
const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
 | 
					const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
 | 
				
			||||||
@@ -242,9 +241,6 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  resolve: {
 | 
					  resolve: {
 | 
				
			||||||
    symlinks: false,
 | 
					    symlinks: false,
 | 
				
			||||||
    alias: {
 | 
					 | 
				
			||||||
      vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  watchOptions: {
 | 
					  watchOptions: {
 | 
				
			||||||
    ignored: [
 | 
					    ignored: [
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user