/
githubmirror
/
element
Обзор
Документация
Войти
/
githubmirror
/
element
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
examples/extension/src/editor/editor.vue
212 строк
6 KB
iamkun
Chore: Theme Extension (#16686)
09 авг 2019, 12:53
Не верифицирован
09 авг 2019, 12:53
f29f49a
Код
Авторство
О чём код?
<template> <div class="ext-panel" :class="{moving : moving}" :style="{top: `${top}px`, left: `${left}px`}" ref="editor" > <img class="entrance touch-icon" src="./icon-entrance.png" v-show="!showSidebar" @click="toggleSidebar" /> <img class="close touch-icon" src="./icon-close.png" v-show="showSidebar" @click="toggleSidebar" /> <div class="editor" :style="{height: `${height}px`}" v-show="showSidebar"> <el-tabs v-model="activeTab" @tab-click="onTabClick"> <el-tab-pane label="Config" name="config"> <theme-configurator :themeConfig="themeConfig" :previewConfig="previewConfig" :onUserConfigUpdate="onUserConfigUpdate" from="extension" ></theme-configurator> </el-tab-pane> <el-tab-pane label="Gallery" name="gallery"> <gallery ref='gallery' :height="height" :width="width - 7" @action="onGalleryAction" /> </el-tab-pane> </el-tabs> </div> </div> </template> <script> import ThemeConfigurator from '../../../components/theme-configurator'; import themeLoader from '../../../components/theme/loader'; import gallery from './gallery'; import { loadUserThemeFromLocal, saveUserThemeToLocal } from './utils'; import bus from '../../../bus.js'; import { ACTION_APPLY_THEME } from '../../../components/theme/constant.js'; let initX; let initY; let leftX = 0; let topY = 25; export default { mixins: [themeLoader], components: { ThemeConfigurator, gallery }, data() { return { showSidebar: true, previewConfig: {}, themeConfig: {}, top: topY, left: leftX, height: window.innerHeight - 30 * 2, width: 0, moving: false, activeTab: 'config', themeName: '', userTheme: [] }; }, mounted() { const editor = this.$refs.editor; this.width = editor.offsetWidth; leftX = window.innerWidth - 20 - this.width; this.left = leftX; editor.addEventListener('mousedown', e => { initX = e.clientX; initY = e.clientY; leftX = this.left; topY = this.top; document.addEventListener('mousemove', this.moveFunc); }); document.addEventListener('mouseup', e => { document.removeEventListener('mousemove', this.moveFunc); setTimeout(() => {this.moving = false;}, 0); }); // chrome.storage.local.remove('ELEMENT_THEME_USER_CONFIG'); loadUserThemeFromLocal() .then((result) => { if (result) { this.activeTab = 'gallery'; this.userTheme = result; } }); }, methods: { checkLocalThemeConfig() {}, // disable mixin auto loading toggleSidebar() { if (this.moving) return; this.showSidebar = !this.showSidebar; if (!this.showSidebar) { const windowWidth = window.innerWidth; if (this.left + this.width * 0.5 < windowWidth * 0.5) { this.left = 0; } else { this.left = windowWidth - 50; } } else { this.moveEditor(this.left, this.top); } }, moveFunc(e) { e.preventDefault(); const deltaX = initX - e.clientX; const deltaY = initY - e.clientY; if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) { this.moving = true; } this.moveEditor(leftX - deltaX, topY - deltaY); }, moveEditor(x, y) { const showSidebar = this.showSidebar; let nextTop = y; if (nextTop < 0) nextTop = 0; const maxTop = window.innerHeight - (showSidebar ? (this.height + 5) : 50); if (nextTop > maxTop) nextTop = maxTop; this.top = nextTop; let nextLeft = x; if (nextLeft < 0) nextLeft = 0; const maxLeft = window.innerWidth - (showSidebar ? (this.width + 5) : 50); if (nextLeft > maxLeft) nextLeft = maxLeft; this.left = nextLeft; }, onGalleryAction(key, value) { switch (key) { case 'edit': this.themeName = value.name; this.themeConfig = JSON.parse(value.theme); bus.$emit(ACTION_APPLY_THEME, this.themeConfig); this.activeTab = 'config'; break; default: return; } }, onTabClick(e) { if (e && e.name === 'gallery') { this.$refs.gallery.init(); } }, onUserConfigUpdate(userConfig) { if (this.themeName) { this.userTheme.forEach((config) => { if (config.name === this.themeName) { config.update = Date.now(); config.theme = JSON.stringify(userConfig); } }); } else { this.themeName = `Theme-${Date.now()}`; this.userTheme.push({ update: Date.now(), name: this.themeName, theme: JSON.stringify(userConfig) }); } saveUserThemeToLocal(this.userTheme); } } }; </script> <style scoped> .ext-panel { position: fixed; background: transparent; user-select: none; z-index: 100000; } .ext-panel.moving{ cursor: move; } .ext-panel.moving .touch-icon{ cursor: move; } .ext-panel .touch-icon{ cursor: pointer; } .ext-panel .close { position: absolute; right: 0; top: 0; height: 20px; width: 20px; z-index: 100001; } .ext-panel .entrance { height: 50px; width: 50px; } .ext-panel .editor { overflow: hidden; background: #f5f7fa; border: 1px solid #ebeef5; border-radius: 5px; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); margin: 5px 5px 0 0; min-width: 261px; } </style> <style> .ext-panel .editor .el-tabs__content, .ext-panel .editor .el-tabs--top, .ext-panel .editor .el-tab-pane { height: 100%; } .ext-panel .el-tabs__nav-scroll >div { transform: translateX(60px)!important; } .ext-panel .editor-main { padding: 0 18px 70px; } </style>