diff options
| author | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-11 18:38:12 +0900 |
|---|---|---|
| committer | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-11 18:38:12 +0900 |
| commit | a7f62e50f97167d5826ea6a3390aecd51ab7df73 (patch) | |
| tree | a3dea1900de200c627c0ed120e3e6cf180d17bde /src/web | |
| parent | wip (diff) | |
| download | sharkey-a7f62e50f97167d5826ea6a3390aecd51ab7df73.tar.gz sharkey-a7f62e50f97167d5826ea6a3390aecd51ab7df73.tar.bz2 sharkey-a7f62e50f97167d5826ea6a3390aecd51ab7df73.zip | |
wip
Diffstat (limited to 'src/web')
| -rw-r--r-- | src/web/app/desktop/-tags/window.tag | 549 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/window.vue | 558 |
2 files changed, 557 insertions, 550 deletions
diff --git a/src/web/app/desktop/-tags/window.tag b/src/web/app/desktop/-tags/window.tag deleted file mode 100644 index 051b43f076..0000000000 --- a/src/web/app/desktop/-tags/window.tag +++ /dev/null @@ -1,549 +0,0 @@ -<mk-window data-flexible={ isFlexible } ondragover={ ondragover }> - <div class="bg" ref="bg" show={ isModal } @click="bgClick"></div> - <div class="main" ref="main" tabindex="-1" data-is-modal={ isModal } onmousedown={ onBodyMousedown } onkeydown={ onKeydown }> - <div class="body"> - <header ref="header" onmousedown={ onHeaderMousedown }> - <h1 data-yield="header"><yield from="header"/></h1> - <div> - <button class="popout" v-if="popoutUrl" onmousedown={ repelMove } @click="popout" title="ポップアウト">%fa:R window-restore%</button> - <button class="close" v-if="canClose" onmousedown={ repelMove } @click="close" title="閉じる">%fa:times%</button> - </div> - </header> - <div class="content" data-yield="content"><yield from="content"/></div> - </div> - <div class="handle top" v-if="canResize" onmousedown={ onTopHandleMousedown }></div> - <div class="handle right" v-if="canResize" onmousedown={ onRightHandleMousedown }></div> - <div class="handle bottom" v-if="canResize" onmousedown={ onBottomHandleMousedown }></div> - <div class="handle left" v-if="canResize" onmousedown={ onLeftHandleMousedown }></div> - <div class="handle top-left" v-if="canResize" onmousedown={ onTopLeftHandleMousedown }></div> - <div class="handle top-right" v-if="canResize" onmousedown={ onTopRightHandleMousedown }></div> - <div class="handle bottom-right" v-if="canResize" onmousedown={ onBottomRightHandleMousedown }></div> - <div class="handle bottom-left" v-if="canResize" onmousedown={ onBottomLeftHandleMousedown }></div> - </div> - <style lang="stylus" scoped> - :scope - display block - - > .bg - display block - position fixed - z-index 2048 - top 0 - left 0 - width 100% - height 100% - background rgba(0, 0, 0, 0.7) - opacity 0 - pointer-events none - - > .main - display block - position fixed - z-index 2048 - top 15% - left 0 - margin 0 - opacity 0 - pointer-events none - - &:focus - &:not([data-is-modal]) - > .body - box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2) - - > .handle - $size = 8px - - position absolute - - &.top - top -($size) - left 0 - width 100% - height $size - cursor ns-resize - - &.right - top 0 - right -($size) - width $size - height 100% - cursor ew-resize - - &.bottom - bottom -($size) - left 0 - width 100% - height $size - cursor ns-resize - - &.left - top 0 - left -($size) - width $size - height 100% - cursor ew-resize - - &.top-left - top -($size) - left -($size) - width $size * 2 - height $size * 2 - cursor nwse-resize - - &.top-right - top -($size) - right -($size) - width $size * 2 - height $size * 2 - cursor nesw-resize - - &.bottom-right - bottom -($size) - right -($size) - width $size * 2 - height $size * 2 - cursor nwse-resize - - &.bottom-left - bottom -($size) - left -($size) - width $size * 2 - height $size * 2 - cursor nesw-resize - - > .body - height 100% - overflow hidden - background #fff - border-radius 6px - box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2) - - > header - $header-height = 40px - - z-index 128 - height $header-height - overflow hidden - white-space nowrap - cursor move - background #fff - border-radius 6px 6px 0 0 - box-shadow 0 1px 0 rgba(#000, 0.1) - - &, * - user-select none - - > h1 - pointer-events none - display block - margin 0 auto - overflow hidden - height $header-height - text-overflow ellipsis - text-align center - font-size 1em - line-height $header-height - font-weight normal - color #666 - - > div:last-child - position absolute - top 0 - right 0 - display block - z-index 1 - - > * - display inline-block - margin 0 - padding 0 - cursor pointer - font-size 1.2em - color rgba(#000, 0.4) - border none - outline none - background transparent - - &:hover - color rgba(#000, 0.6) - - &:active - color darken(#000, 30%) - - > [data-fa] - padding 0 - width $header-height - line-height $header-height - text-align center - - > .content - height 100% - - &:not([flexible]) - > .main > .body > .content - height calc(100% - 40px) - - </style> - <script lang="typescript"> - import anime from 'animejs'; - import contains from '../../common/scripts/contains'; - - this.minHeight = 40; - this.minWidth = 200; - - this.isModal = this.opts.isModal != null ? this.opts.isModal : false; - this.canClose = this.opts.canClose != null ? this.opts.canClose : true; - this.popoutUrl = this.opts.popout; - this.isFlexible = this.opts.height == null; - this.canResize = !this.isFlexible; - - this.on('mount', () => { - this.$refs.main.style.width = this.opts.width || '530px'; - this.$refs.main.style.height = this.opts.height || 'auto'; - - this.$refs.main.style.top = '15%'; - this.$refs.main.style.left = (window.innerWidth / 2) - (this.$refs.main.offsetWidth / 2) + 'px'; - - this.$refs.header.addEventListener('contextmenu', e => { - e.preventDefault(); - }); - - window.addEventListener('resize', this.onBrowserResize); - - this.open(); - }); - - this.on('unmount', () => { - window.removeEventListener('resize', this.onBrowserResize); - }); - - this.onBrowserResize = () => { - const position = this.$refs.main.getBoundingClientRect(); - const browserWidth = window.innerWidth; - const browserHeight = window.innerHeight; - const windowWidth = this.$refs.main.offsetWidth; - const windowHeight = this.$refs.main.offsetHeight; - if (position.left < 0) this.$refs.main.style.left = 0; - if (position.top < 0) this.$refs.main.style.top = 0; - if (position.left + windowWidth > browserWidth) this.$refs.main.style.left = browserWidth - windowWidth + 'px'; - if (position.top + windowHeight > browserHeight) this.$refs.main.style.top = browserHeight - windowHeight + 'px'; - }; - - this.open = () => { - this.$emit('opening'); - - this.top(); - - if (this.isModal) { - this.$refs.bg.style.pointerEvents = 'auto'; - anime({ - targets: this.$refs.bg, - opacity: 1, - duration: 100, - easing: 'linear' - }); - } - - this.$refs.main.style.pointerEvents = 'auto'; - anime({ - targets: this.$refs.main, - opacity: 1, - scale: [1.1, 1], - duration: 200, - easing: 'easeOutQuad' - }); - - //this.$refs.main.focus(); - - setTimeout(() => { - this.$emit('opened'); - }, 300); - }; - - this.popout = () => { - const position = this.$refs.main.getBoundingClientRect(); - - const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); - const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); - const x = window.screenX + position.left; - const y = window.screenY + position.top; - - const url = typeof this.popoutUrl == 'function' ? this.popoutUrl() : this.popoutUrl; - - window.open(url, url, - `height=${height},width=${width},left=${x},top=${y}`); - - this.close(); - }; - - this.close = () => { - this.$emit('closing'); - - if (this.isModal) { - this.$refs.bg.style.pointerEvents = 'none'; - anime({ - targets: this.$refs.bg, - opacity: 0, - duration: 300, - easing: 'linear' - }); - } - - this.$refs.main.style.pointerEvents = 'none'; - - anime({ - targets: this.$refs.main, - opacity: 0, - scale: 0.8, - duration: 300, - easing: [0.5, -0.5, 1, 0.5] - }); - - setTimeout(() => { - this.$emit('closed'); - }, 300); - }; - - // 最前面へ移動します - this.top = () => { - let z = 0; - - const ws = document.querySelectorAll('mk-window'); - ws.forEach(w => { - if (w == this.root) return; - const m = w.querySelector(':scope > .main'); - const mz = Number(document.defaultView.getComputedStyle(m, null).zIndex); - if (mz > z) z = mz; - }); - - if (z > 0) { - this.$refs.main.style.zIndex = z + 1; - if (this.isModal) this.$refs.bg.style.zIndex = z + 1; - } - }; - - this.repelMove = e => { - e.stopPropagation(); - return true; - }; - - this.bgClick = () => { - if (this.canClose) this.close(); - }; - - this.onBodyMousedown = () => { - this.top(); - }; - - // ヘッダー掴み時 - this.onHeaderMousedown = e => { - e.preventDefault(); - - if (!contains(this.$refs.main, document.activeElement)) this.$refs.main.focus(); - - const position = this.$refs.main.getBoundingClientRect(); - - const clickX = e.clientX; - const clickY = e.clientY; - const moveBaseX = clickX - position.left; - const moveBaseY = clickY - position.top; - const browserWidth = window.innerWidth; - const browserHeight = window.innerHeight; - const windowWidth = this.$refs.main.offsetWidth; - const windowHeight = this.$refs.main.offsetHeight; - - // 動かした時 - dragListen(me => { - let moveLeft = me.clientX - moveBaseX; - let moveTop = me.clientY - moveBaseY; - - // 上はみ出し - if (moveTop < 0) moveTop = 0; - - // 左はみ出し - if (moveLeft < 0) moveLeft = 0; - - // 下はみ出し - if (moveTop + windowHeight > browserHeight) moveTop = browserHeight - windowHeight; - - // 右はみ出し - if (moveLeft + windowWidth > browserWidth) moveLeft = browserWidth - windowWidth; - - this.$refs.main.style.left = moveLeft + 'px'; - this.$refs.main.style.top = moveTop + 'px'; - }); - }; - - // 上ハンドル掴み時 - this.onTopHandleMousedown = e => { - e.preventDefault(); - - const base = e.clientY; - const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); - const top = parseInt(getComputedStyle(this.$refs.main, '').top, 10); - - // 動かした時 - dragListen(me => { - const move = me.clientY - base; - if (top + move > 0) { - if (height + -move > this.minHeight) { - this.applyTransformHeight(height + -move); - this.applyTransformTop(top + move); - } else { // 最小の高さより小さくなろうとした時 - this.applyTransformHeight(this.minHeight); - this.applyTransformTop(top + (height - this.minHeight)); - } - } else { // 上のはみ出し時 - this.applyTransformHeight(top + height); - this.applyTransformTop(0); - } - }); - }; - - // 右ハンドル掴み時 - this.onRightHandleMousedown = e => { - e.preventDefault(); - - const base = e.clientX; - const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); - const left = parseInt(getComputedStyle(this.$refs.main, '').left, 10); - const browserWidth = window.innerWidth; - - // 動かした時 - dragListen(me => { - const move = me.clientX - base; - if (left + width + move < browserWidth) { - if (width + move > this.minWidth) { - this.applyTransformWidth(width + move); - } else { // 最小の幅より小さくなろうとした時 - this.applyTransformWidth(this.minWidth); - } - } else { // 右のはみ出し時 - this.applyTransformWidth(browserWidth - left); - } - }); - }; - - // 下ハンドル掴み時 - this.onBottomHandleMousedown = e => { - e.preventDefault(); - - const base = e.clientY; - const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); - const top = parseInt(getComputedStyle(this.$refs.main, '').top, 10); - const browserHeight = window.innerHeight; - - // 動かした時 - dragListen(me => { - const move = me.clientY - base; - if (top + height + move < browserHeight) { - if (height + move > this.minHeight) { - this.applyTransformHeight(height + move); - } else { // 最小の高さより小さくなろうとした時 - this.applyTransformHeight(this.minHeight); - } - } else { // 下のはみ出し時 - this.applyTransformHeight(browserHeight - top); - } - }); - }; - - // 左ハンドル掴み時 - this.onLeftHandleMousedown = e => { - e.preventDefault(); - - const base = e.clientX; - const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); - const left = parseInt(getComputedStyle(this.$refs.main, '').left, 10); - - // 動かした時 - dragListen(me => { - const move = me.clientX - base; - if (left + move > 0) { - if (width + -move > this.minWidth) { - this.applyTransformWidth(width + -move); - this.applyTransformLeft(left + move); - } else { // 最小の幅より小さくなろうとした時 - this.applyTransformWidth(this.minWidth); - this.applyTransformLeft(left + (width - this.minWidth)); - } - } else { // 左のはみ出し時 - this.applyTransformWidth(left + width); - this.applyTransformLeft(0); - } - }); - }; - - // 左上ハンドル掴み時 - this.onTopLeftHandleMousedown = e => { - this.onTopHandleMousedown(e); - this.onLeftHandleMousedown(e); - }; - - // 右上ハンドル掴み時 - this.onTopRightHandleMousedown = e => { - this.onTopHandleMousedown(e); - this.onRightHandleMousedown(e); - }; - - // 右下ハンドル掴み時 - this.onBottomRightHandleMousedown = e => { - this.onBottomHandleMousedown(e); - this.onRightHandleMousedown(e); - }; - - // 左下ハンドル掴み時 - this.onBottomLeftHandleMousedown = e => { - this.onBottomHandleMousedown(e); - this.onLeftHandleMousedown(e); - }; - - // 高さを適用 - this.applyTransformHeight = height => { - this.$refs.main.style.height = height + 'px'; - }; - - // 幅を適用 - this.applyTransformWidth = width => { - this.$refs.main.style.width = width + 'px'; - }; - - // Y座標を適用 - this.applyTransformTop = top => { - this.$refs.main.style.top = top + 'px'; - }; - - // X座標を適用 - this.applyTransformLeft = left => { - this.$refs.main.style.left = left + 'px'; - }; - - function dragListen(fn) { - window.addEventListener('mousemove', fn); - window.addEventListener('mouseleave', dragClear.bind(null, fn)); - window.addEventListener('mouseup', dragClear.bind(null, fn)); - } - - function dragClear(fn) { - window.removeEventListener('mousemove', fn); - window.removeEventListener('mouseleave', dragClear); - window.removeEventListener('mouseup', dragClear); - } - - this.ondragover = e => { - e.dataTransfer.dropEffect = 'none'; - }; - - this.onKeydown = e => { - if (e.which == 27) { // Esc - if (this.canClose) { - e.preventDefault(); - e.stopPropagation(); - this.close(); - } - } - }; - - </script> -</mk-window> diff --git a/src/web/app/desktop/views/components/window.vue b/src/web/app/desktop/views/components/window.vue index 6961d9f08f..6c75918e02 100644 --- a/src/web/app/desktop/views/components/window.vue +++ b/src/web/app/desktop/views/components/window.vue @@ -1,5 +1,5 @@ <template> -<div :data-flexible="isFlexible" @dragover="onDragover"> +<div class="mk-window" :data-flexible="isFlexible" @dragover="onDragover"> <div class="bg" ref="bg" v-show="isModal" @click="onBgClick"></div> <div class="main" ref="main" tabindex="-1" :data-is-modal="isModal" @mousedown="onBodyMousedown" @keydown="onKeydown"> <div class="body"> @@ -23,3 +23,559 @@ </div> </div> </template> + +<script lang="ts"> +import Vue from 'vue'; +import anime from 'animejs'; +import contains from '../../common/scripts/contains'; + +const minHeight = 40; +const minWidth = 200; + +export default Vue.extend({ + props: { + isModal: { + type: Boolean, + default: false + }, + canClose: { + type: Boolean, + default: true + }, + height: { + type: Number + }, + popoutUrl: { + type: String + } + }, + computed: { + isFlexible(): boolean { + return this.height == null; + }, + canResize(): boolean { + return !this.isFlexible; + } + } +}); +</script> + + +<script lang="typescript"> + +this.on('mount', () => { + this.$refs.main.style.width = this.opts.width || '530px'; + this.$refs.main.style.height = this.opts.height || 'auto'; + + this.$refs.main.style.top = '15%'; + this.$refs.main.style.left = (window.innerWidth / 2) - (this.$refs.main.offsetWidth / 2) + 'px'; + + this.$refs.header.addEventListener('contextmenu', e => { + e.preventDefault(); + }); + + window.addEventListener('resize', this.onBrowserResize); + + this.open(); +}); + +this.on('unmount', () => { + window.removeEventListener('resize', this.onBrowserResize); +}); + +this.onBrowserResize = () => { + const position = this.$refs.main.getBoundingClientRect(); + const browserWidth = window.innerWidth; + const browserHeight = window.innerHeight; + const windowWidth = this.$refs.main.offsetWidth; + const windowHeight = this.$refs.main.offsetHeight; + if (position.left < 0) this.$refs.main.style.left = 0; + if (position.top < 0) this.$refs.main.style.top = 0; + if (position.left + windowWidth > browserWidth) this.$refs.main.style.left = browserWidth - windowWidth + 'px'; + if (position.top + windowHeight > browserHeight) this.$refs.main.style.top = browserHeight - windowHeight + 'px'; +}; + +this.open = () => { + this.$emit('opening'); + + this.top(); + + if (this.isModal) { + this.$refs.bg.style.pointerEvents = 'auto'; + anime({ + targets: this.$refs.bg, + opacity: 1, + duration: 100, + easing: 'linear' + }); + } + + this.$refs.main.style.pointerEvents = 'auto'; + anime({ + targets: this.$refs.main, + opacity: 1, + scale: [1.1, 1], + duration: 200, + easing: 'easeOutQuad' + }); + + //this.$refs.main.focus(); + + setTimeout(() => { + this.$emit('opened'); + }, 300); +}; + +this.popout = () => { + const position = this.$refs.main.getBoundingClientRect(); + + const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); + const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); + const x = window.screenX + position.left; + const y = window.screenY + position.top; + + const url = typeof this.popoutUrl == 'function' ? this.popoutUrl() : this.popoutUrl; + + window.open(url, url, + `height=${height},width=${width},left=${x},top=${y}`); + + this.close(); +}; + +this.close = () => { + this.$emit('closing'); + + if (this.isModal) { + this.$refs.bg.style.pointerEvents = 'none'; + anime({ + targets: this.$refs.bg, + opacity: 0, + duration: 300, + easing: 'linear' + }); + } + + this.$refs.main.style.pointerEvents = 'none'; + + anime({ + targets: this.$refs.main, + opacity: 0, + scale: 0.8, + duration: 300, + easing: [0.5, -0.5, 1, 0.5] + }); + + setTimeout(() => { + this.$emit('closed'); + }, 300); +}; + +// 最前面へ移動します +this.top = () => { + let z = 0; + + const ws = document.querySelectorAll('mk-window'); + ws.forEach(w => { + if (w == this.root) return; + const m = w.querySelector(':scope > .main'); + const mz = Number(document.defaultView.getComputedStyle(m, null).zIndex); + if (mz > z) z = mz; + }); + + if (z > 0) { + this.$refs.main.style.zIndex = z + 1; + if (this.isModal) this.$refs.bg.style.zIndex = z + 1; + } +}; + +this.repelMove = e => { + e.stopPropagation(); + return true; +}; + +this.bgClick = () => { + if (this.canClose) this.close(); +}; + +this.onBodyMousedown = () => { + this.top(); +}; + +// ヘッダー掴み時 +this.onHeaderMousedown = e => { + e.preventDefault(); + + if (!contains(this.$refs.main, document.activeElement)) this.$refs.main.focus(); + + const position = this.$refs.main.getBoundingClientRect(); + + const clickX = e.clientX; + const clickY = e.clientY; + const moveBaseX = clickX - position.left; + const moveBaseY = clickY - position.top; + const browserWidth = window.innerWidth; + const browserHeight = window.innerHeight; + const windowWidth = this.$refs.main.offsetWidth; + const windowHeight = this.$refs.main.offsetHeight; + + // 動かした時 + dragListen(me => { + let moveLeft = me.clientX - moveBaseX; + let moveTop = me.clientY - moveBaseY; + + // 上はみ出し + if (moveTop < 0) moveTop = 0; + + // 左はみ出し + if (moveLeft < 0) moveLeft = 0; + + // 下はみ出し + if (moveTop + windowHeight > browserHeight) moveTop = browserHeight - windowHeight; + + // 右はみ出し + if (moveLeft + windowWidth > browserWidth) moveLeft = browserWidth - windowWidth; + + this.$refs.main.style.left = moveLeft + 'px'; + this.$refs.main.style.top = moveTop + 'px'; + }); +}; + +// 上ハンドル掴み時 +this.onTopHandleMousedown = e => { + e.preventDefault(); + + const base = e.clientY; + const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); + const top = parseInt(getComputedStyle(this.$refs.main, '').top, 10); + + // 動かした時 + dragListen(me => { + const move = me.clientY - base; + if (top + move > 0) { + if (height + -move > this.minHeight) { + this.applyTransformHeight(height + -move); + this.applyTransformTop(top + move); + } else { // 最小の高さより小さくなろうとした時 + this.applyTransformHeight(this.minHeight); + this.applyTransformTop(top + (height - this.minHeight)); + } + } else { // 上のはみ出し時 + this.applyTransformHeight(top + height); + this.applyTransformTop(0); + } + }); +}; + +// 右ハンドル掴み時 +this.onRightHandleMousedown = e => { + e.preventDefault(); + + const base = e.clientX; + const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); + const left = parseInt(getComputedStyle(this.$refs.main, '').left, 10); + const browserWidth = window.innerWidth; + + // 動かした時 + dragListen(me => { + const move = me.clientX - base; + if (left + width + move < browserWidth) { + if (width + move > this.minWidth) { + this.applyTransformWidth(width + move); + } else { // 最小の幅より小さくなろうとした時 + this.applyTransformWidth(this.minWidth); + } + } else { // 右のはみ出し時 + this.applyTransformWidth(browserWidth - left); + } + }); +}; + +// 下ハンドル掴み時 +this.onBottomHandleMousedown = e => { + e.preventDefault(); + + const base = e.clientY; + const height = parseInt(getComputedStyle(this.$refs.main, '').height, 10); + const top = parseInt(getComputedStyle(this.$refs.main, '').top, 10); + const browserHeight = window.innerHeight; + + // 動かした時 + dragListen(me => { + const move = me.clientY - base; + if (top + height + move < browserHeight) { + if (height + move > this.minHeight) { + this.applyTransformHeight(height + move); + } else { // 最小の高さより小さくなろうとした時 + this.applyTransformHeight(this.minHeight); + } + } else { // 下のはみ出し時 + this.applyTransformHeight(browserHeight - top); + } + }); +}; + +// 左ハンドル掴み時 +this.onLeftHandleMousedown = e => { + e.preventDefault(); + + const base = e.clientX; + const width = parseInt(getComputedStyle(this.$refs.main, '').width, 10); + const left = parseInt(getComputedStyle(this.$refs.main, '').left, 10); + + // 動かした時 + dragListen(me => { + const move = me.clientX - base; + if (left + move > 0) { + if (width + -move > this.minWidth) { + this.applyTransformWidth(width + -move); + this.applyTransformLeft(left + move); + } else { // 最小の幅より小さくなろうとした時 + this.applyTransformWidth(this.minWidth); + this.applyTransformLeft(left + (width - this.minWidth)); + } + } else { // 左のはみ出し時 + this.applyTransformWidth(left + width); + this.applyTransformLeft(0); + } + }); +}; + +// 左上ハンドル掴み時 +this.onTopLeftHandleMousedown = e => { + this.onTopHandleMousedown(e); + this.onLeftHandleMousedown(e); +}; + +// 右上ハンドル掴み時 +this.onTopRightHandleMousedown = e => { + this.onTopHandleMousedown(e); + this.onRightHandleMousedown(e); +}; + +// 右下ハンドル掴み時 +this.onBottomRightHandleMousedown = e => { + this.onBottomHandleMousedown(e); + this.onRightHandleMousedown(e); +}; + +// 左下ハンドル掴み時 +this.onBottomLeftHandleMousedown = e => { + this.onBottomHandleMousedown(e); + this.onLeftHandleMousedown(e); +}; + +// 高さを適用 +this.applyTransformHeight = height => { + this.$refs.main.style.height = height + 'px'; +}; + +// 幅を適用 +this.applyTransformWidth = width => { + this.$refs.main.style.width = width + 'px'; +}; + +// Y座標を適用 +this.applyTransformTop = top => { + this.$refs.main.style.top = top + 'px'; +}; + +// X座標を適用 +this.applyTransformLeft = left => { + this.$refs.main.style.left = left + 'px'; +}; + +function dragListen(fn) { + window.addEventListener('mousemove', fn); + window.addEventListener('mouseleave', dragClear.bind(null, fn)); + window.addEventListener('mouseup', dragClear.bind(null, fn)); +} + +function dragClear(fn) { + window.removeEventListener('mousemove', fn); + window.removeEventListener('mouseleave', dragClear); + window.removeEventListener('mouseup', dragClear); +} + +this.ondragover = e => { + e.dataTransfer.dropEffect = 'none'; +}; + +this.onKeydown = e => { + if (e.which == 27) { // Esc + if (this.canClose) { + e.preventDefault(); + e.stopPropagation(); + this.close(); + } + } +}; + +</script> + + +<style lang="stylus" scoped> +.mk-window + display block + + > .bg + display block + position fixed + z-index 2048 + top 0 + left 0 + width 100% + height 100% + background rgba(0, 0, 0, 0.7) + opacity 0 + pointer-events none + + > .main + display block + position fixed + z-index 2048 + top 15% + left 0 + margin 0 + opacity 0 + pointer-events none + + &:focus + &:not([data-is-modal]) + > .body + box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2) + + > .handle + $size = 8px + + position absolute + + &.top + top -($size) + left 0 + width 100% + height $size + cursor ns-resize + + &.right + top 0 + right -($size) + width $size + height 100% + cursor ew-resize + + &.bottom + bottom -($size) + left 0 + width 100% + height $size + cursor ns-resize + + &.left + top 0 + left -($size) + width $size + height 100% + cursor ew-resize + + &.top-left + top -($size) + left -($size) + width $size * 2 + height $size * 2 + cursor nwse-resize + + &.top-right + top -($size) + right -($size) + width $size * 2 + height $size * 2 + cursor nesw-resize + + &.bottom-right + bottom -($size) + right -($size) + width $size * 2 + height $size * 2 + cursor nwse-resize + + &.bottom-left + bottom -($size) + left -($size) + width $size * 2 + height $size * 2 + cursor nesw-resize + + > .body + height 100% + overflow hidden + background #fff + border-radius 6px + box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2) + + > header + $header-height = 40px + + z-index 128 + height $header-height + overflow hidden + white-space nowrap + cursor move + background #fff + border-radius 6px 6px 0 0 + box-shadow 0 1px 0 rgba(#000, 0.1) + + &, * + user-select none + + > h1 + pointer-events none + display block + margin 0 auto + overflow hidden + height $header-height + text-overflow ellipsis + text-align center + font-size 1em + line-height $header-height + font-weight normal + color #666 + + > div:last-child + position absolute + top 0 + right 0 + display block + z-index 1 + + > * + display inline-block + margin 0 + padding 0 + cursor pointer + font-size 1.2em + color rgba(#000, 0.4) + border none + outline none + background transparent + + &:hover + color rgba(#000, 0.6) + + &:active + color darken(#000, 30%) + + > [data-fa] + padding 0 + width $header-height + line-height $header-height + text-align center + + > .content + height 100% + + &:not([flexible]) + > .main > .body > .content + height calc(100% - 40px) + +</style> + |