Resolve #3644
This commit is contained in:
		
							parent
							
								
									517ea6a119
								
							
						
					
					
						commit
						892cb44d84
					
				
					 2 changed files with 104 additions and 1 deletions
				
			
		
							
								
								
									
										55
									
								
								src/client/components/url-preview-popup.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/client/components/url-preview-popup.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="fgmtyycl _panel" :style="{ top: top + 'px', left: left + 'px' }" @mouseover="() => { $emit('mouseover'); }" @mouseleave="() => { $emit('mouseleave'); }">
 | 
			
		||||
	<x-url-preview :url="url" style="width: 600px;"/>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../i18n';
 | 
			
		||||
import XUrlPreview from './url-preview.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n,
 | 
			
		||||
 | 
			
		||||
	components: {
 | 
			
		||||
		XUrlPreview
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	props: {
 | 
			
		||||
		url: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: true
 | 
			
		||||
		},
 | 
			
		||||
		source: {
 | 
			
		||||
			required: true
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			u: null,
 | 
			
		||||
			top: 0,
 | 
			
		||||
			left: 0,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		const rect = this.source.getBoundingClientRect();
 | 
			
		||||
		const x = ((rect.left + (this.source.offsetWidth / 2)) - (300 / 2)) + window.pageXOffset;
 | 
			
		||||
		const y = rect.top + this.source.offsetHeight + window.pageYOffset;
 | 
			
		||||
 | 
			
		||||
		this.top = y;
 | 
			
		||||
		this.left = x;
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.fgmtyycl {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	z-index: 11000;
 | 
			
		||||
	//width: 300px;
 | 
			
		||||
	overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,8 @@
 | 
			
		|||
<template>
 | 
			
		||||
<component :is="hasRoute ? 'router-link' : 'a'" class="ieqqeuvs _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target">
 | 
			
		||||
<component :is="hasRoute ? 'router-link' : 'a'" class="ieqqeuvs _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target"
 | 
			
		||||
	@mouseover="onMouseover"
 | 
			
		||||
	@mouseleave="onMouseleave"
 | 
			
		||||
>
 | 
			
		||||
	<template v-if="!self">
 | 
			
		||||
		<span class="schema">{{ schema }}//</span>
 | 
			
		||||
		<span class="hostname">{{ hostname }}</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +23,7 @@ import Vue from 'vue';
 | 
			
		|||
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import { toUnicode as decodePunycode } from 'punycode';
 | 
			
		||||
import { url as local } from '../config';
 | 
			
		||||
import XUrlPreview from './url-preview-popup.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +55,9 @@ export default Vue.extend({
 | 
			
		|||
			hasRoute: hasRoute,
 | 
			
		||||
			attr: hasRoute ? 'to' : 'href',
 | 
			
		||||
			target: hasRoute ? null : '_blank',
 | 
			
		||||
			showTimer: null,
 | 
			
		||||
			hideTimer: null,
 | 
			
		||||
			preview: null,
 | 
			
		||||
			faExternalLinkSquareAlt
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +69,47 @@ export default Vue.extend({
 | 
			
		|||
		this.pathname = decodeURIComponent(url.pathname);
 | 
			
		||||
		this.query = decodeURIComponent(url.search);
 | 
			
		||||
		this.hash = decodeURIComponent(url.hash);
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		showPreview() {
 | 
			
		||||
			if (!document.body.contains(this.$el)) return;
 | 
			
		||||
			if (this.preview) return;
 | 
			
		||||
 | 
			
		||||
			this.preview = new XUrlPreview({
 | 
			
		||||
				parent: this,
 | 
			
		||||
				propsData: {
 | 
			
		||||
					url: this.url,
 | 
			
		||||
					source: this.$el
 | 
			
		||||
				}
 | 
			
		||||
			}).$mount();
 | 
			
		||||
 | 
			
		||||
			this.preview.$on('mouseover', () => {
 | 
			
		||||
				clearTimeout(this.hideTimer);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.preview.$on('mouseleave', () => {
 | 
			
		||||
				clearTimeout(this.showTimer);
 | 
			
		||||
				this.hideTimer = setTimeout(this.closePreview, 500);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			document.body.appendChild(this.preview.$el);
 | 
			
		||||
		},
 | 
			
		||||
		closePreview() {
 | 
			
		||||
			if (this.preview) {
 | 
			
		||||
				this.preview.destroyDom();
 | 
			
		||||
				this.preview = null;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		onMouseover() {
 | 
			
		||||
			clearTimeout(this.showTimer);
 | 
			
		||||
			clearTimeout(this.hideTimer);
 | 
			
		||||
			this.showTimer = setTimeout(this.showPreview, 500);
 | 
			
		||||
		},
 | 
			
		||||
		onMouseleave() {
 | 
			
		||||
			clearTimeout(this.showTimer);
 | 
			
		||||
			clearTimeout(this.hideTimer);
 | 
			
		||||
			this.hideTimer = setTimeout(this.closePreview, 500);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue