Stackedit/src/components/Preview.vue

176 lines
4.4 KiB
Vue
Raw Normal View History

2017-07-23 18:42:08 +00:00
<template>
<div class="preview">
<div class="preview__inner-1" @click="onClick" @scroll="onScroll">
<div class="preview__inner-2" :style="{padding: styles.previewPadding}">
</div>
2017-11-15 08:12:56 +00:00
<div class="gutter" :style="{left: styles.previewGutterLeft + 'px'}">
<comment-list v-if="styles.previewGutterWidth"></comment-list>
2018-03-12 00:45:54 +00:00
<preview-new-discussion-button v-if="!isCurrentTemp"></preview-new-discussion-button>
2017-11-15 08:12:56 +00:00
</div>
</div>
2017-11-15 08:12:56 +00:00
<div v-if="!styles.showEditor" class="preview__corner">
2022-06-01 23:45:13 +00:00
<button class="preview__button button" @click="toggleEditor(true)" v-title="'编辑文件'">
<icon-pen></icon-pen>
2017-11-15 08:12:56 +00:00
</button>
2017-07-23 18:42:08 +00:00
</div>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
2017-11-15 08:12:56 +00:00
import CommentList from './gutters/CommentList';
import PreviewNewDiscussionButton from './gutters/PreviewNewDiscussionButton';
2018-09-19 08:59:22 +00:00
import store from '../store';
2017-07-23 18:42:08 +00:00
2018-05-06 00:46:33 +00:00
const appUri = `${window.location.protocol}//${window.location.host}`;
2017-07-23 18:42:08 +00:00
export default {
components: {
2017-11-15 08:12:56 +00:00
CommentList,
PreviewNewDiscussionButton,
},
data: () => ({
previewTop: true,
}),
2018-03-12 00:45:54 +00:00
computed: {
...mapGetters('file', [
'isCurrentTemp',
]),
...mapGetters('layout', [
'styles',
]),
},
methods: {
...mapActions('data', [
'toggleEditor',
]),
onClick(evt) {
2017-07-23 18:42:08 +00:00
let elt = evt.target;
while (elt !== this.$el) {
if (elt.href && elt.href.match(/^https?:\/\//)
&& (!elt.hash || elt.href.slice(0, appUri.length) !== appUri)) {
evt.preventDefault();
const wnd = window.open(elt.href, '_blank');
wnd.focus();
return;
}
elt = elt.parentNode;
}
},
onScroll(evt) {
this.previewTop = evt.target.scrollTop < 10;
},
2017-07-23 18:42:08 +00:00
},
mounted() {
const previewElt = this.$el.querySelector('.preview__inner-2');
const onDiscussionEvt = cb => (evt) => {
let elt = evt.target;
while (elt && elt !== previewElt) {
if (elt.discussionId) {
cb(elt.discussionId);
return;
}
elt = elt.parentNode;
}
};
2017-11-15 08:12:56 +00:00
const classToggler = toggle => (discussionId) => {
previewElt.getElementsByClassName(`discussion-preview-highlighting--${discussionId}`)
.cl_each(elt => elt.classList.toggle('discussion-preview-highlighting--hover', toggle));
document.getElementsByClassName(`comment--discussion-${discussionId}`)
.cl_each(elt => elt.classList.toggle('comment--hover', toggle));
};
previewElt.addEventListener('mouseover', onDiscussionEvt(classToggler(true)));
previewElt.addEventListener('mouseout', onDiscussionEvt(classToggler(false)));
previewElt.addEventListener('click', onDiscussionEvt((discussionId) => {
2018-09-19 08:59:22 +00:00
store.commit('discussion/setCurrentDiscussionId', discussionId);
}));
2017-11-15 08:12:56 +00:00
this.$watch(
2018-09-19 08:59:22 +00:00
() => store.state.discussion.currentDiscussionId,
(discussionId, oldDiscussionId) => {
if (oldDiscussionId) {
2017-11-15 08:12:56 +00:00
previewElt.querySelectorAll(`.discussion-preview-highlighting--${oldDiscussionId}`)
.cl_each(elt => elt.classList.remove('discussion-preview-highlighting--selected'));
}
if (discussionId) {
2017-11-15 08:12:56 +00:00
previewElt.querySelectorAll(`.discussion-preview-highlighting--${discussionId}`)
.cl_each(elt => elt.classList.add('discussion-preview-highlighting--selected'));
}
2018-05-06 00:46:33 +00:00
},
);
},
2017-07-23 18:42:08 +00:00
};
</script>
<style lang="scss">
2018-05-06 00:46:33 +00:00
@import '../styles/variables.scss';
.preview,
.preview__inner-1 {
2017-07-23 18:42:08 +00:00
position: absolute;
width: 100%;
height: 100%;
}
.preview__inner-1 {
2017-07-23 18:42:08 +00:00
overflow: auto;
}
.preview__inner-2 {
2017-07-23 18:42:08 +00:00
margin: 0;
}
2017-07-31 09:04:01 +00:00
.preview__inner-2 > :first-child > :first-child {
margin-top: 0;
}
2017-11-15 08:12:56 +00:00
$corner-size: 110px;
.preview__corner {
position: absolute;
2017-11-15 08:12:56 +00:00
top: 0;
right: 0;
&::before {
content: '';
position: absolute;
right: 0;
border-top: $corner-size solid rgba(0, 0, 0, 0.075);
border-left: $corner-size solid transparent;
pointer-events: none;
2018-01-14 16:27:06 +00:00
.app--dark & {
border-top-color: rgba(255, 255, 255, 0.075);
}
2017-11-15 08:12:56 +00:00
}
}
.preview__button {
2017-11-15 08:12:56 +00:00
position: absolute;
top: 15px;
right: 15px;
width: 40px;
height: 40px;
padding: 5px;
2017-11-15 08:12:56 +00:00
color: rgba(0, 0, 0, 0.25);
2018-01-14 16:27:06 +00:00
.app--dark & {
color: rgba(255, 255, 255, 0.25);
}
2017-11-15 08:12:56 +00:00
&:active,
&:focus,
&:hover {
2017-11-15 08:12:56 +00:00
color: rgba(0, 0, 0, 0.33);
background-color: transparent;
2018-01-14 16:27:06 +00:00
.app--dark & {
color: rgba(255, 255, 255, 0.33);
}
2017-07-31 09:04:01 +00:00
}
}
2017-07-23 18:42:08 +00:00
</style>