重绘一大波icon;修复框架子vm的props属性传递;重写datepicker组件;重写分页组件;
parent
c76a1b3264
commit
88dab988da
|
@ -19,7 +19,12 @@ const prefixer = postcss().use(
|
||||||
)
|
)
|
||||||
const jsOpt = {
|
const jsOpt = {
|
||||||
presets: ['es2015'],
|
presets: ['es2015'],
|
||||||
plugins: ['transform-es2015-modules-amd']
|
plugins: [
|
||||||
|
'transform-es2015-modules-amd',
|
||||||
|
'transform-decorators-legacy',
|
||||||
|
'transform-class-properties',
|
||||||
|
'transform-object-rest-spread'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
const cssOpt = {
|
const cssOpt = {
|
||||||
includePaths: ['src/css/'],
|
includePaths: ['src/css/'],
|
||||||
|
|
|
@ -18,7 +18,12 @@ const prefixer = postcss().use(
|
||||||
)
|
)
|
||||||
const jsOpt = {
|
const jsOpt = {
|
||||||
presets: ['es2015', 'minify'],
|
presets: ['es2015', 'minify'],
|
||||||
plugins: ['transform-es2015-modules-amd']
|
plugins: [
|
||||||
|
'transform-es2015-modules-amd',
|
||||||
|
'transform-decorators-legacy',
|
||||||
|
'transform-class-properties',
|
||||||
|
'transform-object-rest-spread'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
const cssOpt = {
|
const cssOpt = {
|
||||||
includePaths: ['src/css/'],
|
includePaths: ['src/css/'],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "doui-yua",
|
"name": "doui-anot",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
|
@ -463,6 +463,47 @@
|
||||||
"babel-helper-is-void-0": "0.2.0"
|
"babel-helper-is-void-0": "0.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-syntax-class-properties": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-decorators": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-object-rest-spread": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-class-properties": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-function-name": "6.24.1",
|
||||||
|
"babel-plugin-syntax-class-properties": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-decorators-legacy": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz",
|
||||||
|
"integrity": "sha1-dBtY9sW86eYCfgiC2cmU8E82aSU=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-decorators": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-es2015-arrow-functions": {
|
"babel-plugin-transform-es2015-arrow-functions": {
|
||||||
"version": "6.22.0",
|
"version": "6.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||||
|
@ -721,6 +762,16 @@
|
||||||
"integrity": "sha512-bPbUhkeN2Nc0KH0/A19GwQGj8w+CvdJzyu8t59VoEDgsNMQ9Bopzi5DrVkrSsVjbYUaZpzq/DYLrH+wD5K2Tig==",
|
"integrity": "sha512-bPbUhkeN2Nc0KH0/A19GwQGj8w+CvdJzyu8t59VoEDgsNMQ9Bopzi5DrVkrSsVjbYUaZpzq/DYLrH+wD5K2Tig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"babel-plugin-transform-object-rest-spread": {
|
||||||
|
"version": "6.26.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
|
||||||
|
"integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-object-rest-spread": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-property-literals": {
|
"babel-plugin-transform-property-literals": {
|
||||||
"version": "6.8.5",
|
"version": "6.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "doui-yua",
|
"name": "doui-anot",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "基于Anot框架的doUI组件库。支持IE10+,及现代浏览器。",
|
"description": "基于Anot框架的doUI组件库。支持IE10+,及现代浏览器。",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
@ -13,13 +13,16 @@
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"doui",
|
"doui",
|
||||||
"yua"
|
"Anot"
|
||||||
],
|
],
|
||||||
"author": "yutent",
|
"author": "yutent",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^7.2.5",
|
"autoprefixer": "^7.2.5",
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||||
|
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-minify": "^0.2.0",
|
"babel-preset-minify": "^0.2.0",
|
||||||
"chalk": "^2.3.0",
|
"chalk": "^2.3.0",
|
||||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -3297,11 +3297,12 @@
|
||||||
if (/^:/.test(attr.name)) {
|
if (/^:/.test(attr.name)) {
|
||||||
var name = attr.name.match(rmsAttr)[1]
|
var name = attr.name.match(rmsAttr)[1]
|
||||||
var value = null
|
var value = null
|
||||||
if (!name || Anot.directives[name]) {
|
if (!name || Anot.directives[name] || events[name]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
value = parseExpr(attr.value, vmodels, {}).apply(0, vmodels)
|
value = parseExpr(attr.value, vmodels, {}).apply(0, vmodels)
|
||||||
|
value = toJson(value)
|
||||||
elem.removeAttribute(attr.name)
|
elem.removeAttribute(attr.name)
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return
|
return
|
||||||
|
@ -4092,7 +4093,7 @@
|
||||||
elem.addEventListener(type, callback, false)
|
elem.addEventListener(type, callback, false)
|
||||||
var old = binding.rollback
|
var old = binding.rollback
|
||||||
binding.rollback = function() {
|
binding.rollback = function() {
|
||||||
elem.anotStter = null
|
elem.anotSetter = null
|
||||||
Anot.unbind(elem, type, callback)
|
Anot.unbind(elem, type, callback)
|
||||||
old && old()
|
old && old()
|
||||||
}
|
}
|
||||||
|
@ -4196,7 +4197,7 @@
|
||||||
elem.msFocus = false
|
elem.msFocus = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
elem.anotStter = updateVModel //#765
|
elem.anotSetter = updateVModel //#765
|
||||||
watchValueInTimer(function() {
|
watchValueInTimer(function() {
|
||||||
if (root.contains(elem)) {
|
if (root.contains(elem)) {
|
||||||
if (!elem.msFocus) {
|
if (!elem.msFocus) {
|
||||||
|
@ -4346,8 +4347,8 @@
|
||||||
function newSetter(value) {
|
function newSetter(value) {
|
||||||
// jshint ignore:line
|
// jshint ignore:line
|
||||||
setters[this.tagName].call(this, value)
|
setters[this.tagName].call(this, value)
|
||||||
if (!this.msFocus && this.anotStter) {
|
if (!this.msFocus && this.anotSetter) {
|
||||||
this.anotStter()
|
this.anotSetter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var inputProto = HTMLInputElement.prototype
|
var inputProto = HTMLInputElement.prototype
|
||||||
|
|
|
@ -42,16 +42,16 @@
|
||||||
&:active {font-weight:bold;
|
&:active {font-weight:bold;
|
||||||
&::before {animation:ripple .3s cubic-bezier(0.23, 1, 0.32, 1);}
|
&::before {animation:ripple .3s cubic-bezier(0.23, 1, 0.32, 1);}
|
||||||
}
|
}
|
||||||
&::after {content:"\e652";}
|
&::after {content:"\e692";}
|
||||||
|
|
||||||
&.prev-month {left:35px;
|
&.prev-month {left:35px;
|
||||||
&::after {content:"\e659"}
|
&::after {content:"\e67c"}
|
||||||
}
|
}
|
||||||
&.next-month {left:auto; right:35px;
|
&.next-month {left:auto; right:35px;
|
||||||
&::after {content:"\e658"}
|
&::after {content:"\e66e"}
|
||||||
}
|
}
|
||||||
&.next-year {left:auto; right:0;
|
&.next-year {left:auto; right:0;
|
||||||
&::after {content:"\e653"}
|
&::after {content:"\e694"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-03-29 18:39:35
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
function getBindingCallback(elem, name, vmodels) {
|
||||||
|
var callback = elem.getAttribute(name)
|
||||||
|
if (callback) {
|
||||||
|
for (var i = 0, vm; (vm = vmodels[i++]); ) {
|
||||||
|
if (vm.hasOwnProperty(callback) && typeof vm[callback] === 'function') {
|
||||||
|
return vm[callback]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Anot.ui.drag = '1.0.0'
|
||||||
|
// 元素拖动
|
||||||
|
Anot.directive('drag', {
|
||||||
|
priority: 1500,
|
||||||
|
init: function(binding) {
|
||||||
|
binding.expr = '"' + binding.expr + '"'
|
||||||
|
Anot(binding.element).css('cursor', 'move')
|
||||||
|
|
||||||
|
//取得拖动的3种状态回调
|
||||||
|
//按下,且拖拽之前
|
||||||
|
binding.beforedrag = getBindingCallback(
|
||||||
|
binding.element,
|
||||||
|
'data-beforedrag',
|
||||||
|
binding.vmodels
|
||||||
|
)
|
||||||
|
//拖拽过程
|
||||||
|
binding.dragging = getBindingCallback(
|
||||||
|
binding.element,
|
||||||
|
'data-dragging',
|
||||||
|
binding.vmodels
|
||||||
|
)
|
||||||
|
// 拖拽结束,且释放鼠标
|
||||||
|
binding.dragged = getBindingCallback(
|
||||||
|
binding.element,
|
||||||
|
'data-dragged',
|
||||||
|
binding.vmodels
|
||||||
|
)
|
||||||
|
|
||||||
|
//默认允许溢出可视区
|
||||||
|
binding.overflow = true
|
||||||
|
|
||||||
|
//方向,x轴, y轴, xy轴
|
||||||
|
binding.axis = 'xy'
|
||||||
|
if (!!binding.element.dataset.axis) {
|
||||||
|
binding.axis = binding.element.dataset.axis
|
||||||
|
delete binding.element.dataset.axis
|
||||||
|
}
|
||||||
|
|
||||||
|
//默认不限制拖拽区域
|
||||||
|
binding.limit = false
|
||||||
|
if (!!binding.element.dataset.limit) {
|
||||||
|
binding.limit = binding.element.dataset.limit
|
||||||
|
//这里,只要不为空,除parent外,其他值都默认为window, 故"可溢出"为false
|
||||||
|
binding.overflow = false
|
||||||
|
delete binding.element.dataset.limit
|
||||||
|
}
|
||||||
|
|
||||||
|
delete binding.element.dataset.beforedrag
|
||||||
|
delete binding.element.dataset.dragging
|
||||||
|
delete binding.element.dataset.dragged
|
||||||
|
},
|
||||||
|
update: function(val) {
|
||||||
|
var _this = this,
|
||||||
|
target = val ? this.element.parentNode : this.element,
|
||||||
|
$drag = Anot(this.element),
|
||||||
|
$doc = Anot(document),
|
||||||
|
$target = null,
|
||||||
|
parentElem = null
|
||||||
|
|
||||||
|
// val值不为空时, 获取真正的拖动元素
|
||||||
|
// 仅从父级上找
|
||||||
|
while (val && target) {
|
||||||
|
if (target.classList.contains(val) || target.id === val) {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$target = Anot(target)
|
||||||
|
// 限制范围为parent时,获取父级元素
|
||||||
|
if (this.limit === 'parent') {
|
||||||
|
parentElem = target.parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
var dx, dy, mx, my, ox, oy, fox, foy, tw, th, ww, wh, bst, bsl
|
||||||
|
$drag.bind('mousedown', function(ev) {
|
||||||
|
var gcs = getComputedStyle(target),
|
||||||
|
cst = gcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
||||||
|
offset = $target.offset()
|
||||||
|
|
||||||
|
cst = cst !== 'none' ? cst.split(', ') : [1, 0, 0, 1, 0, 0]
|
||||||
|
cst[4] -= 0
|
||||||
|
cst[5] -= 0
|
||||||
|
|
||||||
|
//记录初始的transform位移
|
||||||
|
dx = cst[4]
|
||||||
|
dy = cst[5]
|
||||||
|
|
||||||
|
//滚动条的偏移
|
||||||
|
bst = $doc.scrollTop()
|
||||||
|
bsl = $doc.scrollLeft()
|
||||||
|
|
||||||
|
// 计算元素的offset值, 需要修正
|
||||||
|
ox = offset.left - dx - bsl
|
||||||
|
oy = offset.top - dy - bst
|
||||||
|
|
||||||
|
mx = ev.pageX //按下鼠标的的坐标值
|
||||||
|
my = ev.pageY //按下鼠标的的坐标值
|
||||||
|
|
||||||
|
// 在按下时才获取窗口大小, 是为了防止人为的改变窗口大小,导致计算不准备
|
||||||
|
// 同时减少不必要的事件监听(页面上可能会很多可拖动元素)
|
||||||
|
ww = window.innerWidth
|
||||||
|
wh = window.innerHeight
|
||||||
|
|
||||||
|
// 同样,在点击之后获取元素的宽高,可保证获取到的是真实的值
|
||||||
|
tw = target.clientWidth
|
||||||
|
th = target.clientHeight
|
||||||
|
|
||||||
|
//拖拽前回调
|
||||||
|
if (_this.beforedrag) {
|
||||||
|
var result = _this.beforedrag.call(_this.vmodels, target, ox, oy)
|
||||||
|
if (result === false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//限制区域, 4个值依次是: 上, 下, 左, 右
|
||||||
|
var limit = [0, wh - th, 0, ww - tw]
|
||||||
|
|
||||||
|
if (_this.limit === 'parent') {
|
||||||
|
var pgcs = getComputedStyle(parentElem),
|
||||||
|
pcst = pgcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
||||||
|
poffset = Anot(parentElem).offset()
|
||||||
|
|
||||||
|
pcst = pcst !== 'none' ? pcst.split(', ') : [1, 0, 0, 1, 0, 0]
|
||||||
|
|
||||||
|
var pox = poffset.left - pcst[4] - bsl,
|
||||||
|
poy = poffset.top - pcst[5] - bst
|
||||||
|
|
||||||
|
limit = [
|
||||||
|
poy,
|
||||||
|
poy + parentElem.clientHeight - th,
|
||||||
|
pox,
|
||||||
|
pox + parentElem.clientWidth - tw
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
var mvfn = $doc.bind('mousemove', function(ev) {
|
||||||
|
//坐标轴限制
|
||||||
|
if (_this.axis !== 'y') {
|
||||||
|
cst[4] = ev.pageX - mx + dx
|
||||||
|
}
|
||||||
|
if (_this.axis !== 'x') {
|
||||||
|
cst[5] = ev.pageY - my + dy
|
||||||
|
}
|
||||||
|
|
||||||
|
;(fox = ox + cst[4]), //修正的offset
|
||||||
|
(foy = oy + cst[5]) //修正的offset
|
||||||
|
|
||||||
|
//如果不允许溢出可视区
|
||||||
|
if (!_this.overflow) {
|
||||||
|
if (_this.axis !== 'y') {
|
||||||
|
if (fox <= limit[2]) {
|
||||||
|
fox = limit[2]
|
||||||
|
//修正矩阵
|
||||||
|
cst[4] = fox - ox
|
||||||
|
}
|
||||||
|
if (fox >= limit[3]) {
|
||||||
|
fox = limit[3]
|
||||||
|
//修正矩阵
|
||||||
|
cst[4] = fox - ox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_this.axis !== 'x') {
|
||||||
|
if (foy <= limit[0]) {
|
||||||
|
foy = limit[0]
|
||||||
|
//修正矩阵
|
||||||
|
cst[5] = foy - oy
|
||||||
|
}
|
||||||
|
if (foy >= limit[1]) {
|
||||||
|
foy = limit[1]
|
||||||
|
//修正矩阵
|
||||||
|
cst[5] = foy - oy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$target.css({
|
||||||
|
transform: 'matrix(' + cst.join(', ') + ')'
|
||||||
|
})
|
||||||
|
|
||||||
|
//拖拽过程的回调
|
||||||
|
if (_this.dragging) {
|
||||||
|
_this.dragging.call(_this.vmodels, target, fox, foy)
|
||||||
|
}
|
||||||
|
// 防止拖动到边缘时导致页面滚动
|
||||||
|
ev.preventDefault()
|
||||||
|
}),
|
||||||
|
upfn = $doc.bind('mouseup', function(ev) {
|
||||||
|
$doc.unbind('mousemove', mvfn)
|
||||||
|
$doc.unbind('mouseup', upfn)
|
||||||
|
//结束回调
|
||||||
|
if (_this.dragged) {
|
||||||
|
_this.dragged.call(_this.vmodels, target, fox, foy)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,216 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2017-03-29 18:39:35
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
define(['yua'], function(){
|
|
||||||
|
|
||||||
function getBindingCallback(elem, name, vmodels) {
|
|
||||||
var callback = elem.getAttribute(name)
|
|
||||||
if (callback) {
|
|
||||||
for (var i = 0, vm; vm = vmodels[i++]; ) {
|
|
||||||
if (vm.hasOwnProperty(callback) && typeof vm[callback] === "function") {
|
|
||||||
return vm[callback]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yua.ui.drag = '1.0.0'
|
|
||||||
// 元素拖动
|
|
||||||
yua.directive('drag', {
|
|
||||||
priority: 1500,
|
|
||||||
init: function(binding){
|
|
||||||
binding.expr = '"' + binding.expr + '"'
|
|
||||||
yua(binding.element).css('cursor', 'move')
|
|
||||||
|
|
||||||
//取得拖动的3种状态回调
|
|
||||||
//按下,且拖拽之前
|
|
||||||
binding.beforedrag = getBindingCallback(binding.element, 'data-beforedrag', binding.vmodels)
|
|
||||||
//拖拽过程
|
|
||||||
binding.dragging = getBindingCallback(binding.element, 'data-dragging', binding.vmodels)
|
|
||||||
// 拖拽结束,且释放鼠标
|
|
||||||
binding.dragged = getBindingCallback(binding.element, 'data-dragged', binding.vmodels)
|
|
||||||
|
|
||||||
//默认允许溢出可视区
|
|
||||||
binding.overflow = true
|
|
||||||
|
|
||||||
//方向,x轴, y轴, xy轴
|
|
||||||
binding.axis = 'xy'
|
|
||||||
if(!!binding.element.dataset.axis){
|
|
||||||
binding.axis = binding.element.dataset.axis
|
|
||||||
delete binding.element.dataset.axis
|
|
||||||
}
|
|
||||||
|
|
||||||
//默认不限制拖拽区域
|
|
||||||
binding.limit = false
|
|
||||||
if(!!binding.element.dataset.limit) {
|
|
||||||
binding.limit = binding.element.dataset.limit
|
|
||||||
//这里,只要不为空,除parent外,其他值都默认为window, 故"可溢出"为false
|
|
||||||
binding.overflow = false
|
|
||||||
delete binding.element.dataset.limit
|
|
||||||
}
|
|
||||||
|
|
||||||
delete binding.element.dataset.beforedrag
|
|
||||||
delete binding.element.dataset.dragging
|
|
||||||
delete binding.element.dataset.dragged
|
|
||||||
},
|
|
||||||
update: function(val){
|
|
||||||
var _this = this,
|
|
||||||
target = val ? this.element.parentNode : this.element,
|
|
||||||
$drag = yua(this.element),
|
|
||||||
$doc = yua(document),
|
|
||||||
$target = null,
|
|
||||||
parentElem = null;
|
|
||||||
|
|
||||||
// val值不为空时, 获取真正的拖动元素
|
|
||||||
// 仅从父级上找
|
|
||||||
while(val && target){
|
|
||||||
if(target.classList.contains(val) || target.id === val){
|
|
||||||
break
|
|
||||||
}else{
|
|
||||||
target = target.parentNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$target = yua(target);
|
|
||||||
// 限制范围为parent时,获取父级元素
|
|
||||||
if(this.limit === 'parent'){
|
|
||||||
parentElem = target.parentNode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var dx,dy,mx,my,ox,oy,fox,foy,tw,th,ww,wh,bst,bsl;
|
|
||||||
$drag.bind('mousedown', function(ev){
|
|
||||||
var gcs = getComputedStyle(target),
|
|
||||||
cst = gcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
|
||||||
offset = $target.offset();
|
|
||||||
|
|
||||||
cst = cst !== 'none' ? cst.split(', ') : [1,0,0,1,0,0]
|
|
||||||
cst[4] -= 0
|
|
||||||
cst[5] -= 0
|
|
||||||
|
|
||||||
//记录初始的transform位移
|
|
||||||
dx = cst[4]
|
|
||||||
dy = cst[5]
|
|
||||||
|
|
||||||
//滚动条的偏移
|
|
||||||
bst = $doc.scrollTop()
|
|
||||||
bsl = $doc.scrollLeft()
|
|
||||||
|
|
||||||
// 计算元素的offset值, 需要修正
|
|
||||||
ox = offset.left - dx - bsl
|
|
||||||
oy = offset.top - dy - bst
|
|
||||||
|
|
||||||
mx = ev.pageX //按下鼠标的的坐标值
|
|
||||||
my = ev.pageY //按下鼠标的的坐标值
|
|
||||||
|
|
||||||
// 在按下时才获取窗口大小, 是为了防止人为的改变窗口大小,导致计算不准备
|
|
||||||
// 同时减少不必要的事件监听(页面上可能会很多可拖动元素)
|
|
||||||
ww = window.innerWidth;
|
|
||||||
wh = window.innerHeight;
|
|
||||||
|
|
||||||
// 同样,在点击之后获取元素的宽高,可保证获取到的是真实的值
|
|
||||||
tw = target.clientWidth;
|
|
||||||
th = target.clientHeight;
|
|
||||||
|
|
||||||
//拖拽前回调
|
|
||||||
if(_this.beforedrag){
|
|
||||||
var result = _this.beforedrag.call(_this.vmodels, target, ox, oy)
|
|
||||||
if(result === false){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//限制区域, 4个值依次是: 上, 下, 左, 右
|
|
||||||
var limit = [0, wh - th, 0, ww - tw]
|
|
||||||
|
|
||||||
if(_this.limit === 'parent') {
|
|
||||||
var pgcs = getComputedStyle(parentElem),
|
|
||||||
pcst = pgcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
|
||||||
poffset = yua(parentElem).offset();
|
|
||||||
|
|
||||||
pcst = pcst !== 'none' ? pcst.split(', ') : [1,0,0,1,0,0]
|
|
||||||
|
|
||||||
var pox = poffset.left - pcst[4] - bsl,
|
|
||||||
poy = poffset.top - pcst[5] - bst;
|
|
||||||
|
|
||||||
limit = [poy, poy + parentElem.clientHeight - th, pox, pox + parentElem.clientWidth - tw]
|
|
||||||
}
|
|
||||||
|
|
||||||
var mvfn = $doc.bind('mousemove', function(ev){
|
|
||||||
|
|
||||||
//坐标轴限制
|
|
||||||
if(_this.axis !== 'y'){
|
|
||||||
cst[4] = ev.pageX - mx + dx
|
|
||||||
}
|
|
||||||
if(_this.axis !== 'x'){
|
|
||||||
cst[5] = ev.pageY - my + dy
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fox = ox + cst[4], //修正的offset
|
|
||||||
foy = oy + cst[5]; //修正的offset
|
|
||||||
|
|
||||||
|
|
||||||
//如果不允许溢出可视区
|
|
||||||
if(!_this.overflow){
|
|
||||||
if(_this.axis !== 'y'){
|
|
||||||
if(fox <= limit[2]) {
|
|
||||||
fox = limit[2]
|
|
||||||
//修正矩阵
|
|
||||||
cst[4] = fox - ox
|
|
||||||
}
|
|
||||||
if(fox >= limit[3]){
|
|
||||||
fox = limit[3]
|
|
||||||
//修正矩阵
|
|
||||||
cst[4] = fox - ox
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_this.axis !== 'x'){
|
|
||||||
if(foy <= limit[0]) {
|
|
||||||
foy = limit[0]
|
|
||||||
//修正矩阵
|
|
||||||
cst[5] = foy - oy
|
|
||||||
}
|
|
||||||
if(foy >= limit[1]){
|
|
||||||
foy = limit[1]
|
|
||||||
//修正矩阵
|
|
||||||
cst[5] = foy - oy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$target.css({
|
|
||||||
transform: 'matrix(' + cst.join(', ') + ')'
|
|
||||||
})
|
|
||||||
|
|
||||||
//拖拽过程的回调
|
|
||||||
if(_this.dragging){
|
|
||||||
_this.dragging.call(_this.vmodels, target, fox, foy)
|
|
||||||
}
|
|
||||||
// 防止拖动到边缘时导致页面滚动
|
|
||||||
ev.preventDefault()
|
|
||||||
}),
|
|
||||||
upfn = $doc.bind('mouseup', function(ev){
|
|
||||||
$doc.unbind('mousemove', mvfn)
|
|
||||||
$doc.unbind('mouseup', upfn)
|
|
||||||
//结束回调
|
|
||||||
if(_this.dragged){
|
|
||||||
_this.dragged.call(_this.vmodels, target, fox, foy)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,578 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-09-21 01:36:29
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
|
||||||
|
|
||||||
|
|
||||||
var layerDom = {},
|
|
||||||
layerObj = {},
|
|
||||||
unique = null, //储存当前打开的1/2/3类型的弹窗
|
|
||||||
lid = 0,
|
|
||||||
defconf = {
|
|
||||||
type: 1, // 弹窗类型
|
|
||||||
skin: 'def', //默认主题
|
|
||||||
icon: 1, //图标类型
|
|
||||||
background: '#fff',
|
|
||||||
shade: true, //遮罩
|
|
||||||
shadeClose: false, //遮罩点击关闭弹窗
|
|
||||||
radius: '0px', //弹窗圆角半径
|
|
||||||
area: ['auto', 'auto'],
|
|
||||||
title: '', //弹窗主标题(在工具栏上的)
|
|
||||||
menubar: true, //是否显示菜单栏
|
|
||||||
content: '', // 弹窗的内容
|
|
||||||
fixed: false, //是否固定不可拖拽
|
|
||||||
offset: null, //弹窗出来时的坐标, 为数组,可有4个值,依次是 上右下左
|
|
||||||
btns: ['确定', '取消'], //弹窗的2个按钮的文字
|
|
||||||
yes: close, //确定按钮对应的回调
|
|
||||||
no: close, //取消按钮对应的回调
|
|
||||||
success: null //弹窗初始化完成时的回调
|
|
||||||
};
|
|
||||||
|
|
||||||
function uuid(){
|
|
||||||
return 'layer-' + (++lid)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function close(id){
|
|
||||||
if(typeof id !== 'string' && typeof id !== 'number'){
|
|
||||||
return console.error(new Error('要关闭的layer实例不存在'))
|
|
||||||
}
|
|
||||||
if(/^\$wrap\-/.test(id) || layerObj['$wrap-' + id]){
|
|
||||||
|
|
||||||
try {
|
|
||||||
id = (layerObj['$wrap-' + id] ? '$wrap-' : '') + id;
|
|
||||||
//未显示过,忽略
|
|
||||||
if(!layerObj[id].show){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
layerObj[id].parentElem.replaceChild(layerObj[id].wrap, layerDom[id][1])
|
|
||||||
unique = null
|
|
||||||
}catch(err){}
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
document.body.removeChild(layerDom[id][1])
|
|
||||||
document.body.removeChild(layerDom[id][0])
|
|
||||||
unique = null
|
|
||||||
}catch(err){}
|
|
||||||
|
|
||||||
delete layerDom[id]
|
|
||||||
delete yua.vmodels[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function reapeat(str, num){
|
|
||||||
var idx = 0,
|
|
||||||
result = ''
|
|
||||||
while(idx < num){
|
|
||||||
result += str
|
|
||||||
idx++
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixOffset(val){
|
|
||||||
if(!val && val !== 0){
|
|
||||||
return 'auto'
|
|
||||||
}else{
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var __constructor = function(conf){
|
|
||||||
if(conf){
|
|
||||||
this.ready(conf).append().show()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
__layer = {
|
|
||||||
alert: function(msg, conf){
|
|
||||||
if(typeof conf === 'function'){
|
|
||||||
conf = {yes: conf}
|
|
||||||
}else if(typeof conf === 'object'){
|
|
||||||
conf = conf
|
|
||||||
}else{
|
|
||||||
conf = {}
|
|
||||||
}
|
|
||||||
conf.icon = 6
|
|
||||||
conf.content = msg
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
confirm: function(msg, conf){
|
|
||||||
if(typeof conf === 'function'){
|
|
||||||
conf = {yes: conf}
|
|
||||||
}else if(typeof conf === 'object'){
|
|
||||||
conf = conf
|
|
||||||
}else{
|
|
||||||
conf = {}
|
|
||||||
}
|
|
||||||
conf.type = 2
|
|
||||||
conf.icon = 8
|
|
||||||
conf.content = msg
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
msg: function(msg, conf){
|
|
||||||
if(typeof conf !== 'object'){
|
|
||||||
var tmp = conf
|
|
||||||
conf = {timeout: 2500}
|
|
||||||
if(typeof tmp === 'number'){
|
|
||||||
conf.icon = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!conf.hasOwnProperty('timeout')){
|
|
||||||
conf.timeout = 2500
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.specialMode = true;//特殊模式
|
|
||||||
conf.content = '<p class="msg-box">' + msg + '</p>'
|
|
||||||
conf.type = 7
|
|
||||||
conf.fixed = true
|
|
||||||
conf.shade = false
|
|
||||||
conf.menubar = false
|
|
||||||
conf.radius = '5px'
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
loading: function(style, time, cb){
|
|
||||||
style = style >>> 0
|
|
||||||
|
|
||||||
if(typeof time === 'function'){
|
|
||||||
cb = time;
|
|
||||||
time = 0
|
|
||||||
} else{
|
|
||||||
time = time >>> 0
|
|
||||||
if(typeof cb !== 'function'){
|
|
||||||
cb = yua.noop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __layer.open({type: 6, load: style, yes: cb, timeout: time, menubar: false, background: 'none', fixed: true})
|
|
||||||
},
|
|
||||||
tips: function(msg, elem, conf){
|
|
||||||
if(!(elem instanceof HTMLElement)){
|
|
||||||
return console.error(new Error('tips类型必须指定一个目标容器'))
|
|
||||||
}
|
|
||||||
if(typeof conf !== 'object'){
|
|
||||||
var tmp = conf
|
|
||||||
conf = {timeout: 2500}
|
|
||||||
if(typeof tmp === 'number'){
|
|
||||||
conf.icon = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!conf.hasOwnProperty('timeout')){
|
|
||||||
conf.timeout = 2500
|
|
||||||
}
|
|
||||||
if(!conf.background){
|
|
||||||
conf.background = 'rgba(0,0,0,.5)'
|
|
||||||
}
|
|
||||||
if(!conf.color){
|
|
||||||
conf.color = '#fff'
|
|
||||||
}
|
|
||||||
conf.$elem = elem
|
|
||||||
conf.content = msg
|
|
||||||
conf.type = 5;
|
|
||||||
conf.icon = 0;
|
|
||||||
conf.fixed = true;
|
|
||||||
conf.shade = false;
|
|
||||||
conf.menubar = false;
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
prompt: function(msg, callback){
|
|
||||||
if(typeof callback !== 'function'){
|
|
||||||
return console.error('argument [callback] requires a function, but ' + (typeof callback) + ' given')
|
|
||||||
}
|
|
||||||
var conf = {
|
|
||||||
type: 3,
|
|
||||||
icon: 7,
|
|
||||||
prompt: '',
|
|
||||||
title: msg,
|
|
||||||
content: '<input class="prompt-value" :duplex="prompt" />',
|
|
||||||
yes: function(id){
|
|
||||||
callback(id, yua.vmodels[id].prompt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
use: function(skin, callback){
|
|
||||||
require(['css!./skin/' + skin], callback)
|
|
||||||
},
|
|
||||||
close: close,
|
|
||||||
open: function(conf){
|
|
||||||
if(typeof conf === 'string'){
|
|
||||||
conf = '$wrap-' + conf
|
|
||||||
if(!layerObj[conf]){
|
|
||||||
throw new Error('layer实例不存在')
|
|
||||||
}else{
|
|
||||||
//只能显示一个实例
|
|
||||||
if(layerObj[conf].show){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
layerObj[conf].show = true
|
|
||||||
|
|
||||||
if(!yua.vmodels[conf]){
|
|
||||||
yua.define(layerObj[conf].obj.init)
|
|
||||||
}
|
|
||||||
|
|
||||||
yua.scan(layerDom[conf][1])
|
|
||||||
layerObj[conf].obj.show()
|
|
||||||
|
|
||||||
layerObj[conf].parentElem.appendChild(layerDom[conf][1])
|
|
||||||
layerObj[conf].parentElem.replaceChild(layerDom[conf][1], layerObj[conf].wrap)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return new __constructor(conf).init.$id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
version: '0.0.1-base'
|
|
||||||
};
|
|
||||||
|
|
||||||
/*type: { // 弹窗类型对应的id值
|
|
||||||
1: 'alert',
|
|
||||||
2: 'confirm',
|
|
||||||
3: 'prompt',
|
|
||||||
4: 'iframe',
|
|
||||||
5: 'tips',
|
|
||||||
6: 'loading',
|
|
||||||
7: 'msg',
|
|
||||||
}*/
|
|
||||||
__constructor.prototype = {
|
|
||||||
dot: { //loading的子元素数量
|
|
||||||
0: 4,
|
|
||||||
1: 9,
|
|
||||||
2: 2,
|
|
||||||
3: 3,
|
|
||||||
4: 2,
|
|
||||||
5: 5,
|
|
||||||
6: 5,
|
|
||||||
7: 5
|
|
||||||
},
|
|
||||||
timeout: null,
|
|
||||||
create: function(){
|
|
||||||
var layBox = document.createElement('div'),
|
|
||||||
coverBox = document.createElement('div');
|
|
||||||
|
|
||||||
coverBox.className = 'do-layer-cover type-' + this.init.type
|
|
||||||
// 允许点击遮罩关闭弹层时, 添加控制器
|
|
||||||
if(this.init.shadeClose){
|
|
||||||
coverBox.setAttribute(':controller', this.cInit.$id)
|
|
||||||
coverBox.setAttribute(':click', 'close(\'' + this.init.$id + '\')')
|
|
||||||
}
|
|
||||||
|
|
||||||
layBox.className = 'do-layer skin-'
|
|
||||||
+ this.init.skin
|
|
||||||
+ (this.init.type === 5 && ' active' || '')
|
|
||||||
+ ' type-'
|
|
||||||
+ ((!this.init.specialMode && this.init.type === 7) ? 'unspecial' : this.init.type);
|
|
||||||
|
|
||||||
//暂时隐藏,避免修正定位时,能看到闪一下
|
|
||||||
layBox.style.visibility = 'hidden'
|
|
||||||
layBox.style.borderRadius = this.init.radius
|
|
||||||
|
|
||||||
layBox.setAttribute(':controller', this.init.$id)
|
|
||||||
|
|
||||||
//没有菜单栏, 且未禁止拖拽,则加上可拖拽属性
|
|
||||||
if(!this.init.menubar && !this.init.fixed){
|
|
||||||
layBox.setAttribute(':drag', '')
|
|
||||||
layBox.setAttribute('data-limit', 'window')
|
|
||||||
}
|
|
||||||
|
|
||||||
//弹窗的宽高
|
|
||||||
var boxcss = ''
|
|
||||||
if(this.init.area[0] !== 'auto'){
|
|
||||||
boxcss += 'width: ' + this.init.area[0] + ';'
|
|
||||||
}
|
|
||||||
if(this.init.area[1] !== 'auto'){
|
|
||||||
boxcss += 'height: ' + this.init.area[1] + ';'
|
|
||||||
}
|
|
||||||
|
|
||||||
layBox.innerHTML = this.getMenubar()
|
|
||||||
+ '<div class="layer-content do-fn-cl '
|
|
||||||
+ (this.init.icon === 0 && 'none-icon' || '')
|
|
||||||
+ '" style="'
|
|
||||||
+ boxcss
|
|
||||||
+ '">'
|
|
||||||
+ this.getCont()
|
|
||||||
+ '</div>'
|
|
||||||
+ this.getBtns()
|
|
||||||
+ (this.init.type === 5 && '<i class="arrow" style="border-top-color: '
|
|
||||||
+ this.init.background
|
|
||||||
+ '"></i>' || '')
|
|
||||||
|
|
||||||
return [this.init.shade ? coverBox : null, layBox]
|
|
||||||
},
|
|
||||||
getCont: function(){
|
|
||||||
if(this.init.type === 6){
|
|
||||||
return this.getLoading(this.init.load)
|
|
||||||
}else{
|
|
||||||
return this.getIcon()
|
|
||||||
+ '<div class="detail" :html="content"></div>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getLoading: function(style){
|
|
||||||
return '<div class="do-ui-load load-style-'
|
|
||||||
+ style
|
|
||||||
+ '">'
|
|
||||||
+ '<span class="dot-box">'
|
|
||||||
+ reapeat('<i></i>', this.dot[style])
|
|
||||||
+ '</span>'
|
|
||||||
+ '</div>'
|
|
||||||
},
|
|
||||||
//获取窗口导航条
|
|
||||||
getMenubar: function(){
|
|
||||||
var html = ''
|
|
||||||
if(this.init.menubar){
|
|
||||||
html += '<div class="layer-title do-fn-noselect" ';
|
|
||||||
//可拖拽
|
|
||||||
if(!this.init.fixed){
|
|
||||||
html += ':drag="do-layer" data-limit="window" '
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '>{{title}}'
|
|
||||||
+ '<a class="action-close deficon" :click="no(\'' + this.init.$id + '\')"></a>'
|
|
||||||
+ '</div>'
|
|
||||||
}
|
|
||||||
return html
|
|
||||||
},
|
|
||||||
//获取窗口内容的图标
|
|
||||||
getIcon: function(){
|
|
||||||
if(this.init.icon === 0){
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
if(this.init.type < 4 || this.init.type === 5 || this.init.specialMode){
|
|
||||||
return '<span class="deficon icon-' + this.init.icon + '"></span>'
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
},
|
|
||||||
// 获取窗口按钮
|
|
||||||
getBtns: function(){
|
|
||||||
if(this.init.type > 3){
|
|
||||||
return ''
|
|
||||||
}else{
|
|
||||||
var html = '<div class="layer-btns do-fn-noselect">';
|
|
||||||
if(this.init.type > 1){
|
|
||||||
html += '<a href="javascript:;" class="action-no" '
|
|
||||||
+ ':click="no(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[1]"></a>'
|
|
||||||
+ '<a href="javascript:;" class="action-yes" '
|
|
||||||
+ ':click="yes(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[0]"></a>'
|
|
||||||
}else{
|
|
||||||
html += '<a href="javascript:;" class="action-yes" '
|
|
||||||
+ ':click="yes(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[0]"></a>'
|
|
||||||
}
|
|
||||||
html += '</div>'
|
|
||||||
|
|
||||||
return html
|
|
||||||
}
|
|
||||||
},
|
|
||||||
append: function(){
|
|
||||||
//如果有已经打开的弹窗,则关闭
|
|
||||||
if(unique){
|
|
||||||
__layer.close(unique)
|
|
||||||
}
|
|
||||||
if(this.init.type < 4){
|
|
||||||
unique = this.init.$id
|
|
||||||
}
|
|
||||||
layerDom[this.init.$id] = this.create()
|
|
||||||
if(layerDom[this.init.$id][0]){
|
|
||||||
document.body.appendChild(layerDom[this.init.$id][0])
|
|
||||||
//仅在允许点击遮罩时,初始化控制器,减少资源消耗
|
|
||||||
if(this.init.shadeClose){
|
|
||||||
yua.define(this.cInit)
|
|
||||||
yua.scan(layerDom[this.init.$id][0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.appendChild(layerDom[this.init.$id][1])
|
|
||||||
yua.define(this.init)
|
|
||||||
yua.scan(layerDom[this.init.$id][1])
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
show: function(){
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
var style = {visibility: '', background: _this.init.background},
|
|
||||||
css = getComputedStyle(layerDom[_this.init.$id][1]);
|
|
||||||
|
|
||||||
if(_this.init.type === 5){
|
|
||||||
style.color = _this.init.color
|
|
||||||
|
|
||||||
var $elem = yua(_this.init.$elem),
|
|
||||||
ew = $elem.innerWidth(),
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft,
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop;
|
|
||||||
|
|
||||||
style.left = ol + (ew * 0.7)
|
|
||||||
style.top = ot - parseInt(css.height) - 8
|
|
||||||
|
|
||||||
}else{
|
|
||||||
if(_this.init.offset){
|
|
||||||
style.top = fixOffset(_this.init.offset[0])
|
|
||||||
style.right = fixOffset(_this.init.offset[1])
|
|
||||||
style.bottom = fixOffset(_this.init.offset[2])
|
|
||||||
style.left = fixOffset(_this.init.offset[3])
|
|
||||||
}else{
|
|
||||||
style = yua.mix(style, {
|
|
||||||
marginLeft: -parseInt(css.width) / 2,
|
|
||||||
marginTop: -parseInt(css.height) / 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yua(layerDom[_this.init.$id][1]).css(style)
|
|
||||||
|
|
||||||
}, 4)
|
|
||||||
|
|
||||||
|
|
||||||
if(this.init.success && typeof this.init.success === 'function'){
|
|
||||||
//弹窗成功的回调
|
|
||||||
this.init.success(this.init.$id)
|
|
||||||
}
|
|
||||||
// loading类型,回调需要自动触发
|
|
||||||
if(this.init.type > 3) {
|
|
||||||
//大于0自动触发超时关闭
|
|
||||||
if(this.init.timeout > 0){
|
|
||||||
clearTimeout(this.timeout)
|
|
||||||
this.timeout = setTimeout(function(){
|
|
||||||
|
|
||||||
clearTimeout(_this.timeout)
|
|
||||||
__layer.close(_this.init.$id)
|
|
||||||
|
|
||||||
// 为loading类型时,自动关闭同时触发回调
|
|
||||||
if(_this.init.type === 6){
|
|
||||||
_this.init.yes(_this.init.$id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}, this.init.timeout)
|
|
||||||
|
|
||||||
} else if(this.init.type === 6) {
|
|
||||||
// loading类型, 非自动关闭时, 主动触发回调
|
|
||||||
this.init.yes(this.init.$id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
ready: function(conf){
|
|
||||||
this.init = yua.mix({}, defconf, conf)
|
|
||||||
if(!this.init.$id){
|
|
||||||
this.init.$id = uuid();
|
|
||||||
}
|
|
||||||
if(this.init.icon > 17){
|
|
||||||
this.icon.icon = 17
|
|
||||||
}
|
|
||||||
//base版没有iframe类型
|
|
||||||
if(this.init.type === 4){
|
|
||||||
this.icon.type = 7
|
|
||||||
}
|
|
||||||
this.cInit = {
|
|
||||||
$id: this.init.$id + '-c',
|
|
||||||
close: this.init.shadeClose ? close : yua.noop
|
|
||||||
};
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
yua.directive('layer', {
|
|
||||||
priority: 1400,
|
|
||||||
init: function(binding){
|
|
||||||
if(!binding.param){
|
|
||||||
binding.element.style.display = 'none'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: function(val){
|
|
||||||
if(!val){
|
|
||||||
return console.error(new Error(':layer指令格式不正确或无效属性. [' + this.name + '="' + this.expr) + '"]')
|
|
||||||
}
|
|
||||||
|
|
||||||
var _this = this,
|
|
||||||
init = Object.assign({}, this.element.dataset);
|
|
||||||
|
|
||||||
if(!this.param){
|
|
||||||
init.type = 7;
|
|
||||||
init.$id = '$wrap-' + val;
|
|
||||||
if(!init.hasOwnProperty('menubar')){
|
|
||||||
init.menubar = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = new __constructor().ready(init);
|
|
||||||
|
|
||||||
tmp.init.content = this.element.cloneNode(true);
|
|
||||||
|
|
||||||
layerObj[tmp.init.$id] = {obj: tmp, parentElem: this.element.parentNode, wrap: this.element, show: false};
|
|
||||||
layerDom[tmp.init.$id] = tmp.create();
|
|
||||||
}else if(this.param === 'tips'){
|
|
||||||
var $elem = yua(this.element),
|
|
||||||
ew = $elem.innerWidth(),
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft,
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop,
|
|
||||||
tipsBox = document.createElement('div'),
|
|
||||||
tipsArrow = document.createElement('i'),
|
|
||||||
tipsCont = document.createElement('div');
|
|
||||||
|
|
||||||
|
|
||||||
tipsBox.className = 'do-layer skin-def type-5'
|
|
||||||
tipsBox.style.left = ol + (ew * 0.7) + 'px'
|
|
||||||
if(init.background){
|
|
||||||
tipsBox.style.background = init.background
|
|
||||||
tipsArrow.style.borderTopColor = init.background
|
|
||||||
}
|
|
||||||
if(init.color){
|
|
||||||
tipsBox.style.color = init.color
|
|
||||||
}
|
|
||||||
tipsCont.className = 'layer-content'
|
|
||||||
tipsCont.textContent = val
|
|
||||||
tipsArrow.className = 'arrow'
|
|
||||||
tipsBox.appendChild(tipsCont)
|
|
||||||
tipsBox.appendChild(tipsArrow)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yua(document).bind('scroll', function(){
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft;
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop;
|
|
||||||
|
|
||||||
tipsBox.style.left = ol + (ew * 0.7) + 'px'
|
|
||||||
tipsBox.style.top = (ot - tipsBox.offsetHeight - 8) + 'px'
|
|
||||||
})
|
|
||||||
|
|
||||||
$elem.bind('mouseenter', function(ev){
|
|
||||||
_this.element.parentNode.appendChild(tipsBox)
|
|
||||||
clearTimeout(_this.showTime)
|
|
||||||
clearTimeout(_this.hideTime)
|
|
||||||
_this.showTime = setTimeout(function(){
|
|
||||||
tipsBox.style.top = (ot - tipsBox.offsetHeight - 8) + 'px'
|
|
||||||
tipsBox.classList.add('active')
|
|
||||||
|
|
||||||
}, 4)
|
|
||||||
|
|
||||||
})
|
|
||||||
$elem.bind('mouseleave', function(){
|
|
||||||
_this.hideTime = setTimeout(function(){
|
|
||||||
clearTimeout(_this.hideTime)
|
|
||||||
try{
|
|
||||||
_this.element.parentNode.removeChild(tipsBox)
|
|
||||||
}catch(err){}
|
|
||||||
}, 150)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!window.layer)
|
|
||||||
window.layer = __layer
|
|
||||||
|
|
||||||
|
|
||||||
return __layer
|
|
||||||
|
|
||||||
})
|
|
|
@ -1,578 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-09-21 01:36:29
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
|
||||||
|
|
||||||
|
|
||||||
var layerDom = {},
|
|
||||||
layerObj = {},
|
|
||||||
unique = null, //储存当前打开的1/2/3类型的弹窗
|
|
||||||
lid = 0,
|
|
||||||
defconf = {
|
|
||||||
type: 1, // 弹窗类型
|
|
||||||
skin: 'def', //默认主题
|
|
||||||
icon: 1, //图标类型
|
|
||||||
background: '#fff',
|
|
||||||
shade: true, //遮罩
|
|
||||||
shadeClose: false, //遮罩点击关闭弹窗
|
|
||||||
radius: '0px', //弹窗圆角半径
|
|
||||||
area: ['auto', 'auto'],
|
|
||||||
title: '', //弹窗主标题(在工具栏上的)
|
|
||||||
menubar: true, //是否显示菜单栏
|
|
||||||
content: '', // 弹窗的内容
|
|
||||||
fixed: false, //是否固定不可拖拽
|
|
||||||
offset: null, //弹窗出来时的坐标, 为数组,可有4个值,依次是 上右下左
|
|
||||||
btns: ['确定', '取消'], //弹窗的2个按钮的文字
|
|
||||||
yes: close, //确定按钮对应的回调
|
|
||||||
no: close, //取消按钮对应的回调
|
|
||||||
success: null //弹窗初始化完成时的回调
|
|
||||||
};
|
|
||||||
|
|
||||||
function uuid(){
|
|
||||||
return 'layer-' + (++lid)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function close(id){
|
|
||||||
if(typeof id !== 'string' && typeof id !== 'number'){
|
|
||||||
return console.error(new Error('要关闭的layer实例不存在'))
|
|
||||||
}
|
|
||||||
if(/^\$wrap\-/.test(id) || layerObj['$wrap-' + id]){
|
|
||||||
|
|
||||||
try {
|
|
||||||
id = (layerObj['$wrap-' + id] ? '$wrap-' : '') + id;
|
|
||||||
//未显示过,忽略
|
|
||||||
if(!layerObj[id].show){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
layerObj[id].parentElem.replaceChild(layerObj[id].wrap, layerDom[id][1])
|
|
||||||
unique = null
|
|
||||||
}catch(err){}
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
document.body.removeChild(layerDom[id][1])
|
|
||||||
document.body.removeChild(layerDom[id][0])
|
|
||||||
unique = null
|
|
||||||
}catch(err){}
|
|
||||||
|
|
||||||
delete layerDom[id]
|
|
||||||
delete yua.vmodels[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function reapeat(str, num){
|
|
||||||
var idx = 0,
|
|
||||||
result = ''
|
|
||||||
while(idx < num){
|
|
||||||
result += str
|
|
||||||
idx++
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixOffset(val){
|
|
||||||
if(!val && val !== 0){
|
|
||||||
return 'auto'
|
|
||||||
}else{
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var __constructor = function(conf){
|
|
||||||
if(conf){
|
|
||||||
this.ready(conf).append().show()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
__layer = {
|
|
||||||
alert: function(msg, conf){
|
|
||||||
if(typeof conf === 'function'){
|
|
||||||
conf = {yes: conf}
|
|
||||||
}else if(typeof conf === 'object'){
|
|
||||||
conf = conf
|
|
||||||
}else{
|
|
||||||
conf = {}
|
|
||||||
}
|
|
||||||
conf.icon = 6
|
|
||||||
conf.content = msg
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
confirm: function(msg, conf){
|
|
||||||
if(typeof conf === 'function'){
|
|
||||||
conf = {yes: conf}
|
|
||||||
}else if(typeof conf === 'object'){
|
|
||||||
conf = conf
|
|
||||||
}else{
|
|
||||||
conf = {}
|
|
||||||
}
|
|
||||||
conf.type = 2
|
|
||||||
conf.icon = 8
|
|
||||||
conf.content = msg
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
msg: function(msg, conf){
|
|
||||||
if(typeof conf !== 'object'){
|
|
||||||
var tmp = conf
|
|
||||||
conf = {timeout: 2500}
|
|
||||||
if(typeof tmp === 'number'){
|
|
||||||
conf.icon = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!conf.hasOwnProperty('timeout')){
|
|
||||||
conf.timeout = 2500
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.specialMode = true;//特殊模式
|
|
||||||
conf.content = '<p class="msg-box">' + msg + '</p>'
|
|
||||||
conf.type = 7
|
|
||||||
conf.fixed = true
|
|
||||||
conf.shade = false
|
|
||||||
conf.menubar = false
|
|
||||||
conf.radius = '5px'
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
loading: function(style, time, cb){
|
|
||||||
style = style >>> 0
|
|
||||||
|
|
||||||
if(typeof time === 'function'){
|
|
||||||
cb = time;
|
|
||||||
time = 0
|
|
||||||
} else{
|
|
||||||
time = time >>> 0
|
|
||||||
if(typeof cb !== 'function'){
|
|
||||||
cb = yua.noop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __layer.open({type: 6, load: style, yes: cb, timeout: time, menubar: false, background: 'none', fixed: true})
|
|
||||||
},
|
|
||||||
tips: function(msg, elem, conf){
|
|
||||||
if(!(elem instanceof HTMLElement)){
|
|
||||||
return console.error(new Error('tips类型必须指定一个目标容器'))
|
|
||||||
}
|
|
||||||
if(typeof conf !== 'object'){
|
|
||||||
var tmp = conf
|
|
||||||
conf = {timeout: 2500}
|
|
||||||
if(typeof tmp === 'number'){
|
|
||||||
conf.icon = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!conf.hasOwnProperty('timeout')){
|
|
||||||
conf.timeout = 2500
|
|
||||||
}
|
|
||||||
if(!conf.background){
|
|
||||||
conf.background = 'rgba(0,0,0,.5)'
|
|
||||||
}
|
|
||||||
if(!conf.color){
|
|
||||||
conf.color = '#fff'
|
|
||||||
}
|
|
||||||
conf.$elem = elem
|
|
||||||
conf.content = msg
|
|
||||||
conf.type = 5;
|
|
||||||
conf.icon = 0;
|
|
||||||
conf.fixed = true;
|
|
||||||
conf.shade = false;
|
|
||||||
conf.menubar = false;
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
prompt: function(msg, callback){
|
|
||||||
if(typeof callback !== 'function'){
|
|
||||||
return console.error('argument [callback] requires a function, but ' + (typeof callback) + ' given')
|
|
||||||
}
|
|
||||||
var conf = {
|
|
||||||
type: 3,
|
|
||||||
icon: 7,
|
|
||||||
prompt: '',
|
|
||||||
title: msg,
|
|
||||||
content: '<input class="prompt-value" :duplex="prompt" />',
|
|
||||||
yes: function(id){
|
|
||||||
callback(id, yua.vmodels[id].prompt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return __layer.open(conf)
|
|
||||||
},
|
|
||||||
use: function(skin, callback){
|
|
||||||
require(['css!./skin/' + skin], callback)
|
|
||||||
},
|
|
||||||
close: close,
|
|
||||||
open: function(conf){
|
|
||||||
if(typeof conf === 'string'){
|
|
||||||
conf = '$wrap-' + conf
|
|
||||||
if(!layerObj[conf]){
|
|
||||||
throw new Error('layer实例不存在')
|
|
||||||
}else{
|
|
||||||
//只能显示一个实例
|
|
||||||
if(layerObj[conf].show){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
layerObj[conf].show = true
|
|
||||||
|
|
||||||
if(!yua.vmodels[conf]){
|
|
||||||
yua.define(layerObj[conf].obj.init)
|
|
||||||
}
|
|
||||||
|
|
||||||
yua.scan(layerDom[conf][1])
|
|
||||||
layerObj[conf].obj.show()
|
|
||||||
|
|
||||||
layerObj[conf].parentElem.appendChild(layerDom[conf][1])
|
|
||||||
layerObj[conf].parentElem.replaceChild(layerDom[conf][1], layerObj[conf].wrap)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return new __constructor(conf).init.$id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
version: '0.0.1-base'
|
|
||||||
};
|
|
||||||
|
|
||||||
/*type: { // 弹窗类型对应的id值
|
|
||||||
1: 'alert',
|
|
||||||
2: 'confirm',
|
|
||||||
3: 'prompt',
|
|
||||||
4: 'iframe',
|
|
||||||
5: 'tips',
|
|
||||||
6: 'loading',
|
|
||||||
7: 'msg',
|
|
||||||
}*/
|
|
||||||
__constructor.prototype = {
|
|
||||||
dot: { //loading的子元素数量
|
|
||||||
0: 4,
|
|
||||||
1: 9,
|
|
||||||
2: 2,
|
|
||||||
3: 3,
|
|
||||||
4: 2,
|
|
||||||
5: 5,
|
|
||||||
6: 5,
|
|
||||||
7: 5
|
|
||||||
},
|
|
||||||
timeout: null,
|
|
||||||
create: function(){
|
|
||||||
var layBox = document.createElement('div'),
|
|
||||||
coverBox = document.createElement('div');
|
|
||||||
|
|
||||||
coverBox.className = 'do-layer-cover type-' + this.init.type
|
|
||||||
// 允许点击遮罩关闭弹层时, 添加控制器
|
|
||||||
if(this.init.shadeClose){
|
|
||||||
coverBox.setAttribute(':controller', this.cInit.$id)
|
|
||||||
coverBox.setAttribute(':click', 'close(\'' + this.init.$id + '\')')
|
|
||||||
}
|
|
||||||
|
|
||||||
layBox.className = 'do-layer skin-'
|
|
||||||
+ this.init.skin
|
|
||||||
+ (this.init.type === 5 && ' active' || '')
|
|
||||||
+ ' type-'
|
|
||||||
+ ((!this.init.specialMode && this.init.type === 7) ? 'unspecial' : this.init.type);
|
|
||||||
|
|
||||||
//暂时隐藏,避免修正定位时,能看到闪一下
|
|
||||||
layBox.style.visibility = 'hidden'
|
|
||||||
layBox.style.borderRadius = this.init.radius
|
|
||||||
|
|
||||||
layBox.setAttribute(':controller', this.init.$id)
|
|
||||||
|
|
||||||
//没有菜单栏, 且未禁止拖拽,则加上可拖拽属性
|
|
||||||
if(!this.init.menubar && !this.init.fixed){
|
|
||||||
layBox.setAttribute(':drag', '')
|
|
||||||
layBox.setAttribute('data-limit', 'window')
|
|
||||||
}
|
|
||||||
|
|
||||||
//弹窗的宽高
|
|
||||||
var boxcss = ''
|
|
||||||
if(this.init.area[0] !== 'auto'){
|
|
||||||
boxcss += 'width: ' + this.init.area[0] + ';'
|
|
||||||
}
|
|
||||||
if(this.init.area[1] !== 'auto'){
|
|
||||||
boxcss += 'height: ' + this.init.area[1] + ';'
|
|
||||||
}
|
|
||||||
|
|
||||||
layBox.innerHTML = this.getMenubar()
|
|
||||||
+ '<div class="layer-content do-fn-cl '
|
|
||||||
+ (this.init.icon === 0 && 'none-icon' || '')
|
|
||||||
+ '" style="'
|
|
||||||
+ boxcss
|
|
||||||
+ '">'
|
|
||||||
+ this.getCont()
|
|
||||||
+ '</div>'
|
|
||||||
+ this.getBtns()
|
|
||||||
+ (this.init.type === 5 && '<i class="arrow" style="border-top-color: '
|
|
||||||
+ this.init.background
|
|
||||||
+ '"></i>' || '')
|
|
||||||
|
|
||||||
return [this.init.shade ? coverBox : null, layBox]
|
|
||||||
},
|
|
||||||
getCont: function(){
|
|
||||||
if(this.init.type === 6){
|
|
||||||
return this.getLoading(this.init.load)
|
|
||||||
}else{
|
|
||||||
return this.getIcon()
|
|
||||||
+ '<div class="detail" :html="content"></div>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getLoading: function(style){
|
|
||||||
return '<div class="do-ui-load load-style-'
|
|
||||||
+ style
|
|
||||||
+ '">'
|
|
||||||
+ '<span class="dot-box">'
|
|
||||||
+ reapeat('<i></i>', this.dot[style])
|
|
||||||
+ '</span>'
|
|
||||||
+ '</div>'
|
|
||||||
},
|
|
||||||
//获取窗口导航条
|
|
||||||
getMenubar: function(){
|
|
||||||
var html = ''
|
|
||||||
if(this.init.menubar){
|
|
||||||
html += '<div class="layer-title do-fn-noselect" ';
|
|
||||||
//可拖拽
|
|
||||||
if(!this.init.fixed){
|
|
||||||
html += ':drag="do-layer" data-limit="window" '
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '>{{title}}'
|
|
||||||
+ '<a class="action-close deficon" :click="no(\'' + this.init.$id + '\')"></a>'
|
|
||||||
+ '</div>'
|
|
||||||
}
|
|
||||||
return html
|
|
||||||
},
|
|
||||||
//获取窗口内容的图标
|
|
||||||
getIcon: function(){
|
|
||||||
if(this.init.icon === 0){
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
if(this.init.type < 4 || this.init.type === 5 || this.init.specialMode){
|
|
||||||
return '<span class="deficon icon-' + this.init.icon + '"></span>'
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
},
|
|
||||||
// 获取窗口按钮
|
|
||||||
getBtns: function(){
|
|
||||||
if(this.init.type > 3){
|
|
||||||
return ''
|
|
||||||
}else{
|
|
||||||
var html = '<div class="layer-btns do-fn-noselect">';
|
|
||||||
if(this.init.type > 1){
|
|
||||||
html += '<a href="javascript:;" class="action-no" '
|
|
||||||
+ ':click="no(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[1]"></a>'
|
|
||||||
+ '<a href="javascript:;" class="action-yes" '
|
|
||||||
+ ':click="yes(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[0]"></a>'
|
|
||||||
}else{
|
|
||||||
html += '<a href="javascript:;" class="action-yes" '
|
|
||||||
+ ':click="yes(\'' + this.init.$id + '\')" '
|
|
||||||
+ ':text="btns[0]"></a>'
|
|
||||||
}
|
|
||||||
html += '</div>'
|
|
||||||
|
|
||||||
return html
|
|
||||||
}
|
|
||||||
},
|
|
||||||
append: function(){
|
|
||||||
//如果有已经打开的弹窗,则关闭
|
|
||||||
if(unique){
|
|
||||||
__layer.close(unique)
|
|
||||||
}
|
|
||||||
if(this.init.type < 4){
|
|
||||||
unique = this.init.$id
|
|
||||||
}
|
|
||||||
layerDom[this.init.$id] = this.create()
|
|
||||||
if(layerDom[this.init.$id][0]){
|
|
||||||
document.body.appendChild(layerDom[this.init.$id][0])
|
|
||||||
//仅在允许点击遮罩时,初始化控制器,减少资源消耗
|
|
||||||
if(this.init.shadeClose){
|
|
||||||
yua.define(this.cInit)
|
|
||||||
yua.scan(layerDom[this.init.$id][0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.appendChild(layerDom[this.init.$id][1])
|
|
||||||
yua.define(this.init)
|
|
||||||
yua.scan(layerDom[this.init.$id][1])
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
show: function(){
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
var style = {visibility: '', background: _this.init.background},
|
|
||||||
css = getComputedStyle(layerDom[_this.init.$id][1]);
|
|
||||||
|
|
||||||
if(_this.init.type === 5){
|
|
||||||
style.color = _this.init.color
|
|
||||||
|
|
||||||
var $elem = yua(_this.init.$elem),
|
|
||||||
ew = $elem.innerWidth(),
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft,
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop;
|
|
||||||
|
|
||||||
style.left = ol + (ew * 0.7)
|
|
||||||
style.top = ot - parseInt(css.height) - 8
|
|
||||||
|
|
||||||
}else{
|
|
||||||
if(_this.init.offset){
|
|
||||||
style.top = fixOffset(_this.init.offset[0])
|
|
||||||
style.right = fixOffset(_this.init.offset[1])
|
|
||||||
style.bottom = fixOffset(_this.init.offset[2])
|
|
||||||
style.left = fixOffset(_this.init.offset[3])
|
|
||||||
}else{
|
|
||||||
style = yua.mix(style, {
|
|
||||||
marginLeft: -parseInt(css.width) / 2,
|
|
||||||
marginTop: -parseInt(css.height) / 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yua(layerDom[_this.init.$id][1]).css(style)
|
|
||||||
|
|
||||||
}, 4)
|
|
||||||
|
|
||||||
|
|
||||||
if(this.init.success && typeof this.init.success === 'function'){
|
|
||||||
//弹窗成功的回调
|
|
||||||
this.init.success(this.init.$id)
|
|
||||||
}
|
|
||||||
// loading类型,回调需要自动触发
|
|
||||||
if(this.init.type > 3) {
|
|
||||||
//大于0自动触发超时关闭
|
|
||||||
if(this.init.timeout > 0){
|
|
||||||
clearTimeout(this.timeout)
|
|
||||||
this.timeout = setTimeout(function(){
|
|
||||||
|
|
||||||
clearTimeout(_this.timeout)
|
|
||||||
__layer.close(_this.init.$id)
|
|
||||||
|
|
||||||
// 为loading类型时,自动关闭同时触发回调
|
|
||||||
if(_this.init.type === 6){
|
|
||||||
_this.init.yes(_this.init.$id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}, this.init.timeout)
|
|
||||||
|
|
||||||
} else if(this.init.type === 6) {
|
|
||||||
// loading类型, 非自动关闭时, 主动触发回调
|
|
||||||
this.init.yes(this.init.$id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
ready: function(conf){
|
|
||||||
this.init = yua.mix({}, defconf, conf)
|
|
||||||
if(!this.init.$id){
|
|
||||||
this.init.$id = uuid();
|
|
||||||
}
|
|
||||||
if(this.init.icon > 17){
|
|
||||||
this.icon.icon = 17
|
|
||||||
}
|
|
||||||
//base版没有iframe类型
|
|
||||||
if(this.init.type === 4){
|
|
||||||
this.icon.type = 7
|
|
||||||
}
|
|
||||||
this.cInit = {
|
|
||||||
$id: this.init.$id + '-c',
|
|
||||||
close: this.init.shadeClose ? close : yua.noop
|
|
||||||
};
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
yua.directive('layer', {
|
|
||||||
priority: 1400,
|
|
||||||
init: function(binding){
|
|
||||||
if(!binding.param){
|
|
||||||
binding.element.style.display = 'none'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: function(val){
|
|
||||||
if(!val){
|
|
||||||
return console.error(new Error(':layer指令格式不正确或无效属性. [' + this.name + '="' + this.expr) + '"]')
|
|
||||||
}
|
|
||||||
|
|
||||||
var _this = this,
|
|
||||||
init = Object.assign({}, this.element.dataset);
|
|
||||||
|
|
||||||
if(!this.param){
|
|
||||||
init.type = 7;
|
|
||||||
init.$id = '$wrap-' + val;
|
|
||||||
if(!init.hasOwnProperty('menubar')){
|
|
||||||
init.menubar = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = new __constructor().ready(init);
|
|
||||||
|
|
||||||
tmp.init.content = this.element.cloneNode(true);
|
|
||||||
|
|
||||||
layerObj[tmp.init.$id] = {obj: tmp, parentElem: this.element.parentNode, wrap: this.element, show: false};
|
|
||||||
layerDom[tmp.init.$id] = tmp.create();
|
|
||||||
}else if(this.param === 'tips'){
|
|
||||||
var $elem = yua(this.element),
|
|
||||||
ew = $elem.innerWidth(),
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft,
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop,
|
|
||||||
tipsBox = document.createElement('div'),
|
|
||||||
tipsArrow = document.createElement('i'),
|
|
||||||
tipsCont = document.createElement('div');
|
|
||||||
|
|
||||||
|
|
||||||
tipsBox.className = 'do-layer skin-def type-5'
|
|
||||||
tipsBox.style.left = ol + (ew * 0.7) + 'px'
|
|
||||||
if(init.background){
|
|
||||||
tipsBox.style.background = init.background
|
|
||||||
tipsArrow.style.borderTopColor = init.background
|
|
||||||
}
|
|
||||||
if(init.color){
|
|
||||||
tipsBox.style.color = init.color
|
|
||||||
}
|
|
||||||
tipsCont.className = 'layer-content'
|
|
||||||
tipsCont.textContent = val
|
|
||||||
tipsArrow.className = 'arrow'
|
|
||||||
tipsBox.appendChild(tipsCont)
|
|
||||||
tipsBox.appendChild(tipsArrow)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yua(document).bind('scroll', function(){
|
|
||||||
ol = $elem.offset().left - document.body.scrollLeft;
|
|
||||||
ot = $elem.offset().top - document.body.scrollTop;
|
|
||||||
|
|
||||||
tipsBox.style.left = ol + (ew * 0.7) + 'px'
|
|
||||||
tipsBox.style.top = (ot - tipsBox.offsetHeight - 8) + 'px'
|
|
||||||
})
|
|
||||||
|
|
||||||
$elem.bind('mouseenter', function(ev){
|
|
||||||
_this.element.parentNode.appendChild(tipsBox)
|
|
||||||
clearTimeout(_this.showTime)
|
|
||||||
clearTimeout(_this.hideTime)
|
|
||||||
_this.showTime = setTimeout(function(){
|
|
||||||
tipsBox.style.top = (ot - tipsBox.offsetHeight - 8) + 'px'
|
|
||||||
tipsBox.classList.add('active')
|
|
||||||
|
|
||||||
}, 4)
|
|
||||||
|
|
||||||
})
|
|
||||||
$elem.bind('mouseleave', function(){
|
|
||||||
_this.hideTime = setTimeout(function(){
|
|
||||||
clearTimeout(_this.hideTime)
|
|
||||||
try{
|
|
||||||
_this.element.parentNode.removeChild(tipsBox)
|
|
||||||
}catch(err){}
|
|
||||||
}, 150)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!window.layer)
|
|
||||||
window.layer = __layer
|
|
||||||
|
|
||||||
|
|
||||||
return __layer
|
|
||||||
|
|
||||||
})
|
|
|
@ -6,22 +6,28 @@
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "../../../../css/var.scss";
|
@import "var.scss";
|
||||||
|
|
||||||
|
|
||||||
.do-layer {position:fixed;left:50%;top:50%;z-index:65535;width:auto;height:auto;
|
.do-layer {width:auto;height:auto;
|
||||||
|
|
||||||
|
&.mask {position:fixed;z-index:65534;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.3);}
|
||||||
|
|
||||||
a {text-decoration:none;}
|
a {text-decoration:none;}
|
||||||
|
|
||||||
/* 默认皮肤 */
|
.layer-box {position:absolute;left:50%;top:50%;z-index:65535;
|
||||||
&.skin-def {color:#666;font-size:14px;box-shadow:0 0 10px rgba(0,0,0,.3);
|
|
||||||
|
|
||||||
.icon-0::before {content:"\e62e";color:nth($cr, 1);} // question
|
&.scale {transform:scale(1.02);transition:transform .1s linear;}
|
||||||
|
|
||||||
|
/* 默认皮肤 */
|
||||||
|
&.skin-def {padding:15px 10px;border-radius:3px;color:#666;font-size:14px;box-shadow:0 5px 20px rgba(0,0,0,.3);
|
||||||
|
|
||||||
|
.icon-0::before {content:"\e674";color:nth($cr, 1);} // question
|
||||||
.icon-1::before {content:"\e610";color:nth($ct, 1);} // get
|
.icon-1::before {content:"\e610";color:nth($ct, 1);} // get
|
||||||
.icon-2::before {content:"\e6f8";color:nth($cb, 1);} // happy
|
.icon-2::before {content:"\e6f8";color:nth($cb, 1);} // happy
|
||||||
.icon-3::before {content:"\e6fd";color:nth($co, 1);} // sad
|
.icon-3::before {content:"\e6fd";color:nth($co, 1);} // sad
|
||||||
.icon-4::before {content:"\e6f6";color:nth($co, 1);} // warn
|
.icon-4::before {content:"\e6f6";color:nth($co, 1);} // warn
|
||||||
.icon-5::before {content:"\e630";color:nth($ct, 1);} // face
|
.icon-5::before {content:"\e673";color:nth($ct, 1);} // face
|
||||||
.icon-6::before {content:"\e636";color:nth($cgr, 1);} // time
|
.icon-6::before {content:"\e636";color:nth($cgr, 1);} // time
|
||||||
.icon-7::before {content:"\e623";color:nth($co, 1);} // star
|
.icon-7::before {content:"\e623";color:nth($co, 1);} // star
|
||||||
.icon-8::before {content:"\e604";color:nth($cr, 1);} // mute
|
.icon-8::before {content:"\e604";color:nth($cr, 1);} // mute
|
||||||
|
@ -29,25 +35,13 @@
|
||||||
|
|
||||||
|
|
||||||
/* 弹层标题栏 */
|
/* 弹层标题栏 */
|
||||||
.layer-title {width:100%;height:43px;padding:0 8px;line-height:43px;background:#f5f5f5;font-size:16px;color:nth($cgr, 1);}
|
.layer-title {width:100%;height:43px;padding:0 10px;line-height:43px;font-size:16px;color:nth($cgr, 1);}
|
||||||
|
|
||||||
.action-min,
|
|
||||||
.action-close {position:absolute;display:block;top:12px;width:20px;height:20px;line-height:20px;font-size:14px;text-align:center;cursor:pointer;color:nth($cgr, 2);
|
|
||||||
|
|
||||||
&:hover {color:nth($ct, 1);}
|
|
||||||
}
|
|
||||||
.action-min {right:40px;
|
|
||||||
&::before {content:"\e634"}
|
|
||||||
}
|
|
||||||
.action-close {right:10px;
|
|
||||||
&::before {content:"\e687"}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 弹层主体内容 */
|
/* 弹层主体内容 */
|
||||||
.layer-content {position:relative;width:100%;height:auto;min-height:50px;padding:10px;
|
.layer-content {position:relative;width:100%;height:auto;min-height:50px;padding:10px;
|
||||||
|
|
||||||
.msg-icon {position:absolute;left:10px;top:10px;width:50px;height:auto;line-height:40px;font-size:35px;text-align:center;}
|
.msg-icon {position:absolute;left:10px;top:10px;width:50px;height:auto;line-height:40px;font-size:35px;text-align:center;}
|
||||||
.detail {width:auto;height:100%;margin:auto auto auto 60px;padding:5px 15px;word-break:break-all;word-wrap: break-word;
|
.detail {width:auto;height:100%;margin:auto auto auto 50px;padding:5px 15px;word-break:break-all;word-wrap: break-word;
|
||||||
|
|
||||||
.prompt-value {width: 230px;height: 30px;padding: 0 8px;border: 1px solid #ddd;border-radius: 3px;
|
.prompt-value {width: 230px;height: 30px;padding: 0 8px;border: 1px solid #ddd;border-radius: 3px;
|
||||||
|
|
||||||
|
@ -62,12 +56,16 @@
|
||||||
|
|
||||||
|
|
||||||
/* 弹层按钮部分 */
|
/* 弹层按钮部分 */
|
||||||
.layer-btns {width:100%;height:40px;padding:0 5px;line-height:30px;font-size:14px;color:#454545;text-align:right;
|
.layer-ctrl {width:100%;height:40px;padding:5px 0;line-height:30px;font-size:14px;color:#454545;text-align:right;
|
||||||
|
|
||||||
a {display:inline-block;width:auto;min-width:60px;height:30px;margin:0 5px;padding:0 10px;color:nth($cgr, 1);text-align:center;background:nth($cp, 1);@include ts();
|
a {overflow:hidden;position:relative;display:inline-block;width:auto;min-width:60px;height:30px;margin-left:5px;padding:0 10px;color:nth($ct, 1);text-align:center;
|
||||||
|
|
||||||
&:hover {background:nth($cp, 2)}
|
&::before {position:absolute;left:-50%;top:-50%;z-index:-1;display:block;width:200%;height:200%;border-radius:50%;background:nth($cp, 2); content:"";opacity:0;transform: scale(0, .0); transition:opacity 1.3s cubic-bezier(0.23, 1, 0.32, 1),transform 1.3s cubic-bezier(0.23, 1, 0.32, 1);}
|
||||||
&:active {background:nth($cp, 3)}
|
|
||||||
|
&:hover {
|
||||||
|
&::before {opacity:1;transform:scale(1, .8);}
|
||||||
|
}
|
||||||
|
&:active {background:nth($cp, 1)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +74,7 @@
|
||||||
/* ;alert/confirm/prompt 3类弹层 */
|
/* ;alert/confirm/prompt 3类弹层 */
|
||||||
&.type-1,
|
&.type-1,
|
||||||
&.type-2,
|
&.type-2,
|
||||||
&.type-3 {max-width:600px;min-width:230px;}
|
&.type-3 {max-width:600px;min-width:300px;}
|
||||||
|
|
||||||
|
|
||||||
/* tips类弹层(type 5) */
|
/* tips类弹层(type 5) */
|
||||||
|
@ -178,9 +176,15 @@
|
||||||
|
|
||||||
&:active {z-index:65536;}
|
&:active {z-index:65536;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.do-layer-cover {position:fixed;left:0;top:0;z-index:65534;width:100%;height:100%;background:rgba(255,255,255,.05);
|
.do-layer-cover {
|
||||||
|
|
||||||
&.type-6 {background:rgba(0,0,0,.3);}
|
&.type-6 {background:rgba(0,0,0,.3);}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -5,101 +5,107 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
'use strict'
|
||||||
|
import 'layer/base'
|
||||||
|
|
||||||
define(['lib/layer/base'], function(){
|
function objArr(num) {
|
||||||
|
|
||||||
function objArr(num){
|
|
||||||
var arr = []
|
var arr = []
|
||||||
while(num > 0){
|
while (num > 0) {
|
||||||
arr.push({v: 0})
|
arr.push({ v: 0 })
|
||||||
num--
|
num--
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
function trim(str, sign){
|
function trim(str, sign) {
|
||||||
return str.replace(new RegExp('^' + sign + '|' + sign + '$', 'g'), '')
|
return str.replace(new RegExp('^' + sign + '|' + sign + '$', 'g'), '')
|
||||||
}
|
}
|
||||||
function getOrderArr(len){
|
function getOrderArr(len) {
|
||||||
var arr = [], i = 0;
|
var arr = [],
|
||||||
while(i < len){
|
i = 0
|
||||||
|
while (i < len) {
|
||||||
arr.push(i++)
|
arr.push(i++)
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
ME.addon = {
|
const addon = {
|
||||||
h1: function(elem, vm){
|
h1: function(elem, vm) {
|
||||||
var offset = yua(elem).offset(),
|
var offset = Anot(elem).offset(),
|
||||||
wrap = ME.selection(vm.$editor, true) || '在此输入文本',
|
wrap = ME.selection(vm.$editor, true) || '在此输入文本',
|
||||||
h1ID = layer.open({
|
h1ID = layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
menubar: false,
|
menubar: false,
|
||||||
shadeClose: true,
|
shadeClose: true,
|
||||||
fixed: true,
|
fixed: true,
|
||||||
$insert: function(level){
|
$insert: function(level) {
|
||||||
wrap = wrap.replace(/^#{1,6} /, '')
|
wrap = wrap.replace(/^#{1,6} /, '')
|
||||||
wrap = ME.repeat('#', level) + ' ' + wrap
|
wrap = ME.repeat('#', level) + ' ' + wrap
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
layer.close(h1ID)
|
layer.close(h1ID)
|
||||||
},
|
},
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop(), 'auto', 'auto', offset.left - ME.doc.scrollLeft()],
|
offset: [
|
||||||
content: '<ul class="do-meditor-h1 do-fn-noselect do-meditor-font">'
|
offset.top + 37 - ME.doc.scrollTop(),
|
||||||
+ '<li :click="$insert(1)" class="h1">一级标题</li>'
|
'auto',
|
||||||
+ '<li :click="$insert(2)" class="h2">二级标题</li>'
|
'auto',
|
||||||
+ '<li :click="$insert(3)" class="h3">三级标题</li>'
|
offset.left - ME.doc.scrollLeft()
|
||||||
+ '<li :click="$insert(4)" class="h4">四级标题</li>'
|
],
|
||||||
+ '<li :click="$insert(5)" class="h5">五级标题</li>'
|
content:
|
||||||
+ '<li :click="$insert(6)" class="h6">六级标题</li>'
|
'<ul class="do-meditor-h1 do-fn-noselect do-meditor-font">' +
|
||||||
+ '</ul>'
|
'<li :click="$insert(1)" class="h1">一级标题</li>' +
|
||||||
|
'<li :click="$insert(2)" class="h2">二级标题</li>' +
|
||||||
|
'<li :click="$insert(3)" class="h3">三级标题</li>' +
|
||||||
|
'<li :click="$insert(4)" class="h4">四级标题</li>' +
|
||||||
|
'<li :click="$insert(5)" class="h5">五级标题</li>' +
|
||||||
|
'<li :click="$insert(6)" class="h6">六级标题</li>' +
|
||||||
|
'</ul>'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
quote: function(elem, vm){
|
quote: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
wrap = '> ' + wrap
|
wrap = '> ' + wrap
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
},
|
},
|
||||||
bold: function(elem, vm){
|
bold: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
wraped = trim(wrap, '\\*\\*')
|
wraped = trim(wrap, '\\*\\*')
|
||||||
|
|
||||||
wrap = wrap === wraped ? ('**' + wrap + '**') : wraped
|
wrap = wrap === wraped ? '**' + wrap + '**' : wraped
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
},
|
},
|
||||||
italic: function(elem, vm){
|
italic: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
wraped = trim(wrap, '_')
|
wraped = trim(wrap, '_')
|
||||||
|
|
||||||
wrap = wrap === wraped ? ('_' + wrap + '_') : wraped
|
wrap = wrap === wraped ? '_' + wrap + '_' : wraped
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
},
|
},
|
||||||
through: function(elem, vm){
|
through: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
wraped = trim(wrap, '~~')
|
wraped = trim(wrap, '~~')
|
||||||
|
|
||||||
wrap = wrap === wraped ? ('~~' + wrap + '~~') : wraped
|
wrap = wrap === wraped ? '~~' + wrap + '~~' : wraped
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
},
|
},
|
||||||
unordered: function(elem, vm){
|
unordered: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
wrap = '* ' + wrap
|
wrap = '* ' + wrap
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, false)
|
ME.insert(vm.$editor, wrap, false)
|
||||||
},
|
},
|
||||||
ordered: function(elem, vm){
|
ordered: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
wrap = '1. ' + wrap
|
wrap = '1. ' + wrap
|
||||||
|
|
||||||
ME.insert(vm.$editor, wrap, false)
|
ME.insert(vm.$editor, wrap, false)
|
||||||
},
|
},
|
||||||
hr: function(elem, vm){
|
hr: function(elem, vm) {
|
||||||
ME.insert(vm.$editor, '\n\n---\n\n', false)
|
ME.insert(vm.$editor, '\n\n---\n\n', false)
|
||||||
},
|
},
|
||||||
link: function(elem, vm){
|
link: function(elem, vm) {
|
||||||
var offset = yua(elem).offset(),
|
var offset = Anot(elem).offset(),
|
||||||
wrap = ME.selection(vm.$editor) || '',
|
wrap = ME.selection(vm.$editor) || '',
|
||||||
layid = layer.open({
|
layid = layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
|
@ -109,41 +115,50 @@ define(['lib/layer/base'], function(){
|
||||||
link: '',
|
link: '',
|
||||||
linkName: wrap,
|
linkName: wrap,
|
||||||
linkTarget: 1,
|
linkTarget: 1,
|
||||||
$confirm: function(){
|
$confirm: function() {
|
||||||
var lvm = yua.vmodels[layid]
|
var lvm = Anot.vmodels[layid]
|
||||||
if(!lvm.link || !lvm.linkName){
|
if (!lvm.link || !lvm.linkName) {
|
||||||
return layer.alert('链接文字和地址不能为空')
|
return layer.alert('链接文字和地址不能为空')
|
||||||
}
|
}
|
||||||
var val = '[' + lvm.linkName + ']('
|
var val =
|
||||||
+ lvm.link
|
'[' +
|
||||||
+ (lvm.linkTarget === 1 ? ' "target=_blank"' : '')
|
lvm.linkName +
|
||||||
+ ')'
|
'](' +
|
||||||
|
lvm.link +
|
||||||
|
(lvm.linkTarget === 1 ? ' "target=_blank"' : '') +
|
||||||
|
')'
|
||||||
ME.insert(vm.$editor, val, false)
|
ME.insert(vm.$editor, val, false)
|
||||||
layer.close(layid)
|
layer.close(layid)
|
||||||
},
|
},
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop(), 'auto', 'auto', offset.left - ME.doc.scrollLeft()],
|
offset: [
|
||||||
content: '<div class="do-meditor-common do-meditor-font">'
|
offset.top + 37 - ME.doc.scrollTop(),
|
||||||
+ '<section class="input"><span class="label">链接文字</span>'
|
'auto',
|
||||||
+ '<input class="txt" :duplex="linkName" />'
|
'auto',
|
||||||
+ '</section>'
|
offset.left - ME.doc.scrollLeft()
|
||||||
+ '<section class="input"><span class="label">链接地址</span>'
|
],
|
||||||
+ '<input class="txt" :duplex="link"/>'
|
content:
|
||||||
+ '</section>'
|
'<div class="do-meditor-common do-meditor-font">' +
|
||||||
+ '<section>'
|
'<section class="input"><span class="label">链接文字</span>' +
|
||||||
+ '<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="1"/> 新窗口打开</label>'
|
'<input class="txt" :duplex="linkName" />' +
|
||||||
+ '<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="2"/> 本窗口打开</label>'
|
'</section>' +
|
||||||
+ '</section>'
|
'<section class="input"><span class="label">链接地址</span>' +
|
||||||
+ '<section>'
|
'<input class="txt" :duplex="link"/>' +
|
||||||
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
'</section>' +
|
||||||
+ '</section>'
|
'<section>' +
|
||||||
+ '</div>'
|
'<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="1"/> 新窗口打开</label>' +
|
||||||
|
'<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="2"/> 本窗口打开</label>' +
|
||||||
|
'</section>' +
|
||||||
|
'<section>' +
|
||||||
|
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||||
|
'</section>' +
|
||||||
|
'</div>'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
time: function(elem, vm){
|
time: function(elem, vm) {
|
||||||
ME.insert(vm.$editor, new Date().format(), false)
|
ME.insert(vm.$editor, new Date().format(), false)
|
||||||
},
|
},
|
||||||
face: function(elem, vm){
|
face: function(elem, vm) {
|
||||||
var offset = yua(elem).offset(),
|
var offset = Anot(elem).offset(),
|
||||||
faceid = 0,
|
faceid = 0,
|
||||||
layid = layer.open({
|
layid = layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
|
@ -151,67 +166,86 @@ define(['lib/layer/base'], function(){
|
||||||
fixed: true,
|
fixed: true,
|
||||||
shadeClose: true,
|
shadeClose: true,
|
||||||
arr: getOrderArr(36),
|
arr: getOrderArr(36),
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop(), 'auto', 'auto', offset.left - ME.doc.scrollLeft()],
|
offset: [
|
||||||
content: '<ul class="do-meditor-face">'
|
offset.top + 37 - ME.doc.scrollTop(),
|
||||||
+ '<li class="item" :repeat="arr" ><img :attr-src="ME.path + \'/addon/face/\' + el + \'.gif\'" :click="$insert(this.src)" /></li>'
|
'auto',
|
||||||
+ '</ul>',
|
'auto',
|
||||||
$insert: function(src){
|
offset.left - ME.doc.scrollLeft()
|
||||||
|
],
|
||||||
|
content:
|
||||||
|
'<ul class="do-meditor-face">' +
|
||||||
|
'<li class="item" :repeat="arr" ><img :attr-src="ME.path + \'/addon/face/\' + el + \'.gif\'" :click="$insert(this.src)" /></li>' +
|
||||||
|
'</ul>',
|
||||||
|
$insert: function(src) {
|
||||||
ME.insert(vm.$editor, '![](' + src + ')', false)
|
ME.insert(vm.$editor, '![](' + src + ')', false)
|
||||||
layer.close(layid)
|
layer.close(layid)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
table: function(elem, vm){
|
table: function(elem, vm) {
|
||||||
var offset = yua(elem).offset();
|
var offset = Anot(elem).offset()
|
||||||
layer.open({
|
layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
title: '0行 x 0列',
|
title: '0行 x 0列',
|
||||||
fixed: true,
|
fixed: true,
|
||||||
shadeClose: true,
|
shadeClose: true,
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop(), 'auto', 'auto', offset.left - ME.doc.scrollLeft()],
|
offset: [
|
||||||
matrix: objArr(10).map(function(){return objArr(10)}),
|
offset.top + 37 - ME.doc.scrollTop(),
|
||||||
content: '<ul class="do-meditor-table">'
|
'auto',
|
||||||
+ '<li :repeat="matrix"><span :repeat-o="el" :class="{active: o.v}" :data="{x: $index, y: $outer.$index}"></span></li>'
|
'auto',
|
||||||
+ '</ul>',
|
offset.left - ME.doc.scrollLeft()
|
||||||
success: function(id){
|
],
|
||||||
|
matrix: objArr(10).map(function() {
|
||||||
|
return objArr(10)
|
||||||
|
}),
|
||||||
|
content:
|
||||||
|
'<ul class="do-meditor-table">' +
|
||||||
|
'<li :repeat="matrix"><span :repeat-o="el" :class="{active: o.v}" :data="{x: $index, y: $outer.$index}"></span></li>' +
|
||||||
|
'</ul>',
|
||||||
|
success: function(id) {
|
||||||
var tb = document.querySelector('.do-meditor-table'),
|
var tb = document.querySelector('.do-meditor-table'),
|
||||||
_this = yua.vmodels[id],
|
_this = Anot.vmodels[id],
|
||||||
lastx,lasty;
|
lastx,
|
||||||
yua(tb).bind('mousemove', function(ev){
|
lasty
|
||||||
if(ev.target.nodeName === 'SPAN'){
|
Anot(tb).bind('mousemove', function(ev) {
|
||||||
|
if (ev.target.nodeName === 'SPAN') {
|
||||||
var x = ev.target.dataset.x - 0,
|
var x = ev.target.dataset.x - 0,
|
||||||
y = ev.target.dataset.y - 0;
|
y = ev.target.dataset.y - 0
|
||||||
if(x === lastx && y === lasty){
|
if (x === lastx && y === lasty) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lastx = x;
|
lastx = x
|
||||||
lasty = y;
|
lasty = y
|
||||||
_this.title = (y + 1) + '行 x ' + (x + 1) + '列'
|
_this.title = y + 1 + '行 x ' + (x + 1) + '列'
|
||||||
for(var i = 0; i <= 9; i++){
|
for (var i = 0; i <= 9; i++) {
|
||||||
for(var j = 0; j <= 9; j++){
|
for (var j = 0; j <= 9; j++) {
|
||||||
_this.matrix[i][j].v = (i <= y && j <= x) ? 1 : 0
|
_this.matrix[i][j].v = i <= y && j <= x ? 1 : 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yua(tb).bind('mouseleave', function(ev){
|
Anot(tb).bind('mouseleave', function(ev) {
|
||||||
lastx = -1;
|
lastx = -1
|
||||||
lasty = -1;
|
lasty = -1
|
||||||
_this.title = '0行 x 0列'
|
_this.title = '0行 x 0列'
|
||||||
for(var i = 0; i <= 9; i++){
|
for (var i = 0; i <= 9; i++) {
|
||||||
for(var j = 0; j <= 9; j++){
|
for (var j = 0; j <= 9; j++) {
|
||||||
_this.matrix[i][j].v = 0
|
_this.matrix[i][j].v = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yua(tb).bind('click', function(ev){
|
Anot(tb).bind('click', function(ev) {
|
||||||
if(ev.target.nodeName === 'SPAN'){
|
if (ev.target.nodeName === 'SPAN') {
|
||||||
var x = ev.target.dataset.x - 0 + 1,
|
var x = ev.target.dataset.x - 0 + 1,
|
||||||
y = ev.target.dataset.y - 0 + 1;
|
y = ev.target.dataset.y - 0 + 1
|
||||||
|
|
||||||
var val = '\n\n' + ME.repeat('| 表头 ', x) + '|\n'
|
var val =
|
||||||
+ ME.repeat('| -- ', x) + '|\n'
|
'\n\n' +
|
||||||
+ ME.repeat(ME.repeat('| ', x) + '|\n', y)
|
ME.repeat('| 表头 ', x) +
|
||||||
|
'|\n' +
|
||||||
|
ME.repeat('| -- ', x) +
|
||||||
|
'|\n' +
|
||||||
|
ME.repeat(ME.repeat('| ', x) + '|\n', y)
|
||||||
ME.insert(vm.$editor, val, false)
|
ME.insert(vm.$editor, val, false)
|
||||||
layer.close(id)
|
layer.close(id)
|
||||||
}
|
}
|
||||||
|
@ -219,8 +253,8 @@ define(['lib/layer/base'], function(){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
image: function(elem, vm){
|
image: function(elem, vm) {
|
||||||
var offset = yua(elem).offset(),
|
var offset = Anot(elem).offset(),
|
||||||
wrap = ME.selection(vm.$editor) || '',
|
wrap = ME.selection(vm.$editor) || '',
|
||||||
layid = layer.open({
|
layid = layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
|
@ -229,9 +263,9 @@ define(['lib/layer/base'], function(){
|
||||||
fixed: true,
|
fixed: true,
|
||||||
img: '',
|
img: '',
|
||||||
imgAlt: wrap,
|
imgAlt: wrap,
|
||||||
$confirm: function(){
|
$confirm: function() {
|
||||||
var lvm = yua.vmodels[layid]
|
var lvm = Anot.vmodels[layid]
|
||||||
if(!lvm.img || !lvm.imgAlt){
|
if (!lvm.img || !lvm.imgAlt) {
|
||||||
return layer.alert('图片描述和图片地址不能为空')
|
return layer.alert('图片描述和图片地址不能为空')
|
||||||
}
|
}
|
||||||
var val = '![' + lvm.imgAlt + '](' + lvm.img + ')'
|
var val = '![' + lvm.imgAlt + '](' + lvm.img + ')'
|
||||||
|
@ -239,125 +273,135 @@ define(['lib/layer/base'], function(){
|
||||||
ME.insert(vm.$editor, val, false)
|
ME.insert(vm.$editor, val, false)
|
||||||
layer.close(layid)
|
layer.close(layid)
|
||||||
},
|
},
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop(), 'auto', 'auto', offset.left - ME.doc.scrollLeft()],
|
offset: [
|
||||||
content: '<div class="do-meditor-common do-meditor-font">'
|
offset.top + 37 - ME.doc.scrollTop(),
|
||||||
+ '<section class="input"><span class="label">图片描述</span>'
|
'auto',
|
||||||
+ '<input class="txt" :duplex="imgAlt" />'
|
'auto',
|
||||||
+ '</section>'
|
offset.left - ME.doc.scrollLeft()
|
||||||
+ '<section class="input"><span class="label">图片地址</span>'
|
],
|
||||||
+ '<input class="txt" :duplex="img"/>'
|
content:
|
||||||
+ '</section>'
|
'<div class="do-meditor-common do-meditor-font">' +
|
||||||
+ '<section>'
|
'<section class="input"><span class="label">图片描述</span>' +
|
||||||
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
'<input class="txt" :duplex="imgAlt" />' +
|
||||||
+ '</section>'
|
'</section>' +
|
||||||
+ '</div>'
|
'<section class="input"><span class="label">图片地址</span>' +
|
||||||
|
'<input class="txt" :duplex="img"/>' +
|
||||||
|
'</section>' +
|
||||||
|
'<section>' +
|
||||||
|
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||||
|
'</section>' +
|
||||||
|
'</div>'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
file: function(elem, vm){
|
file: function(elem, vm) {
|
||||||
this.link(elem, vm, false)
|
this.link(elem, vm, false)
|
||||||
},
|
},
|
||||||
inlinecode: function(elem, vm){
|
inlinecode: function(elem, vm) {
|
||||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
wraped = trim(wrap, '`');
|
wraped = trim(wrap, '`')
|
||||||
|
|
||||||
wrap = wrap === wraped ? ('`' + wrap + '`') : wraped
|
wrap = wrap === wraped ? '`' + wrap + '`' : wraped
|
||||||
ME.insert(vm.$editor, wrap, true)
|
ME.insert(vm.$editor, wrap, true)
|
||||||
},
|
},
|
||||||
blockcode: function(elem, vm){
|
blockcode: function(elem, vm) {
|
||||||
var layid = layer.open({
|
var layid = layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
title: '添加代码块',
|
title: '添加代码块',
|
||||||
$lang: [
|
$lang: [
|
||||||
{id: 'asp'},
|
{ id: 'asp' },
|
||||||
{id: 'actionscript', name: 'ActionScript(3.0)/Flash/Flex'},
|
{ id: 'actionscript', name: 'ActionScript(3.0)/Flash/Flex' },
|
||||||
{id: 'bash', name: 'Bash/Shell/Bat'},
|
{ id: 'bash', name: 'Bash/Shell/Bat' },
|
||||||
{id: 'css'},
|
{ id: 'css' },
|
||||||
{id: 'c', name: 'C'},
|
{ id: 'c', name: 'C' },
|
||||||
{id: 'cpp', name: 'C++'},
|
{ id: 'cpp', name: 'C++' },
|
||||||
{id: 'csharp', name: 'C#'},
|
{ id: 'csharp', name: 'C#' },
|
||||||
{id: 'coffeescript', name: 'CoffeeScript'},
|
{ id: 'coffeescript', name: 'CoffeeScript' },
|
||||||
{id: 'd', name: 'D'},
|
{ id: 'd', name: 'D' },
|
||||||
{id: 'dart'},
|
{ id: 'dart' },
|
||||||
{id: 'delphi', name: 'Delphi/Pascal'},
|
{ id: 'delphi', name: 'Delphi/Pascal' },
|
||||||
{id: 'erlang'},
|
{ id: 'erlang' },
|
||||||
{id: 'go', name: 'Golang'},
|
{ id: 'go', name: 'Golang' },
|
||||||
{id: 'html'},
|
{ id: 'html' },
|
||||||
{id: 'java'},
|
{ id: 'java' },
|
||||||
{id: 'javascript'},
|
{ id: 'javascript' },
|
||||||
{id: 'json'},
|
{ id: 'json' },
|
||||||
{id: 'lua'},
|
{ id: 'lua' },
|
||||||
{id: 'less'},
|
{ id: 'less' },
|
||||||
{id: 'markdown'},
|
{ id: 'markdown' },
|
||||||
{id: 'nginx'},
|
{ id: 'nginx' },
|
||||||
{id: 'objective-c'},
|
{ id: 'objective-c' },
|
||||||
{id: 'php'},
|
{ id: 'php' },
|
||||||
{id: 'perl'},
|
{ id: 'perl' },
|
||||||
{id: 'python'},
|
{ id: 'python' },
|
||||||
{id: 'r', name: 'R'},
|
{ id: 'r', name: 'R' },
|
||||||
{id: 'ruby'},
|
{ id: 'ruby' },
|
||||||
{id: 'sql'},
|
{ id: 'sql' },
|
||||||
{id: 'sass', name: 'SASS/SCSS'},
|
{ id: 'sass', name: 'SASS/SCSS' },
|
||||||
{id: 'swift'},
|
{ id: 'swift' },
|
||||||
{id: 'typescript'},
|
{ id: 'typescript' },
|
||||||
{id: 'xml'},
|
{ id: 'xml' },
|
||||||
{id: 'yaml'},
|
{ id: 'yaml' },
|
||||||
{id: 'other', name: '其他语言'},
|
{ id: 'other', name: '其他语言' }
|
||||||
],
|
],
|
||||||
lang: 'javascript',
|
lang: 'javascript',
|
||||||
code: '',
|
code: '',
|
||||||
$confirm: function(){
|
$confirm: function() {
|
||||||
var lvm = yua.vmodels[layid]
|
var lvm = Anot.vmodels[layid]
|
||||||
var val = '\n```' + lvm.lang + '\n' + (lvm.code || '//在此输入代码') + '\n```\n'
|
var val =
|
||||||
|
'\n```' + lvm.lang + '\n' + (lvm.code || '//在此输入代码') + '\n```\n'
|
||||||
|
|
||||||
ME.insert(vm.$editor, val, false)
|
ME.insert(vm.$editor, val, false)
|
||||||
layer.close(layid)
|
layer.close(layid)
|
||||||
},
|
},
|
||||||
content: '<div class="do-meditor-codeblock do-meditor-font">'
|
content:
|
||||||
+ '<section class="do-fn-cl"><span class="label">语言类型</span>'
|
'<div class="do-meditor-codeblock do-meditor-font">' +
|
||||||
+ '<select :duplex="lang">'
|
'<section class="do-fn-cl"><span class="label">语言类型</span>' +
|
||||||
+ '<option :repeat="$lang" :attr-value="el.id">{{el.name || el.id}}</option>'
|
'<select :duplex="lang">' +
|
||||||
+ '</select>'
|
'<option :repeat="$lang" :attr-value="el.id">{{el.name || el.id}}</option>' +
|
||||||
+ '</section>'
|
'</select>' +
|
||||||
+ '<section>'
|
'</section>' +
|
||||||
+ '<textarea :duplex="code" placeholder="在这里输入/粘贴代码"></textarea>'
|
'<section>' +
|
||||||
+ '</section>'
|
'<textarea :duplex="code" placeholder="在这里输入/粘贴代码"></textarea>' +
|
||||||
+ '<section class="do-fn-cl">'
|
'</section>' +
|
||||||
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
'<section class="do-fn-cl">' +
|
||||||
+ '</section>'
|
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||||
+ '</div>'
|
'</section>' +
|
||||||
|
'</div>'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
preview: function(elem, vm){
|
preview: function(elem, vm) {
|
||||||
vm.preview = !vm.preview
|
vm.preview = !vm.preview
|
||||||
if(vm.preview){
|
if (vm.preview) {
|
||||||
vm.htmlTxt = vm.$htmlTxt
|
vm.htmlTxt = vm.$htmlTxt
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fullscreen: function(elem, vm){
|
fullscreen: function(elem, vm) {
|
||||||
vm.fullscreen = !vm.fullscreen
|
vm.fullscreen = !vm.fullscreen
|
||||||
vm.$onFullscreen(vm.fullscreen)
|
vm.$onFullscreen(vm.fullscreen)
|
||||||
},
|
},
|
||||||
about: function(elem){
|
about: function(elem) {
|
||||||
var offset = yua(elem).offset()
|
var offset = Anot(elem).offset()
|
||||||
layer.open({
|
layer.open({
|
||||||
type: 7,
|
type: 7,
|
||||||
title: '关于编辑器',
|
title: '关于编辑器',
|
||||||
offset: [offset.top + 37 - ME.doc.scrollTop()],
|
offset: [offset.top + 37 - ME.doc.scrollTop()],
|
||||||
content: '<div class="do-meditor-about do-meditor-font">'
|
content:
|
||||||
+ '<pre>'
|
'<div class="do-meditor-about do-meditor-font">' +
|
||||||
+ ' __ __ _____ _ _ _\n'
|
'<pre>' +
|
||||||
+ '| \\/ | ____|__| (_) |_ ___ _ __\n'
|
' __ __ _____ _ _ _\n' +
|
||||||
+ '| |\\/| | _| / _` | | __/ _ \\| \'__|\n'
|
'| \\/ | ____|__| (_) |_ ___ _ __\n' +
|
||||||
+ '| | | | |__| (_| | | || (_) | |\n'
|
"| |\\/| | _| / _` | | __/ _ \\| '__|\n" +
|
||||||
+ '|_| |_|_____\\__,_|_|\\__\\___/|_| '
|
'| | | | |__| (_| | | || (_) | |\n' +
|
||||||
+ 'v' + ME.version + '</pre>'
|
'|_| |_|_____\\__,_|_|\\__\\___/|_| ' +
|
||||||
+ '<p>开源在线Markdown编辑器</p>'
|
'v' +
|
||||||
+ '<p><a target="_blank" href="https://doui.cc/product/meditor">https://doui.cc/product/meditor</a></p>'
|
ME.version +
|
||||||
+ '<p>Copyright © 2017 Yutent, The MIT License.</p>'
|
'</pre>' +
|
||||||
+ '</div>'
|
'<p>开源在线Markdown编辑器</p>' +
|
||||||
|
'<p><a target="_blank" href="https://doui.cc/product/meditor">https://doui.cc/product/meditor</a></p>' +
|
||||||
|
'<p>Copyright © 2017 Yutent, The MIT License.</p>' +
|
||||||
|
'</div>'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
export default addon
|
||||||
|
|
||||||
})
|
|
||||||
|
|
|
@ -0,0 +1,470 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-17 16:37:12
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import 'prism/base'
|
||||||
|
import 'marked/index'
|
||||||
|
import addon from './addon/base'
|
||||||
|
import './skin/main.scss'
|
||||||
|
|
||||||
|
marked.setOptions({
|
||||||
|
highlight: function(code, lang) {
|
||||||
|
return Prism.highlight(code, Prism.languages[lang])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var editorVM = []
|
||||||
|
Anot.ui.meditor = '1.0.0'
|
||||||
|
//存放编辑器公共静态资源
|
||||||
|
window.ME = {
|
||||||
|
version: Anot.ui.meditor,
|
||||||
|
toolbar: {
|
||||||
|
//工具栏title
|
||||||
|
pipe: '',
|
||||||
|
h1: '标题',
|
||||||
|
quote: '引用文本',
|
||||||
|
bold: '粗体',
|
||||||
|
italic: '斜体',
|
||||||
|
through: '删除线',
|
||||||
|
unordered: '无序列表',
|
||||||
|
ordered: '有序列表',
|
||||||
|
link: '超链接',
|
||||||
|
hr: '横线',
|
||||||
|
time: '插入当前时间',
|
||||||
|
face: '表情',
|
||||||
|
table: '插入表格',
|
||||||
|
image: '插入图片',
|
||||||
|
file: '插入附件',
|
||||||
|
inlinecode: '行内代码',
|
||||||
|
blockcode: '代码块',
|
||||||
|
preview: '预览',
|
||||||
|
fullscreen: '全屏',
|
||||||
|
about: '关于编辑器'
|
||||||
|
},
|
||||||
|
addon, //已有插件
|
||||||
|
//往文本框中插入内容
|
||||||
|
insert: function(dom, val, isSelect) {
|
||||||
|
if (document.selection) {
|
||||||
|
dom.focus()
|
||||||
|
var range = document.selection.createRange()
|
||||||
|
range.text = val
|
||||||
|
dom.focus()
|
||||||
|
range.moveStart('character', -1)
|
||||||
|
} else if (dom.selectionStart || dom.selectionStart === 0) {
|
||||||
|
var startPos = dom.selectionStart,
|
||||||
|
endPos = dom.selectionEnd,
|
||||||
|
scrollTop = dom.scrollTop
|
||||||
|
|
||||||
|
dom.value =
|
||||||
|
dom.value.slice(0, startPos) +
|
||||||
|
val +
|
||||||
|
dom.value.slice(endPos, dom.value.length)
|
||||||
|
|
||||||
|
dom.selectionStart = isSelect ? startPos : startPos + val.length
|
||||||
|
dom.selectionEnd = startPos + val.length
|
||||||
|
dom.scrollTop = scrollTop
|
||||||
|
dom.focus()
|
||||||
|
} else {
|
||||||
|
dom.value += val
|
||||||
|
dom.focus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* [selection 获取选中的文本]
|
||||||
|
* @param {[type]} dom [要操作的元素]
|
||||||
|
* @param {[type]} line [是否强制选取整行]
|
||||||
|
*/
|
||||||
|
selection: function(dom, line) {
|
||||||
|
if (document.selection) {
|
||||||
|
return document.selection.createRange().text
|
||||||
|
} else {
|
||||||
|
var startPos = dom.selectionStart,
|
||||||
|
endPos = dom.selectionEnd
|
||||||
|
|
||||||
|
if (endPos) {
|
||||||
|
//强制选择整行
|
||||||
|
if (line) {
|
||||||
|
startPos = dom.value.slice(0, startPos).lastIndexOf('\n')
|
||||||
|
|
||||||
|
var tmpEnd = dom.value.slice(endPos).indexOf('\n')
|
||||||
|
tmpEnd = tmpEnd < 0 ? 0 : tmpEnd
|
||||||
|
|
||||||
|
startPos += 1 //把\n加上
|
||||||
|
endPos += tmpEnd
|
||||||
|
|
||||||
|
dom.selectionStart = startPos
|
||||||
|
dom.selectionEnd = endPos
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//强制选择整行
|
||||||
|
if (line) {
|
||||||
|
endPos = dom.value.indexOf('\n')
|
||||||
|
endPos = endPos < 0 ? dom.value.length : endPos
|
||||||
|
dom.selectionEnd = endPos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dom.value.slice(startPos, endPos)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
repeat: function(str, num) {
|
||||||
|
if (String.prototype.repeat) {
|
||||||
|
return str.repeat(num)
|
||||||
|
} else {
|
||||||
|
var result = ''
|
||||||
|
while (num > 0) {
|
||||||
|
result += str
|
||||||
|
num--
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: function(id) {
|
||||||
|
if (id === void 0) {
|
||||||
|
id = editorVM.length - 1
|
||||||
|
}
|
||||||
|
var vm = editorVM[id]
|
||||||
|
if (vm) {
|
||||||
|
return {
|
||||||
|
id: vm.$id,
|
||||||
|
getVal: function() {
|
||||||
|
return vm.plainTxt.trim()
|
||||||
|
},
|
||||||
|
getHtml: function() {
|
||||||
|
return vm.$htmlTxt
|
||||||
|
},
|
||||||
|
setVal: function(txt) {
|
||||||
|
vm.plainTxt = txt || ''
|
||||||
|
},
|
||||||
|
show: function() {
|
||||||
|
vm.editorVisible = true
|
||||||
|
},
|
||||||
|
hide: function() {
|
||||||
|
vm.editorVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
doc: Anot(document)
|
||||||
|
}
|
||||||
|
//获取真实的引用路径,避免因为不同的目录结构导致加载失败的情况
|
||||||
|
for (var i in Anot.modules) {
|
||||||
|
if (/meditor/.test(i)) {
|
||||||
|
ME.path = i.slice(0, i.lastIndexOf('/'))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var elems = {
|
||||||
|
p: function(str, attr, inner) {
|
||||||
|
return inner ? '\n' + inner + '\n' : ''
|
||||||
|
},
|
||||||
|
br: '\n',
|
||||||
|
'h([1-6])': function(str, level, attr, inner) {
|
||||||
|
var h = ME.repeat('#', level)
|
||||||
|
return '\n' + h + ' ' + inner + '\n'
|
||||||
|
},
|
||||||
|
hr: '\n\n___\n\n',
|
||||||
|
a: function(str, attr, inner) {
|
||||||
|
var href = attr.match(attrExp('href')),
|
||||||
|
title = attr.match(attrExp('title')),
|
||||||
|
tar = attr.match(attrExp('target'))
|
||||||
|
|
||||||
|
href = (href && href[1]) || ''
|
||||||
|
title = (title && title[1]) || ''
|
||||||
|
tar = (tar && tar[1]) || '_self'
|
||||||
|
|
||||||
|
href = href === 'javascript:void(0);' ? 'javascript:;' : href
|
||||||
|
|
||||||
|
return (
|
||||||
|
'[' +
|
||||||
|
(inner || href) +
|
||||||
|
'](' +
|
||||||
|
href +
|
||||||
|
' "title=' +
|
||||||
|
title +
|
||||||
|
';target=' +
|
||||||
|
tar +
|
||||||
|
'")'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
em: function(str, attr, inner) {
|
||||||
|
return (inner && '_' + inner + '_') || ''
|
||||||
|
},
|
||||||
|
strong: function(str, attr, inner) {
|
||||||
|
return (inner && '**' + inner + '**') || ''
|
||||||
|
},
|
||||||
|
code: function(str, attr, inner) {
|
||||||
|
return (inner && '`' + inner + '`') || ''
|
||||||
|
},
|
||||||
|
pre: function(str, attr, inner) {
|
||||||
|
return '\n\n```\n' + inner + '\n```\n'
|
||||||
|
},
|
||||||
|
blockquote: function(str, attr, inner) {
|
||||||
|
return '> ' + inner.trim()
|
||||||
|
},
|
||||||
|
img: function(str, attr, inner) {
|
||||||
|
var src = attr.match(attrExp('src')),
|
||||||
|
alt = attr.match(attrExp('alt'))
|
||||||
|
|
||||||
|
src = (src && src[1]) || ''
|
||||||
|
alt = (alt && alt[1]) || ''
|
||||||
|
|
||||||
|
return '![' + alt + '](' + src + ')'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function attrExp(field) {
|
||||||
|
return new RegExp(field + '\\s?=\\s?["\']?([^"\']*)["\']?', 'i')
|
||||||
|
}
|
||||||
|
function tagExp(tag, open) {
|
||||||
|
var exp = ''
|
||||||
|
if (['br', 'hr', 'img'].indexOf(tag) > -1) {
|
||||||
|
exp = '<' + tag + '([^>]*)\\/?>'
|
||||||
|
} else {
|
||||||
|
exp = '<' + tag + '([^>]*)>([\\s\\S]*?)<\\/' + tag + '>'
|
||||||
|
}
|
||||||
|
return new RegExp(exp, 'gi')
|
||||||
|
}
|
||||||
|
function html2md(str) {
|
||||||
|
try {
|
||||||
|
str = decodeURIComponent(str)
|
||||||
|
} catch (err) {}
|
||||||
|
str = str.replace(/\t/g, ' ').replace(/<meta [^>]*>/, '')
|
||||||
|
|
||||||
|
for (var i in elems) {
|
||||||
|
var cb = elems[i],
|
||||||
|
exp = tagExp(i)
|
||||||
|
|
||||||
|
if (i === 'blockquote') {
|
||||||
|
while (str.match(exp)) {
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === 'em') {
|
||||||
|
exp = tagExp('i')
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
if (i === 'strong') {
|
||||||
|
exp = tagExp('b')
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var liExp = /<(ul|ol)[^>]*>(?:(?!<ul|<ol)[\s\S])*?<\/\1>/gi
|
||||||
|
while (str.match(liExp)) {
|
||||||
|
str = str.replace(liExp, function(match) {
|
||||||
|
match = match.replace(/<(ul|ol)[^>]*>([\s\S]*?)<\/\1>/gi, function(
|
||||||
|
m,
|
||||||
|
t,
|
||||||
|
inner
|
||||||
|
) {
|
||||||
|
var li = inner.split('</li>')
|
||||||
|
li.pop()
|
||||||
|
|
||||||
|
for (var i = 0, len = li.length; i < len; i++) {
|
||||||
|
var pre = t === 'ol' ? i + 1 + '. ' : '* '
|
||||||
|
li[i] =
|
||||||
|
pre +
|
||||||
|
li[i]
|
||||||
|
.replace(/\s*<li[^>]*>([\s\S]*)/i, function(m, n) {
|
||||||
|
n = n.trim().replace(/\n/g, '\n ')
|
||||||
|
return n
|
||||||
|
})
|
||||||
|
.replace(/<[\/]?[\w]*[^>]*>/g, '')
|
||||||
|
}
|
||||||
|
return li.join('\n')
|
||||||
|
})
|
||||||
|
return '\n' + match.trim()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
str = str
|
||||||
|
.replace(/<[\/]?[\w]*[^>]*>/g, '')
|
||||||
|
.replace(/```([\w\W]*)```/g, function(str, inner) {
|
||||||
|
inner = inner
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
return '```' + inner + '```'
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultToolbar = [
|
||||||
|
'h1',
|
||||||
|
'quote',
|
||||||
|
'|',
|
||||||
|
'bold',
|
||||||
|
'italic',
|
||||||
|
'through',
|
||||||
|
'|',
|
||||||
|
'unordered',
|
||||||
|
'ordered',
|
||||||
|
'|',
|
||||||
|
'hr',
|
||||||
|
'link',
|
||||||
|
'time',
|
||||||
|
'face',
|
||||||
|
'|',
|
||||||
|
'table',
|
||||||
|
'image',
|
||||||
|
'file',
|
||||||
|
'inlinecode',
|
||||||
|
'blockcode',
|
||||||
|
'|',
|
||||||
|
'preview',
|
||||||
|
'fullscreen',
|
||||||
|
'|',
|
||||||
|
'about'
|
||||||
|
],
|
||||||
|
extraAddons = []
|
||||||
|
|
||||||
|
function tool(name) {
|
||||||
|
name = (name + '').trim().toLowerCase()
|
||||||
|
name = '|' === name ? 'pipe' : name
|
||||||
|
return (
|
||||||
|
'<span title="' +
|
||||||
|
ME.toolbar[name] +
|
||||||
|
'" class="icon-' +
|
||||||
|
name +
|
||||||
|
'" ' +
|
||||||
|
(name !== 'pipe' ? ':click="onToolClick(\'' + name + '\', $event)"' : '') +
|
||||||
|
'></span>'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Anot.component('meditor', {
|
||||||
|
render: function() {
|
||||||
|
var toolbar = (this.toolbar || defaultToolbar)
|
||||||
|
.map(function(it) {
|
||||||
|
return tool(it)
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
delete this.toolbar
|
||||||
|
return (
|
||||||
|
'<div class="do-meditor do-meditor-font" :visible="editorVisible"' +
|
||||||
|
' :class="{fullscreen: fullscreen, preview: preview}">' +
|
||||||
|
'<div class="tool-bar do-ui-font do-fn-noselect">{toolbar}</div>' +
|
||||||
|
'<textarea ref="textarea" class="editor-body" spellcheck="false" :duplex="plainTxt" :attr="{disabled: disabled}" :on-paste="$paste($event)"></textarea>' +
|
||||||
|
'<content class="md-preview do-marked-theme" :visible="preview" :html="htmlTxt"></content>' +
|
||||||
|
'</div>'
|
||||||
|
).replace(/\{toolbar\}/g, toolbar)
|
||||||
|
},
|
||||||
|
|
||||||
|
construct: function(base, opt, attr) {
|
||||||
|
Anot.mix(base, opt, attr)
|
||||||
|
if (base.$addons && Array.isArray(base.$addons)) {
|
||||||
|
extraAddons = base.$addons.map(function(name) {
|
||||||
|
return ME.path + '/addon/' + name
|
||||||
|
})
|
||||||
|
delete base.$addons
|
||||||
|
}
|
||||||
|
if (base.hasOwnProperty('$show')) {
|
||||||
|
base.editorVisible = base.$show
|
||||||
|
delete base.$show
|
||||||
|
}
|
||||||
|
return base
|
||||||
|
},
|
||||||
|
componentWillMount: function(vm) {},
|
||||||
|
componentDidMount: function(vm, elem) {
|
||||||
|
console.log(this)
|
||||||
|
// vm.$editor = elem.children[1]
|
||||||
|
|
||||||
|
// editorVM.push(vm)
|
||||||
|
// //自动加载额外的插件
|
||||||
|
// require(extraAddons, function() {
|
||||||
|
// var args = Array.prototype.slice.call(arguments, 0)
|
||||||
|
// args.forEach(function(addon) {
|
||||||
|
// addon && addon(vm)
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
|
||||||
|
// Anot(vm.$editor).bind('keydown', function(ev) {
|
||||||
|
// var wrap = ME.selection(vm.$editor) || '',
|
||||||
|
// select = !!wrap
|
||||||
|
// //tab键改为插入2个空格,阻止默认事件,防止焦点失去
|
||||||
|
// if (ev.keyCode === 9) {
|
||||||
|
// wrap = wrap
|
||||||
|
// .split('\n')
|
||||||
|
// .map(function(it) {
|
||||||
|
// return ev.shiftKey ? it.replace(/^\s\s/, '') : ' ' + it
|
||||||
|
// })
|
||||||
|
// .join('\n')
|
||||||
|
// ME.insert(this, wrap, select)
|
||||||
|
// ev.preventDefault()
|
||||||
|
// }
|
||||||
|
// //修复按退格键删除选中文本时,选中的状态不更新的bug
|
||||||
|
// if (ev.keyCode === 8) {
|
||||||
|
// if (select) {
|
||||||
|
// ME.insert(this, '', select)
|
||||||
|
// ev.preventDefault()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// //编辑器成功加载的回调
|
||||||
|
// vm.$onSuccess(ME.get(), vm)
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
plainTxt: function(val) {
|
||||||
|
this.$compile()
|
||||||
|
//只有开启实时预览,才会赋值给htmlTxt
|
||||||
|
if (this.preview) {
|
||||||
|
this.htmlTxt = this.$htmlTxt
|
||||||
|
}
|
||||||
|
this.$onUpdate(this.plainTxt, vm.$htmlTxt)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
disabled: false, //禁用编辑器
|
||||||
|
fullscreen: false, //是否全屏
|
||||||
|
preview: false, //是否显示预览
|
||||||
|
$editor: null, //编辑器元素
|
||||||
|
editorVisible: true,
|
||||||
|
$htmlTxt: '', //临时储存html文本
|
||||||
|
htmlTxt: '', //用于预览渲染
|
||||||
|
plainTxt: '', //纯md文本
|
||||||
|
$safelyCompile: true
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onToolClick: function(name, ev) {
|
||||||
|
if (ME.addon[name]) {
|
||||||
|
ME.addon[name].call(ME, ev.target, this)
|
||||||
|
} else {
|
||||||
|
console.log('%c没有对应的插件%c[%s]', 'color:#f00;', '', name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$onSuccess: Anot.noop,
|
||||||
|
$onUpdate: Anot.noop,
|
||||||
|
$onFullscreen: Anot.noop,
|
||||||
|
$paste: function(ev) {
|
||||||
|
ev.preventDefault()
|
||||||
|
var txt = ev.clipboardData.getData('text/plain').trim(),
|
||||||
|
html = ev.clipboardData.getData('text/html').trim()
|
||||||
|
|
||||||
|
html = html2md(html)
|
||||||
|
|
||||||
|
if (html) {
|
||||||
|
ME.insert(this, html)
|
||||||
|
} else if (txt) {
|
||||||
|
ME.insert(this, txt)
|
||||||
|
}
|
||||||
|
this.plainTxt = this.value
|
||||||
|
},
|
||||||
|
compile: function() {
|
||||||
|
var txt = this.plainTxt.trim()
|
||||||
|
|
||||||
|
if (this.$safelyCompile) {
|
||||||
|
txt = txt
|
||||||
|
.replace(/<script([^>]*?)>/g, '<script$1>')
|
||||||
|
.replace(/<\/script>/g, '</script>')
|
||||||
|
}
|
||||||
|
//只解析,不渲染
|
||||||
|
this.$htmlTxt = marked(txt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,440 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2017-04-17 16:37:12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
define([
|
|
||||||
'yua',
|
|
||||||
'lib/prism/base',
|
|
||||||
'lib/marked/main',
|
|
||||||
'css!./skin/main',
|
|
||||||
], function(yua){
|
|
||||||
|
|
||||||
marked.setOptions({
|
|
||||||
highlight: function(code, lang){
|
|
||||||
return Prism.highlight(code, Prism.languages[lang])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var editorVM = []
|
|
||||||
yua.ui.meditor = '1.0.0'
|
|
||||||
//存放编辑器公共静态资源
|
|
||||||
window.ME = {
|
|
||||||
version: yua.ui.meditor,
|
|
||||||
toolbar: { //工具栏title
|
|
||||||
pipe: '',
|
|
||||||
h1: '标题',
|
|
||||||
quote: '引用文本',
|
|
||||||
bold: '粗体',
|
|
||||||
italic: '斜体',
|
|
||||||
through: '删除线',
|
|
||||||
unordered: '无序列表',
|
|
||||||
ordered: '有序列表',
|
|
||||||
link: '超链接',
|
|
||||||
hr: '横线',
|
|
||||||
time: '插入当前时间',
|
|
||||||
face: '表情',
|
|
||||||
table: '插入表格',
|
|
||||||
image: '插入图片',
|
|
||||||
file: '插入附件',
|
|
||||||
inlinecode: '行内代码',
|
|
||||||
blockcode: '代码块',
|
|
||||||
preview: '预览',
|
|
||||||
fullscreen: '全屏',
|
|
||||||
about: '关于编辑器',
|
|
||||||
},
|
|
||||||
addon: {}, //已有插件
|
|
||||||
//往文本框中插入内容
|
|
||||||
insert: function(dom, val, isSelect){
|
|
||||||
if(document.selection){
|
|
||||||
dom.focus()
|
|
||||||
var range = document.selection.createRange()
|
|
||||||
range.text = val
|
|
||||||
dom.focus()
|
|
||||||
range.moveStart('character', -1)
|
|
||||||
|
|
||||||
}else if(dom.selectionStart || dom.selectionStart === 0) {
|
|
||||||
var startPos = dom.selectionStart,
|
|
||||||
endPos = dom.selectionEnd,
|
|
||||||
scrollTop = dom.scrollTop;
|
|
||||||
|
|
||||||
dom.value = dom.value.slice(0, startPos)
|
|
||||||
+ val
|
|
||||||
+ dom.value.slice(endPos, dom.value.length);
|
|
||||||
|
|
||||||
dom.selectionStart = isSelect ? startPos : (startPos + val.length)
|
|
||||||
dom.selectionEnd = startPos + val.length
|
|
||||||
dom.scrollTop = scrollTop
|
|
||||||
dom.focus()
|
|
||||||
}else{
|
|
||||||
dom.value += val;
|
|
||||||
dom.focus()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* [selection 获取选中的文本]
|
|
||||||
* @param {[type]} dom [要操作的元素]
|
|
||||||
* @param {[type]} line [是否强制选取整行]
|
|
||||||
*/
|
|
||||||
selection: function(dom, line){
|
|
||||||
if(document.selection){
|
|
||||||
return document.selection.createRange().text
|
|
||||||
}else{
|
|
||||||
|
|
||||||
var startPos = dom.selectionStart,
|
|
||||||
endPos = dom.selectionEnd;
|
|
||||||
|
|
||||||
if(endPos){
|
|
||||||
//强制选择整行
|
|
||||||
if(line) {
|
|
||||||
startPos = dom.value.slice(0, startPos).lastIndexOf('\n');
|
|
||||||
|
|
||||||
var tmpEnd = dom.value.slice(endPos).indexOf('\n');
|
|
||||||
tmpEnd = tmpEnd < 0 ? 0 : tmpEnd
|
|
||||||
|
|
||||||
startPos += 1 //把\n加上
|
|
||||||
endPos += tmpEnd;
|
|
||||||
|
|
||||||
dom.selectionStart = startPos
|
|
||||||
dom.selectionEnd = endPos
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//强制选择整行
|
|
||||||
if(line) {
|
|
||||||
endPos = dom.value.indexOf('\n')
|
|
||||||
endPos = endPos < 0 ? dom.value.length : endPos
|
|
||||||
dom.selectionEnd = endPos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dom.value.slice(startPos, endPos)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
repeat: function(str, num){
|
|
||||||
if(String.prototype.repeat){
|
|
||||||
return str.repeat(num)
|
|
||||||
}else{
|
|
||||||
var result = ''
|
|
||||||
while(num > 0){
|
|
||||||
result += str;
|
|
||||||
num--
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get: function(id){
|
|
||||||
if(id === void 0){
|
|
||||||
id = editorVM.length - 1
|
|
||||||
}
|
|
||||||
var vm = editorVM[id]
|
|
||||||
if(vm){
|
|
||||||
return {
|
|
||||||
id: vm.$id,
|
|
||||||
getVal: function(){
|
|
||||||
return vm.plainTxt.trim()
|
|
||||||
},
|
|
||||||
getHtml: function(){
|
|
||||||
return vm.$htmlTxt
|
|
||||||
},
|
|
||||||
setVal: function(txt){
|
|
||||||
vm.plainTxt = txt || ''
|
|
||||||
},
|
|
||||||
show: function(){
|
|
||||||
vm.editorVisible = true
|
|
||||||
},
|
|
||||||
hide: function(){
|
|
||||||
vm.editorVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
doc: yua(document)
|
|
||||||
}
|
|
||||||
//获取真实的引用路径,避免因为不同的目录结构导致加载失败的情况
|
|
||||||
for(var i in yua.modules){
|
|
||||||
if(/meditor/.test(i)) {
|
|
||||||
ME.path = i.slice(0, i.lastIndexOf('/'))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var elems = {
|
|
||||||
p: function(str, attr, inner){
|
|
||||||
return inner ? ('\n' + inner + '\n') : ''
|
|
||||||
},
|
|
||||||
br: '\n',
|
|
||||||
'h([1-6])': function(str, level, attr, inner){
|
|
||||||
var h = ME.repeat('#', level)
|
|
||||||
return '\n' + h + ' ' + inner + '\n'
|
|
||||||
},
|
|
||||||
hr: '\n\n___\n\n',
|
|
||||||
a: function(str, attr, inner){
|
|
||||||
var href = attr.match(attrExp('href')),
|
|
||||||
title = attr.match(attrExp('title')),
|
|
||||||
tar = attr.match(attrExp('target'));
|
|
||||||
|
|
||||||
href = href && href[1] || ''
|
|
||||||
title = title && title[1] || ''
|
|
||||||
tar = tar && tar[1] || '_self'
|
|
||||||
|
|
||||||
href = href === 'javascript:void(0);' ? 'javascript:;' : href
|
|
||||||
|
|
||||||
return '[' + (inner || href) + '](' + href + ' "title=' + title + ';target=' + tar + '")'
|
|
||||||
},
|
|
||||||
em: function(str, attr, inner){
|
|
||||||
return inner && ('_' + inner + '_') || ''
|
|
||||||
},
|
|
||||||
strong: function(str, attr, inner){
|
|
||||||
return inner && ('**' + inner + '**') || ''
|
|
||||||
},
|
|
||||||
code: function(str, attr, inner){
|
|
||||||
return inner && ('`' + inner + '`') || ''
|
|
||||||
},
|
|
||||||
pre: function(str, attr, inner){
|
|
||||||
|
|
||||||
return '\n\n```\n' + inner + '\n```\n'
|
|
||||||
},
|
|
||||||
blockquote: function(str, attr, inner){
|
|
||||||
return '> ' + inner.trim()
|
|
||||||
},
|
|
||||||
img: function(str, attr, inner){
|
|
||||||
var src = attr.match(attrExp('src')),
|
|
||||||
alt = attr.match(attrExp('alt'));
|
|
||||||
|
|
||||||
src = src && src[1] || ''
|
|
||||||
alt = alt && alt[1] || ''
|
|
||||||
|
|
||||||
return '![' + alt + '](' + src + ')'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function attrExp(field){
|
|
||||||
return new RegExp(field + '\\s?=\\s?["\']?([^"\']*)["\']?', 'i')
|
|
||||||
}
|
|
||||||
function tagExp(tag, open){
|
|
||||||
var exp = ''
|
|
||||||
if(['br', 'hr', 'img'].indexOf(tag) > -1){
|
|
||||||
exp = '<' + tag + '([^>]*)\\/?>'
|
|
||||||
}else{
|
|
||||||
exp = '<' + tag + '([^>]*)>([\\s\\S]*?)<\\/' + tag + '>'
|
|
||||||
}
|
|
||||||
return new RegExp(exp, 'gi')
|
|
||||||
}
|
|
||||||
function html2md(str){
|
|
||||||
try{
|
|
||||||
str = decodeURIComponent(str)
|
|
||||||
}catch(err){}
|
|
||||||
str = str.replace(/\t/g, ' ').replace(/<meta [^>]*>/, '')
|
|
||||||
|
|
||||||
for(var i in elems){
|
|
||||||
var cb = elems[i],
|
|
||||||
exp = tagExp(i);
|
|
||||||
|
|
||||||
if(i === 'blockquote'){
|
|
||||||
while(str.match(exp)){
|
|
||||||
str = str.replace(exp, cb)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
str = str.replace(exp, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i === 'em'){
|
|
||||||
exp = tagExp('i')
|
|
||||||
str = str.replace(exp, cb)
|
|
||||||
}
|
|
||||||
if(i === 'strong'){
|
|
||||||
exp = tagExp('b')
|
|
||||||
str = str.replace(exp, cb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var liExp = /<(ul|ol)[^>]*>(?:(?!<ul|<ol)[\s\S])*?<\/\1>/gi
|
|
||||||
while(str.match(liExp)) {
|
|
||||||
str = str.replace(liExp, function(match){
|
|
||||||
match = match.replace(/<(ul|ol)[^>]*>([\s\S]*?)<\/\1>/gi, function(m, t, inner){
|
|
||||||
var li = inner.split('</li>')
|
|
||||||
li.pop()
|
|
||||||
|
|
||||||
for(var i = 0,len = li.length; i < len; i++){
|
|
||||||
var pre = t === 'ol' ? ((i + 1) + '. ') : '* '
|
|
||||||
li[i] = pre + li[i].replace(/\s*<li[^>]*>([\s\S]*)/i, function(m, n){
|
|
||||||
n = n.trim()
|
|
||||||
.replace(/\n/g, '\n ')
|
|
||||||
return n
|
|
||||||
}).replace(/<[\/]?[\w]*[^>]*>/g, '')
|
|
||||||
}
|
|
||||||
return li.join('\n')
|
|
||||||
})
|
|
||||||
return '\n' + match.trim()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
str = str.replace(/<[\/]?[\w]*[^>]*>/g, '')
|
|
||||||
.replace(/```([\w\W]*)```/g, function(str, inner){
|
|
||||||
inner = inner.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
||||||
return '```' + inner + '```'
|
|
||||||
})
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
require([
|
|
||||||
ME.path + '/addon/base'
|
|
||||||
], function(){
|
|
||||||
|
|
||||||
|
|
||||||
var defaultToolbar = ['h1', 'quote', '|',
|
|
||||||
'bold', 'italic', 'through', '|',
|
|
||||||
'unordered', 'ordered', '|',
|
|
||||||
'hr', 'link', 'time', 'face', '|',
|
|
||||||
'table','image', 'file','inlinecode', 'blockcode','|',
|
|
||||||
'preview', 'fullscreen', '|',
|
|
||||||
'about'
|
|
||||||
],
|
|
||||||
extraAddons = [];
|
|
||||||
|
|
||||||
|
|
||||||
function tool(name){
|
|
||||||
name = (name + '').trim().toLowerCase()
|
|
||||||
name = '|' === name ? 'pipe' : name
|
|
||||||
return '<span title="' + ME.toolbar[name] + '" class="icon-' + name+ '" '
|
|
||||||
+ (name !== 'pipe' ? (':click="$onToolbarClick(\'' + name + '\')"') : '')
|
|
||||||
+ '></span>'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yua.component('meditor', {
|
|
||||||
$template: '<div class="do-meditor do-meditor-font" :visible="editorVisible"'
|
|
||||||
+ ' :class="{fullscreen: fullscreen, preview: preview}">'
|
|
||||||
+ '<div class="tool-bar do-ui-font do-fn-noselect">{toolbar}</div>'
|
|
||||||
+ '<textarea class="editor-body" spellcheck="false" :duplex="plainTxt" :attr="{disabled: disabled}" :on-paste="$paste($event)"></textarea>'
|
|
||||||
+ '<content class="md-preview do-marked-theme" :visible="preview" :html="htmlTxt"></content>'
|
|
||||||
+ '</div>',
|
|
||||||
$$template: function(txt){
|
|
||||||
|
|
||||||
var toolbar = (this.toolbar || defaultToolbar).map(function(it){
|
|
||||||
return tool(it)
|
|
||||||
}).join('')
|
|
||||||
|
|
||||||
delete this.toolbar
|
|
||||||
return txt.replace(/\{uuid\}/g, this.$id).replace(/\{toolbar\}/g, toolbar)
|
|
||||||
},
|
|
||||||
$construct: function(base, opt, attr){
|
|
||||||
yua.mix(base, opt, attr)
|
|
||||||
if(base.$addons && Array.isArray(base.$addons)){
|
|
||||||
extraAddons = base.$addons.map(function(name){
|
|
||||||
return ME.path + '/addon/' + name
|
|
||||||
})
|
|
||||||
delete base.$addons
|
|
||||||
}
|
|
||||||
if(base.hasOwnProperty('$show')){
|
|
||||||
base.editorVisible = base.$show
|
|
||||||
delete base.$show
|
|
||||||
}
|
|
||||||
return base
|
|
||||||
},
|
|
||||||
$init: function(vm){
|
|
||||||
vm.$watch('plainTxt', function(val){
|
|
||||||
vm.$compile()
|
|
||||||
//只有开启实时预览,才会赋值给htmlTxt
|
|
||||||
if(vm.preview){
|
|
||||||
vm.htmlTxt = vm.$htmlTxt
|
|
||||||
}
|
|
||||||
vm.$onUpdate(vm.plainTxt, vm.$htmlTxt)
|
|
||||||
})
|
|
||||||
|
|
||||||
vm.$onToolbarClick = function(name){
|
|
||||||
if(ME.addon[name]){
|
|
||||||
ME.addon[name].call(ME.addon, this, vm)
|
|
||||||
}else{
|
|
||||||
console.log('%c没有对应的插件%c[%s]', 'color:#f00;', '',name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vm.$paste = function(ev){
|
|
||||||
ev.preventDefault()
|
|
||||||
var txt = ev.clipboardData.getData('text/plain').trim(),
|
|
||||||
html = ev.clipboardData.getData('text/html').trim();
|
|
||||||
|
|
||||||
html = html2md(html)
|
|
||||||
|
|
||||||
if(html){
|
|
||||||
ME.insert(this, html)
|
|
||||||
}else if(txt) {
|
|
||||||
ME.insert(this, txt)
|
|
||||||
}
|
|
||||||
vm.plainTxt = this.value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
$ready: function(vm, elem){
|
|
||||||
|
|
||||||
vm.$editor = elem.children[1]
|
|
||||||
|
|
||||||
editorVM.push(vm)
|
|
||||||
//自动加载额外的插件
|
|
||||||
require(extraAddons, function(){
|
|
||||||
var args = Array.prototype.slice.call(arguments, 0)
|
|
||||||
args.forEach(function(addon){
|
|
||||||
addon && addon(vm)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
yua(vm.$editor).bind('keydown', function(ev){
|
|
||||||
|
|
||||||
var wrap = ME.selection(vm.$editor) || '',
|
|
||||||
select = !!wrap;
|
|
||||||
//tab键改为插入2个空格,阻止默认事件,防止焦点失去
|
|
||||||
if(ev.keyCode === 9){
|
|
||||||
wrap = wrap.split('\n').map(function(it){
|
|
||||||
return ev.shiftKey ? it.replace(/^\s\s/, '') : ' ' + it
|
|
||||||
}).join('\n')
|
|
||||||
ME.insert(this, wrap, select)
|
|
||||||
ev.preventDefault()
|
|
||||||
}
|
|
||||||
//修复按退格键删除选中文本时,选中的状态不更新的bug
|
|
||||||
if(ev.keyCode === 8){
|
|
||||||
if(select){
|
|
||||||
ME.insert(this, '', select)
|
|
||||||
ev.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
//编辑器成功加载的回调
|
|
||||||
vm.$onSuccess(ME.get(), vm)
|
|
||||||
},
|
|
||||||
$paste: yua.noop,
|
|
||||||
$compile: function(){
|
|
||||||
var txt = this.plainTxt.trim()
|
|
||||||
|
|
||||||
if(this.$safelyCompile){
|
|
||||||
txt = txt.replace(/<script([^>]*?)>/g, '<script$1>')
|
|
||||||
.replace(/<\/script>/g, '</script>')
|
|
||||||
}
|
|
||||||
//只解析,不渲染
|
|
||||||
this.$htmlTxt = marked(txt)
|
|
||||||
},
|
|
||||||
$onToolbarClick: yua.noop,
|
|
||||||
$onSuccess: yua.noop,
|
|
||||||
$onUpdate: yua.noop,
|
|
||||||
$onFullscreen: yua.noop,
|
|
||||||
$safelyCompile: true,
|
|
||||||
disabled: false, //禁用编辑器
|
|
||||||
fullscreen: false, //是否全屏
|
|
||||||
preview: false, //是否显示预览
|
|
||||||
$editor: null, //编辑器元素
|
|
||||||
editorVisible: true,
|
|
||||||
$htmlTxt: '', //临时储存html文本
|
|
||||||
htmlTxt: '', //用于预览渲染
|
|
||||||
plainTxt: '' //纯md文本
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
|
@ -6,7 +6,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "../../../../css/var.scss";
|
@import "var.scss";
|
||||||
|
|
||||||
.do-meditor {position:relative;width:100%;height:100%;min-height:180px;padding-top:43px;border:1px solid #ddd;background:#fff;color:#666;
|
.do-meditor {position:relative;width:100%;height:100%;min-height:180px;padding-top:43px;border:1px solid #ddd;background:#fff;color:#666;
|
||||||
|
|
||||||
|
@ -96,30 +96,30 @@
|
||||||
.do-meditor {
|
.do-meditor {
|
||||||
.tool-bar {overflow:hidden;position:absolute;top:0;left:0;z-index:99;width:100%;height:43px;padding:5px 10px;border-bottom:1px solid #ddd;background:#f5f5f5;color:#666;
|
.tool-bar {overflow:hidden;position:absolute;top:0;left:0;z-index:99;width:100%;height:43px;padding:5px 10px;border-bottom:1px solid #ddd;background:#f5f5f5;color:#666;
|
||||||
|
|
||||||
span {display:inline-block;width:30px;height:32px;line-height:32px;text-align:center;font-size:20px;}
|
span {display:inline-block;width:32px;height:32px;line-height:32px;text-align:center;font-size:28px;}
|
||||||
span:hover {background:#e5e5e5;}
|
span:hover {background:#e5e5e5;}
|
||||||
.icon-pipe {width:20px;}
|
.icon-pipe {width:20px;color:nth($cp, 3)}
|
||||||
.icon-pipe:hover {background:none;}
|
.icon-pipe:hover {background:none;}
|
||||||
.icon-pipe::before {content:"\e62c"}
|
.icon-pipe::before {content:"\e677"}
|
||||||
.icon-h1::before {content:"\e62b"}
|
.icon-h1::before {content:"\e65c"}
|
||||||
.icon-bold::before {content:"\e62f"}
|
.icon-bold::before {content:"\e66c"}
|
||||||
.icon-italic::before {content:"\e639"}
|
.icon-italic::before {content:"\e670"}
|
||||||
.icon-through::before {content:"\e619"}
|
.icon-through::before {content:"\e66d"}
|
||||||
.icon-link::before {content:"\e61c"}
|
.icon-link::before {content:"\e667"}
|
||||||
.icon-inlinecode::before {content:"\e63a"}
|
.icon-inlinecode::before {content:"\e67a"}
|
||||||
.icon-blockcode::before {content:"\e632"}
|
.icon-blockcode::before {content:"\e67b"}
|
||||||
.icon-quote::before {content:"\e61b"}
|
.icon-quote::before {content:"\e66a"}
|
||||||
.icon-hr::before {content:"\e614"}
|
.icon-hr::before {content:"\e676"}
|
||||||
.icon-time::before {content:"\e636"}
|
.icon-time::before {content:"\e675"}
|
||||||
.icon-face::before {content:"\e630"}
|
.icon-face::before {content:"\e673"}
|
||||||
.icon-image::before {content:"\e637"}
|
.icon-image::before {content:"\e682"}
|
||||||
.icon-file::before {content:"\e618"}
|
.icon-file::before {content:"\e66b"}
|
||||||
.icon-preview::before {content:"\e61f"}
|
.icon-preview::before {content:"\e67d"}
|
||||||
.icon-fullscreen::before {content:"\e621"}
|
.icon-fullscreen::before {content:"\e67e"}
|
||||||
.icon-table::before {content:"\e617"}
|
.icon-table::before {content:"\e65a"}
|
||||||
.icon-ordered::before {content:"\e638"}
|
.icon-ordered::before {content:"\e664"}
|
||||||
.icon-unordered::before {content:"\e633"}
|
.icon-unordered::before {content:"\e663"}
|
||||||
.icon-about::before {content:"\e700"}
|
.icon-about::before {content:"\e672"}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-body{overflow:hidden;overflow-y:auto;float:left;width:100%;height:100%;padding:5px 5px 50px;border:0;outline:none;resize:none;color:#666;background:#fff;}
|
.editor-body{overflow:hidden;overflow-y:auto;float:left;width:100%;height:100%;padding:5px 5px 50px;border:0;outline:none;resize:none;color:#666;background:#fff;}
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
|
|
||||||
.button,.page {display:inline-block;border:0;color: nth($cgr, 1);text-decoration:none;cursor:pointer;vertical-align:top;font-size:14px;font-weight:100;
|
.button,.page {display:inline-block;border:0;color: nth($cgr, 1);text-decoration:none;cursor:pointer;vertical-align:top;font-size:14px;font-weight:100;
|
||||||
|
|
||||||
&.home::after {content:"\e652";font-size:18px;}
|
&.home::after {content:"\e691";font-size:18px;}
|
||||||
&.prev::after {content:"\e659";font-size:18px;}
|
&.prev::after {content:"\e67c";font-size:18px;}
|
||||||
&.next::after {content:"\e658";font-size:18px;}
|
&.next::after {content:"\e66e";font-size:18px;}
|
||||||
&.end::after {content:"\e653";font-size:18px;}
|
&.end::after {content:"\e693";font-size:18px;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
1889
src/js/prism/full.js
1889
src/js/prism/full.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue