Commit 769ab5aa authored by baiyaaaaa's avatar baiyaaaaa Committed by GitHub

Merge pull request #1982 from QingWei-Li/feat/ssr

SSR feature
parents 427d6498 2b096a56
...@@ -42,7 +42,7 @@ if [ "$TRAVIS_TAG" ]; then ...@@ -42,7 +42,7 @@ if [ "$TRAVIS_TAG" ]; then
export SUB_FOLDER=$(echo "$TRAVIS_TAG" | grep -o -E "\d+\.\d+") export SUB_FOLDER=$(echo "$TRAVIS_TAG" | grep -o -E "\d+\.\d+")
echo $SUB_FOLDER echo $SUB_FOLDER
SUB_FOLDER='1.0' SUB_FOLDER='1.1'
mkdir $SUB_FOLDER mkdir $SUB_FOLDER
rm -rf *.js *.css *.map static rm -rf *.js *.css *.map static
rm -rf $SUB_FOLDER/** rm -rf $SUB_FOLDER/**
......
<script> <script>
import { addClass } from 'wind-dom/src/class'; import { addClass } from 'element-ui/src/utils/dom';
export default { export default {
data() { data() {
return { return {
...@@ -78,7 +78,7 @@ Different colors represent different meanings. ...@@ -78,7 +78,7 @@ Different colors represent different meanings.
``` ```
::: :::
### Icon Button ### Icon Button
Use icons to add more meaning to Button. You can use icon alone to save some space, or with text together. Use icons to add more meaning to Button. You can use icon alone to save some space, or with text together.
......
## Pagination ## Pagination
If you have too much data to display in one page, use pagination. If you have too much data to display in one page, use pagination.
...@@ -117,7 +117,7 @@ Add more modules based on your scenario. ...@@ -117,7 +117,7 @@ Add more modules based on your scenario.
``` ```
::: :::
<script> <script>
import { addClass } from 'wind-dom/src/class'; import { addClass } from 'element-ui/src/utils/dom';
export default { export default {
data() { data() {
return { return {
......
<script> <script>
import { addClass } from 'wind-dom/src/class'; import { addClass } from 'element-ui/src/utils/dom';
export default { export default {
data() { data() {
return { return {
......
...@@ -117,7 +117,7 @@ ...@@ -117,7 +117,7 @@
``` ```
::: :::
<script> <script>
import { addClass } from 'wind-dom/src/class'; import { addClass } from 'element-ui/src/utils/dom';
export default { export default {
methods: { methods: {
handleSizeChange(val) { handleSizeChange(val) {
......
...@@ -47,9 +47,7 @@ ...@@ -47,9 +47,7 @@
"async-validator": "^1.6.6", "async-validator": "^1.6.6",
"babel-helper-vue-jsx-merge-props": "^2.0.0", "babel-helper-vue-jsx-merge-props": "^2.0.0",
"deepmerge": "^1.2.0", "deepmerge": "^1.2.0",
"throttle-debounce": "^1.0.1", "throttle-debounce": "^1.0.1"
"vue-popup": "^0.2.14",
"wind-dom": "0.0.3"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "^2.1.6" "vue": "^2.1.6"
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "long.zhang@ele.me", "author": "long.zhang@ele.me",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<script> <script>
import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, DAY_DURATION } from '../util'; import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, DAY_DURATION } from '../util';
import { hasClass } from 'wind-dom/src/class'; import { hasClass } from 'element-ui/src/utils/dom';
import Locale from 'element-ui/src/mixins/locale'; import Locale from 'element-ui/src/mixins/locale';
const clearHours = function(time) { const clearHours = function(time) {
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<script type="text/babel"> <script type="text/babel">
import Locale from 'element-ui/src/mixins/locale'; import Locale from 'element-ui/src/mixins/locale';
import { hasClass } from 'wind-dom/src/class'; import { hasClass } from 'element-ui/src/utils/dom';
export default { export default {
props: { props: {
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
</template> </template>
<script type="text/babel"> <script type="text/babel">
import { hasClass } from 'wind-dom/src/class'; import { hasClass } from 'element-ui/src/utils/dom';
export default { export default {
props: { props: {
......
...@@ -375,6 +375,7 @@ export default { ...@@ -375,6 +375,7 @@ export default {
}, },
showPicker() { showPicker() {
if (this.$isServer) return;
if (!this.picker) { if (!this.picker) {
this.panel.defaultValue = this.internalValue; this.panel.defaultValue = this.internalValue;
this.picker = new Vue(this.panel).$mount(document.createElement('div')); this.picker = new Vue(this.panel).$mount(document.createElement('div'));
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
</template> </template>
<script> <script>
import Popup from 'vue-popup'; import Popup from 'element-ui/src/utils/popup';
export default { export default {
name: 'el-dialog', name: 'el-dialog',
......
...@@ -13,6 +13,5 @@ ...@@ -13,6 +13,5 @@
"license": "MIT", "license": "MIT",
"repository": "https://github.com/ElemeFE/element/tree/master/packages/input-number", "repository": "https://github.com/ElemeFE/element/tree/master/packages/input-number",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
</template> </template>
<template slot="append" v-if="$slots.append"> <template slot="append" v-if="$slots.append">
<slot name="append"></slot> <slot name="append"></slot>
</template> </template>
</el-input> </el-input>
<span <span
v-if="controls" v-if="controls"
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
</template> </template>
<script> <script>
import ElInput from 'element-ui/packages/input'; import ElInput from 'element-ui/packages/input';
import { once, on } from 'wind-dom/src/event'; import { once, on } from 'element-ui/src/utils/dom';
export default { export default {
name: 'ElInputNumber', name: 'ElInputNumber',
...@@ -79,11 +79,8 @@ ...@@ -79,11 +79,8 @@
let interval = null; let interval = null;
let startTime; let startTime;
const handler = () => { const handler = () => vnode.context[binding.expression]();
vnode.context[binding.expression](); const clear = () => {
};
const clear = function() {
if (new Date() - startTime < 100) { if (new Date() - startTime < 100) {
handler(); handler();
} }
...@@ -91,12 +88,10 @@ ...@@ -91,12 +88,10 @@
interval = null; interval = null;
}; };
on(el, 'mousedown', function() { on(el, 'mousedown', () => {
startTime = new Date(); startTime = new Date();
once(document, 'mouseup', clear); once(document, 'mouseup', clear);
interval = setInterval(function() { interval = setInterval(handler, 100);
handler();
}, 100);
}); });
} }
} }
......
...@@ -117,10 +117,9 @@ ...@@ -117,10 +117,9 @@
this.$refs.input.select(); this.$refs.input.select();
}, },
resizeTextarea() { resizeTextarea() {
if (this.$isServer) return;
var { autosize, type } = this; var { autosize, type } = this;
if (!autosize || type !== 'textarea') { if (!autosize || type !== 'textarea') return;
return;
}
const minRows = autosize.minRows; const minRows = autosize.minRows;
const maxRows = autosize.maxRows; const maxRows = autosize.maxRows;
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
import Vue from 'vue'; import Vue from 'vue';
import { addClass, removeClass } from 'wind-dom/src/class'; import { addClass, removeClass } from 'element-ui/src/utils/dom';
let Mask = Vue.extend(require('./loading.vue')); let Mask = Vue.extend(require('./loading.vue'));
exports.install = Vue => { exports.install = Vue => {
if (Vue.prototype.$isServer) return;
let toggleLoading = (el, binding) => { let toggleLoading = (el, binding) => {
if (binding.value) { if (binding.value) {
Vue.nextTick(() => { Vue.nextTick(() => {
......
...@@ -61,6 +61,7 @@ const addStyle = (options, parent, instance) => { ...@@ -61,6 +61,7 @@ const addStyle = (options, parent, instance) => {
}; };
const Loading = (options = {}) => { const Loading = (options = {}) => {
if (Vue.prototype.$isServer) return;
options = merge({}, defaults, options); options = merge({}, defaults, options);
if (typeof options.target === 'string') { if (typeof options.target === 'string') {
options.target = document.querySelector(options.target); options.target = document.querySelector(options.target);
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -102,6 +102,7 @@ const showNextMsg = () => { ...@@ -102,6 +102,7 @@ const showNextMsg = () => {
}; };
const MessageBox = function(options, callback) { const MessageBox = function(options, callback) {
if (Vue.prototype.$isServer) return;
if (typeof options === 'string') { if (typeof options === 'string') {
options = { options = {
message: options message: options
......
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
</template> </template>
<script type="text/babel"> <script type="text/babel">
import Popup from 'vue-popup'; import Popup from 'element-ui/src/utils/popup';
import Locale from 'element-ui/src/mixins/locale'; import Locale from 'element-ui/src/mixins/locale';
import ElInput from 'element-ui/packages/input'; import ElInput from 'element-ui/packages/input';
import ElButton from 'element-ui/packages/button'; import ElButton from 'element-ui/packages/button';
import { addClass, removeClass } from 'wind-dom/src/class'; import { addClass, removeClass } from 'element-ui/src/utils/dom';
import { t } from 'element-ui/src/locale'; import { t } from 'element-ui/src/locale';
let typeMap = { let typeMap = {
......
import Vue from 'vue'; import Vue from 'vue';
import { PopupManager } from 'vue-popup'; import { PopupManager } from 'element-ui/src/utils/popup';
let MessageConstructor = Vue.extend(require('./main.vue')); let MessageConstructor = Vue.extend(require('./main.vue'));
let instance; let instance;
...@@ -7,6 +7,7 @@ let instances = []; ...@@ -7,6 +7,7 @@ let instances = [];
let seed = 1; let seed = 1;
var Message = function(options) { var Message = function(options) {
if (Vue.prototype.$isServer) return;
options = options || {}; options = options || {};
if (typeof options === 'string') { if (typeof options === 'string') {
options = { options = {
......
import Vue from 'vue'; import Vue from 'vue';
import { PopupManager } from 'vue-popup'; import { PopupManager } from 'element-ui/src/utils/popup';
let NotificationConstructor = Vue.extend(require('./main.vue')); let NotificationConstructor = Vue.extend(require('./main.vue'));
let instance; let instance;
...@@ -7,6 +7,7 @@ let instances = []; ...@@ -7,6 +7,7 @@ let instances = [];
let seed = 1; let seed = 1;
var Notification = function(options) { var Notification = function(options) {
if (Vue.prototype.$isServer) return;
options = options || {}; options = options || {};
let userOnClose = options.onClose; let userOnClose = options.onClose;
let id = 'notification_' + seed++; let id = 'notification_' + seed++;
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<script> <script>
import Popper from 'element-ui/src/utils/vue-popper'; import Popper from 'element-ui/src/utils/vue-popper';
import { on, off } from 'wind-dom/src/event'; import { on, off } from 'element-ui/src/utils/dom';
export default { export default {
name: 'el-popover', name: 'el-popover',
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
</template> </template>
<script type="text/babel"> <script type="text/babel">
import { hasClass } from 'wind-dom/src/class'; import { hasClass } from 'element-ui/src/utils/dom';
export default { export default {
name: 'el-rate', name: 'el-rate',
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
"license": "MIT", "license": "MIT",
"repository": "https://github.com/ElemeFE/element/tree/master/packages/select", "repository": "https://github.com/ElemeFE/element/tree/master/packages/select",
"devDependencies": { "devDependencies": {
"throttle-debounce": "^1.0.1", "throttle-debounce": "^1.0.1"
"wind-dom": "0.0.3"
} }
} }
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
import ElScrollbar from 'element-ui/packages/scrollbar'; import ElScrollbar from 'element-ui/packages/scrollbar';
import debounce from 'throttle-debounce/debounce'; import debounce from 'throttle-debounce/debounce';
import Clickoutside from 'element-ui/src/utils/clickoutside'; import Clickoutside from 'element-ui/src/utils/clickoutside';
import { addClass, removeClass, hasClass } from 'wind-dom/src/class'; import { addClass, removeClass, hasClass } from 'element-ui/src/utils/dom';
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'; import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
import { t } from 'element-ui/src/locale'; import { t } from 'element-ui/src/locale';
const sizeMap = { const sizeMap = {
...@@ -303,6 +303,7 @@ ...@@ -303,6 +303,7 @@
}, },
options(val) { options(val) {
if (this.$isServer) return;
this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length; this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length;
if (this.multiple) { if (this.multiple) {
this.resetInputHeight(); this.resetInputHeight();
......
...@@ -12,6 +12,5 @@ ...@@ -12,6 +12,5 @@
"author": "elemefe", "author": "elemefe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"wind-dom": "0.0.3"
} }
} }
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<script type="text/babel"> <script type="text/babel">
import ElInputNumber from 'element-ui/packages/input-number'; import ElInputNumber from 'element-ui/packages/input-number';
import ElTooltip from 'element-ui/packages/tooltip'; import ElTooltip from 'element-ui/packages/tooltip';
import { getStyle } from 'wind-dom/src/style'; import { getStyle } from 'element-ui/src/utils/dom';
export default { export default {
name: 'ElSlider', name: 'ElSlider',
......
import Vue from 'vue';
var dropdowns = []; var dropdowns = [];
document.addEventListener('click', function(event) { !Vue.prototype.$isServer && document.addEventListener('click', function(event) {
dropdowns.forEach(function(dropdown) { dropdowns.forEach(function(dropdown) {
var target = event.target; var target = event.target;
if (!dropdown || !dropdown.$el) return; if (!dropdown || !dropdown.$el) return;
......
...@@ -226,7 +226,7 @@ export default { ...@@ -226,7 +226,7 @@ export default {
filterPanel.table = table; filterPanel.table = table;
filterPanel.cell = cell; filterPanel.cell = cell;
filterPanel.column = column; filterPanel.column = column;
filterPanel.$mount(document.createElement('div')); !this.$isServer && filterPanel.$mount(document.createElement('div'));
} }
setTimeout(() => { setTimeout(() => {
...@@ -239,6 +239,7 @@ export default { ...@@ -239,6 +239,7 @@ export default {
}, },
handleMouseDown(event, column) { handleMouseDown(event, column) {
if (this.$isServer) return;
if (column.children && column.children.length > 0) return; if (column.children && column.children.length > 0) return;
/* istanbul ignore if */ /* istanbul ignore if */
if (this.draggingColumn && this.border) { if (this.draggingColumn && this.border) {
...@@ -329,6 +330,7 @@ export default { ...@@ -329,6 +330,7 @@ export default {
}, },
handleMouseOut() { handleMouseOut() {
if (this.$isServer) return;
document.body.style.cursor = ''; document.body.style.cursor = '';
}, },
......
...@@ -74,7 +74,7 @@ export const getColumnByCell = function(table, cell) { ...@@ -74,7 +74,7 @@ export const getColumnByCell = function(table, cell) {
return null; return null;
}; };
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
export const mousewheel = function(element, callback) { export const mousewheel = function(element, callback) {
if (element && element.addEventListener) { if (element && element.addEventListener) {
......
...@@ -31,7 +31,5 @@ ...@@ -31,7 +31,5 @@
"gulp-postcss": "^6.1.1", "gulp-postcss": "^6.1.1",
"postcss-salad": "^1.0.5" "postcss-salad": "^1.0.5"
}, },
"dependencies": { "dependencies": {}
"vue-popup": "^0.2.9"
}
} }
.v-modal-enter {
animation: v-modal-in .2s ease;
}
.v-modal-leave {
animation: v-modal-out .2s ease forwards;
}
@keyframes v-modal-in {
0% {
opacity: 0;
}
100% {
}
}
@keyframes v-modal-out {
0% {
}
100% {
opacity: 0;
}
}
.v-modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
background: #000;
}
@charset "UTF-8"; @charset "UTF-8";
@import "./common/var.css"; @import "./common/var.css";
@import "vue-popup/lib/popup.css"; @import "./common/popup.css";
@component-namespace el { @component-namespace el {
......
@charset "UTF-8"; @charset "UTF-8";
@import "./common/var.css"; @import "./common/var.css";
@import "./common/popup.css";
@import "./button.css"; @import "./button.css";
@import "./input.css"; @import "./input.css";
@import "vue-popup/lib/popup.css";
@component-namespace el { @component-namespace el {
......
...@@ -113,7 +113,7 @@ export default { ...@@ -113,7 +113,7 @@ export default {
}, },
mounted() { mounted() {
window.addEventListener('message', (event) => { !this.$isServer && window.addEventListener('message', (event) => {
var targetOrigin = new URL(this.action).origin; var targetOrigin = new URL(this.action).origin;
if (event.origin !== targetOrigin) { if (event.origin !== targetOrigin) {
return false; return false;
...@@ -158,7 +158,7 @@ export default { ...@@ -158,7 +158,7 @@ export default {
on-change={this.handleChange} on-change={this.handleChange}
accept={this.accept}> accept={this.accept}>
</input> </input>
<input type="hidden" name="documentDomain" value={document.domain} /> <input type="hidden" name="documentDomain" value={ this.$isServer ? '' : document.domain } />
<span ref="data"></span> <span ref="data"></span>
</form> </form>
{!this.showCover ? this.$slots.default : cover} {!this.showCover ? this.$slots.default : cover}
......
...@@ -209,7 +209,7 @@ export default { ...@@ -209,7 +209,7 @@ export default {
ref: 'upload-inner' ref: 'upload-inner'
}; };
var uploadComponent = typeof FormData !== 'undefined' var uploadComponent = this.$isServer ? '' : typeof FormData !== 'undefined'
? <upload {...props}>{this.$slots.default}</upload> ? <upload {...props}>{this.$slots.default}</upload>
: <iframeUpload {...props}>{this.$slots.default}</iframeUpload>; : <iframeUpload {...props}>{this.$slots.default}</iframeUpload>;
......
import { on } from 'wind-dom/src/event'; import Vue from 'vue';
import { on } from 'element-ui/src/utils/dom';
const nodeList = []; const nodeList = [];
const ctx = '@@clickoutsideContext'; const ctx = '@@clickoutsideContext';
on(document, 'click', e => { !Vue.prototype.$isServer && on(document, 'click', e => {
nodeList.forEach(node => node[ctx].documentHandler(e)); nodeList.forEach(node => node[ctx].documentHandler(e));
}); });
/** /**
......
/* istanbul ignore next */
import Vue from 'vue';
const isServer = Vue.prototype.$isServer;
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
const ieVersion = isServer ? 0 : Number(document.documentMode);
/* istanbul ignore next */
const trim = function(string) {
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
};
/* istanbul ignore next */
const camelCase = function(name) {
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).replace(MOZ_HACK_REGEXP, 'Moz$1');
};
/* istanbul ignore next */
export const on = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const off = (function() {
if (!isServer && document.removeEventListener) {
return function(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const once = function(el, event, fn) {
var listener = function() {
if (fn) {
fn.apply(this, arguments);
}
off(el, event, listener);
};
on(el, event, listener);
};
/* istanbul ignore next */
export function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
};
/* istanbul ignore next */
export function addClass(el, cls) {
if (!el) return;
var curClass = el.className;
var classes = (cls || '').split(' ');
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else {
if (!hasClass(el, clsName)) {
curClass += ' ' + clsName;
}
}
}
if (!el.classList) {
el.className = curClass;
}
};
/* istanbul ignore next */
export function removeClass(el, cls) {
if (!el || !cls) return;
var classes = cls.split(' ');
var curClass = ' ' + el.className + ' ';
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else {
if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ');
}
}
}
if (!el.classList) {
el.className = trim(curClass);
}
};
/* istanbul ignore next */
export const getStyle = ieVersion < 9 ? function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'styleFloat';
}
try {
switch (styleName) {
case 'opacity':
try {
return element.filters.item('alpha').opacity / 100;
} catch (e) {
return 1.0;
}
default:
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
}
} catch (e) {
return element.style[styleName];
}
} : function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
return element.style[styleName];
}
};
/* istanbul ignore next */
export function setStyle(element, styleName, value) {
if (!element || !styleName) return;
if (typeof styleName === 'object') {
for (var prop in styleName) {
if (styleName.hasOwnProperty(prop)) {
setStyle(element, prop, styleName[prop]);
}
}
} else {
styleName = camelCase(styleName);
if (styleName === 'opacity' && ieVersion < 9) {
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')';
} else {
element.style[styleName] = value;
}
}
};
import Vue from 'vue';
import merge from 'element-ui/src/utils/merge';
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
let idSeed = 1;
const transitions = [];
const hookTransition = (transition) => {
if (transitions.indexOf(transition) !== -1) return;
const getVueInstance = (element) => {
let instance = element.__vue__;
if (!instance) {
const textNode = element.previousSibling;
if (textNode.__vue__) {
instance = textNode.__vue__;
}
}
return instance;
};
Vue.transition(transition, {
afterEnter(el) {
const instance = getVueInstance(el);
if (instance) {
instance.doAfterOpen && instance.doAfterOpen();
}
},
afterLeave(el) {
const instance = getVueInstance(el);
if (instance) {
instance.doAfterClose && instance.doAfterClose();
}
}
});
};
let scrollBarWidth;
const getScrollBarWidth = () => {
if (Vue.prototype.$isServer) return;
if (scrollBarWidth !== undefined) return scrollBarWidth;
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
};
const getDOM = function(dom) {
if (dom.nodeType === 3) {
dom = dom.nextElementSibling || dom.nextSibling;
getDOM(dom);
}
return dom;
};
export default {
props: {
value: {
type: Boolean,
default: false
},
transition: {
type: String,
default: ''
},
openDelay: {},
closeDelay: {},
zIndex: {},
modal: {
type: Boolean,
default: false
},
modalFade: {
type: Boolean,
default: true
},
modalClass: {
},
lockScroll: {
type: Boolean,
default: true
},
closeOnPressEscape: {
type: Boolean,
default: false
},
closeOnClickModal: {
type: Boolean,
default: false
}
},
created() {
if (this.transition) {
hookTransition(this.transition);
}
},
beforeMount() {
this._popupId = 'popup-' + idSeed++;
PopupManager.register(this._popupId, this);
},
beforeDestroy() {
PopupManager.deregister(this._popupId);
PopupManager.closeModal(this._popupId);
if (this.modal && this.bodyOverflow !== null && this.bodyOverflow !== 'hidden') {
document.body.style.overflow = this.bodyOverflow;
document.body.style.paddingRight = this.bodyPaddingRight;
}
this.bodyOverflow = null;
this.bodyPaddingRight = null;
},
data() {
return {
opened: false,
bodyOverflow: null,
bodyPaddingRight: null,
rendered: false
};
},
watch: {
value(val) {
if (val) {
if (this._opening) return;
if (!this.rendered) {
this.rendered = true;
Vue.nextTick(() => {
this.open();
});
} else {
this.open();
}
} else {
this.close();
}
}
},
methods: {
open(options) {
if (!this.rendered) {
this.rendered = true;
this.$emit('input', true);
}
const props = merge({}, this, options);
if (this._closeTimer) {
clearTimeout(this._closeTimer);
this._closeTimer = null;
}
clearTimeout(this._openTimer);
const openDelay = Number(props.openDelay);
if (openDelay > 0) {
this._openTimer = setTimeout(() => {
this._openTimer = null;
this.doOpen(props);
}, openDelay);
} else {
this.doOpen(props);
}
},
doOpen(props) {
if (this.$isServer) return;
if (this.willOpen && !this.willOpen()) return;
if (this.opened) return;
this._opening = true;
// 使用 vue-popup 的组件,如果需要和父组件通信显示的状态,应该使用 value,它是一个 prop,
// 这样在父组件中用 v-model 即可;否则可以使用 visible,它是一个 data
this.visible = true;
this.$emit('input', true);
const dom = getDOM(this.$el);
const modal = props.modal;
const zIndex = props.zIndex;
if (zIndex) {
PopupManager.zIndex = zIndex;
}
if (modal) {
if (this._closing) {
PopupManager.closeModal(this._popupId);
this._closing = false;
}
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), dom, props.modalClass, props.modalFade);
if (props.lockScroll) {
if (!this.bodyOverflow) {
this.bodyPaddingRight = document.body.style.paddingRight;
this.bodyOverflow = document.body.style.overflow;
}
scrollBarWidth = getScrollBarWidth();
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
if (scrollBarWidth > 0 && bodyHasOverflow) {
document.body.style.paddingRight = scrollBarWidth + 'px';
}
document.body.style.overflow = 'hidden';
}
}
if (getComputedStyle(dom).position === 'static') {
dom.style.position = 'absolute';
}
dom.style.zIndex = PopupManager.nextZIndex();
this.opened = true;
this.onOpen && this.onOpen();
if (!this.transition) {
this.doAfterOpen();
}
},
doAfterOpen() {
this._opening = false;
},
close() {
if (this.willClose && !this.willClose()) return;
if (this._openTimer !== null) {
clearTimeout(this._openTimer);
this._openTimer = null;
}
clearTimeout(this._closeTimer);
const closeDelay = Number(this.closeDelay);
if (closeDelay > 0) {
this._closeTimer = setTimeout(() => {
this._closeTimer = null;
this.doClose();
}, closeDelay);
} else {
this.doClose();
}
},
doClose() {
this.visible = false;
this.$emit('input', false);
this._closing = true;
this.onClose && this.onClose();
if (this.lockScroll) {
setTimeout(() => {
if (this.modal && this.bodyOverflow !== 'hidden') {
document.body.style.overflow = this.bodyOverflow;
document.body.style.paddingRight = this.bodyPaddingRight;
}
this.bodyOverflow = null;
this.bodyPaddingRight = null;
}, 200);
}
this.opened = false;
if (!this.transition) {
this.doAfterClose();
}
},
doAfterClose() {
PopupManager.closeModal(this._popupId);
this._closing = false;
}
}
};
export { PopupManager };
import Vue from 'vue';
import { addClass, removeClass } from 'element-ui/src/utils/dom';
let hasModal = false;
const getModal = function() {
if (Vue.prototype.$isServer) return;
let modalDom = PopupManager.modalDom;
if (modalDom) {
hasModal = true;
} else {
hasModal = false;
modalDom = document.createElement('div');
PopupManager.modalDom = modalDom;
modalDom.addEventListener('touchmove', function(event) {
event.preventDefault();
event.stopPropagation();
});
modalDom.addEventListener('click', function() {
PopupManager.doOnModalClick && PopupManager.doOnModalClick();
});
}
return modalDom;
};
const instances = {};
const PopupManager = {
zIndex: 2000,
modalFade: true,
getInstance: function(id) {
return instances[id];
},
register: function(id, instance) {
if (id && instance) {
instances[id] = instance;
}
},
deregister: function(id) {
if (id) {
instances[id] = null;
delete instances[id];
}
},
nextZIndex: function() {
return PopupManager.zIndex++;
},
modalStack: [],
doOnModalClick: function() {
const topItem = PopupManager.modalStack[PopupManager.modalStack.length - 1];
if (!topItem) return;
const instance = PopupManager.getInstance(topItem.id);
if (instance && instance.closeOnClickModal) {
instance.close();
}
},
openModal: function(id, zIndex, dom, modalClass, modalFade) {
if (Vue.prototype.$isServer) return;
if (!id || zIndex === undefined) return;
this.modalFade = modalFade;
const modalStack = this.modalStack;
for (let i = 0, j = modalStack.length; i < j; i++) {
const item = modalStack[i];
if (item.id === id) {
return;
}
}
const modalDom = getModal();
addClass(modalDom, 'v-modal');
if (this.modalFade && !hasModal) {
addClass(modalDom, 'v-modal-enter');
}
if (modalClass) {
let classArr = modalClass.trim().split(/\s+/);
classArr.forEach(item => addClass(modalDom, item));
}
setTimeout(() => {
removeClass(modalDom, 'v-modal-enter');
}, 200);
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {
dom.parentNode.appendChild(modalDom);
} else {
document.body.appendChild(modalDom);
}
if (zIndex) {
modalDom.style.zIndex = zIndex;
}
modalDom.style.display = '';
this.modalStack.push({ id: id, zIndex: zIndex, modalClass: modalClass });
},
closeModal: function(id) {
const modalStack = this.modalStack;
const modalDom = getModal();
if (modalStack.length > 0) {
const topItem = modalStack[modalStack.length - 1];
if (topItem.id === id) {
if (topItem.modalClass) {
let classArr = topItem.modalClass.trim().split(/\s+/);
classArr.forEach(item => removeClass(modalDom, item));
}
modalStack.pop();
if (modalStack.length > 0) {
modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex;
}
} else {
for (let i = modalStack.length - 1; i >= 0; i--) {
if (modalStack[i].id === id) {
modalStack.splice(i, 1);
break;
}
}
}
}
if (modalStack.length === 0) {
if (this.modalFade) {
addClass(modalDom, 'v-modal-leave');
}
setTimeout(() => {
if (modalStack.length === 0) {
if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom);
modalDom.style.display = 'none';
PopupManager.modalDom = undefined;
}
removeClass(modalDom, 'v-modal-leave');
}, 200);
}
}
};
!Vue.prototype.$isServer && window.addEventListener('keydown', function(event) {
if (event.keyCode === 27) { // ESC
if (PopupManager.modalStack.length > 0) {
const topItem = PopupManager.modalStack[PopupManager.modalStack.length - 1];
if (!topItem) return;
const instance = PopupManager.getInstance(topItem.id);
if (instance.closeOnPressEscape) {
instance.close();
}
}
}
});
export default PopupManager;
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
* *
* version: 0.5.3 * version: 0.5.3
**/ **/
const isServer = typeof window === 'undefined';
/* istanbul ignore next */ /* istanbul ignore next */
const requestFrame = (function() { const requestFrame = (function() {
if (isServer) return;
const raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || const raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
function(fn) { function(fn) {
return window.setTimeout(fn, 20); return window.setTimeout(fn, 20);
...@@ -17,6 +19,7 @@ const requestFrame = (function() { ...@@ -17,6 +19,7 @@ const requestFrame = (function() {
/* istanbul ignore next */ /* istanbul ignore next */
const cancelFrame = (function() { const cancelFrame = (function() {
if (isServer) return;
const cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; const cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout;
return function(id) { return function(id) {
return cancel(id); return cancel(id);
...@@ -59,7 +62,7 @@ const scrollListener = function(event) { ...@@ -59,7 +62,7 @@ const scrollListener = function(event) {
}; };
/* Detect CSS Animations support to detect element display/re-attach */ /* Detect CSS Animations support to detect element display/re-attach */
const attachEvent = document.attachEvent; const attachEvent = isServer ? {} : document.attachEvent;
const DOM_PREFIXES = 'Webkit Moz O ms'.split(' '); const DOM_PREFIXES = 'Webkit Moz O ms'.split(' ');
const START_EVENTS = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '); const START_EVENTS = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' ');
const RESIZE_ANIMATION_NAME = 'resizeanim'; const RESIZE_ANIMATION_NAME = 'resizeanim';
...@@ -68,7 +71,7 @@ let keyFramePrefix = ''; ...@@ -68,7 +71,7 @@ let keyFramePrefix = '';
let animationStartEvent = 'animationstart'; let animationStartEvent = 'animationstart';
/* istanbul ignore next */ /* istanbul ignore next */
if (!attachEvent) { if (!attachEvent && !isServer) {
const testElement = document.createElement('fakeelement'); const testElement = document.createElement('fakeelement');
if (testElement.style.animationName !== undefined) { if (testElement.style.animationName !== undefined) {
animation = true; animation = true;
...@@ -91,7 +94,7 @@ if (!attachEvent) { ...@@ -91,7 +94,7 @@ if (!attachEvent) {
let stylesCreated = false; let stylesCreated = false;
/* istanbul ignore next */ /* istanbul ignore next */
const createStyles = function() { const createStyles = function() {
if (!stylesCreated) { if (!stylesCreated && !isServer) {
const animationKeyframes = `@${keyFramePrefix}keyframes ${RESIZE_ANIMATION_NAME} { from { opacity: 0; } to { opacity: 0; } } `; const animationKeyframes = `@${keyFramePrefix}keyframes ${RESIZE_ANIMATION_NAME} { from { opacity: 0; } to { opacity: 0; } } `;
const animationStyle = `${keyFramePrefix}animation: 1ms ${RESIZE_ANIMATION_NAME};`; const animationStyle = `${keyFramePrefix}animation: 1ms ${RESIZE_ANIMATION_NAME};`;
...@@ -119,6 +122,7 @@ const createStyles = function() { ...@@ -119,6 +122,7 @@ const createStyles = function() {
/* istanbul ignore next */ /* istanbul ignore next */
export const addResizeListener = function(element, fn) { export const addResizeListener = function(element, fn) {
if (isServer) return;
if (attachEvent) { if (attachEvent) {
element.attachEvent('onresize', fn); element.attachEvent('onresize', fn);
} else { } else {
......
import PopperJS from './popper'; import Vue from 'vue';
import { PopupManager } from 'vue-popup'; import { PopupManager } from 'element-ui/src/utils/popup';
const PopperJS = Vue.prototype.$isServer ? function() {} : require('./popper');
const stop = e => e.stopPropagation(); const stop = e => e.stopPropagation();
/** /**
...@@ -66,6 +67,7 @@ export default { ...@@ -66,6 +67,7 @@ export default {
methods: { methods: {
createPopper() { createPopper() {
if (this.$isServer) return;
if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) { if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
return; return;
} }
......
import VuePopup from 'vue-popup'; import VuePopup from 'element-ui/src/utils/popup';
import { createTest, destroyVM } from '../util'; import { createTest, destroyVM } from '../util';
const Popup = Object.assign({}, VuePopup, { const Popup = Object.assign({}, VuePopup, {
......
...@@ -6863,12 +6863,6 @@ vue-markdown-loader@^0.5.1: ...@@ -6863,12 +6863,6 @@ vue-markdown-loader@^0.5.1:
markdown-it "^6.0.5" markdown-it "^6.0.5"
rimraf "^2.5.2" rimraf "^2.5.2"
vue-popup@^0.2.14:
version "0.2.14"
resolved "https://registry.yarnpkg.com/vue-popup/-/vue-popup-0.2.14.tgz#aa3d461c6f2ab01ef4546665d730395ec6028302"
dependencies:
wind-dom "0.0.3"
vue-router@^2.0.0: vue-router@^2.0.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.1.1.tgz#10c31bbdcb6da92bd3e0223fa12345e73018625a" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.1.1.tgz#10c31bbdcb6da92bd3e0223fa12345e73018625a"
...@@ -7020,10 +7014,6 @@ wide-align@^1.1.0: ...@@ -7020,10 +7014,6 @@ wide-align@^1.1.0:
dependencies: dependencies:
string-width "^1.0.1" string-width "^1.0.1"
wind-dom@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wind-dom/-/wind-dom-0.0.3.tgz#3456e3d959dbebdcbf76ca68c6a4e8142f26360f"
window-size@^0.2.0: window-size@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment