%PDF- %PDF-
| Direktori : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/previews/ |
| Current File : /home/dopla/www/wp-content/plugins/ml-slider/admin/assets/js/app/previews/Preview.vue |
<template>
<div
id="preview-component"
:class="{ 'ms-has-error': errorMessage.length }"
class="h-full z-max relative">
<sweet-modal
:ref="'preview'"
:class="{'control-light': lightsOn}"
:overlay-theme="overlayTheme"
:modal-theme="overlayTheme"
:blocking="true"
:pulse-on-block="false"
hide-close-button>
<div
slot="box-action"
class="flex w-full bg-gray-light fixed top-0 left-0 right-0 h-8 items-center justify-between">
<div class="flex h-full">
<h2
:class="{
'bg-white text-black': overlayTheme !== 'dark',
'bg-black text-white': overlayTheme === 'dark'
}"
class="font-bold flex items-center h-full m-0 pl-6 pr-8 relative overflow-hidden uppercase leading-normal">
{{ __('Preview', 'ml-slider') }}
</h2>
<button
:title="__('Toggle overlay type', 'ml-slider') + ' (L)'"
class="lightbulb w-10 px-2 hover:bg-black hover:text-white hover:p-px transition duration-200"
:class="{
'bg-black text-white p-px': overlayTheme !== 'dark',
'bg-transparent text-black': overlayTheme === 'dark'
}"
@click="toggleLights">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
</button>
<button
:title="__('Toggle full width', 'ml-slider') + ' (F)'"
:class="{
'bg-black text-white p-px': showFullwidth,
'bg-transparent text-black': !showFullwidth
}"
class="w-10 px-2 hover:bg-black hover:text-white hover:p-px transition duration-200"
@click="toggleFullwidth">
<svg
class="w-full" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
</svg>
</button>
</div>
<button
:title="__('Exit preview', 'ml-slider') + ' (ESC)'"
class="mr-2 rtl:ml-2 rtl:mr-0 w-6 text-black"
@click="closePreview">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<iframe
v-if="'' !== html"
:class="{'invisible':!iframeLoaded}"
:id="'iframe-' + _uid"
:srcdoc="html"
frameborder="0"
@load="setupIframe"
/>
<div v-else>
<span v-if="!iframeLoaded && !errorMessage.length">
{{ __('Loading...', 'ml-slider') }}
</span>
<p
v-if="errorMessage.length"
class="ms-error"
v-text="errorMessage"/>
<p
v-if="notFullySupported"
class="ms-feature-not-supported">
{{ __('This feature is not fully supported in this browser.', 'ml-slider') }}
</p>
</div>
</sweet-modal>
</div>
</template>
<script>
// TODO Maybe we dont need to save first if on a theme view
// green checkmark
import { EventManager } from '../utils'
import { Axios } from '../api'
import './components'
import srcDoc from 'srcdoc-polyfill'
import hotkeys from 'hotkeys-js';
import { mapGetters } from 'vuex'
export default {
props: {},
data() {
return {
html: '',
slideshowId: '',
theme_id: '',
iframeLoaded: false,
errorMessage: '',
previewIframe: {},
overlayTheme: 'dark',
showFullwidth: false,
notFullySupported: !('srcdoc' in document.createElement('iframe')),
resizeEvent: {}
}
},
computed: {
lightsOn() {
// TODO: save the state in the settings behind the scenes
return 'dark' !== this.overlayTheme
},
maxWidth() {
// TODO: refactor when settings object is implimented in vue store
let width = parseInt(document.getElementsByName('settings[width]')[0].value, 10)
// This accounts the 40px padding on each side.
return (!this.showFullwidth && width) ? width + 'px' : '100%'
},
...mapGetters({
current: 'slideshows/getCurrent'
})
},
mounted() {
// Note, the slideshow should be saved BEFORE this event is fired
EventManager.$on('metaslider/open-preview', ({ slideshowId, themeId }) => {
this.openPreview(slideshowId, themeId)
})
hotkeys('alt+p', () => this.handleOpeningPreviewByKeyboard())
},
methods: {
hasSlides() {
return document.querySelector('tr.slide:not(.ms-deleted)')
},
openPreview(slideshowId = null, themeId = null) {
// If no images are found, offer to import some.
if (!this.hasSlides()) {
EventManager.$emit('import-notice', themeId || this.current.theme.folder)
return false
}
// Add events for keyboard controls
document.addEventListener('keyup', this.handleKeyups)
// Reset to not show fullwidth whenever loaded.
this.showFullwidth = false
// Open the specific preview
this.$refs['preview'].open()
// Fetch the iframe
this.fetchIframe(slideshowId, themeId)
},
closePreview() {
this.$refs['preview'].close()
this.html = ''
this.iframeLoaded = false
this.errorMessage = ''
document.removeEventListener('keyup', this.handleKeyups)
},
fetchIframe(slideshowId = null, themeId = null) {
this.errorMessage = ''
Axios.get('slideshow/preview', {
params: {
action: 'ms_get_preview',
theme_slug: themeId || this.current.theme.folder, // Used for pro themes
slideshow_id: slideshowId || this.current.id,
theme_id: themeId || this.current.theme.folder
}
}).then(response => {
this.html = response.data.data
// polyfill for ie11
this.$nextTick(() => {
srcDoc.set(document.getElementById('iframe-' + this._uid))
// ! Somehow this is an IE11 fix. I'm guessing it forces Vuejs to compare
// ! the dom to the virtual dom and force the update. Oh well, it works
if (this.notFullySupported) console.log(document.getElementById('iframe-' + this._uid))
})
this.notifySuccess('metaslider/preview-loaded', 'Preview loaded')
}).catch(error => {
this.iframeLoaded = true
this.errorMessage = this.getErrorMessage(error.response)
this.notifyError('metaslider/preview-error', error)
})
},
setupIframe(event) {
this.previewIframe = {
window: event.target.contentWindow,
document: event.target.contentDocument,
container: event.target.contentDocument.getElementById('preview-container'),
slideshow: event.target.contentDocument.querySelector('.metaslider')
}
// Add events for keyboard controls for when focus is inside the iframe
this.previewIframe.document.addEventListener('keyup', this.handleKeyups)
// Set the slideshow to 100% width
this.previewIframe.slideshow.style.width = '100%'
// Add a way to fake a resize event inside the iframe, and trigger it
if ('function' !== typeof window.Event) { // IE 11 polyfill
this.resizeEvent = this.previewIframe.window.document.createEvent('UIEvents')
this.resizeEvent.initUIEvent('resize', true, false, window, 0)
} else {
this.resizeEvent = new Event('resize')
}
// If the slideshow is a carousel make full width
if (document.getElementsByName('settings[carouselMode]')[0].checked) {
this.toggleFullwidth()
}
this.previewIframe.window.dispatchEvent(this.resizeEvent)
this.iframeLoaded = true
},
toggleFullwidth() {
this.showFullwidth = !this.showFullwidth
// Set the container and slideshow to full width
this.previewIframe.container.style.maxWidth = this.maxWidth
this.previewIframe.slideshow.style.maxWidth = this.maxWidth
// trigger a resize in the iframe to let the slider recalculate itself
this.previewIframe.window.dispatchEvent(this.resizeEvent)
},
toggleLights() {
this.overlayTheme = 'dark' === this.overlayTheme ? 'light' : 'dark'
},
handleKeyups(event) {
70 === event.keyCode && this.toggleFullwidth() // F
76 === event.keyCode && this.toggleLights() // L
27 === event.keyCode && this.closePreview() // ESC
},
handleOpeningPreviewByKeyboard() {
if (this.$parent.saving) return false
if (document.getElementById('preview-component').length) {
return false
}
// This will also offer to import slides if none exist
EventManager.$emit('metaslider/preview')
}
}
}
</script>
<style lang="scss">
@import '../assets/styles/globals.scss';
div#preview-component {
float: left;
> .sweet-modal-overlay {
background: #FFF;
&.theme-dark {
background: $wp-black;
}
.sweet-modal {
background: transparent;
box-shadow: none;
min-width: 100%;
padding: 0;
.sweet-content,
.sweet-content-content,
iframe {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height:100%;
}
}
}
}
</style>