新增meditor;优化框架及组件的结构
|
@ -33,7 +33,7 @@ q:before, q:after {content: '';content: none;}
|
||||||
table {border-collapse: collapse;border-spacing: 0;}
|
table {border-collapse: collapse;border-spacing: 0;}
|
||||||
|
|
||||||
.do-fn-cl { *zoom: 1; }
|
.do-fn-cl { *zoom: 1; }
|
||||||
.do-fn-cl:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; overflow:hidden;}
|
.do-fn-cl:after {visibility: hidden;overflow:hidden; display: block;height: 0;content: "."; clear: both;}
|
||||||
.do-fn-clear {clear:both;display:inline;}
|
.do-fn-clear {clear:both;display:inline;}
|
||||||
|
|
||||||
.do-fn-show{display:block;}
|
.do-fn-show{display:block;}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define(["./codemirror", 'css!./codemirror'], function(CodeMirror) {
|
define(["./codemirror", 'css!./theme-dark'], function(CodeMirror) {
|
||||||
CodeMirror.defineMode("htmlmixed", function(config) {
|
CodeMirror.defineMode("htmlmixed", function(config) {
|
||||||
var htmlMode = CodeMirror.getMode(config, {
|
var htmlMode = CodeMirror.getMode(config, {
|
||||||
name: "xml",
|
name: "xml",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
.CodeMirror{height:100%;line-height:1.5;font-family:monospace;position:relative;overflow:hidden;background:#272822;color:#f8f8f2}.CodeMirror-scroll{overflow:auto;height:100%;width:100%;position:relative;outline:0}.CodeMirror-scrollbar{position:absolute;right:0;top:0;overflow-x:hidden;overflow-y:scroll;z-index:5}.CodeMirror-scrollbar-inner{width:1px}.CodeMirror-scrollbar.cm-sb-overlap{position:absolute;z-index:1;float:none;right:0;min-width:12px}.CodeMirror-scrollbar.cm-sb-nonoverlap{min-width:12px}.CodeMirror-scrollbar.cm-sb-ie7{min-width:18px}.CodeMirror-gutter{position:absolute;left:0;top:0;z-index:10;background-color:transparent;border-right:1px solid #454545;min-width:2em;height:100%}.CodeMirror-gutter-text{color:#aaa;text-align:right;padding:.4em .2em .4em .4em;white-space:pre!important;cursor:default}.CodeMirror-lines{padding:.4em;white-space:pre;cursor:text}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;-o-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;padding:0;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror textarea{outline:0!important}.CodeMirror pre.CodeMirror-cursor{z-index:10;position:absolute;visibility:hidden;border-left:1px solid #9effff;border-right:none;width:0}.cm-keymap-fat-cursor pre.CodeMirror-cursor{width:auto;border:0;background:0 0;background:rgba(0,200,0,.4);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800)}.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id){filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.CodeMirror-focused pre.CodeMirror-cursor{visibility:visible}.CodeMirror-focused div.CodeMirror-selected,div.CodeMirror-selected{background:#49483E}.CodeMirror-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-s-default span.cm-keyword{color:#f92672}.cm-s-default span.cm-atom{color:#ae81ff}.cm-s-default span.cm-number{color:#f30}.cm-s-default span.cm-def{color:#fd971f}.cm-s-default span.cm-variable{color:#f8f8f2}.cm-s-default span.cm-variable-2{color:#9effff}.cm-s-default span.cm-property,.cm-s-default span.cm-variable-3{color:#66d9ef}.cm-s-default span.cm-operator{color:#9effff}.cm-s-default span.cm-comment{color:#75715e}.cm-s-default span.cm-string{color:#e6db74}.cm-s-default span.cm-string-2{color:#f50}.cm-s-default span.cm-meta{color:#555}.cm-s-default span.cm-error{background:#f92672;color:#f8f8f0}.cm-s-default span.cm-qualifier{color:#75d908}.cm-s-default span.cm-builtin{color:#66d9ef}.cm-s-default span.cm-bracket{color:#f8f8f2}.cm-s-default span.cm-tag{color:#f92672}.cm-s-default span.cm-attribute{color:#a6e22e}.cm-s-default span.cm-header{color:#ae81ff}.cm-s-default span.cm-quote{color:#090}.cm-s-default span.cm-hr{color:#999}.cm-s-default span.cm-link{color:#ae81ff}span.cm-header,span.cm-strong{font-weight:700}span.cm-em{font-style:italic}span.cm-emstrong{font-style:italic;font-weight:700}span.cm-link{text-decoration:underline}span.cm-invalidchar{color:red}div.CodeMirror span.CodeMirror-matchingbracket{text-decoration:underline;color:#fff!important}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}@media print{.CodeMirror pre.CodeMirror-cursor{visibility:hidden}}
|
|
@ -19,7 +19,7 @@ define(['yua'], function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
yua.ui.drag = '0.0.1'
|
||||||
// 元素拖动
|
// 元素拖动
|
||||||
yua.directive('drag', {
|
yua.directive('drag', {
|
||||||
priority: 1500,
|
priority: 1500,
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
v0.0.4-base / 2017-04-20
|
||||||
|
==================
|
||||||
|
+ 优化offset的处理
|
||||||
|
+ 优化样式
|
||||||
|
|
||||||
|
|
||||||
|
v0.0.3-base / 2017-04-15
|
||||||
|
==================
|
||||||
|
+ 重构wrap方式创建弹窗实例的实现
|
||||||
|
|
||||||
|
|
||||||
v0.0.2-base / 2017-04-13
|
v0.0.2-base / 2017-04-13
|
||||||
==================
|
==================
|
||||||
+ 修复:layer方式创建实例时,漏掉自身的bug;
|
+ 修复:layer方式创建实例时,漏掉自身的bug;
|
||||||
|
|
|
@ -13,6 +13,8 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
if(window.layer){
|
if(window.layer){
|
||||||
return window.layer
|
return window.layer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yua.ui.layer = '0.0.4-base'
|
||||||
var layerDom = {},
|
var layerDom = {},
|
||||||
layerObj = {},
|
layerObj = {},
|
||||||
unique = null, //储存当前打开的1/2/3类型的弹窗
|
unique = null, //储存当前打开的1/2/3类型的弹窗
|
||||||
|
@ -55,6 +57,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
layerObj[id].parentElem.replaceChild(layerObj[id].wrap, layerDom[id][1])
|
layerObj[id].parentElem.replaceChild(layerObj[id].wrap, layerDom[id][1])
|
||||||
|
layerObj[id].wrap.style.display = 'none'
|
||||||
layerObj[id].show = false
|
layerObj[id].show = false
|
||||||
|
|
||||||
}catch(err){}
|
}catch(err){}
|
||||||
|
@ -221,20 +224,21 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
yua(layerObj[conf].obj.init)
|
yua(layerObj[conf].obj.init)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layerObj[conf].parentElem.appendChild(layerDom[conf][1])
|
||||||
|
layerDom[conf][1].querySelector('.detail').appendChild(layerObj[conf].wrap)
|
||||||
|
layerObj[conf].wrap.style.display = ''
|
||||||
yua.scan(layerDom[conf][1])
|
yua.scan(layerDom[conf][1])
|
||||||
layerObj[conf].obj.show()
|
layerObj[conf].obj.show()
|
||||||
|
|
||||||
layerObj[conf].parentElem.appendChild(layerDom[conf][1])
|
|
||||||
layerObj[conf].parentElem.replaceChild(layerDom[conf][1], layerObj[conf].wrap)
|
|
||||||
return conf
|
return conf
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
return new __constructor(conf).init.$id
|
return new __constructor(conf).init.$id
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
version: '0.0.2-base'
|
version: yua.ui.layer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*type: { // 弹窗类型对应的id值
|
/*type: { // 弹窗类型对应的id值
|
||||||
1: 'alert',
|
1: 'alert',
|
||||||
2: 'confirm',
|
2: 'confirm',
|
||||||
|
@ -295,7 +299,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
}
|
}
|
||||||
|
|
||||||
layBox.innerHTML = this.getMenubar()
|
layBox.innerHTML = this.getMenubar()
|
||||||
+ '<div class="layer-content do-fn-cl '
|
+ '<div class="layer-content do-layer-cl '
|
||||||
+ (this.init.icon === 0 && 'none-icon' || '')
|
+ (this.init.icon === 0 && 'none-icon' || '')
|
||||||
+ '" style="'
|
+ '" style="'
|
||||||
+ boxcss
|
+ boxcss
|
||||||
|
@ -306,7 +310,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
+ (this.init.type === 5 && '<i class="arrow" style="border-top-color: '
|
+ (this.init.type === 5 && '<i class="arrow" style="border-top-color: '
|
||||||
+ this.init.background
|
+ this.init.background
|
||||||
+ '"></i>' || '')
|
+ '"></i>' || '')
|
||||||
|
delete this.init.wrap
|
||||||
return [this.init.shade ? coverBox : null, layBox]
|
return [this.init.shade ? coverBox : null, layBox]
|
||||||
},
|
},
|
||||||
getCont: function(){
|
getCont: function(){
|
||||||
|
@ -314,7 +318,9 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
return this.getLoading(this.init.load)
|
return this.getLoading(this.init.load)
|
||||||
}else{
|
}else{
|
||||||
return this.getIcon()
|
return this.getIcon()
|
||||||
+ '<div class="detail" :html="content"></div>'
|
+ '<div class="detail" '
|
||||||
|
+ (this.init.wrap ? '' : ':html="content"')
|
||||||
|
+ '></div>'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLoading: function(style){
|
getLoading: function(style){
|
||||||
|
@ -337,7 +343,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '>{{title}}'
|
html += '>{{title}}'
|
||||||
+ '<a class="action-close deficon" :click="no(\'' + this.init.$id + '\')"></a>'
|
+ '<a class="action-close def-font" :click="no(\'' + this.init.$id + '\')"></a>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
}
|
}
|
||||||
return html
|
return html
|
||||||
|
@ -348,7 +354,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
if(this.init.type < 4 || this.init.type === 5 || this.init.specialMode){
|
if(this.init.type < 4 || this.init.type === 5 || this.init.specialMode){
|
||||||
return '<span class="deficon icon-' + this.init.icon + '"></span>'
|
return '<span class="def-font msg-icon icon-' + this.init.icon + '"></span>'
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
|
@ -422,6 +428,16 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
style.right = fixOffset(_this.init.offset[1])
|
style.right = fixOffset(_this.init.offset[1])
|
||||||
style.bottom = fixOffset(_this.init.offset[2])
|
style.bottom = fixOffset(_this.init.offset[2])
|
||||||
style.left = fixOffset(_this.init.offset[3])
|
style.left = fixOffset(_this.init.offset[3])
|
||||||
|
//左右都为auto时,改为居中
|
||||||
|
if(style.left === 'auto' && style.right === 'auto'){
|
||||||
|
style.left = '50%'
|
||||||
|
style.marginLeft = -parseInt(css.width) / 2;
|
||||||
|
}
|
||||||
|
//上下都为auto时,同样改为居中
|
||||||
|
if(style.top === 'auto' && style.bottom === 'auto'){
|
||||||
|
style.top = '50%'
|
||||||
|
style.marginTop = -parseInt(css.height) / 2;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
style = yua.mix(style, {
|
style = yua.mix(style, {
|
||||||
marginLeft: -parseInt(css.width) / 2,
|
marginLeft: -parseInt(css.width) / 2,
|
||||||
|
@ -515,18 +531,19 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.param){
|
if(!this.param){
|
||||||
|
init.wrap = true
|
||||||
init.type = 7;
|
init.type = 7;
|
||||||
init.$id = '$wrap-' + val;
|
init.$id = '$wrap-' + val;
|
||||||
if(!init.hasOwnProperty('menubar')){
|
if(!init.hasOwnProperty('menubar')){
|
||||||
init.menubar = false;
|
init.menubar = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmp = new __constructor().ready(init),
|
var tmp = new __constructor().ready(init);
|
||||||
elem = this.element.cloneNode(true);
|
|
||||||
|
|
||||||
// 去掉隐藏之后,再放入content中
|
//去掉data-*属性
|
||||||
elem.style.display = ''
|
for(var i in this.element.dataset){
|
||||||
tmp.init.content = elem.outerHTML;
|
delete this.element.dataset[i]
|
||||||
|
}
|
||||||
|
|
||||||
layerObj[tmp.init.$id] = {obj: tmp, parentElem: this.element.parentNode, wrap: this.element, show: false};
|
layerObj[tmp.init.$id] = {obj: tmp, parentElem: this.element.parentNode, wrap: this.element, show: false};
|
||||||
layerDom[tmp.init.$id] = tmp.create();
|
layerDom[tmp.init.$id] = tmp.create();
|
|
@ -6,16 +6,16 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.do-fn-cl { *zoom: 1; }
|
|
||||||
.do-fn-cl:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; overflow:hidden;}
|
.do-layer, .do-layer * {vertical-align: baseline;box-sizing:border-box;}
|
||||||
.do-layer, .do-layer * {margin: 0;padding: 0;vertical-align: baseline;box-sizing:border-box;}
|
|
||||||
.do-layer a {text-decoration:none;}
|
.do-layer a {text-decoration:none;}
|
||||||
|
|
||||||
@font-face {font-family: "deficon";
|
@font-face {font-family: "def-font";
|
||||||
src: url('def.eot'); /* IE9*/
|
src: url('def.eot'); /* IE9*/
|
||||||
src: url('def.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
src: url('def.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.do-layer-cl::after {visibility:hidden;overflow:hidden;display:block;height: 0;content: ".";clear: both;}
|
||||||
.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 {position:fixed;left:0;top:0;z-index:65534;width:100%;height:100%;background:rgba(255,255,255,.05);}
|
||||||
.do-layer {position:fixed;left:50%;top:50%;z-index:65535;width:auto;height:auto;}
|
.do-layer {position:fixed;left:50%;top:50%;z-index:65535;width:auto;height:auto;}
|
||||||
.do-layer:active {z-index:65536;}
|
.do-layer:active {z-index:65536;}
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/*默认皮肤样式*/
|
/*默认皮肤样式*/
|
||||||
.do-layer.skin-def {color:#666;font-size:14px;box-shadow:0 0 10px rgba(0,0,0,.3);}
|
.do-layer.skin-def {color:#666;font-size:14px;box-shadow:0 0 10px rgba(0,0,0,.3);}
|
||||||
.do-layer.skin-def .deficon {display: inline-block;font-family:"deficon" !important;font-style:normal;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
.do-layer.skin-def .def-font {display: inline-block;font-family:"def-font" !important;font-style:normal;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
||||||
.do-layer.skin-def .icon-1:before {content:"\e6f1";color:#11b330;}/*discover*/
|
.do-layer.skin-def .icon-1:before {content:"\e6f1";color:#11b330;}/*discover*/
|
||||||
.do-layer.skin-def .icon-2:before {content:"\e6fa";color:#f30;}/*position*/
|
.do-layer.skin-def .icon-2:before {content:"\e6fa";color:#f30;}/*position*/
|
||||||
.do-layer.skin-def .icon-3:before {content:"\e6f0";color:#f30;}/*del*/
|
.do-layer.skin-def .icon-3:before {content:"\e6f0";color:#f30;}/*del*/
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
.do-layer.skin-def .action-close:before {content:"\e659";}
|
.do-layer.skin-def .action-close:before {content:"\e659";}
|
||||||
|
|
||||||
.do-layer.skin-def .layer-content {position:relative;width:100%;height:auto;min-height:50px;padding:10px;}
|
.do-layer.skin-def .layer-content {position:relative;width:100%;height:auto;min-height:50px;padding:10px;}
|
||||||
.do-layer.skin-def .layer-content .deficon {position:absolute;left:10px;top:10px;width:50px;height:auto;line-height:40px;font-size:40px;text-align:center;}
|
.do-layer.skin-def .layer-content .msg-icon {position:absolute;left:10px;top:10px;width:50px;height:auto;line-height:40px;font-size:40px;text-align:center;}
|
||||||
.do-layer.skin-def .layer-content .detail {width:auto;height:100%;margin:auto auto auto 60px;padding:5px 15px;word-break:break-all;word-wrap: break-word;}
|
.do-layer.skin-def .layer-content .detail {width:auto;height:100%;margin:auto auto auto 60px;padding:5px 15px;word-break:break-all;word-wrap: break-word;}
|
||||||
.do-layer.skin-def .layer-content.none-icon .detail {margin:0 auto;}
|
.do-layer.skin-def .layer-content.none-icon .detail {margin:0 auto;}
|
||||||
.do-layer.skin-def .layer-content .detail .prompt-value {width: 230px;height: 30px;padding: 0 8px;border: 1px solid #ddd;border-radius: 3px;}
|
.do-layer.skin-def .layer-content .detail .prompt-value {width: 230px;height: 30px;padding: 0 8px;border: 1px solid #ddd;border-radius: 3px;}
|
||||||
|
|
|
@ -827,9 +827,11 @@ Renderer.prototype.heading = function(text, level, raw) {
|
||||||
+ level
|
+ level
|
||||||
+ ' class="md-hd" id="'
|
+ ' class="md-hd" id="'
|
||||||
+ raw
|
+ raw
|
||||||
|
+ '"><a href="#'
|
||||||
|
+ raw
|
||||||
+ '">'
|
+ '">'
|
||||||
+ text
|
+ text
|
||||||
+ '</h'
|
+ '</a></h'
|
||||||
+ level
|
+ level
|
||||||
+ '>\n';
|
+ '>\n';
|
||||||
};
|
};
|
||||||
|
@ -1027,7 +1029,7 @@ Parser.prototype.tok = function() {
|
||||||
}
|
}
|
||||||
case 'code': {
|
case 'code': {
|
||||||
return this.renderer.code(this.token.text,
|
return this.renderer.code(this.token.text,
|
||||||
this.token.lang,
|
this.token.lang || 'other',
|
||||||
this.token.escaped);
|
this.token.escaped);
|
||||||
}
|
}
|
||||||
case 'table': {
|
case 'table': {
|
||||||
|
@ -1124,7 +1126,7 @@ Parser.prototype.tok = function() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function escape(html, encode) {
|
function escape(html, encode) {
|
||||||
return html
|
return (html)
|
||||||
.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
|
.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
.replace(/>/g, '>')
|
.replace(/>/g, '>')
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-20 19:13:24
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.do-meditor-attach {width:630px;height:auto;background:#f7f7f7;cursor:default;}
|
||||||
|
.do-meditor-attach .attach-wrap {width:100%;height:auto;}
|
||||||
|
|
||||||
|
.do-meditor-attach .tab-box {width:100%;height:50px;line-height:49px;border-bottom:1px solid #e2e2e2;text-align:center;}
|
||||||
|
.do-meditor-attach .tab-box .item {position:relative;float:left;width:100px;height:49px;border-right:1px solid #ddd;cursor:pointer;}
|
||||||
|
.do-meditor-attach .tab-box .item.active {background:#fff;}
|
||||||
|
.do-meditor-attach .tab-box .item.active::after {position:absolute;left:0;bottom:-1px;width:100%;height:1px;background:#fff;content:""}
|
||||||
|
.do-meditor-attach .tab-box a.action-close {top:5px;width:40px;height:40px;line-height:40px;font-size:20px;}
|
||||||
|
.do-meditor-attach .tab-box a.action-close:hover {line-height:40px;border:0;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box {position:relative;width:100%;height:auto;min-height:200px;background:#fff;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .remote,
|
||||||
|
.do-meditor-attach .cont-box .local {position:relative;width:60%;height:auto;margin:0 auto;padding:15px 0 30px;}
|
||||||
|
.do-meditor-attach .cont-box .local {width:96%;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .hide {display:none;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .section {display:block;width:100%;height:auto;margin:15px 0;line-height:35px;}
|
||||||
|
.do-meditor-attach .cont-box .section::after {visibility: hidden;overflow:hidden; display: block;height: 0;content: "."; clear: both;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .section .label {float: left;width:30%;text-align:center;background:#e2e2e2;}
|
||||||
|
.do-meditor-attach .cont-box .section label {float: left;width:50%;}
|
||||||
|
.do-meditor-attach .cont-box .section .input {float: left;width:70%;height:35px;padding:0 8px;border:1px solid #e2e2e2;border-left:0;background:#fff;color:#666;}
|
||||||
|
.do-meditor-attach .cont-box .section .submit {float:right;width:30%;height:35px;border:1px solid #ddd;background:#f7f7f7;color:#666;text-align:center;}
|
||||||
|
.do-meditor-attach .cont-box .section .submit:hover {border:1px solid #049789;}
|
||||||
|
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .select-file {width:100%;height:35px;line-height:33px}
|
||||||
|
.do-meditor-attach .cont-box .select-file span.file {float:left;width:100px;height:35px;border:1px solid #ddd;background:#f7f7f7;color:#666;text-align:center;cursor:pointer;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box {width:100%;height:auto;min-height:190px;margin:10px 0;border:1px solid #e2e2e2;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .tr {width:100%;height:35px;line-height:35px;text-align:center;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .tr:hover {background:#fafafa}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .thead {line-height:34px;border-bottom:1px solid #e2e2e2;background:#f7f7f7;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .upload-box .td {float:left;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .td.name {width:50%;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .td.progress {width:20%;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .td.option {width:30%;}
|
||||||
|
.do-meditor-attach .cont-box .upload-box .td.option a {display:inline-block;padding:3px 5px;line-height:13px;border:1px solid #e2e2e2;background:#f7f7f7;color:#666;}
|
||||||
|
|
||||||
|
.do-meditor-attach .cont-box .manager {overflow:hidden;overflow-y:auto;width:100%;height:320px;padding:10px;}
|
||||||
|
.do-meditor-attach .cont-box .manager .item {float:left;width:22%;height:130px;margin:10px 1.5%;}
|
||||||
|
.do-meditor-attach .cont-box .manager .item:hover {background:#f7f7f7;}
|
||||||
|
.do-meditor-attach .cont-box .manager .thumb {display:block;width:100%;height:100px;}
|
||||||
|
.do-meditor-attach .cont-box .manager .name {overflow:hidden;line-height:30px;text-align:center;}
|
||||||
|
.do-meditor-attach .cont-box .manager img {width:100%;height:100%;}
|
||||||
|
.do-meditor-attach .cont-box .manager .attac-icon {display:inline-block;width:100%;height:100px;text-align:center;font:50px/100px "edicon" !important;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
||||||
|
|
|
@ -0,0 +1,331 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-19 21:17:26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
define([
|
||||||
|
'lib/layer/base',
|
||||||
|
'css!./attach'
|
||||||
|
], function(){
|
||||||
|
|
||||||
|
var Uploader = function(url){
|
||||||
|
this.url = url || ''
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
Uploader.prototype = {
|
||||||
|
init: function(){
|
||||||
|
this.xhr = new XMLHttpRequest()
|
||||||
|
this.form = new FormData()
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
field: function(key, val){
|
||||||
|
if(typeof key === 'object'){
|
||||||
|
for(var i in key){
|
||||||
|
this.form.append(i, key[i])
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.form.append(key, val)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
start: function(){
|
||||||
|
var _this = this
|
||||||
|
|
||||||
|
this.xhr.open('POST', this.url, true)
|
||||||
|
|
||||||
|
var startTime = Date.now()
|
||||||
|
|
||||||
|
this.xhr.upload.addEventListener('progress', function(evt){
|
||||||
|
|
||||||
|
if(evt.lengthComputable && _this.progress){
|
||||||
|
var res = Math.round(evt.loaded * 100 / evt.total)
|
||||||
|
_this.progress(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
this.xhr.onreadystatechange = function(){
|
||||||
|
if(_this.xhr.readyState === 4){
|
||||||
|
if(_this.xhr.status >= 200 && _this.xhr.status < 205){
|
||||||
|
var res = _this.xhr.responseText
|
||||||
|
try{
|
||||||
|
res = JSON.parse(res)
|
||||||
|
}catch(err){}
|
||||||
|
_this.end && _this.end(res)
|
||||||
|
}else{
|
||||||
|
console.error(_this.xhr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.xhr.send(this.form)
|
||||||
|
|
||||||
|
},
|
||||||
|
onProgress: function(fn){
|
||||||
|
this.progress = fn
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
onEnd: function(fn){
|
||||||
|
this.end = fn
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var $init = function(vm){
|
||||||
|
if(!vm.uploadUrl && !ME.uploadUrl){
|
||||||
|
console.error('使用附件上传,必须先设置uploadUrl;\n可以给vm增加uploadUrl属性,也可以通过ME.uploadUrl设置')
|
||||||
|
}
|
||||||
|
if(!vm.manageUrl && !ME.manageUrl){
|
||||||
|
console.error('使用附件管理功能,必须先设置manageUrl;\n可以给vm增加manageUrl属性,也可以通过ME.manageUrl设置')
|
||||||
|
}
|
||||||
|
// ME.addon.image()
|
||||||
|
|
||||||
|
vm.$editor.addEventListener('paste', function(ev){
|
||||||
|
var txt = ev.clipboardData.getData('text/plain').trim(),
|
||||||
|
html = ev.clipboardData.getData('text/html').trim();
|
||||||
|
|
||||||
|
//文本类型直接默认处理
|
||||||
|
if(txt || html){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ev.clipboardData.items){
|
||||||
|
var items = ev.clipboardData.items,
|
||||||
|
len = items.length,
|
||||||
|
blob = null;
|
||||||
|
for(var i = 0,it; it = items[i++];){
|
||||||
|
if(it.type.indexOf('image') > -1){
|
||||||
|
blob = it.getAsFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blob !== null) {
|
||||||
|
var upload = new Uploader(vm.uploadUrl || ME.uploadUrl)
|
||||||
|
|
||||||
|
upload.field('image', blob)
|
||||||
|
.onEnd(function(json){
|
||||||
|
ME.insert(vm.$editor, '![截图](' + json.data.url + ')')
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ev.preventDefault()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
lang = {
|
||||||
|
image: ['远程图片', '图片管理', '图片描述', '图片地址'],
|
||||||
|
file: ['远程附件', '附件管理', '附件描述', '附件地址']
|
||||||
|
},
|
||||||
|
opened = false, //记录是否已经打开
|
||||||
|
openType = 'image', //打开类型, 图片/附件
|
||||||
|
cache = { //缓存附件列表
|
||||||
|
image: [],
|
||||||
|
file: []
|
||||||
|
},
|
||||||
|
fixCont = function(){
|
||||||
|
return '<div class="do-meditor-attach meditor-font">'
|
||||||
|
+ '<dl class="attach-wrap">'
|
||||||
|
+ '<dt class="tab-box">'
|
||||||
|
+ '<span class="item" :class="active:tab === 1" :click="$switch(1)">' + lang[openType][0] +'</span>'
|
||||||
|
+ '<span class="item" :class="active:tab === 2" :click="$switch(2)">本地上传</span>'
|
||||||
|
+ '<span class="item" :class="active:tab === 3" :click="$switch(3)">' + lang[openType][1] + '</span>'
|
||||||
|
+ '<a href="javascript:;" :click="no" class="action-close def-font"></a>'
|
||||||
|
+ '</dt>'
|
||||||
|
+ '<dt class="cont-box">'
|
||||||
|
+ '<div class="remote" :visible="tab === 1">'
|
||||||
|
+ '<section class="section"><span class="label">'+ lang[openType][2] + '</span>'
|
||||||
|
+ '<input class="input" :duplex="attachAlt" />'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section class="section"><span class="label">'+ lang[openType][3] + '</span>'
|
||||||
|
+ '<input class="input" :duplex="attach" />'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section class="section">'
|
||||||
|
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '<div class="local" :visible="tab === 2">'
|
||||||
|
+ '<div class="select-file"><input id="meditor-attch" multiple :change="$change" type="file" class="hide" /><span class="file" :click="$select">选择文件</span></div>'
|
||||||
|
+ '<ul class="upload-box">'
|
||||||
|
+ '<li class="tr thead"><span class="td name">文件名</span><span class="td progress">上传进度</span><span class="td option">操作</span></li>'
|
||||||
|
+ '<li class="tr" :repeat="uploadFile">'
|
||||||
|
+ '<span class="td name" :text="el.name"></span>'
|
||||||
|
+ '<span class="td progress" :text="el.progress"></span>'
|
||||||
|
+ '<span class="td option"><a href="javascript:;" :click="$insert(el)">插入</a></span>'
|
||||||
|
+ '</li>'
|
||||||
|
+ '</ul>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '<ul class="manager" :visible="tab === 3">'
|
||||||
|
+ '<li class="item" :repeat="attachList" :click="$insert(el)">'
|
||||||
|
+ '<span class="thumb" :html="el.thumb"></span>'
|
||||||
|
+ '<p class="name" :text="el.name"></p>'
|
||||||
|
+ '</li>'
|
||||||
|
+ '</ul>'
|
||||||
|
+ '</dt>'
|
||||||
|
+ '</dl>'
|
||||||
|
+ '</div>'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [uploadFile 文件上传]
|
||||||
|
* @param {[type]} files [文件列表]
|
||||||
|
* @param {[type]} vm [vm对象]
|
||||||
|
* @param {[type]} type [image/file]
|
||||||
|
*/
|
||||||
|
function uploadFile(files, vm){
|
||||||
|
for(var i = 0, it; it = files[i++];){
|
||||||
|
if(openType === 'image' && !/image/.test(it.type)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var idx = vm.uploadFile.length,
|
||||||
|
upload = new Uploader(vm.uploadUrl || ME.uploadUrl)
|
||||||
|
|
||||||
|
|
||||||
|
vm.uploadFile.push({name: it.name, progress: '0%', url: ''})
|
||||||
|
upload.field(openType, it)
|
||||||
|
.onProgress(function(val){
|
||||||
|
vm.uploadFile[idx].progress = val + '%'
|
||||||
|
}).onEnd(function(json){
|
||||||
|
vm.uploadFile[idx].url = json.data.url
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAttach(vm, cb){
|
||||||
|
var xhr = new XMLHttpRequest(),
|
||||||
|
url = vm.manageUrl || ME.manageUrl;
|
||||||
|
|
||||||
|
if(/\?/.test(url)){
|
||||||
|
url += '&type=' + openType
|
||||||
|
}else{
|
||||||
|
url += '?type=' + openType
|
||||||
|
}
|
||||||
|
url += '&t=' + Math.random()
|
||||||
|
|
||||||
|
xhr.open('GET', url, true)
|
||||||
|
xhr.onreadystatechange = function(){
|
||||||
|
if(this.readyState === 4 &&
|
||||||
|
this.status === 200 &&
|
||||||
|
this.responseText !== ''){
|
||||||
|
var res = this.responseText
|
||||||
|
try{
|
||||||
|
res = JSON.parse(res)
|
||||||
|
}catch(err){}
|
||||||
|
cb(res)
|
||||||
|
}else{
|
||||||
|
if(this.status !== 200 && this.responseText)
|
||||||
|
console.error(this.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.send()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDialog(elem, vm){
|
||||||
|
opened = true
|
||||||
|
var offset = yua(elem).offset(),
|
||||||
|
layid = layer.open({
|
||||||
|
type: 7,
|
||||||
|
menubar: false,
|
||||||
|
shade: false,
|
||||||
|
offset: [offset.top + 37],
|
||||||
|
tab: 2,
|
||||||
|
attach: '',
|
||||||
|
attachAlt: '',
|
||||||
|
uploadFile: [], //当前上传的列表
|
||||||
|
attachList: [], //附件管理列表
|
||||||
|
$switch: function(id){
|
||||||
|
var lvm = yua.vmodels[layid]
|
||||||
|
|
||||||
|
lvm.tab = id
|
||||||
|
if(id === 3){
|
||||||
|
lvm.attachList.clear()
|
||||||
|
if(cache[openType].length){
|
||||||
|
lvm.attachList = cache[openType]
|
||||||
|
}else{
|
||||||
|
getAttach(vm, function(json){
|
||||||
|
if(json){
|
||||||
|
cache[openType] = json.data.list.map(function(it){
|
||||||
|
it.thumb = openType === 'image' ? '<img src="' + it.url + '"/>' : '<em class="attac-icon"></em>'
|
||||||
|
return it
|
||||||
|
})
|
||||||
|
lvm.attachList = json.data.list
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
$select: yua.noop,
|
||||||
|
$change: yua.noop,
|
||||||
|
$insert: function(it){
|
||||||
|
var val = (openType === 'image' ? '!' : '')
|
||||||
|
+ '[' + it.name + '](' + it.url + ')'
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
},
|
||||||
|
$confirm: function(){
|
||||||
|
var lvm = yua.vmodels[layid]
|
||||||
|
if(!lvm.img || !lvm.imgAlt){
|
||||||
|
return layer.alert('描述和地址不能为空')
|
||||||
|
}
|
||||||
|
var val = '![' + lvm.imgAlt + '](' + lvm.img + ')'
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
lvm.no()
|
||||||
|
},
|
||||||
|
success: function(id){
|
||||||
|
var _this = yua.vmodels[id],
|
||||||
|
$file = document.body.querySelector('#meditor-attch')
|
||||||
|
|
||||||
|
_this.no = function(){
|
||||||
|
layer.close(id)
|
||||||
|
opened = false
|
||||||
|
}
|
||||||
|
_this.$select = function(){
|
||||||
|
var ev = document.createEvent('MouseEvent')
|
||||||
|
ev.initEvent('click', false, false)
|
||||||
|
$file.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
_this.$change = function(){
|
||||||
|
uploadFile(this.files, _this)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content: fixCont()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ME.addon.image = function(elem, vm){
|
||||||
|
if(opened){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
openType = 'image'
|
||||||
|
showDialog(elem, vm)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ME.addon.file = function(elem, vm){
|
||||||
|
if(opened){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
openType = 'file'
|
||||||
|
showDialog(elem, vm)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return $init
|
||||||
|
|
||||||
|
|
||||||
|
})
|
|
@ -0,0 +1,366 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-17 21:41:48
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define(['lib/layer/base'], function(){
|
||||||
|
|
||||||
|
function objArr(num){
|
||||||
|
var arr = []
|
||||||
|
while(num > 0){
|
||||||
|
arr.push({v: 0})
|
||||||
|
num--
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
function trim(str, sign){
|
||||||
|
return str.replace(new RegExp('^' + sign + '|' + sign + '$', 'g'), '')
|
||||||
|
}
|
||||||
|
function getOrderArr(len){
|
||||||
|
var arr = [], i = 0;
|
||||||
|
while(i < len){
|
||||||
|
arr.push(i++)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
ME.addon = {
|
||||||
|
h1: function(elem, vm){
|
||||||
|
var offset = yua(elem).offset(),
|
||||||
|
wrap = ME.selection(vm.$editor, true) || '在此输入文本',
|
||||||
|
h1Obj = layer.open({
|
||||||
|
type: 7,
|
||||||
|
menubar: false,
|
||||||
|
shadeClose: true,
|
||||||
|
fixed: true,
|
||||||
|
$insert: function(level){
|
||||||
|
wrap = wrap.replace(/^#{1,6} /, '')
|
||||||
|
wrap = ME.repeat('#', level) + ' ' + wrap
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
layer.close(h1Obj)
|
||||||
|
},
|
||||||
|
offset: [offset.top + 37, 'auto', 'auto', offset.left],
|
||||||
|
content: '<ul class="do-meditor-h1 do-fn-noselect meditor-font">'
|
||||||
|
+ '<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){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
|
wrap = '> ' + wrap
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
bold: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
|
wraped = trim(wrap, '\\*\\*')
|
||||||
|
|
||||||
|
wrap = wrap === wraped ? ('**' + wrap + '**') : wraped
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
italic: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
|
wraped = trim(wrap, '_')
|
||||||
|
|
||||||
|
wrap = wrap === wraped ? ('_' + wrap + '_') : wraped
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
through: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||||
|
wraped = trim(wrap, '~~')
|
||||||
|
|
||||||
|
wrap = wrap === wraped ? ('~~' + wrap + '~~') : wraped
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
unordered: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
|
wrap = '* ' + wrap
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
ordered: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
|
wrap = '1. ' + wrap
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
hr: function(elem, vm){
|
||||||
|
ME.insert(vm.$editor, '\n\n---\n\n')
|
||||||
|
},
|
||||||
|
link: function(elem, vm){
|
||||||
|
var offset = yua(elem).offset(),
|
||||||
|
wrap = ME.selection(vm.$editor) || '',
|
||||||
|
layid = layer.open({
|
||||||
|
type: 7,
|
||||||
|
menubar: false,
|
||||||
|
shadeClose: true,
|
||||||
|
fixed: true,
|
||||||
|
link: '',
|
||||||
|
linkName: wrap,
|
||||||
|
linkTarget: 1,
|
||||||
|
$confirm: function(){
|
||||||
|
var lvm = yua.vmodels[layid]
|
||||||
|
if(!lvm.link || !lvm.linkName){
|
||||||
|
return layer.alert('链接文字和地址不能为空')
|
||||||
|
}
|
||||||
|
var val = '[' + lvm.linkName + ']('
|
||||||
|
+ lvm.link
|
||||||
|
+ (lvm.linkTarget === 1 ? ' "target=_blank"' : '')
|
||||||
|
+ ')'
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
layer.close(layid)
|
||||||
|
},
|
||||||
|
offset: [offset.top + 37, 'auto', 'auto', offset.left],
|
||||||
|
content: '<div class="do-meditor-common meditor-font">'
|
||||||
|
+ '<section><span class="label">链接文字</span>'
|
||||||
|
+ '<input class="input" :duplex="linkName" />'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section><span class="label">链接地址</span>'
|
||||||
|
+ '<input class="input" :duplex="link"/>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section>'
|
||||||
|
+ '<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){
|
||||||
|
ME.insert(vm.$editor, new Date().format())
|
||||||
|
},
|
||||||
|
face: function(elem, vm){
|
||||||
|
var offset = yua(elem).offset(),
|
||||||
|
faceid = 0,
|
||||||
|
layid = layer.open({
|
||||||
|
type: 7,
|
||||||
|
title: '插入表情',
|
||||||
|
fixed: true,
|
||||||
|
shadeClose: true,
|
||||||
|
arr: getOrderArr(36),
|
||||||
|
offset: [offset.top + 37, 'auto', 'auto', offset.left],
|
||||||
|
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 + ')')
|
||||||
|
layer.close(layid)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
table: function(elem, vm){
|
||||||
|
var offset = yua(elem).offset();
|
||||||
|
layer.open({
|
||||||
|
type: 7,
|
||||||
|
title: '0行 x 0列',
|
||||||
|
fixed: true,
|
||||||
|
shadeClose: true,
|
||||||
|
offset: [offset.top + 37, 'auto', 'auto', offset.left],
|
||||||
|
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'),
|
||||||
|
_this = yua.vmodels[id],
|
||||||
|
lastx,lasty;
|
||||||
|
yua(tb).bind('mousemove', function(ev){
|
||||||
|
if(ev.target.nodeName === 'SPAN'){
|
||||||
|
var x = ev.target.dataset.x - 0,
|
||||||
|
y = ev.target.dataset.y - 0;
|
||||||
|
if(x === lastx && y === lasty){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastx = x;
|
||||||
|
lasty = y;
|
||||||
|
_this.title = (y + 1) + '行 x ' + (x + 1) + '列'
|
||||||
|
for(var i = 0; i <= 9; i++){
|
||||||
|
for(var j = 0; j <= 9; j++){
|
||||||
|
_this.matrix[i][j].v = (i <= y && j <= x) ? 1 : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
yua(tb).bind('mouseleave', function(ev){
|
||||||
|
lastx = -1;
|
||||||
|
lasty = -1;
|
||||||
|
_this.title = '0行 x 0列'
|
||||||
|
for(var i = 0; i <= 9; i++){
|
||||||
|
for(var j = 0; j <= 9; j++){
|
||||||
|
_this.matrix[i][j].v = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
yua(tb).bind('click', function(ev){
|
||||||
|
if(ev.target.nodeName === 'SPAN'){
|
||||||
|
var x = ev.target.dataset.x - 0 + 1,
|
||||||
|
y = ev.target.dataset.y - 0 + 1;
|
||||||
|
|
||||||
|
var val = '\n\n' + ME.repeat('| 表头 ', x) + '|\n'
|
||||||
|
+ ME.repeat('| -- ', x) + '|\n'
|
||||||
|
+ ME.repeat(ME.repeat('| ', x) + '|\n', y)
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
layer.close(id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
image: function(elem, vm){
|
||||||
|
var offset = yua(elem).offset(),
|
||||||
|
wrap = ME.selection(vm.$editor) || '',
|
||||||
|
layid = layer.open({
|
||||||
|
type: 7,
|
||||||
|
menubar: false,
|
||||||
|
shadeClose: true,
|
||||||
|
fixed: true,
|
||||||
|
img: '',
|
||||||
|
imgAlt: wrap,
|
||||||
|
$confirm: function(){
|
||||||
|
var lvm = yua.vmodels[layid]
|
||||||
|
if(!lvm.img || !lvm.imgAlt){
|
||||||
|
return layer.alert('图片描述和图片地址不能为空')
|
||||||
|
}
|
||||||
|
var val = '![' + lvm.imgAlt + '](' + lvm.img + ')'
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
layer.close(layid)
|
||||||
|
},
|
||||||
|
offset: [offset.top + 37, 'auto', 'auto', offset.left],
|
||||||
|
content: '<div class="do-meditor-common meditor-font">'
|
||||||
|
+ '<section><span class="label">图片描述</span>'
|
||||||
|
+ '<input class="input" :duplex="imgAlt" />'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section><span class="label">图片地址</span>'
|
||||||
|
+ '<input class="input" :duplex="img"/>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section>'
|
||||||
|
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '</div>'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
file: function(elem, vm){
|
||||||
|
this.link(elem, vm)
|
||||||
|
},
|
||||||
|
inlinecode: function(elem, vm){
|
||||||
|
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||||
|
wrap = '`' + wrap + '`'
|
||||||
|
ME.insert(vm.$editor, wrap)
|
||||||
|
},
|
||||||
|
blockcode: function(elem, vm){
|
||||||
|
var layid = layer.open({
|
||||||
|
type: 7,
|
||||||
|
title: '添加代码块',
|
||||||
|
$lang: [
|
||||||
|
{id: 'asp'},
|
||||||
|
{id: 'actionscript', name: 'ActionScript(3.0)/Flash/Flex'},
|
||||||
|
{id: 'bash', name: 'Bash/Shell/Bat'},
|
||||||
|
{id: 'css'},
|
||||||
|
{id: 'c', name: 'C'},
|
||||||
|
{id: 'cpp', name: 'C++'},
|
||||||
|
{id: 'csharp', name: 'C#'},
|
||||||
|
{id: 'coffeescript', name: 'CoffeeScript'},
|
||||||
|
{id: 'd', name: 'D'},
|
||||||
|
{id: 'dart'},
|
||||||
|
{id: 'delphi', name: 'Delphi/Pascal'},
|
||||||
|
{id: 'erlang'},
|
||||||
|
{id: 'go', name: 'Golang'},
|
||||||
|
{id: 'html'},
|
||||||
|
{id: 'java'},
|
||||||
|
{id: 'javascript'},
|
||||||
|
{id: 'json'},
|
||||||
|
{id: 'lua'},
|
||||||
|
{id: 'less'},
|
||||||
|
{id: 'markdown'},
|
||||||
|
{id: 'nginx'},
|
||||||
|
{id: 'objective-c'},
|
||||||
|
{id: 'php'},
|
||||||
|
{id: 'perl'},
|
||||||
|
{id: 'python'},
|
||||||
|
{id: 'r', name: 'R'},
|
||||||
|
{id: 'ruby'},
|
||||||
|
{id: 'sql'},
|
||||||
|
{id: 'sass', name: 'SASS/SCSS'},
|
||||||
|
{id: 'swift'},
|
||||||
|
{id: 'typescript'},
|
||||||
|
{id: 'xml'},
|
||||||
|
{id: 'yaml'},
|
||||||
|
{id: 'other', name: '其他语言'},
|
||||||
|
],
|
||||||
|
lang: 'javascript',
|
||||||
|
code: '',
|
||||||
|
$confirm: function(){
|
||||||
|
var lvm = yua.vmodels[layid]
|
||||||
|
var val = '\n```' + lvm.lang + '\n' + (lvm.code || '//在此输入代码') + '\n```\n'
|
||||||
|
|
||||||
|
ME.insert(vm.$editor, val)
|
||||||
|
layer.close(layid)
|
||||||
|
},
|
||||||
|
content: '<div class="do-meditor-codeblock meditor-font">'
|
||||||
|
+ '<section><span class="label">语言类型</span>'
|
||||||
|
+ '<select :duplex="lang">'
|
||||||
|
+ '<option :ME.repeat="$lang" :attr-value="el.id">{{el.name || el.id}}</option>'
|
||||||
|
+ '</select>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section>'
|
||||||
|
+ '<textarea :duplex="code" placeholder="在这里输入/粘贴代码"></textarea>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '<section>'
|
||||||
|
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
||||||
|
+ '</section>'
|
||||||
|
+ '</div>'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
preview: function(elem, vm){
|
||||||
|
vm.preview = !vm.preview
|
||||||
|
if(vm.preview){
|
||||||
|
vm.htmlTxt = vm.$htmlTxt
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fullscreen: function(elem, vm){
|
||||||
|
vm.fullscreen = !vm.fullscreen
|
||||||
|
if(vm.fullscreen){
|
||||||
|
vm.preview = true
|
||||||
|
vm.htmlTxt = vm.$htmlTxt
|
||||||
|
}else{
|
||||||
|
vm.preview = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
about: function(elem){
|
||||||
|
var offset = yua(elem).offset()
|
||||||
|
layer.open({
|
||||||
|
type: 7,
|
||||||
|
title: '关于编辑器',
|
||||||
|
offset: [offset.top + 37],
|
||||||
|
content: '<div class="do-meditor-about meditor-font">'
|
||||||
|
+ '<pre>'
|
||||||
|
+ ' __ __ _____ _ _ _\n'
|
||||||
|
+ '| \\/ | ____|__| (_) |_ ___ _ __\n'
|
||||||
|
+ '| |\\/| | _| / _` | | __/ _ \\| \'__|\n'
|
||||||
|
+ '| | | | |__| (_| | | || (_) | |\n'
|
||||||
|
+ '|_| |_|_____\\__,_|_|\\__\\___/|_| '
|
||||||
|
+ 'v' + ME.version + '</pre>'
|
||||||
|
+ '<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>'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,383 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-17 16:37:12
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var log = console.log;
|
||||||
|
define([
|
||||||
|
'yua',
|
||||||
|
'lib/prism/main',
|
||||||
|
'lib/marked',
|
||||||
|
'css!./skin/main',
|
||||||
|
], function(yua){
|
||||||
|
|
||||||
|
marked.setOptions({
|
||||||
|
highlight: function(code, lang){
|
||||||
|
return Prism.highlight(code, Prism.languages[lang])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
yua.ui.meditor = '0.0.1'
|
||||||
|
//存放编辑器公共静态资源
|
||||||
|
window.ME = {
|
||||||
|
version: yua.ui.meditor,
|
||||||
|
toolbar: { //工具栏title
|
||||||
|
pipe: '',
|
||||||
|
h1: '标题',
|
||||||
|
bold: '粗体',
|
||||||
|
italic: '斜体',
|
||||||
|
through: '删除线',
|
||||||
|
unordered: '无序列表',
|
||||||
|
ordered: '有序列表',
|
||||||
|
hr: '横线',
|
||||||
|
time: '插入当前时间',
|
||||||
|
face: '表情',
|
||||||
|
table: '插入表格',
|
||||||
|
image: '插入图片',
|
||||||
|
file: '插入附件',
|
||||||
|
inlinecode: '行内代码',
|
||||||
|
blockcode: '代码块',
|
||||||
|
preview: '预览',
|
||||||
|
fullscreen: '全屏',
|
||||||
|
about: '关于编辑器',
|
||||||
|
},
|
||||||
|
addon: {}, //已有插件
|
||||||
|
//往文本框中插入内容
|
||||||
|
insert: function(dom, val){
|
||||||
|
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 = startPos
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取真实的引用路径,避免因为不同的目录结构导致加载失败的情况
|
||||||
|
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){
|
||||||
|
str = decodeURIComponent(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')
|
||||||
|
})
|
||||||
|
log(match)
|
||||||
|
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="edicon icon-' + name+ '" '
|
||||||
|
+ (name !== 'pipe' ? (':click="$onToolbarClick(\'' + name + '\')"') : '')
|
||||||
|
+ '></span>'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
yua.component('meditor', {
|
||||||
|
$template: '<div class="do-meditor meditor-font" :class="{fullscreen: fullscreen}">'
|
||||||
|
+ '<div class="tool-bar do-fn-noselect">{toolbar}</div>'
|
||||||
|
+ '<div class="editor-body">'
|
||||||
|
+ '<textarea spellcheck="false" :duplex="plainTxt" :attr="{disabled: disabled}" :on-paste="$paste($event)" id="{uuid}"></textarea>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '<div class="editor-md-preview" :visible="preview">'
|
||||||
|
+ '<content class="preview" :html="htmlTxt"></content>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '</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
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$ready: function(vm){
|
||||||
|
vm.$editor = document.querySelector('#' + vm.$id)
|
||||||
|
|
||||||
|
//自动加载额外的插件
|
||||||
|
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){
|
||||||
|
|
||||||
|
//tab键改为插入4个空格,阻止默认事件,防止焦点失去
|
||||||
|
if(ev.keyCode === 9){
|
||||||
|
var wrap = ME.selection(vm.$editor) || ''
|
||||||
|
wrap = wrap.split('\n').map(function(it){
|
||||||
|
return ev.shiftKey ? it.replace(/^\s\s/, '') : ' ' + it
|
||||||
|
}).join('\n')
|
||||||
|
ME.insert(this, wrap)
|
||||||
|
ev.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
$paste: function(ev){
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
ev.preventDefault()
|
||||||
|
},
|
||||||
|
$compile: function(){
|
||||||
|
//只解析,不渲染
|
||||||
|
this.$htmlTxt = marked(this.plainTxt.trim())
|
||||||
|
},
|
||||||
|
$onToolbarClick: yua.noop,
|
||||||
|
$onUpdate: yua.noop,
|
||||||
|
disabled: false, //禁用编辑器
|
||||||
|
fullscreen: true, //是否全屏
|
||||||
|
preview: false, //是否显示预览
|
||||||
|
$editor: null, //编辑器元素
|
||||||
|
$htmlTxt: '', //临时储存html文本
|
||||||
|
htmlTxt: '', //用于预览渲染
|
||||||
|
plainTxt: '' //纯md文本
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
|
@ -0,0 +1,152 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-17 16:43:22
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@font-face {font-family: "edicon";
|
||||||
|
src: url('iconfont.eot'); /* IE9*/
|
||||||
|
src: url('iconfont.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {width:5px;height:5px;background:#ebeeec;}
|
||||||
|
::-webkit-scrollbar:hover {background:rgba(0,0,0,.05);}
|
||||||
|
::-webkit-scrollbar-button {display:none;}
|
||||||
|
::-webkit-scrollbar-thumb {background:#cad5d5;}
|
||||||
|
::-webkit-scrollbar-thumb:hover {background:#9bacac;}
|
||||||
|
|
||||||
|
.do-meditor {position:relative;width:100%;height:100%;min-height:180px;border:1px solid #ddd;background:#fff;color:#666;}
|
||||||
|
.meditor-font {font-family:"PingFang SC","Helvetica Neue","Hiragino Sans GB","Segoe UI","Microsoft YaHei",sans-serif;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 关于编辑器模块*/
|
||||||
|
.do-meditor-about {width:400px;padding:10px 20px;}
|
||||||
|
.do-meditor-about pre {padding-bottom:15px}
|
||||||
|
.do-meditor-about a {color:#049789}
|
||||||
|
.do-meditor-about p {margin:0 auto 5px;}
|
||||||
|
|
||||||
|
/*表格模块*/
|
||||||
|
|
||||||
|
.do-meditor-table {width:270px;height:270px;padding:10px;}
|
||||||
|
.do-meditor-table li {width:100%;height:25px;}
|
||||||
|
.do-meditor-table li span {float:left;width:25px;height:25px;border:2px solid #fff;background:#f2f2f2;}
|
||||||
|
.do-meditor-table li span.active {background:rgba(4,151,137,.2);}
|
||||||
|
|
||||||
|
|
||||||
|
/*表情模块*/
|
||||||
|
.do-meditor-face {float:left;;width:241px;height:241px;margin:10px;border-top:1px solid #e2e2e2;border-left:1px solid #e2e2e2;}
|
||||||
|
.do-meditor-face li {float:left;width:40px;height:40px;padding:8px;border:1px solid #e2e2e2;border-top:0;border-left:0}
|
||||||
|
.do-meditor-face li img {width:100%;}
|
||||||
|
.do-meditor-face li:hover img {-webkit-transform:scale(3);-moz-transform:scale(3);-ms-transform:scale(3);transform:scale(3);}
|
||||||
|
|
||||||
|
|
||||||
|
/*段落模块*/
|
||||||
|
.do-meditor-h1 {width:150px;height:auto;padding:5px 0;}
|
||||||
|
.do-meditor-h1 li {width:100%;height:auto;padding:0 10px;line-height:1.5;font-size:18px;cursor:default;}
|
||||||
|
.do-meditor-h1 li:hover {background:#f2f2f2;}
|
||||||
|
.do-meditor-h1 li::before {font-family:"edicon" !important;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
||||||
|
.do-meditor-h1 li.h1 {font-size:23px;}
|
||||||
|
.do-meditor-h1 li.h2 {font-size:21px;}
|
||||||
|
.do-meditor-h1 li.h1::before {content:"\e611 "}
|
||||||
|
.do-meditor-h1 li.h2::before {content:"\e60d "}
|
||||||
|
.do-meditor-h1 li.h3::before {content:"\e60e "}
|
||||||
|
.do-meditor-h1 li.h4::before {content:"\e60f "}
|
||||||
|
.do-meditor-h1 li.h5::before {content:"\e610 "}
|
||||||
|
.do-meditor-h1 li.h6::before {content:"\e60c "}
|
||||||
|
|
||||||
|
|
||||||
|
/*通用输入模块, 链接/图片插入/文件插入/代码块插入*/
|
||||||
|
.do-meditor-common {width:360px;height:auto;padding:15px 20px;}
|
||||||
|
.do-meditor-common section {width:100%;height: 35px;margin:10px 0;line-height:35px;}
|
||||||
|
.do-meditor-common section .label {float: left;width:30%;text-align:center;background:#ddd;}
|
||||||
|
.do-meditor-common section label {float: left;width:50%;}
|
||||||
|
.do-meditor-common section .input {float: left;width:70%;height:35px;padding:0 8px;border:1px solid #ddd;border-left:0;background:#fff;color:#666;}
|
||||||
|
.do-meditor-common section .submit {float:right;width:30%;height:35px;background:#ddd;color:#666;text-align:center;}
|
||||||
|
|
||||||
|
|
||||||
|
.do-meditor-codeblock {width:780px;height:auto;padding:15px 20px;background:#fafafa;}
|
||||||
|
.do-meditor-codeblock section {display:block;width:100%;height:auto;margin:10px 0;line-height:35px;}
|
||||||
|
.do-meditor-codeblock section::after {visibility: hidden;overflow:hidden; display: block;height: 0;content: "."; clear: both;}
|
||||||
|
.do-meditor-codeblock section .label {float: left;width:80px;}
|
||||||
|
.do-meditor-codeblock section select {float:left;width:200px;height:35px;border:1px solid #ddd;border-radius:5px;background:#fff}
|
||||||
|
.do-meditor-codeblock section textarea {width:100%;height:300px;padding:5px 10px;border:1px solid #ddd;background:#fff;resize:none;}
|
||||||
|
.do-meditor-codeblock section .submit {float:right;width:80px;height:35px;background:#ddd;color:#666;text-align:center;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.do-meditor .tool-bar {position:relative;z-index:99;width:100%;height:auto;min-height:43px;padding:5px 10px;border-bottom:1px solid #ddd;background:#f5f5f5;color:#666;}
|
||||||
|
.do-meditor .tool-bar .edicon {display:inline-block;width:30px;height:32px;text-align:center;font:20px/32px "edicon" !important;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
||||||
|
.do-meditor .tool-bar .edicon:hover {background:#e5e5e5;}
|
||||||
|
.do-meditor .tool-bar .icon-pipe {width:20px;}
|
||||||
|
.do-meditor .tool-bar .icon-pipe:hover {background:none;}
|
||||||
|
.do-meditor .tool-bar .icon-pipe::before {content:"\e612"}
|
||||||
|
.do-meditor .tool-bar .icon-h1::before {content:"\e611"}
|
||||||
|
.do-meditor .tool-bar .icon-bold::before {content:"\e615"}
|
||||||
|
.do-meditor .tool-bar .icon-italic::before {content:"\e61d"}
|
||||||
|
.do-meditor .tool-bar .icon-through::before {content:"\e604"}
|
||||||
|
.do-meditor .tool-bar .icon-link::before {content:"\e606"}
|
||||||
|
.do-meditor .tool-bar .icon-inlinecode::before {content:"\e61e"}
|
||||||
|
.do-meditor .tool-bar .icon-blockcode::before {content:"\e617"}
|
||||||
|
.do-meditor .tool-bar .icon-quote::before {content:"\e607"}
|
||||||
|
.do-meditor .tool-bar .icon-hr::before {content:"\e619"}
|
||||||
|
.do-meditor .tool-bar .icon-time::before {content:"\e61a"}
|
||||||
|
.do-meditor .tool-bar .icon-face::before {content:"\e616"}
|
||||||
|
.do-meditor .tool-bar .icon-image::before {content:"\e61b"}
|
||||||
|
.do-meditor .tool-bar .icon-file::before {content:"\e603"}
|
||||||
|
.do-meditor .tool-bar .icon-preview::before {content:"\e60a"}
|
||||||
|
.do-meditor .tool-bar .icon-fullscreen::before {content:"\e608"}
|
||||||
|
.do-meditor .tool-bar .icon-table::before {content:"\e601"}
|
||||||
|
.do-meditor .tool-bar .icon-ordered::before {content:"\e61c"}
|
||||||
|
.do-meditor .tool-bar .icon-unordered::before {content:"\e618"}
|
||||||
|
.do-meditor .tool-bar .icon-about::before {content:"\e613"}
|
||||||
|
.do-meditor .tool-bar .icon-help::before {content:"\e614"}
|
||||||
|
|
||||||
|
|
||||||
|
.do-meditor .editor-body {float:left;position:absolute;z-index:89;left:0;top:0;width:100%;height:100%;padding-top:43px;}
|
||||||
|
.do-meditor .editor-body>textarea {overflow:hidden;overflow-y:auto;width:100%;height:100%;padding:5px;border:0;outline:none;resize:none;color:#666;}
|
||||||
|
.do-meditor .editor-md-preview {position:absolute;z-index:90;right:0;top:0;width:100%;height:100%;padding-top:43px;}
|
||||||
|
|
||||||
|
.do-meditor .editor-md-preview>content.preview {overflow:hidden;overflow-y:auto;display:block;width:100%;height:100%;padding:10px;color:#666;font-size:14px;background:#fff;}
|
||||||
|
|
||||||
|
|
||||||
|
.do-meditor .editor-md-preview .md-hd {position:relative;margin:15px 0;padding-left:30px;font-weight:normal;font-size:17px;}
|
||||||
|
.do-meditor .editor-md-preview h1.md-hd {padding-left:0;}
|
||||||
|
.do-meditor .editor-md-preview .md-hd a {position:relative;display:inline-block;padding:0 8px;background:#fff;color:#454545}
|
||||||
|
.do-meditor .editor-md-preview h1.md-hd a {padding-left:0;color:#000;}
|
||||||
|
.do-meditor .editor-md-preview h2.md-hd a {color:#000;}
|
||||||
|
|
||||||
|
.do-meditor .editor-md-preview h1.md-hd {margin:0 0 30px;font-size:25px;}
|
||||||
|
.do-meditor .editor-md-preview h2.md-hd {margin:20px 0;font-size:23px;}
|
||||||
|
.do-meditor .editor-md-preview h3.md-hd {margin:20px 0 15px;font-size:20px;}
|
||||||
|
.do-meditor .editor-md-preview h1:after {display:block;width:100%;content:" ";border-bottom:1px solid #ddd;}
|
||||||
|
.do-meditor .editor-md-preview h2:before,
|
||||||
|
.do-meditor .editor-md-preview h3:before,
|
||||||
|
.do-meditor .editor-md-preview h4:before,
|
||||||
|
.do-meditor .editor-md-preview h5:before,
|
||||||
|
.do-meditor .editor-md-preview h6:before {display:block;position:absolute;left:0;top:50%;width:100%;content:" ";border-bottom:1px solid #ddd;}
|
||||||
|
|
||||||
|
.do-meditor .editor-md-preview a {text-decoration:none;}
|
||||||
|
.do-meditor .editor-md-preview blockquote {margin:10px 0;padding:5px 10px;border-left:5px solid #6bb294;background:#f7f7f7}
|
||||||
|
.do-meditor .editor-md-preview table thead tr {background:#f2f2f2}
|
||||||
|
.do-meditor .editor-md-preview table thead th {padding:0 8px;border:1px solid #ddd}
|
||||||
|
.do-meditor .editor-md-preview table tbody td {padding:0 8px;border:1px solid #ddd}
|
||||||
|
|
||||||
|
.do-meditor .editor-md-preview hr {margin:30px 0;}
|
||||||
|
.do-meditor .editor-md-preview ol {list-style:decimal inside none;}
|
||||||
|
.do-meditor .editor-md-preview ul {list-style:disc inside none;}
|
||||||
|
.do-meditor .editor-md-preview li ol {margin-left:2em;}
|
||||||
|
.do-meditor .editor-md-preview li ul {margin-left:2em;list-style-type: circle;}
|
||||||
|
.do-meditor .editor-md-preview li ol ul,
|
||||||
|
.do-meditor .editor-md-preview li ul ul {list-style-type: square;}
|
||||||
|
|
||||||
|
|
||||||
|
/*全屏模式*/
|
||||||
|
.do-meditor.fullscreen {position:fixed;left:0;top:0;z-index:999;}
|
||||||
|
|
||||||
|
.do-meditor.fullscreen .editor-body {width:50%}
|
||||||
|
.do-meditor.fullscreen .editor-md-preview {width:50%;border-left:1px solid #ddd;}
|
|
@ -1,6 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
define(["yua","text!./pages.htm", "css!./pages"], function(yua, tpl) {
|
define(["yua","text!./main.htm", "css!./main"], function(yua, tpl) {
|
||||||
|
|
||||||
|
yua.ui.pages = '0.0.1'
|
||||||
//计算页码列表
|
//计算页码列表
|
||||||
function calculate(vm){
|
function calculate(vm){
|
||||||
if (vm.total < 2)
|
if (vm.total < 2)
|
|
@ -0,0 +1,32 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-02-13 13:53:38
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*代码块*/
|
||||||
|
.do-ui-blockcode {position:relative;border:1px solid #ddd;margin:15px 0;}
|
||||||
|
.do-ui-blockcode::before {position:relative;display:block;width:100%;height:25px;padding:0 8px;background:#eee;border-bottom:1px solid #ddd;line-height:25px;content:"代码示例";box-sizing: border-box;}
|
||||||
|
.do-ui-blockcode section {position:relative;}
|
||||||
|
.do-ui-blockcode .linenum {display:block;position:absolute;z-index:1;left:0;top:0;width:40px;height:100%;background:#eee;border-right:1px solid #ddd;text-align:center;}
|
||||||
|
|
||||||
|
/*语法高亮*/
|
||||||
|
.do-ui-blockcode .lang {position:relative;display:block;overflow-x:auto;z-index:0;padding:0 8px 0 50px;color:#383a42;background:#fafafa;word-wrap:break-word;white-space:pre-wrap;}
|
||||||
|
.do-ui-blockcode .lang .c-comment{color: #8e908c;font-style:italic;}
|
||||||
|
.do-ui-blockcode .lang .c-smartyx {color: #607d8b;}
|
||||||
|
.do-ui-blockcode .lang .c-important {color: #f5871f;font-style:italic;}
|
||||||
|
.do-ui-blockcode .lang .c-punctuation {color: #986756;}
|
||||||
|
.do-ui-blockcode .lang .c-regex {color: #c82829;}
|
||||||
|
.do-ui-blockcode .lang .c-boolean,.do-ui-blockcode .lang .c-number {color: #f5871f;}
|
||||||
|
.do-ui-blockcode .lang .c-function {color:#009688;}
|
||||||
|
.do-ui-blockcode .lang .c-class-name,.do-ui-blockcode .lang .c-build-in {color:#3aa9f3;}
|
||||||
|
.do-ui-blockcode .lang .c-class-name,.do-ui-blockcode .lang .c-build-in {font-style:italic;font-weight:bold;}
|
||||||
|
.do-ui-blockcode .lang .c-attr-name {color: #eab700;}
|
||||||
|
.do-ui-blockcode .lang .c-string,.do-ui-blockcode .lang .c-attr-value {color: #5ab302;}
|
||||||
|
.do-ui-blockcode .lang .c-tag,.do-ui-blockcode .lang .c-keyword,.do-ui-blockcode .lang .c-operator {color: #d81406;}
|
||||||
|
.do-ui-blockcode .lang .c-keyword {font-style:italic;}
|
||||||
|
|
||||||
|
/*行内代码*/
|
||||||
|
.do-ui-inlinecode {margin:0 2px;padding:0 5px;color:#d14;border:1px solid #ddd;border-radius:3px;}
|
|
@ -1,17 +1,6 @@
|
||||||
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+nginx+yaml */
|
define(['css!./highlight'], function() {
|
||||||
var _self = (typeof window !== 'undefined')
|
|
||||||
? window // if in browser
|
|
||||||
: (
|
|
||||||
(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
|
|
||||||
? self // if in worker
|
|
||||||
: {} // if in node js
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
var _self = window;
|
||||||
* Prism: Lightweight, robust, elegant syntax highlighting
|
|
||||||
* MIT license http://www.opensource.org/licenses/mit-license.php/
|
|
||||||
* @author Lea Verou http://lea.verou.me
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Prism = (function() {
|
var Prism = (function() {
|
||||||
|
|
||||||
|
@ -38,7 +27,9 @@ var _ = _self.Prism = {
|
||||||
|
|
||||||
objId: function(obj) {
|
objId: function(obj) {
|
||||||
if (!obj['__id']) {
|
if (!obj['__id']) {
|
||||||
Object.defineProperty(obj, '__id', { value: ++uniqueId });
|
Object.defineProperty(obj, '__id', {
|
||||||
|
value: ++uniqueId
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return obj['__id'];
|
return obj['__id'];
|
||||||
},
|
},
|
||||||
|
@ -56,12 +47,12 @@ var _ = _self.Prism = {
|
||||||
clone[key] = _.util.clone(o[key]);
|
clone[key] = _.util.clone(o[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
|
|
||||||
case 'Array':
|
case 'Array':
|
||||||
// Check for existence for IE8
|
// Check for existence for IE8
|
||||||
return o.map && o.map(function(v) { return _.util.clone(v); });
|
return o.map && o.map(function(v) {
|
||||||
|
return _.util.clone(v);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
|
@ -78,16 +69,6 @@ var _ = _self.Prism = {
|
||||||
|
|
||||||
return lang;
|
return lang;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a token before another token in a language literal
|
|
||||||
* As this needs to recreate the object (we cannot actually insert before keys in object literals),
|
|
||||||
* we cannot just provide an object, we need anobject and a key.
|
|
||||||
* @param inside The key (or language id) of the parent
|
|
||||||
* @param before The key to insert before. If not provided, the function appends instead.
|
|
||||||
* @param insert Object with the key/value pairs to insert
|
|
||||||
* @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
|
|
||||||
*/
|
|
||||||
insertBefore: function(inside, before, insert, root) {
|
insertBefore: function(inside, before, insert, root) {
|
||||||
root = root || _.languages;
|
root = root || _.languages;
|
||||||
var grammar = root[inside];
|
var grammar = root[inside];
|
||||||
|
@ -144,8 +125,7 @@ var _ = _self.Prism = {
|
||||||
if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
|
if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
|
||||||
visited[_.util.objId(o[i])] = true;
|
visited[_.util.objId(o[i])] = true;
|
||||||
_.languages.DFS(o[i], callback, null, visited);
|
_.languages.DFS(o[i], callback, null, visited);
|
||||||
}
|
} else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
|
||||||
else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
|
|
||||||
visited[_.util.objId(o[i])] = true;
|
visited[_.util.objId(o[i])] = true;
|
||||||
_.languages.DFS(o[i], callback, i, visited);
|
_.languages.DFS(o[i], callback, i, visited);
|
||||||
}
|
}
|
||||||
|
@ -234,8 +214,7 @@ var _ = _self.Prism = {
|
||||||
code: env.code,
|
code: env.code,
|
||||||
immediateClose: true
|
immediateClose: true
|
||||||
}));
|
}));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
|
env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
|
||||||
|
|
||||||
_.hooks.run('before-insert', env);
|
_.hooks.run('before-insert', env);
|
||||||
|
@ -250,7 +229,7 @@ var _ = _self.Prism = {
|
||||||
},
|
},
|
||||||
|
|
||||||
highlight: function(text, grammar, language) {
|
highlight: function(text, grammar, language) {
|
||||||
var tokens = _.tokenize(text, grammar);
|
var tokens = _.tokenize(text, grammar || Prism.languages.other);
|
||||||
return Token.stringify(_.util.encode(tokens), language);
|
return Token.stringify(_.util.encode(tokens), language);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -334,10 +313,6 @@ var _ = _self.Prism = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If strarr[i] is a Token, then the match starts inside another Token, which is invalid
|
|
||||||
* If strarr[k - 1] is greedy we are in conflict with another greedy pattern
|
|
||||||
*/
|
|
||||||
if (strarr[i] instanceof Token || strarr[k - 1].greedy) {
|
if (strarr[i] instanceof Token || strarr[k - 1].greedy) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -488,8 +463,7 @@ if (script) {
|
||||||
} else {
|
} else {
|
||||||
window.setTimeout(_.highlightAll, 16);
|
window.setTimeout(_.highlightAll, 16);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
document.addEventListener('DOMContentLoaded', _.highlightAll);
|
document.addEventListener('DOMContentLoaded', _.highlightAll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,19 +473,7 @@ return _self.Prism;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
module.exports = Prism;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hack for components to work correctly in node.js
|
|
||||||
if (typeof global !== 'undefined') {
|
|
||||||
global.Prism = Prism;
|
|
||||||
};
|
|
||||||
if(_self.define && _self.define.amd){
|
|
||||||
define(function(){
|
|
||||||
return Prism
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Prism.languages.markup = {
|
Prism.languages.markup = {
|
||||||
'smartyx': /<!--\{[\w\W]*?\}-->/,
|
'smartyx': /<!--\{[\w\W]*?\}-->/,
|
||||||
'comment': /<!--[\w\W]*?-->/,
|
'comment': /<!--[\w\W]*?-->/,
|
||||||
|
@ -612,16 +574,13 @@ if (Prism.languages.markup) {
|
||||||
}, Prism.languages.markup.tag);
|
}, Prism.languages.markup.tag);
|
||||||
};
|
};
|
||||||
Prism.languages.clike = {
|
Prism.languages.clike = {
|
||||||
'comment': [
|
'comment': [{
|
||||||
{
|
|
||||||
pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
|
pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
|
||||||
lookbehind: true
|
lookbehind: true
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
pattern: /(^|[^\\:])\/\/.*/,
|
pattern: /(^|[^\\:])\/\/.*/,
|
||||||
lookbehind: true
|
lookbehind: true
|
||||||
}
|
}],
|
||||||
],
|
|
||||||
'string': {
|
'string': {
|
||||||
pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
|
pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
|
||||||
greedy: true
|
greedy: true
|
||||||
|
@ -739,8 +698,7 @@ Prism.languages.js = Prism.languages.javascript;
|
||||||
lookbehind: true,
|
lookbehind: true,
|
||||||
greedy: true,
|
greedy: true,
|
||||||
inside: insideString
|
inside: insideString
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g,
|
pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g,
|
||||||
greedy: true,
|
greedy: true,
|
||||||
inside: insideString
|
inside: insideString
|
||||||
|
@ -828,4 +786,8 @@ Prism.languages.yaml = {
|
||||||
'important': /[&*][\w]+/,
|
'important': /[&*][\w]+/,
|
||||||
'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
|
'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
|
||||||
};
|
};
|
||||||
|
Prism.languages.other = {}
|
||||||
|
|
||||||
|
window.Prism = Prism
|
||||||
|
return Prism
|
||||||
|
})
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
define(function(){
|
define(['yua'], function(yua){
|
||||||
var _request = function(url, protocol){
|
var _request = function(url, protocol){
|
||||||
this.transport = true
|
this.transport = true
|
||||||
protocol = (protocol + '').trim().toUpperCase()
|
protocol = (protocol + '').trim().toUpperCase()
|
||||||
|
@ -53,37 +53,7 @@ define(function(){
|
||||||
|
|
||||||
// ------------------- 几个解释方法 -----------------------
|
// ------------------- 几个解释方法 -----------------------
|
||||||
|
|
||||||
var Format = function(){
|
|
||||||
this.tagHooks = new function(){
|
|
||||||
this.option = doc.createElement('select')
|
|
||||||
this.thead = doc.createElement('table')
|
|
||||||
this.td = doc.createElement('tr')
|
|
||||||
this.area = doc.createElement('map')
|
|
||||||
this.tr = doc.createElement('tbody')
|
|
||||||
this.col = doc.createElement('colgroup')
|
|
||||||
this.legend = doc.createElement('fieldset')
|
|
||||||
this._default = doc.createElement('div')
|
|
||||||
this.g = doc.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
||||||
|
|
||||||
this.optgroup = this.option
|
|
||||||
this.tbody = this.tfoot = this.colgroup = this.caption = this.thead
|
|
||||||
this.th = this.td
|
|
||||||
};
|
|
||||||
var _this = this
|
|
||||||
'circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use'.replace(/,/g, function(m){
|
|
||||||
_this.tagHooks[m] = _this.tagHooks.g //处理svg
|
|
||||||
})
|
|
||||||
|
|
||||||
this.rtagName = /<([\w:]+)/
|
|
||||||
this.rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig
|
|
||||||
this.scriptTypes = {
|
|
||||||
'text/javascript': 1,
|
|
||||||
'text/ecmascript': 1,
|
|
||||||
'application/ecmascript': 1,
|
|
||||||
'application/javascript': 1
|
|
||||||
}
|
|
||||||
this.rhtml = /<|&#?\w+;/
|
|
||||||
}
|
|
||||||
|
|
||||||
function serialize(p, obj, q){
|
function serialize(p, obj, q){
|
||||||
var k
|
var k
|
||||||
|
@ -109,6 +79,8 @@ define(function(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Format = function(){}
|
||||||
|
|
||||||
Format.prototype = {
|
Format.prototype = {
|
||||||
parseJS: function(code){
|
parseJS: function(code){
|
||||||
code = (code + '').trim()
|
code = (code + '').trim()
|
||||||
|
@ -141,42 +113,7 @@ define(function(){
|
||||||
return xml
|
return xml
|
||||||
},
|
},
|
||||||
parseHTML: function (html){
|
parseHTML: function (html){
|
||||||
var fragment = (doc.createDocumentFragment()).cloneNode(false)
|
return yua.parseHTML(html)
|
||||||
|
|
||||||
if(typeof html !== 'string')
|
|
||||||
return fragment
|
|
||||||
|
|
||||||
if(!this.rhtml.test(html)){
|
|
||||||
fragment.appendChild(document.createTextNode(html))
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
|
|
||||||
html = html.replace(this.rxhtml, '<$1></$2>').trim()
|
|
||||||
var tag = (this.rtagName.exec(html) || ['', ''])[1].toLowerCase()
|
|
||||||
var wrap = this.tagHooks[tag] || this.tagHooks._default
|
|
||||||
var firstChild = null
|
|
||||||
|
|
||||||
//使用innerHTML生成的script节点不会触发请求与执行text属性
|
|
||||||
wrap.innerHTML = html
|
|
||||||
var script = wrap.getElementsByTagName('script')
|
|
||||||
if(script.length){
|
|
||||||
for(var i = 0, el; el = script[i++];){
|
|
||||||
if(this.scriptTypes[el.type]){
|
|
||||||
var tmp = (doc.createElement("script")).cloneNode(false)
|
|
||||||
el.attributes.forEach(function(attr){
|
|
||||||
tmp.setAttribute(attr.name, attr.value)
|
|
||||||
})
|
|
||||||
tmp.text = el.text
|
|
||||||
el.parentNode.replaceChild(tmp, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(firstChild = wrap.firstChild){
|
|
||||||
fragment.appendChild(firstChild)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fragment
|
|
||||||
},
|
},
|
||||||
param: function(obj){
|
param: function(obj){
|
||||||
if(!obj || typeof obj === 'string' || typeof obj === 'number')
|
if(!obj || typeof obj === 'string' || typeof obj === 'number')
|
||||||
|
@ -731,9 +668,9 @@ define(function(){
|
||||||
},
|
},
|
||||||
cache: {},
|
cache: {},
|
||||||
cid: 0,
|
cid: 0,
|
||||||
version: '1.0.0',
|
version: '0.0.1-es5',
|
||||||
release: 'request ES5 version/1.0.0'
|
|
||||||
}
|
}
|
||||||
|
yua.ui.request = '0.0.1-es5'
|
||||||
}
|
}
|
||||||
|
|
||||||
return request
|
return request
|
||||||
|
|
|
@ -0,0 +1,740 @@
|
||||||
|
/**
|
||||||
|
* Request组件, modern版, 支持IE9+,chrome,FF
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2016-11-27 13:08:40
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
define(function(){
|
||||||
|
var _request = function(url, protocol){
|
||||||
|
this.transport = true
|
||||||
|
protocol = (protocol + '').trim().toUpperCase()
|
||||||
|
this.xhr = Xhr()
|
||||||
|
this.opt = {
|
||||||
|
url: (url + '').trim(),
|
||||||
|
type: protocol || 'GET',
|
||||||
|
form: '',
|
||||||
|
data: {},
|
||||||
|
headers: {},
|
||||||
|
timeoutID: 0,
|
||||||
|
uuid: Math.random().toString(16).substr(2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_requestp = _request.prototype,
|
||||||
|
toS = Object.prototype.toString,
|
||||||
|
win = window,
|
||||||
|
doc = win.document,
|
||||||
|
encode = encodeURIComponent,
|
||||||
|
decode = decodeURIComponent,
|
||||||
|
noop = function(e, res){
|
||||||
|
if(e)
|
||||||
|
throw new Error(e + '')
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
// 本地协议判断正则
|
||||||
|
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
||||||
|
var isLocal = false
|
||||||
|
try{
|
||||||
|
isLocal = rlocalProtocol.test(location.protocol)
|
||||||
|
}catch(e){}
|
||||||
|
|
||||||
|
|
||||||
|
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg
|
||||||
|
|
||||||
|
// ----------------- 一些兼容性预处理 --------------------
|
||||||
|
|
||||||
|
win.Xhr = function(){
|
||||||
|
return new XMLHttpRequest()
|
||||||
|
}
|
||||||
|
// var supportCors = 'withCredentials' in Xhr()
|
||||||
|
|
||||||
|
// ------------------- 几个解释方法 -----------------------
|
||||||
|
|
||||||
|
var Format = function(){
|
||||||
|
this.tagHooks = new function(){
|
||||||
|
this.option = doc.createElement('select')
|
||||||
|
this.thead = doc.createElement('table')
|
||||||
|
this.td = doc.createElement('tr')
|
||||||
|
this.area = doc.createElement('map')
|
||||||
|
this.tr = doc.createElement('tbody')
|
||||||
|
this.col = doc.createElement('colgroup')
|
||||||
|
this.legend = doc.createElement('fieldset')
|
||||||
|
this._default = doc.createElement('div')
|
||||||
|
this.g = doc.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
||||||
|
|
||||||
|
this.optgroup = this.option
|
||||||
|
this.tbody = this.tfoot = this.colgroup = this.caption = this.thead
|
||||||
|
this.th = this.td
|
||||||
|
};
|
||||||
|
var _this = this
|
||||||
|
'circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use'.replace(/,/g, function(m){
|
||||||
|
_this.tagHooks[m] = _this.tagHooks.g //处理svg
|
||||||
|
})
|
||||||
|
|
||||||
|
this.rtagName = /<([\w:]+)/
|
||||||
|
this.rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig
|
||||||
|
this.scriptTypes = {
|
||||||
|
'text/javascript': 1,
|
||||||
|
'text/ecmascript': 1,
|
||||||
|
'application/ecmascript': 1,
|
||||||
|
'application/javascript': 1
|
||||||
|
}
|
||||||
|
this.rhtml = /<|&#?\w+;/
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize(p, obj, q){
|
||||||
|
var k
|
||||||
|
if(Array.isArray(obj)){
|
||||||
|
obj.forEach(function(it, i){
|
||||||
|
k = p ? (p + '[' + (Array.isArray(it) ? i : '') + ']') : i
|
||||||
|
if(typeof it === 'object'){
|
||||||
|
serialize(k, it, q)
|
||||||
|
}else{
|
||||||
|
q(k, it)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
for(var i in obj){
|
||||||
|
k = p ? (p + '[' + i + ']') : i
|
||||||
|
if(typeof obj[i] === 'object'){
|
||||||
|
serialize(k, obj[i], q)
|
||||||
|
}else{
|
||||||
|
q(k, obj[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Format.prototype = {
|
||||||
|
parseJS: function(code){
|
||||||
|
code = (code + '').trim()
|
||||||
|
if(code){
|
||||||
|
if(code.indexOf('use strict') === 1){
|
||||||
|
var script = doc.createElement('script')
|
||||||
|
script.text = code
|
||||||
|
doc.head
|
||||||
|
.appendChild(script)
|
||||||
|
.parentNode
|
||||||
|
.removeChild(script)
|
||||||
|
}else{
|
||||||
|
eval(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseXML: function(data, xml, tmp){
|
||||||
|
try{
|
||||||
|
tmp = new DOMParser();
|
||||||
|
xml = tmp.parseFromString(data, 'text/xml');
|
||||||
|
}catch(e){
|
||||||
|
xml = void 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!xml ||
|
||||||
|
!xml.documentElement ||
|
||||||
|
xml.getElementsByTagName('parsererror').length){
|
||||||
|
console.error('Invalid XML: ' + data)
|
||||||
|
}
|
||||||
|
return xml
|
||||||
|
},
|
||||||
|
parseHTML: function (html){
|
||||||
|
var fragment = (doc.createDocumentFragment()).cloneNode(false)
|
||||||
|
|
||||||
|
if(typeof html !== 'string')
|
||||||
|
return fragment
|
||||||
|
|
||||||
|
if(!this.rhtml.test(html)){
|
||||||
|
fragment.appendChild(document.createTextNode(html))
|
||||||
|
return fragment
|
||||||
|
}
|
||||||
|
|
||||||
|
html = html.replace(this.rxhtml, '<$1></$2>').trim()
|
||||||
|
var tag = (this.rtagName.exec(html) || ['', ''])[1].toLowerCase()
|
||||||
|
var wrap = this.tagHooks[tag] || this.tagHooks._default
|
||||||
|
var firstChild = null
|
||||||
|
|
||||||
|
//使用innerHTML生成的script节点不会触发请求与执行text属性
|
||||||
|
wrap.innerHTML = html
|
||||||
|
var script = wrap.getElementsByTagName('script')
|
||||||
|
if(script.length){
|
||||||
|
for(var i = 0, el; el = script[i++];){
|
||||||
|
if(this.scriptTypes[el.type]){
|
||||||
|
var tmp = (doc.createElement("script")).cloneNode(false)
|
||||||
|
el.attributes.forEach(function(attr){
|
||||||
|
tmp.setAttribute(attr.name, attr.value)
|
||||||
|
})
|
||||||
|
tmp.text = el.text
|
||||||
|
el.parentNode.replaceChild(tmp, el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(firstChild = wrap.firstChild){
|
||||||
|
fragment.appendChild(firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment
|
||||||
|
},
|
||||||
|
param: function(obj){
|
||||||
|
if(!obj || typeof obj === 'string' || typeof obj === 'number')
|
||||||
|
return obj
|
||||||
|
|
||||||
|
var arr = []
|
||||||
|
var q = function(k, v){
|
||||||
|
if(/native code/.test(v))
|
||||||
|
return
|
||||||
|
|
||||||
|
v = (typeof v === 'function') ? v() : v
|
||||||
|
v = (toS.call(v) !== '[object File]') ? encode(v) : v
|
||||||
|
|
||||||
|
arr.push(encode(k) + '=' + v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof obj === 'object')
|
||||||
|
serialize('', obj, q)
|
||||||
|
|
||||||
|
return arr.join('&')
|
||||||
|
},
|
||||||
|
parseForm: function(form){
|
||||||
|
var data = {}
|
||||||
|
for(var i = 0,field; field = form.elements[i++];){
|
||||||
|
|
||||||
|
switch(field.type){
|
||||||
|
case 'select-one':
|
||||||
|
case 'select-multiple':
|
||||||
|
if(field.name.length && !field.disabled){
|
||||||
|
for(var j = 0, opt;opt = field.options[j++];){
|
||||||
|
if(opt.selected){
|
||||||
|
data[field.name] = opt.value || opt.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
if(field.name.length && !field.disabled){
|
||||||
|
data[field.name] = field.files[0]
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case undefined:
|
||||||
|
case 'submit':
|
||||||
|
case 'reset':
|
||||||
|
case 'button':
|
||||||
|
break; //按钮啥的, 直接忽略
|
||||||
|
case 'radio':
|
||||||
|
case 'checkbox':
|
||||||
|
// 只处理选中的
|
||||||
|
if(!field.checked)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(field.name.length && !field.disabled){
|
||||||
|
data[field.name] = field.value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
merge: function(a, b){
|
||||||
|
if(typeof a !== 'object' || typeof b !== 'object')
|
||||||
|
throw new TypeError('argument must be an object')
|
||||||
|
|
||||||
|
if(Object.assign)
|
||||||
|
return Object.assign(a, b)
|
||||||
|
|
||||||
|
for(var i in b){
|
||||||
|
a[i] = b[i]
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var F = new Format()
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// -------------------- request 模块开始 --------------------
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
var requestConvert = {
|
||||||
|
text: function(val){
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
xml: function(val, xml){
|
||||||
|
return xml !== undefined ? xml : F.parseXML(val)
|
||||||
|
},
|
||||||
|
html: function(val){
|
||||||
|
return F.parseHTML(val)
|
||||||
|
},
|
||||||
|
json: function(val){
|
||||||
|
return JSON.parse(val)
|
||||||
|
},
|
||||||
|
script: function(val){
|
||||||
|
return F.parseJS(val)
|
||||||
|
},
|
||||||
|
jsonp: function(name){
|
||||||
|
var json = request.cache[name]
|
||||||
|
delete request.cache[name];
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var requestExtend = {
|
||||||
|
formData: function(){
|
||||||
|
|
||||||
|
if(this.opt.form){
|
||||||
|
var data = F.parseForm(this.opt.form)
|
||||||
|
F.merge(this.opt.data, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var form = new FormData()
|
||||||
|
for(var i in this.opt.data){
|
||||||
|
var el = this.opt.data[i]
|
||||||
|
if(Array.isArray(el)){
|
||||||
|
el.forEach(function(it){
|
||||||
|
form.append(i + '[]', it)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
form.append(i, this.opt.data[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return form
|
||||||
|
|
||||||
|
},
|
||||||
|
jsonp: function(jsonpcallback){
|
||||||
|
win[jsonpcallback] = function(val){
|
||||||
|
delete win[jsonpcallback]
|
||||||
|
request.cache[jsonpcallback] = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dispatch: function(self){
|
||||||
|
|
||||||
|
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
var _this = this,
|
||||||
|
result = {
|
||||||
|
response: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: {'content-type': ''}
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: _this.opt.headers
|
||||||
|
},
|
||||||
|
status: self === null ? 504 : 200,
|
||||||
|
statusText: self === null ? 'Connected timeout' : 'ok',
|
||||||
|
text: '',
|
||||||
|
body: '',
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
|
//状态为4,既已成功, 则清除超时
|
||||||
|
clearTimeout(_this.opt.timeoutID);
|
||||||
|
|
||||||
|
if(typeof this.transport === 'object'
|
||||||
|
&& this.opt.type === 'JSONP'){
|
||||||
|
|
||||||
|
//移除script
|
||||||
|
// this.transport.parentNode.removeChild(this.transport);
|
||||||
|
|
||||||
|
//超时返回
|
||||||
|
if(self !== null){
|
||||||
|
var exec = !this.transport.readyState
|
||||||
|
|| this.transport.readyState === 'loaded'
|
||||||
|
|| this.transport.readyState === 'complete';
|
||||||
|
|
||||||
|
if(exec){
|
||||||
|
result.body = requestConvert.jsonp(this.opt.data.callback)
|
||||||
|
result.text = JSON.stringify(result.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callback(result.error, result)
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
//成功的回调
|
||||||
|
var isSucc = self ? ((self.status >= 200 && self.status < 300) || self.status === 304) : false,
|
||||||
|
headers = self && self.getAllResponseHeaders().split('\n') || [];
|
||||||
|
|
||||||
|
//处理返回的Header
|
||||||
|
headers.forEach(function(it, i){
|
||||||
|
it = it.trim()
|
||||||
|
if(it){
|
||||||
|
it = it.split(':')
|
||||||
|
result.response.headers[it.shift().toLowerCase()] = it.join(':').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if(isSucc){
|
||||||
|
result.status = self.status
|
||||||
|
if(result.status === 204){
|
||||||
|
result.statusText = 'no content'
|
||||||
|
}else if(result.status === 304){
|
||||||
|
result.statusText = 'not modified'
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
result.status = self === null ? 504 : (self.status || 500)
|
||||||
|
result.statusText = self === null ? 'Connected timeout' : (self.statusText || 'Internal Server Error')
|
||||||
|
result.error = F.merge(new Error(result.statusText), {status: result.status})
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
//处理返回的数据
|
||||||
|
var dataType = result.response.headers['content-type'].match(/json|xml|script|html/i) || ['text']
|
||||||
|
|
||||||
|
dataType = dataType[0].toLowerCase()
|
||||||
|
result.text = self && (self.responseText || self.responseXML) || ''
|
||||||
|
result.body = requestConvert[dataType](result.text, self && self.responseXML)
|
||||||
|
}catch(err){
|
||||||
|
result.error = err
|
||||||
|
result.statusText = 'parse error'
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.callback(result.error, result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
delete _this.transport;
|
||||||
|
delete _this.opt
|
||||||
|
delete _this.xhr
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表单类型, 支持2种, form/json
|
||||||
|
_requestp.type = function(t){
|
||||||
|
if(this.opt.formType === 'form-data')
|
||||||
|
return this
|
||||||
|
|
||||||
|
this.opt.formType = t || 'form'
|
||||||
|
if(t === 'form' || this.opt.type === 'GET')
|
||||||
|
this.set('content-type', 'application/x-www-form-urlencoded; charset=UTF-8')
|
||||||
|
else
|
||||||
|
this.set('content-type', 'application/json; charset=UTF-8')
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置头信息
|
||||||
|
_requestp.set = function(k, val){
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(typeof k === 'object'){
|
||||||
|
for(var i in k){
|
||||||
|
i = i.toLowerCase()
|
||||||
|
this.opt.headers[i] = k[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(typeof k === 'string'){
|
||||||
|
if(arguments.length < 2)
|
||||||
|
throw new Error('2 arguments required')
|
||||||
|
|
||||||
|
// 全转小写,避免重复写入
|
||||||
|
k = k.toLowerCase()
|
||||||
|
|
||||||
|
if(val === undefined)
|
||||||
|
delete this.opt.headers[k]
|
||||||
|
else
|
||||||
|
this.opt.headers[k] = val
|
||||||
|
}else{
|
||||||
|
throw new Error('arguments must be string/object, but [' + (typeof k) + '] given')
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置请求参数
|
||||||
|
_requestp.send = function(k, val){
|
||||||
|
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
// 1. send方法可以多次调用, 但必须保证格式一致
|
||||||
|
// 2. 2次圴提交纯字符串也会抛出异常
|
||||||
|
if(typeof k === 'object'){
|
||||||
|
if(this.opt.data && (typeof this.opt.data === 'string'))
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
if(!this.opt.data)
|
||||||
|
this.opt.data = {}
|
||||||
|
|
||||||
|
F.merge(this.opt.data, k)
|
||||||
|
}else{
|
||||||
|
if(typeof k === 'string'){
|
||||||
|
if(arguments.length === 1){
|
||||||
|
if(this.opt.data)
|
||||||
|
throw new Error('invalid param in function send')
|
||||||
|
|
||||||
|
this.opt.data = k
|
||||||
|
}else{
|
||||||
|
if(this.opt.data && (typeof this.opt.data === 'string'))
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
|
||||||
|
if(!this.opt.data)
|
||||||
|
this.opt.data = {}
|
||||||
|
|
||||||
|
this.opt.data[k] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
throw new Error('argument of send must be string/object, but [' + (typeof k) + '] given')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//该方法用于 form-data类型的post请求的参数设置
|
||||||
|
_requestp.field = function(k, val){
|
||||||
|
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
// 此类型优先级最高
|
||||||
|
this.opt.formType = 'form-data'
|
||||||
|
if(!this.opt.data || (this.opt.data && typeof this.opt.data !== 'object'))
|
||||||
|
this.opt.data = {}
|
||||||
|
|
||||||
|
if(arguments.length === 1 && typeof k === 'object'){
|
||||||
|
F.merge(this.opt.data, k)
|
||||||
|
}else if(arguments.length === 2){
|
||||||
|
this.opt.data[k] = val
|
||||||
|
}else{
|
||||||
|
throw new TypeError('argument must be an object, but ' + (typeof k) + ' given')
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//设置缓存
|
||||||
|
_requestp.cache = function(t){
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(this.opt.type === 'GET')
|
||||||
|
this.opt.cache = !!t
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//取消网络请求
|
||||||
|
_requestp.abort = function(){
|
||||||
|
delete this.transport
|
||||||
|
if(!this.opt.form)
|
||||||
|
this.xhr.abort()
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//超时设置, 单位毫秒
|
||||||
|
_requestp.timeout = function(time){
|
||||||
|
if(typeof time !== 'number' || time < 1)
|
||||||
|
return this
|
||||||
|
|
||||||
|
this.opt.timeout = time
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_requestp.form = function(form){
|
||||||
|
if(typeof form === 'object' && form.nodeName === 'FORM'){
|
||||||
|
this.opt.type = 'POST'
|
||||||
|
this.opt.form = form
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var originAnchor = doc.createElement('a');
|
||||||
|
originAnchor.href = location.href;
|
||||||
|
_requestp.end = function(callback){
|
||||||
|
var _this = this;
|
||||||
|
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
||||||
|
if(!this.transport)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!this.opt.url)
|
||||||
|
throw new Error('Invalid request url')
|
||||||
|
|
||||||
|
F.merge(this, requestExtend)
|
||||||
|
|
||||||
|
this.callback = callback || noop
|
||||||
|
|
||||||
|
// 1. url规范化
|
||||||
|
this.opt.url = this.opt.url.replace(/#.*$/, '').replace(/^\/\//, location.protocol + '//')
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 处理跨域
|
||||||
|
if(typeof this.opt.crossDomain !== 'boolean'){
|
||||||
|
var anchor = doc.createElement('a')
|
||||||
|
try{
|
||||||
|
anchor.href = this.opt.url
|
||||||
|
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
||||||
|
// IE7下需要获取绝对路径
|
||||||
|
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
||||||
|
anchor.href = absUrl
|
||||||
|
anchor.async = true
|
||||||
|
this.opt.crossDomain = (originAnchor.protocol !== anchor.protocol) || (originAnchor.host !== anchor.host)
|
||||||
|
}catch(e){
|
||||||
|
this.opt.crossDomain = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 进一步处理跨域配置
|
||||||
|
if(this.opt.type === 'JSONP'){
|
||||||
|
//如果没有跨域,自动转回xhr GET
|
||||||
|
if(!this.opt.crossDomain){
|
||||||
|
this.opt.type = 'GET';
|
||||||
|
}else{
|
||||||
|
this.opt.data['callback'] = this.opt.data['callback'] || ('jsonp' + request.cid++);
|
||||||
|
this.jsonp(this.opt.data['callback']); //创建临时处理方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2.2 如果不是跨域请求,则自动加上一条header信息,用以标识这是ajax请求
|
||||||
|
if(!this.opt.crossDomain){
|
||||||
|
this.set('X-Requested-With', 'XMLHttpRequest')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 3. data转字符串
|
||||||
|
this.opt.param = F.param(this.opt.data)
|
||||||
|
|
||||||
|
|
||||||
|
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
||||||
|
if(!this.opt.formType)
|
||||||
|
this.type('form')
|
||||||
|
|
||||||
|
// 5.处理GET请求
|
||||||
|
this.opt.hasContent = this.opt.type === 'POST' //是否为post请求
|
||||||
|
if(!this.opt.hasContent){
|
||||||
|
|
||||||
|
//GET请求直接把参数拼接到url上
|
||||||
|
if(this.opt.param){
|
||||||
|
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + this.opt.param
|
||||||
|
}
|
||||||
|
//加随机值,避免缓存
|
||||||
|
if(this.opt.cache === false)
|
||||||
|
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + '_=' + Math.random()
|
||||||
|
}else{
|
||||||
|
if(this.opt.formType === 'form-data'){
|
||||||
|
delete this.opt.headers['content-type']
|
||||||
|
this.opt.param = this.formData()
|
||||||
|
|
||||||
|
}else if(this.opt.formType !== 'form'){
|
||||||
|
this.opt.param = JSON.stringify(this.opt.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//jsonp
|
||||||
|
if(this.opt.type === 'JSONP'){
|
||||||
|
|
||||||
|
this.transport = doc.createElement('script')
|
||||||
|
this.transport.onerror = this.transport.onload = function(){
|
||||||
|
_this.dispatch(_this.transport)
|
||||||
|
}
|
||||||
|
this.transport.src = this.opt.url
|
||||||
|
doc.head.insertBefore(this.transport, doc.head.firstChild)
|
||||||
|
|
||||||
|
//6. 超时处理
|
||||||
|
if(this.opt.timeout && this.opt.timeout > 0){
|
||||||
|
this.opt.timeoutID = setTimeout(function(){
|
||||||
|
_this.transport.onerror = _this.transport.onload = null
|
||||||
|
_this.dispatch(null)
|
||||||
|
}, this.opt.timeout)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
|
||||||
|
this.xhr.onreadystatechange = function(ev){
|
||||||
|
|
||||||
|
if(_this.opt.timeout && _this.opt.timeout > 0){
|
||||||
|
_this.opt['time' + this.readyState] = ev.timeStamp
|
||||||
|
if(this.readyState === 4){
|
||||||
|
_this.opt.isTimeout = _this.opt.time4 - _this.opt.time1 > _this.opt.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.readyState !== 4){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.dispatch(_this.opt.isTimeout ? null : _this.xhr)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 6. 初始化xhr提交
|
||||||
|
this.xhr.open(this.opt.type, this.opt.url, true)
|
||||||
|
|
||||||
|
// 7. 设置头信息
|
||||||
|
for(var i in this.opt.headers){
|
||||||
|
if(this.opt.headers[i])
|
||||||
|
this.xhr.setRequestHeader(i, this.opt.headers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 发起网络请求
|
||||||
|
_this.xhr.send(_this.opt.param)
|
||||||
|
|
||||||
|
//超时处理
|
||||||
|
if(this.opt.timeout && this.opt.timeout > 0){
|
||||||
|
this.xhr.timeout = this.opt.timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------- end ------------------------
|
||||||
|
|
||||||
|
|
||||||
|
if(!win.request){
|
||||||
|
win.request = {
|
||||||
|
get: function(url){
|
||||||
|
if(!url)
|
||||||
|
throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'GET')
|
||||||
|
},
|
||||||
|
post: function(url){
|
||||||
|
if(!url)
|
||||||
|
throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'POST')
|
||||||
|
},
|
||||||
|
jsonp: function(url){
|
||||||
|
if(!url)
|
||||||
|
throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'JSONP')
|
||||||
|
},
|
||||||
|
cache: {},
|
||||||
|
cid: 0,
|
||||||
|
version: '1.0.0',
|
||||||
|
release: 'request ES5 version/1.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return request
|
||||||
|
})
|
|
@ -159,5 +159,7 @@ define(['yua'], function(){
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yua.ui.router = '0.0.1'
|
||||||
|
|
||||||
return yua.router = new Router;
|
return yua.router = new Router;
|
||||||
})
|
})
|
|
@ -1 +0,0 @@
|
||||||
define(["yua"],function(){function t(){this.table={get:[]},this.errorFn=null,this.history=null,this.hash="",this.started=!1,this.init={}}function e(t){return!t||t===window.name||"_self"===t||"top"===t&&window==window.top?!0:!1}var r={prefix:/^(#!|#)[\/]?/,historyOpen:!0,allowReload:!0},i=!0,a=/(:id)|(\{id\})|(\{id:([A-z\d\,\[\]\{\}\-\+\*\?\!:\^\$]*)\})/g;return t.prototype={error:function(t){this.errorFn=t},config:function(t){return this.started?console.error("Router config has been set"):(this.started=!0,t.allowReload||(t.historyOpen=!0),void(this.init=yua.mix({},r,t)))},_getRegExp:function(t,e){var r=t.replace(a,function(t,e,r,i,a){var n="([\\w.-]";return e||r?n+"+)":(/^\{[\d\,]+\}$/.test(a)||(n="("),n+a+")")});return r=r.replace(/(([^\\])([\/]+))/g,"$2\\/").replace(/(([^\\])([\.]+))/g,"$2\\.").replace(/(([^\\])([\-]+))/g,"$2\\-").replace(/(\(.*)(\\[\-]+)(.*\))/g,"$1-$3"),r="^"+r+"$",e.regexp=new RegExp(r),e},_add:function(t,e,r){this.started||this.config({});var i=this.table[t.toLowerCase()];if("/"!==e.charAt(0))return void console.error('char "/" must be in front of router rule');e=e.replace(/^[\/]+|[\/]+$|\s+/g,"");var a={};a.rule=e,a.callback=r,yua.Array.ensure(i,this._getRegExp(e,a))},_route:function(t,e){var e=e.trim(),r=this.table[t],i=this.init;if(i.allowReload||e!==this.history){i.historyOpen&&(this.history=e,yua.ls&&yua.ls("lastHash",e));for(var a,n=0;a=r[n++];){var o=e.match(a.regexp);if(o)return o.shift(),a.callback.apply(a,o)}this.errorFn&&this.errorFn(e)}},on:function(t,e){this._add("get",t,e)}},yua.bind(window,"load",function(){if(yua.router.started){var t=yua.router.init.prefix,e=location.hash;e=e.replace(t,"").trim(),yua.router._route("get",e)}}),"onhashchange"in window&&window.addEventListener("hashchange",function(){if(i){var t=yua.router.init.prefix,e=location.hash.replace(t,"").trim();yua.router._route("get",e)}}),yua.bind(document,"mousedown",function(t){var r="defaultPrevented"in t?t.defaultPrevented:t.returnValue===!1;if(!(r||t.ctrlKey||t.metaKey||2===t.which)){for(var a=t.target;"A"!==a.nodeName;)if(a=a.parentNode,!a||"BODY"===a.tagName)return;if(e(a.target)){if(!yua.router.started)return;var n=a.getAttribute("href")||a.getAttribute("xlink:href"),o=yua.router.init.prefix;if(null===n||!o.test(n))return;yua.router.hash=n.replace(o,"").trim(),t.preventDefault(),location.hash=n,i=!1}}}),yua.bind(document,"mouseup",function(){i||(yua.router._route("get",yua.router.hash),i=!0)}),yua.router=new t});
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Tree树型菜单
|
||||||
|
> 顾名思义,就是
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-14 21:04:50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define(['yua', 'css!./skin/def.css'], function(){
|
||||||
|
|
||||||
|
//储存版本信息
|
||||||
|
yua.ui.tree = '0.0.1'
|
||||||
|
|
||||||
|
var box = '<ul class="do-tree skin-{skin}">{li}</ul>',
|
||||||
|
ul = '<ul :class="{open: {it}.open}">{li}</ul>',
|
||||||
|
li = '<li :class="{open: {it}.open, dir: {it}.children}">'
|
||||||
|
+ '<em :click="$toggle({it})"></em><span '
|
||||||
|
+ ':click="$click({it})" '
|
||||||
|
+ ':text="{it}.name"></span>{child}</li>';
|
||||||
|
|
||||||
|
|
||||||
|
function repeat(arr, name){
|
||||||
|
var html = ''
|
||||||
|
arr.forEach(function(it, i){
|
||||||
|
var from = name + '[' + i + ']',
|
||||||
|
child = '';
|
||||||
|
html += li.replace(/\{it\}/g, from);
|
||||||
|
|
||||||
|
if(it.children){
|
||||||
|
child += repeat(it.children, from +'.children')
|
||||||
|
child = ul.replace('{li}', child).replace('{it}', from)
|
||||||
|
}
|
||||||
|
if(child){
|
||||||
|
|
||||||
|
}
|
||||||
|
html = html.replace(/\{child\}/, child)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
|
||||||
|
return yua.component('tree', {
|
||||||
|
$template: '',
|
||||||
|
$construct: function(base, opt, attr){
|
||||||
|
if(!opt.from && !attr.from){
|
||||||
|
throw new Error('tree组件必须传入「from」属性')
|
||||||
|
}
|
||||||
|
|
||||||
|
var from = attr.from || opt.from,
|
||||||
|
arr = base.$up[from].$model,
|
||||||
|
tpl = repeat(arr, from)
|
||||||
|
|
||||||
|
delete attr.from
|
||||||
|
delete opt.from
|
||||||
|
yua.mix(base, opt, attr)
|
||||||
|
|
||||||
|
base.skin = base.skin || 'def'
|
||||||
|
|
||||||
|
|
||||||
|
tpl = box.replace('{li}', tpl).replace('{skin}', base.skin)
|
||||||
|
|
||||||
|
base.$template = tpl
|
||||||
|
|
||||||
|
return base
|
||||||
|
},
|
||||||
|
$init: function(vm){
|
||||||
|
|
||||||
|
vm.$click = function(obj){
|
||||||
|
|
||||||
|
if(vm.$onClick){
|
||||||
|
vm.$onClick(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$click: yua.noop,
|
||||||
|
$toggle: function(obj){
|
||||||
|
obj.open = !obj.open
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
|
@ -0,0 +1,46 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-14 21:18:53
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
.do-fn-cl:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; overflow:hidden;}
|
||||||
|
.do-tree, .do-tree * {margin: 0;padding: 0;vertical-align: baseline;box-sizing:border-box;}
|
||||||
|
|
||||||
|
@font-face {font-family: "iconfont";
|
||||||
|
src: url('iconfont.eot'); /* IE9*/
|
||||||
|
src: url('iconfont.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-tree {width:100%;height:auto;line-height:28px;}
|
||||||
|
|
||||||
|
.do-tree li {overflow:hidden; white-space:nowrap; text-overflow:ellipsis}
|
||||||
|
|
||||||
|
.do-tree li ul {display:none;margin-left:20px;}
|
||||||
|
.do-tree li ul.open {display:block;}
|
||||||
|
|
||||||
|
.do-tree li em,
|
||||||
|
.do-tree li span {display:block;cursor:pointer;}
|
||||||
|
.do-tree li em {float:left;padding:0 5px;color:#000;font-family:"iconfont" !important;font-style:normal;-webkit-font-smoothing: antialiased;-webkit-text-stroke-width: 0.2px;-moz-osx-font-smoothing: grayscale;}
|
||||||
|
.do-tree li span:hover {color:#6bb294;}
|
||||||
|
|
||||||
|
.do-tree.skin-def li>em::before {content:"\e610";}
|
||||||
|
.do-tree.skin-def li.dir>em::before {content:"\e622";}
|
||||||
|
.do-tree.skin-def li.dir.open>em::before {content:"\e8ea";}
|
||||||
|
|
||||||
|
.do-tree.skin-light li>em::before {content:"\e73e";}
|
||||||
|
.do-tree.skin-light li.dir>em::before {content:"\e635";}
|
||||||
|
.do-tree.skin-light li.dir.open>em::before {content:"\e8ea";}
|
||||||
|
|
||||||
|
|
||||||
|
.do-tree.skin-line li>em::before {content:"\e60e";}
|
||||||
|
.do-tree.skin-line li.dir>em::before {content:"\e608";font-weight:bold;}
|
||||||
|
.do-tree.skin-line li.dir.open>em::before {content:"\e662";}
|
||||||
|
|
||||||
|
|
||||||
|
.do-tree.skin-arrow li>em::before {content:"\e73e";}
|
||||||
|
.do-tree.skin-arrow li.dir>em::before {content:"\e616";font-weight:bold;}
|
||||||
|
.do-tree.skin-arrow li.dir.open>em::before {content:"\e607";}
|
|
@ -353,7 +353,7 @@ if(!String.prototype.splice){
|
||||||
Object.defineProperty(String.prototype,
|
Object.defineProperty(String.prototype,
|
||||||
'splice',
|
'splice',
|
||||||
{
|
{
|
||||||
value: function(start, len, sub){
|
value: function(start, len, fill){
|
||||||
var length = this.length,
|
var length = this.length,
|
||||||
argLen = arguments.length;
|
argLen = arguments.length;
|
||||||
|
|
||||||
|
@ -497,6 +497,7 @@ yua.mix({
|
||||||
subscribers: subscribers,
|
subscribers: subscribers,
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
log: log,
|
log: log,
|
||||||
|
ui: {}, //仅用于存放组件版本信息等
|
||||||
slice: function (nodes, start, end) {
|
slice: function (nodes, start, end) {
|
||||||
return aslice.call(nodes, start, end)
|
return aslice.call(nodes, start, end)
|
||||||
},
|
},
|
||||||
|
@ -3349,7 +3350,7 @@ yua.component = function (name, opts) {
|
||||||
delete elemOpts.config
|
delete elemOpts.config
|
||||||
delete elemOpts.$id
|
delete elemOpts.$id
|
||||||
delete elemOpts.identifier
|
delete elemOpts.identifier
|
||||||
var componentDefinition = {}
|
var componentDefinition = {$up: host.vmodels[0], $ups: host.vmodels}
|
||||||
|
|
||||||
yua.mix(true, componentDefinition, hooks)
|
yua.mix(true, componentDefinition, hooks)
|
||||||
|
|
||||||
|
@ -3384,6 +3385,14 @@ yua.component = function (name, opts) {
|
||||||
|
|
||||||
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
||||||
var child = elem.content.firstChild
|
var child = elem.content.firstChild
|
||||||
|
if(!child || serialize.call(child) === '[object Text]'){
|
||||||
|
var tmpDom = document.createElement('div')
|
||||||
|
if(child){
|
||||||
|
tmpDom.appendChild(child)
|
||||||
|
}
|
||||||
|
child = tmpDom
|
||||||
|
tmpDom = null
|
||||||
|
}
|
||||||
elem.parentNode.replaceChild(child, elem)
|
elem.parentNode.replaceChild(child, elem)
|
||||||
child.msResolved = 1
|
child.msResolved = 1
|
||||||
var cssText = elem.style.cssText
|
var cssText = elem.style.cssText
|
||||||
|
|
16
js/yua.js
|
@ -353,7 +353,7 @@ if(!String.prototype.splice){
|
||||||
Object.defineProperty(String.prototype,
|
Object.defineProperty(String.prototype,
|
||||||
'splice',
|
'splice',
|
||||||
{
|
{
|
||||||
value: function(start, len, sub){
|
value: function(start, len, fill){
|
||||||
var length = this.length,
|
var length = this.length,
|
||||||
argLen = arguments.length;
|
argLen = arguments.length;
|
||||||
|
|
||||||
|
@ -497,6 +497,7 @@ yua.mix({
|
||||||
subscribers: subscribers,
|
subscribers: subscribers,
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
log: log,
|
log: log,
|
||||||
|
ui: {}, //仅用于存放组件版本信息等
|
||||||
slice: function (nodes, start, end) {
|
slice: function (nodes, start, end) {
|
||||||
return aslice.call(nodes, start, end)
|
return aslice.call(nodes, start, end)
|
||||||
},
|
},
|
||||||
|
@ -3349,7 +3350,7 @@ yua.component = function (name, opts) {
|
||||||
delete elemOpts.config
|
delete elemOpts.config
|
||||||
delete elemOpts.$id
|
delete elemOpts.$id
|
||||||
delete elemOpts.identifier
|
delete elemOpts.identifier
|
||||||
var componentDefinition = {}
|
var componentDefinition = {$up: host.vmodels[0], $ups: host.vmodels}
|
||||||
|
|
||||||
yua.mix(true, componentDefinition, hooks)
|
yua.mix(true, componentDefinition, hooks)
|
||||||
|
|
||||||
|
@ -3384,12 +3385,23 @@ yua.component = function (name, opts) {
|
||||||
|
|
||||||
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
||||||
var child = elem.content.firstChild
|
var child = elem.content.firstChild
|
||||||
|
|
||||||
|
if(!child || serialize.call(child) === '[object Text]'){
|
||||||
|
var tmpDom = document.createElement('div')
|
||||||
|
if(child){
|
||||||
|
tmpDom.appendChild(child)
|
||||||
|
}
|
||||||
|
child = tmpDom
|
||||||
|
tmpDom = null
|
||||||
|
}
|
||||||
elem.parentNode.replaceChild(child, elem)
|
elem.parentNode.replaceChild(child, elem)
|
||||||
|
|
||||||
child.msResolved = 1
|
child.msResolved = 1
|
||||||
var cssText = elem.style.cssText
|
var cssText = elem.style.cssText
|
||||||
var className = elem.className
|
var className = elem.className
|
||||||
elem = host.element = child
|
elem = host.element = child
|
||||||
elem.style.cssText += ";"+ cssText
|
elem.style.cssText += ";"+ cssText
|
||||||
|
|
||||||
if (className) {
|
if (className) {
|
||||||
yua(elem).addClass(className)
|
yua(elem).addClass(className)
|
||||||
}
|
}
|
||||||
|
|