extracting css

This commit is contained in:
yev
2017-12-27 20:34:51 +00:00
parent 9acd4ddcfc
commit 2be134436f
5 changed files with 549 additions and 513 deletions

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"trailingComma": "none",
"singleQuote": true,
"semi": false
}

View File

@@ -0,0 +1,24 @@
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const base = require('./webpack.srr.config')
module.exports = merge(base, {
plugins: [new ExtractTextPlugin('styles.css')],
output: {
filename: 'ssr.pure.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
}
})

View File

@@ -19,10 +19,11 @@
},
"scripts": {
"build:client": "webpack --config ./build/webpack.client.config.js --progress --hide-modules",
"build:server": "webpack --config ./build/webpack.server.config.js --progress --hide-modules",
"build:srr": "webpack --config ./build/webpack.srr.config.js --progress --hide-modules",
"build:srr-no-css": "webpack --config ./build/webpack.srr-no-css.config.js --progress --hide-modules",
"lint": "eslint --ext .js,.vue src test/unit/specs",
"unit": "./node_modules/karma/bin/karma start test/unit/karma.conf.js",
"build": "npm run lint && npm run unit && npm run build:client && npm run build:server"
"build": "npm run lint && npm run unit && npm run build:client && npm run build:srr"
},
"license": "MIT",
"devDependencies": {

View File

@@ -28,13 +28,13 @@
</transition>
</template>
<script>
import Modal from './index'
import Resizer from './Resizer.vue'
import { inRange } from './util'
import parseNumber from './parser'
import Modal from "./index";
import Resizer from "./Resizer.vue";
import { inRange } from "./util";
import parseNumber from "./parser";
export default {
name: 'VueJsModal',
name: "VueJsModal",
props: {
name: {
required: true,
@@ -73,64 +73,64 @@
},
classes: {
type: [String, Array],
default: 'v--modal'
default: "v--modal"
},
minWidth: {
type: Number,
default: 0,
validator(value) {
return value >= 0
return value >= 0;
}
},
minHeight: {
type: Number,
default: 0,
validator(value) {
return value >= 0
return value >= 0;
}
},
width: {
type: [Number, String],
default: 600,
validator(value) {
if (typeof value === 'string') {
let width = parseNumber(value)
return (width.type === '%' || width.type === 'px') &&
width.value > 0
if (typeof value === "string") {
let width = parseNumber(value);
return (width.type === "%" || width.type === "px") && width.value > 0;
}
return value >= 0
return value >= 0;
}
},
height: {
type: [Number, String],
default: 300,
validator(value) {
if (typeof value === 'string') {
if (value === 'auto') {
return true
if (typeof value === "string") {
if (value === "auto") {
return true;
}
let height = parseNumber(value)
return (height.type === '%' || height.type === 'px') &&
height.value > 0
let height = parseNumber(value);
return (
(height.type === "%" || height.type === "px") && height.value > 0
);
}
return value >= 0
return value >= 0;
}
},
pivotX: {
type: Number,
default: 0.5,
validator(value) {
return value >= 0 && value <= 1
return value >= 0 && value <= 1;
}
},
pivotY: {
type: Number,
default: 0.5,
validator(value) {
return value >= 0 && value <= 1
return value >= 0 && value <= 1;
}
}
},
@@ -153,9 +153,9 @@
modal: {
width: 0,
widthType: 'px',
widthType: "px",
height: 0,
heightType: 'px',
heightType: "px",
renderedHeight: 0
},
@@ -165,7 +165,7 @@
},
mutationObserver: null
}
};
},
watch: {
/**
@@ -176,53 +176,55 @@
*/
visible(value) {
if (value) {
this.visibility.overlay = true
this.visibility.overlay = true;
setTimeout(() => {
this.visibility.modal = true
this.visibility.modal = true;
this.$nextTick(() => {
this.addDraggableListeners()
this.callAfterEvent(true)
})
}, this.delay)
this.addDraggableListeners();
this.callAfterEvent(true);
});
}, this.delay);
} else {
this.visibility.modal = false
this.visibility.modal = false;
setTimeout(() => {
this.visibility.overlay = false
this.visibility.overlay = false;
this.$nextTick(() => {
this.removeDraggableListeners()
this.callAfterEvent(false)
})
}, this.delay)
this.removeDraggableListeners();
this.callAfterEvent(false);
});
}, this.delay);
}
}
},
created() {
this.setInitialSize()
this.setInitialSize();
},
/**
* Sets global listeners
*/
beforeMount() {
Modal.event.$on('toggle', (name, state, params) => {
Modal.event.$on("toggle", (name, state, params) => {
if (name === this.name) {
if (typeof state === 'undefined') {
state = !this.visible
if (typeof state === "undefined") {
state = !this.visible;
}
this.toggle(state, params)
this.toggle(state, params);
}
})
});
window.addEventListener('resize', this.onWindowResize)
this.onWindowResize()
window.addEventListener("resize", this.onWindowResize);
this.onWindowResize();
/**
* Making sure that autoHeight is enabled when using "scrollable"
*/
if (this.scrollable && !this.isAutoHeight) {
console.warn(`Modal "${this.name}" has scrollable flag set to true ` +
`but height is not "auto" (${this.height})`)
console.warn(
`Modal "${this.name}" has scrollable flag set to true ` +
`but height is not "auto" (${this.height})`
);
}
/**
* Only observe when using height: 'auto'
@@ -238,37 +240,37 @@
* (Provide polyfill to support IE < 11)
*/
const MutationObserver = (function() {
const prefixes = ['', 'WebKit', 'Moz', 'O', 'Ms']
const prefixes = ["", "WebKit", "Moz", "O", "Ms"];
for (let i = 0; i < prefixes.length; i++) {
let name = prefixes[i] + 'MutationObserver'
let name = prefixes[i] + "MutationObserver";
if (name in window) {
return window[name]
return window[name];
}
}
return false
}())
return false;
})();
if (MutationObserver) {
this.mutationObserver = new MutationObserver(mutations => {
this.updateRenderedHeight()
})
this.updateRenderedHeight();
});
}
}
if (this.clickToClose) {
window.addEventListener('keyup', this.onEscapeKeyUp)
window.addEventListener("keyup", this.onEscapeKeyUp);
}
},
/**
* Removes "resize" window listener
*/
beforeDestroy() {
window.removeEventListener('resize', this.onWindowResize)
window.removeEventListener("resize", this.onWindowResize);
if (this.clickToClose) {
window.removeEventListener('keyup', this.onEscapeKeyUp)
window.removeEventListener("keyup", this.onEscapeKeyUp);
}
},
computed: {
@@ -276,41 +278,46 @@
* Returns true if height is set to "auto"
*/
isAutoHeight() {
return this.modal.heightType === 'auto'
return this.modal.heightType === "auto";
},
/**
* Calculates and returns modal position based on the
* pivots, window size and modal size
*/
position() {
const { window, shift, pivotX, pivotY,
trueModalWidth, trueModalHeight } = this
const {
window,
shift,
pivotX,
pivotY,
trueModalWidth,
trueModalHeight
} = this;
const maxLeft = window.width - trueModalWidth
const maxTop = window.height - trueModalHeight
const maxLeft = window.width - trueModalWidth;
const maxTop = window.height - trueModalHeight;
const left = shift.left + pivotX * maxLeft
const top = shift.top + pivotY * maxTop
const left = shift.left + pivotX * maxLeft;
const top = shift.top + pivotY * maxTop;
return {
left: inRange(0, maxLeft, left),
top: inRange(0, maxTop, top)
}
};
},
/**
* Returns pixel width (if set with %) and makes sure that modal size
* fits the window
*/
trueModalWidth() {
const { window, modal, adaptive, minWidth } = this
const { window, modal, adaptive, minWidth } = this;
const value = modal.widthType === '%'
const value =
modal.widthType === "%"
? window.width / 100 * modal.width
: modal.width
: modal.width;
return adaptive
? inRange(minWidth, window.width, value)
: value
return adaptive ? inRange(minWidth, window.width, value) : value;
},
/**
* Returns pixel height (if set with %) and makes sure that modal size
@@ -319,48 +326,47 @@
* Returns modal.renderedHeight if height set as "auto"
*/
trueModalHeight() {
const { window, modal, isAutoHeight, adaptive } = this
const { window, modal, isAutoHeight, adaptive } = this;
const value = (modal.heightType === '%')
const value =
modal.heightType === "%"
? window.height / 100 * modal.height
: modal.height
: modal.height;
if (isAutoHeight) {
// use renderedHeight when height 'auto'
return this.modal.renderedHeight
return this.modal.renderedHeight;
}
return adaptive
? inRange(this.minHeight, this.window.height, value)
: value
: value;
},
/**
* Returns class list for screen overlay (modal background)
*/
overlayClass() {
return {
'v--modal-overlay': true,
'scrollable': this.scrollable && this.isAutoHeight
}
"v--modal-overlay": true,
scrollable: this.scrollable && this.isAutoHeight
};
},
/**
* Returns class list for modal itself
*/
modalClass() {
return ['v--modal-box', this.classes]
return ["v--modal-box", this.classes];
},
/**
* CSS styles for position and size of the modal
*/
modalStyle() {
return {
top: this.position.top + 'px',
left: this.position.left + 'px',
width: this.trueModalWidth + 'px',
height: this.isAutoHeight
? 'auto'
: (this.trueModalHeight + 'px')
}
top: this.position.top + "px",
left: this.position.left + "px",
width: this.trueModalWidth + "px",
height: this.isAutoHeight ? "auto" : this.trueModalHeight + "px"
};
}
},
methods: {
@@ -370,25 +376,25 @@
* every time "beforeOpen" is triggered
*/
setInitialSize() {
let { modal } = this
let width = parseNumber(this.width)
let height = parseNumber(this.height)
let { modal } = this;
let width = parseNumber(this.width);
let height = parseNumber(this.height);
modal.width = width.value
modal.widthType = width.type
modal.height = height.value
modal.heightType = height.type
modal.width = width.value;
modal.widthType = width.type;
modal.height = height.value;
modal.heightType = height.type;
},
onEscapeKeyUp(event) {
if (event.which === 27 && this.visible) {
this.$modal.hide(this.name)
this.$modal.hide(this.name);
}
},
onWindowResize() {
this.window.width = window.innerWidth
this.window.height = window.innerHeight
this.window.width = window.innerWidth;
this.window.height = window.innerHeight;
},
/**
@@ -400,24 +406,24 @@
timestamp: Date.now(),
canceled: false,
ref: this.$refs.modal
}
};
return Object.assign(eventData, params || {})
return Object.assign(eventData, params || {});
},
/**
* Event handler which is triggered on modal resize
*/
onModalResize(event) {
this.modal.widthType = 'px'
this.modal.width = event.size.width
this.modal.widthType = "px";
this.modal.width = event.size.width;
this.modal.heightType = 'px'
this.modal.height = event.size.height
this.modal.heightType = "px";
this.modal.height = event.size.height;
const { size } = this.modal
const resizeEvent = this.genEventObject({ size })
const { size } = this.modal;
const resizeEvent = this.genEventObject({ size });
this.$emit('resize', resizeEvent)
this.$emit("resize", resizeEvent);
},
/**
* Event handler which is triggered on $modal.show and $modal.hight
@@ -425,62 +431,59 @@
* but AfterEvents ('opened' and 'closed') are moved to `watch.visible`.
*/
toggle(state, params) {
const { reset, scrollable, visible } = this
const { reset, scrollable, visible } = this;
const beforeEventName = visible
? 'before-close'
: 'before-open'
const beforeEventName = visible ? "before-close" : "before-open";
if (beforeEventName === 'before-open') {
if (beforeEventName === "before-open") {
/**
* Need to unfocus previously focused element, otherwise
* all keypress events (ESC press, for example) will trigger on that element.
*/
if (document.activeElement) {
document.activeElement.blur()
document.activeElement.blur();
}
if (reset) {
this.setInitialSize()
this.setInitialSize();
this.shift.left = 0
this.shift.top = 0
this.shift.left = 0;
this.shift.top = 0;
}
if (scrollable) {
document.body.classList.add('v--modal-block-scroll')
document.body.classList.add("v--modal-block-scroll");
}
} else {
if (scrollable) {
document.body.classList.remove('v--modal-block-scroll')
document.body.classList.remove("v--modal-block-scroll");
}
}
let stopEventExecution = false
let stopEventExecution = false;
const stop = () => {
stopEventExecution = true
}
stopEventExecution = true;
};
const beforeEvent = this.genEventObject({ stop, state, params })
const beforeEvent = this.genEventObject({ stop, state, params });
this.$emit(beforeEventName, beforeEvent)
this.$emit(beforeEventName, beforeEvent);
if (!stopEventExecution) {
this.visible = state
this.visible = state;
// after events are called in `watch.visible`
}
},
getDraggableElement() {
var selector = typeof this.draggable !== 'string'
? '.v--modal-box'
: this.draggable
var selector =
typeof this.draggable !== "string" ? ".v--modal-box" : this.draggable;
if (selector) {
var handler = this.$refs.overlay.querySelector(selector)
var handler = this.$refs.overlay.querySelector(selector);
if (handler) {
return handler
return handler;
}
}
},
@@ -489,72 +492,72 @@
*/
onBackgroundClick() {
if (this.clickToClose) {
this.toggle(false)
this.toggle(false);
}
},
addDraggableListeners() {
if (!this.draggable) {
return
return;
}
let dragger = this.getDraggableElement()
let dragger = this.getDraggableElement();
if (dragger) {
let startX = 0
let startY = 0
let cachedShiftX = 0
let cachedShiftY = 0
let startX = 0;
let startY = 0;
let cachedShiftX = 0;
let cachedShiftY = 0;
let getPosition = (event) => {
let getPosition = event => {
return event.touches && event.touches.length > 0
? event.touches[0]
: event
: event;
};
let mousedown = event => {
let target = event.target;
if (target && target.nodeName === "INPUT") {
return;
}
let mousedown = (event) => {
let target = event.target
let { clientX, clientY } = getPosition(event);
if (target && target.nodeName === 'INPUT') {
return
}
document.addEventListener("mousemove", mousemove);
document.addEventListener("mouseup", mouseup);
let { clientX, clientY } = getPosition(event)
document.addEventListener("touchmove", mousemove);
document.addEventListener("touchend", mouseup);
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
document.addEventListener('touchmove', mousemove)
document.addEventListener('touchend', mouseup)
startX = clientX
startY = clientY
cachedShiftX = this.shift.left
cachedShiftY = this.shift.top
startX = clientX;
startY = clientY;
cachedShiftX = this.shift.left;
cachedShiftY = this.shift.top;
// event.preventDefault()
}
};
let mousemove = (event) => {
let { clientX, clientY } = getPosition(event)
let mousemove = event => {
let { clientX, clientY } = getPosition(event);
this.shift.left = cachedShiftX + clientX - startX
this.shift.top = cachedShiftY + clientY - startY
event.preventDefault()
}
this.shift.left = cachedShiftX + clientX - startX;
this.shift.top = cachedShiftY + clientY - startY;
event.preventDefault();
};
let mouseup = (event) => {
document.removeEventListener('mousemove', mousemove)
document.removeEventListener('mouseup', mouseup)
let mouseup = event => {
document.removeEventListener("mousemove", mousemove);
document.removeEventListener("mouseup", mouseup);
document.removeEventListener('touchmove', mousemove)
document.removeEventListener('touchend', mouseup)
document.removeEventListener("touchmove", mousemove);
document.removeEventListener("touchend", mouseup);
event.preventDefault()
}
event.preventDefault();
};
dragger.addEventListener('mousedown', mousedown)
dragger.addEventListener('touchstart', mousedown)
dragger.addEventListener("mousedown", mousedown);
dragger.addEventListener("touchstart", mousedown);
}
},
@@ -571,15 +574,15 @@
*/
callAfterEvent(state) {
if (state) {
this.connectObserver()
this.connectObserver();
} else {
this.disconnectObserver()
this.disconnectObserver();
}
const eventName = state ? 'opened' : 'closed'
const event = this.genEventObject({ state })
const eventName = state ? "opened" : "closed";
const event = this.genEventObject({ state });
this.$emit(eventName, event)
this.$emit(eventName, event);
},
/**
@@ -590,8 +593,7 @@
*/
updateRenderedHeight() {
if (this.$refs.modal) {
this.modal.renderedHeight = this.$refs.modal
.getBoundingClientRect().height
this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height;
}
},
@@ -605,7 +607,7 @@
childList: true,
attributes: true,
subtree: true
})
});
}
},
@@ -614,11 +616,11 @@
*/
disconnectObserver() {
if (this.mutationObserver) {
this.mutationObserver.disconnect()
}
this.mutationObserver.disconnect();
}
}
}
};
</script>
<style>
.v--modal-block-scroll {
@@ -632,7 +634,7 @@
box-sizing: border-box;
left: 0;
top: 0;
width: 100vw;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.2);
z-index: 999;
@@ -662,7 +664,7 @@
background-color: white;
text-align: left;
border-radius: 3px;
box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4);
box-shadow: 0 20px 60px -2px rgba(27, 33, 58, 0.4);
padding: 0;
}
@@ -681,19 +683,23 @@
top: 0;
}
.overlay-fade-enter-active, .overlay-fade-leave-active {
.overlay-fade-enter-active,
.overlay-fade-leave-active {
transition: all 0.2s;
}
.overlay-fade-enter, .overlay-fade-leave-active {
.overlay-fade-enter,
.overlay-fade-leave-active {
opacity: 0;
}
.nice-modal-fade-enter-active, .nice-modal-fade-leave-active {
.nice-modal-fade-enter-active,
.nice-modal-fade-leave-active {
transition: all 0.4s;
}
.nice-modal-fade-enter, .nice-modal-fade-leave-active {
.nice-modal-fade-enter,
.nice-modal-fade-leave-active {
opacity: 0;
transform: translateY(-20px);
}