diff --git a/css/base.css b/css/base.css index d702134..5799214 100644 --- a/css/base.css +++ b/css/base.css @@ -33,7 +33,7 @@ q:before, q:after {content: '';content: none;} table {border-collapse: collapse;border-spacing: 0;} .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-show{display:block;} diff --git a/js/lib/codemirror/htmlmixed.js b/js/lib/codemirror/htmlmixed.js index 85238d9..5452d58 100644 --- a/js/lib/codemirror/htmlmixed.js +++ b/js/lib/codemirror/htmlmixed.js @@ -1,4 +1,4 @@ -define(["./codemirror", 'css!./codemirror'], function(CodeMirror) { +define(["./codemirror", 'css!./theme-dark'], function(CodeMirror) { CodeMirror.defineMode("htmlmixed", function(config) { var htmlMode = CodeMirror.getMode(config, { name: "xml", diff --git a/js/lib/codemirror/codemirror.css b/js/lib/codemirror/theme-dark.css similarity index 100% rename from js/lib/codemirror/codemirror.css rename to js/lib/codemirror/theme-dark.css diff --git a/js/lib/codemirror/theme-light.css b/js/lib/codemirror/theme-light.css new file mode 100644 index 0000000..e8f4393 --- /dev/null +++ b/js/lib/codemirror/theme-light.css @@ -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}} \ No newline at end of file diff --git a/js/lib/drag/drag.js b/js/lib/drag/drag.js index bb82598..0f0a871 100644 --- a/js/lib/drag/drag.js +++ b/js/lib/drag/drag.js @@ -19,7 +19,7 @@ define(['yua'], function(){ } } } - + yua.ui.drag = '0.0.1' // 元素拖动 yua.directive('drag', { priority: 1500, diff --git a/js/lib/layer.tar.gz b/js/lib/layer.tar.gz deleted file mode 100644 index d945850..0000000 Binary files a/js/lib/layer.tar.gz and /dev/null differ diff --git a/js/lib/layer/Release.md b/js/lib/layer/Release.md index 702fcc4..3d3c6d5 100644 --- a/js/lib/layer/Release.md +++ b/js/lib/layer/Release.md @@ -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 ================== + 修复:layer方式创建实例时,漏掉自身的bug; diff --git a/js/lib/layer/layer-base.js b/js/lib/layer/base.js similarity index 92% rename from js/lib/layer/layer-base.js rename to js/lib/layer/base.js index 729209b..7639ca3 100644 --- a/js/lib/layer/layer-base.js +++ b/js/lib/layer/base.js @@ -13,6 +13,8 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ if(window.layer){ return window.layer } + + yua.ui.layer = '0.0.4-base' var layerDom = {}, layerObj = {}, unique = null, //储存当前打开的1/2/3类型的弹窗 @@ -55,6 +57,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ return } layerObj[id].parentElem.replaceChild(layerObj[id].wrap, layerDom[id][1]) + layerObj[id].wrap.style.display = 'none' layerObj[id].show = false }catch(err){} @@ -220,20 +223,21 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ if(!yua.vmodels[conf]){ yua(layerObj[conf].obj.init) } - - yua.scan(layerDom[conf][1]) - layerObj[conf].obj.show() layerObj[conf].parentElem.appendChild(layerDom[conf][1]) - layerObj[conf].parentElem.replaceChild(layerDom[conf][1], layerObj[conf].wrap) + layerDom[conf][1].querySelector('.detail').appendChild(layerObj[conf].wrap) + layerObj[conf].wrap.style.display = '' + yua.scan(layerDom[conf][1]) + layerObj[conf].obj.show() return conf } }else{ return new __constructor(conf).init.$id } }, - version: '0.0.2-base' + version: yua.ui.layer }; + /*type: { // 弹窗类型对应的id值 1: 'alert', @@ -295,7 +299,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ } layBox.innerHTML = this.getMenubar() - + '
' || '') - + delete this.init.wrap return [this.init.shade ? coverBox : null, layBox] }, getCont: function(){ @@ -314,7 +318,9 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ return this.getLoading(this.init.load) }else{ return this.getIcon() - + '
' + + '
' } }, getLoading: function(style){ @@ -337,7 +343,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ } html += '>{{title}}' - + '' + + '' + '
' } return html @@ -348,7 +354,7 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ return '' } if(this.init.type < 4 || this.init.type === 5 || this.init.specialMode){ - return '' + return '' } return '' }, @@ -422,6 +428,16 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ style.right = fixOffset(_this.init.offset[1]) style.bottom = fixOffset(_this.init.offset[2]) 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{ style = yua.mix(style, { marginLeft: -parseInt(css.width) / 2, @@ -515,18 +531,19 @@ define(['yua', 'lib/drag', 'css!./skin/def'], function(yua){ } if(!this.param){ + init.wrap = true init.type = 7; init.$id = '$wrap-' + val; if(!init.hasOwnProperty('menubar')){ init.menubar = false; } - var tmp = new __constructor().ready(init), - elem = this.element.cloneNode(true); + var tmp = new __constructor().ready(init); - // 去掉隐藏之后,再放入content中 - elem.style.display = '' - tmp.init.content = elem.outerHTML; + //去掉data-*属性 + for(var i in this.element.dataset){ + delete this.element.dataset[i] + } layerObj[tmp.init.$id] = {obj: tmp, parentElem: this.element.parentNode, wrap: this.element, show: false}; layerDom[tmp.init.$id] = tmp.create(); diff --git a/js/lib/layer/layer-full.js b/js/lib/layer/full.js similarity index 100% rename from js/lib/layer/layer-full.js rename to js/lib/layer/full.js diff --git a/js/lib/layer/layer-mobile.js b/js/lib/layer/mobile.js similarity index 100% rename from js/lib/layer/layer-mobile.js rename to js/lib/layer/mobile.js diff --git a/js/lib/layer/skin/def.css b/js/lib/layer/skin/def.css index 5d93f3a..b95ee3a 100644 --- a/js/lib/layer/skin/def.css +++ b/js/lib/layer/skin/def.css @@ -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 * {margin: 0;padding: 0;vertical-align: baseline;box-sizing:border-box;} + +.do-layer, .do-layer * {vertical-align: baseline;box-sizing:border-box;} .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.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 {position:fixed;left:50%;top:50%;z-index:65535;width:auto;height:auto;} .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 .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-2:before {content:"\e6fa";color:#f30;}/*position*/ .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 .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.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;} diff --git a/js/lib/marked/marked.js b/js/lib/marked/marked.js index 8b00bb1..e03745a 100644 --- a/js/lib/marked/marked.js +++ b/js/lib/marked/marked.js @@ -827,9 +827,11 @@ Renderer.prototype.heading = function(text, level, raw) { + level + ' class="md-hd" id="' + raw + + '">' + text - + '\n'; }; @@ -1027,7 +1029,7 @@ Parser.prototype.tok = function() { } case 'code': { return this.renderer.code(this.token.text, - this.token.lang, + this.token.lang || 'other', this.token.escaped); } case 'table': { @@ -1124,7 +1126,7 @@ Parser.prototype.tok = function() { */ function escape(html, encode) { - return html + return (html) .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') .replace(//g, '>') diff --git a/js/lib/meditor/addon/attach.css b/js/lib/meditor/addon/attach.css new file mode 100644 index 0000000..17c60c7 --- /dev/null +++ b/js/lib/meditor/addon/attach.css @@ -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;} + diff --git a/js/lib/meditor/addon/attach.js b/js/lib/meditor/addon/attach.js new file mode 100644 index 0000000..211d110 --- /dev/null +++ b/js/lib/meditor/addon/attach.js @@ -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 '
' + + '
' + + '
' + + '' + lang[openType][0] +'' + + '本地上传' + + '' + lang[openType][1] + '' + + '' + + '
' + + '
' + + '
' + + '
'+ lang[openType][2] + '' + + '' + + '
' + + '
'+ lang[openType][3] + '' + + '' + + '
' + + '
' + + '确定' + + '
' + + '
' + + '
' + + '
选择文件
' + + '
    ' + + '
  • 文件名上传进度操作
  • ' + + '
  • ' + + '' + + '' + + '插入' + + '
  • ' + + '
' + + '
' + + '
    ' + + '
  • ' + + '' + + '

    ' + + '
  • ' + + '
' + + '
' + + '
' + + '
' + }; + + /** + * [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' ? '' : '' + 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 + + +}) \ No newline at end of file diff --git a/js/lib/meditor/addon/base.js b/js/lib/meditor/addon/base.js new file mode 100644 index 0000000..49863ed --- /dev/null +++ b/js/lib/meditor/addon/base.js @@ -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: '' + }) + }, + 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: '
' + + '
链接文字' + + '' + + '
' + + '
链接地址' + + '' + + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '确定' + + '
' + + '
' + }) + }, + 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: '', + $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: '', + 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: '
' + + '
图片描述' + + '' + + '
' + + '
图片地址' + + '' + + '
' + + '
' + + '确定' + + '
' + + '
' + }) + }, + 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: '
' + + '
语言类型' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '确定' + + '
' + + '
' + }) + }, + 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: '
' + + '
'
+                    + ' __  __ _____    _ _ _\n'             
+                    + '|  \\/  | ____|__| (_) |_ ___  _ __\n' 
+                    + '| |\\/| |  _| / _` | | __/ _ \\| \'__|\n'
+                    + '| |  | | |__| (_| | | || (_) | |\n'   
+                    + '|_|  |_|_____\\__,_|_|\\__\\___/|_|    ' 
+                    + 'v' + ME.version + '
' + + '

开源在线Markdown编辑器

' + + '

https://doui.cc/product/meditor

' + + '

Copyright © 2017 Yutent, The MIT License.

' + + '
' + }) + } + + } + +}) \ No newline at end of file diff --git a/js/lib/meditor/addon/face/0.gif b/js/lib/meditor/addon/face/0.gif new file mode 100644 index 0000000..f84ea24 Binary files /dev/null and b/js/lib/meditor/addon/face/0.gif differ diff --git a/js/lib/meditor/addon/face/1.gif b/js/lib/meditor/addon/face/1.gif new file mode 100644 index 0000000..ea55622 Binary files /dev/null and b/js/lib/meditor/addon/face/1.gif differ diff --git a/js/lib/meditor/addon/face/10.gif b/js/lib/meditor/addon/face/10.gif new file mode 100644 index 0000000..05f39cf Binary files /dev/null and b/js/lib/meditor/addon/face/10.gif differ diff --git a/js/lib/meditor/addon/face/11.gif b/js/lib/meditor/addon/face/11.gif new file mode 100644 index 0000000..c73c5c1 Binary files /dev/null and b/js/lib/meditor/addon/face/11.gif differ diff --git a/js/lib/meditor/addon/face/12.gif b/js/lib/meditor/addon/face/12.gif new file mode 100644 index 0000000..3f52e3c Binary files /dev/null and b/js/lib/meditor/addon/face/12.gif differ diff --git a/js/lib/meditor/addon/face/13.gif b/js/lib/meditor/addon/face/13.gif new file mode 100644 index 0000000..ed2dac2 Binary files /dev/null and b/js/lib/meditor/addon/face/13.gif differ diff --git a/js/lib/meditor/addon/face/14.gif b/js/lib/meditor/addon/face/14.gif new file mode 100644 index 0000000..e602647 Binary files /dev/null and b/js/lib/meditor/addon/face/14.gif differ diff --git a/js/lib/meditor/addon/face/15.gif b/js/lib/meditor/addon/face/15.gif new file mode 100644 index 0000000..627ce21 Binary files /dev/null and b/js/lib/meditor/addon/face/15.gif differ diff --git a/js/lib/meditor/addon/face/16.gif b/js/lib/meditor/addon/face/16.gif new file mode 100644 index 0000000..18025fc Binary files /dev/null and b/js/lib/meditor/addon/face/16.gif differ diff --git a/js/lib/meditor/addon/face/17.gif b/js/lib/meditor/addon/face/17.gif new file mode 100644 index 0000000..280d848 Binary files /dev/null and b/js/lib/meditor/addon/face/17.gif differ diff --git a/js/lib/meditor/addon/face/18.gif b/js/lib/meditor/addon/face/18.gif new file mode 100644 index 0000000..062d2ab Binary files /dev/null and b/js/lib/meditor/addon/face/18.gif differ diff --git a/js/lib/meditor/addon/face/19.gif b/js/lib/meditor/addon/face/19.gif new file mode 100644 index 0000000..c4d0bf1 Binary files /dev/null and b/js/lib/meditor/addon/face/19.gif differ diff --git a/js/lib/meditor/addon/face/2.gif b/js/lib/meditor/addon/face/2.gif new file mode 100644 index 0000000..5ee1c51 Binary files /dev/null and b/js/lib/meditor/addon/face/2.gif differ diff --git a/js/lib/meditor/addon/face/20.gif b/js/lib/meditor/addon/face/20.gif new file mode 100644 index 0000000..541575d Binary files /dev/null and b/js/lib/meditor/addon/face/20.gif differ diff --git a/js/lib/meditor/addon/face/21.gif b/js/lib/meditor/addon/face/21.gif new file mode 100644 index 0000000..f65ad8a Binary files /dev/null and b/js/lib/meditor/addon/face/21.gif differ diff --git a/js/lib/meditor/addon/face/22.gif b/js/lib/meditor/addon/face/22.gif new file mode 100644 index 0000000..25a0e2e Binary files /dev/null and b/js/lib/meditor/addon/face/22.gif differ diff --git a/js/lib/meditor/addon/face/23.gif b/js/lib/meditor/addon/face/23.gif new file mode 100644 index 0000000..493cae9 Binary files /dev/null and b/js/lib/meditor/addon/face/23.gif differ diff --git a/js/lib/meditor/addon/face/24.gif b/js/lib/meditor/addon/face/24.gif new file mode 100644 index 0000000..3aba83f Binary files /dev/null and b/js/lib/meditor/addon/face/24.gif differ diff --git a/js/lib/meditor/addon/face/25.gif b/js/lib/meditor/addon/face/25.gif new file mode 100644 index 0000000..436be39 Binary files /dev/null and b/js/lib/meditor/addon/face/25.gif differ diff --git a/js/lib/meditor/addon/face/26.gif b/js/lib/meditor/addon/face/26.gif new file mode 100644 index 0000000..d809261 Binary files /dev/null and b/js/lib/meditor/addon/face/26.gif differ diff --git a/js/lib/meditor/addon/face/27.gif b/js/lib/meditor/addon/face/27.gif new file mode 100644 index 0000000..2746fb6 Binary files /dev/null and b/js/lib/meditor/addon/face/27.gif differ diff --git a/js/lib/meditor/addon/face/28.gif b/js/lib/meditor/addon/face/28.gif new file mode 100644 index 0000000..8177e33 Binary files /dev/null and b/js/lib/meditor/addon/face/28.gif differ diff --git a/js/lib/meditor/addon/face/29.gif b/js/lib/meditor/addon/face/29.gif new file mode 100644 index 0000000..35b983f Binary files /dev/null and b/js/lib/meditor/addon/face/29.gif differ diff --git a/js/lib/meditor/addon/face/3.gif b/js/lib/meditor/addon/face/3.gif new file mode 100644 index 0000000..ecd4716 Binary files /dev/null and b/js/lib/meditor/addon/face/3.gif differ diff --git a/js/lib/meditor/addon/face/30.gif b/js/lib/meditor/addon/face/30.gif new file mode 100644 index 0000000..3cce229 Binary files /dev/null and b/js/lib/meditor/addon/face/30.gif differ diff --git a/js/lib/meditor/addon/face/31.gif b/js/lib/meditor/addon/face/31.gif new file mode 100644 index 0000000..b955b1c Binary files /dev/null and b/js/lib/meditor/addon/face/31.gif differ diff --git a/js/lib/meditor/addon/face/32.gif b/js/lib/meditor/addon/face/32.gif new file mode 100644 index 0000000..4a94f63 Binary files /dev/null and b/js/lib/meditor/addon/face/32.gif differ diff --git a/js/lib/meditor/addon/face/33.gif b/js/lib/meditor/addon/face/33.gif new file mode 100644 index 0000000..6f56878 Binary files /dev/null and b/js/lib/meditor/addon/face/33.gif differ diff --git a/js/lib/meditor/addon/face/34.gif b/js/lib/meditor/addon/face/34.gif new file mode 100644 index 0000000..6512cb5 Binary files /dev/null and b/js/lib/meditor/addon/face/34.gif differ diff --git a/js/lib/meditor/addon/face/35.gif b/js/lib/meditor/addon/face/35.gif new file mode 100644 index 0000000..a4be9ed Binary files /dev/null and b/js/lib/meditor/addon/face/35.gif differ diff --git a/js/lib/meditor/addon/face/4.gif b/js/lib/meditor/addon/face/4.gif new file mode 100644 index 0000000..6b08420 Binary files /dev/null and b/js/lib/meditor/addon/face/4.gif differ diff --git a/js/lib/meditor/addon/face/5.gif b/js/lib/meditor/addon/face/5.gif new file mode 100644 index 0000000..63e37b7 Binary files /dev/null and b/js/lib/meditor/addon/face/5.gif differ diff --git a/js/lib/meditor/addon/face/6.gif b/js/lib/meditor/addon/face/6.gif new file mode 100644 index 0000000..99bb848 Binary files /dev/null and b/js/lib/meditor/addon/face/6.gif differ diff --git a/js/lib/meditor/addon/face/7.gif b/js/lib/meditor/addon/face/7.gif new file mode 100644 index 0000000..59d0814 Binary files /dev/null and b/js/lib/meditor/addon/face/7.gif differ diff --git a/js/lib/meditor/addon/face/8.gif b/js/lib/meditor/addon/face/8.gif new file mode 100644 index 0000000..74567e8 Binary files /dev/null and b/js/lib/meditor/addon/face/8.gif differ diff --git a/js/lib/meditor/addon/face/9.gif b/js/lib/meditor/addon/face/9.gif new file mode 100644 index 0000000..fc20d67 Binary files /dev/null and b/js/lib/meditor/addon/face/9.gif differ diff --git a/js/lib/meditor/main.js b/js/lib/meditor/main.js new file mode 100644 index 0000000..e83f068 --- /dev/null +++ b/js/lib/meditor/main.js @@ -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(/]*>/, '') + + 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)[^>]*>(?:(?!/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.pop() + + for(var i = 0,len = li.length; i < len; i++){ + var pre = t === 'ol' ? ((i + 1) + '. ') : '* ' + li[i] = pre + li[i].replace(/\s*]*>([\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 '' + } + + + + yua.component('meditor', { + $template: '
' + + '
{toolbar}
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
', + $$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文本 + + + }) + + + + }) + +}) diff --git a/js/lib/meditor/skin/iconfont.eot b/js/lib/meditor/skin/iconfont.eot new file mode 100644 index 0000000..3bbb99b Binary files /dev/null and b/js/lib/meditor/skin/iconfont.eot differ diff --git a/js/lib/meditor/skin/iconfont.ttf b/js/lib/meditor/skin/iconfont.ttf new file mode 100644 index 0000000..5e6a583 Binary files /dev/null and b/js/lib/meditor/skin/iconfont.ttf differ diff --git a/js/lib/meditor/skin/main.css b/js/lib/meditor/skin/main.css new file mode 100644 index 0000000..cac84e4 --- /dev/null +++ b/js/lib/meditor/skin/main.css @@ -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;} \ No newline at end of file diff --git a/js/lib/pages/pages.css b/js/lib/pages/main.css similarity index 100% rename from js/lib/pages/pages.css rename to js/lib/pages/main.css diff --git a/js/lib/pages/pages.htm b/js/lib/pages/main.htm similarity index 100% rename from js/lib/pages/pages.htm rename to js/lib/pages/main.htm diff --git a/js/lib/pages/pages.js b/js/lib/pages/main.js similarity index 96% rename from js/lib/pages/pages.js rename to js/lib/pages/main.js index ebf9762..bdbb563 100644 --- a/js/lib/pages/pages.js +++ b/js/lib/pages/main.js @@ -1,6 +1,7 @@ "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){ if (vm.total < 2) diff --git a/js/lib/pages/pages.min.css b/js/lib/pages/pages.min.css deleted file mode 100644 index e69de29..0000000 diff --git a/js/lib/pages/pages.min.js b/js/lib/pages/pages.min.js deleted file mode 100644 index e69de29..0000000 diff --git a/js/lib/prism/highlight.css b/js/lib/prism/highlight.css new file mode 100644 index 0000000..30ea294 --- /dev/null +++ b/js/lib/prism/highlight.css @@ -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;} \ No newline at end of file diff --git a/js/lib/prism/prism.js b/js/lib/prism/prism.js index e5854d5..294a41f 100644 --- a/js/lib/prism/prism.js +++ b/js/lib/prism/prism.js @@ -1,831 +1,793 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+nginx+yaml */ -var _self = (typeof window !== 'undefined') - ? window // if in browser - : ( - (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - ? self // if in worker - : {} // if in node js - ); - -/** - * 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(){ - -// Private helper vars -var lang = /\blang(?:uage)?-(\w+)\b/i; -var uniqueId = 0; - -var _ = _self.Prism = { - manual: _self.Prism && _self.Prism.manual, - util: { - encode: function (tokens) { - if (tokens instanceof Token) { - return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); - } else if (_.util.type(tokens) === 'Array') { - return tokens.map(_.util.encode); - } else { - return tokens.replace(/&/g, '&').replace(/ text.length) { - // Something went terribly wrong, ABORT, ABORT! - break tokenloop; - } + var rest = grammar.rest; - if (str instanceof Token) { - continue; - } + if (rest) { + for (var token in rest) { + grammar[token] = rest[token]; + } - pattern.lastIndex = 0; + delete grammar.rest; + } - var match = pattern.exec(str), - delNum = 1; + tokenloop: for (var token in grammar) { + if (!grammar.hasOwnProperty(token) || !grammar[token]) { + continue; + } - // Greedy patterns can override/remove up to two previously matched tokens - if (!match && greedy && i != strarr.length - 1) { - pattern.lastIndex = pos; - match = pattern.exec(text); - if (!match) { - break; - } - - var from = match.index + (lookbehind ? match[1].length : 0), - to = match.index + match[0].length, - k = i, - p = pos; - - for (var len = strarr.length; k < len && p < to; ++k) { - p += strarr[k].length; - // Move the index i to the element in strarr that is closest to from - if (from >= p) { - ++i; - pos = p; - } - } - - /* - * 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) { - continue; - } - - // Number of tokens to delete and replace with the new match - delNum = k - i; - str = text.slice(pos, p); - match.index -= pos; - } - - if (!match) { - continue; - } - - if(lookbehind) { - lookbehindLength = match[1].length; - } - - var from = match.index + lookbehindLength, - match = match[0].slice(lookbehindLength), - to = from + match.length, - before = str.slice(0, from), - after = str.slice(to); - - var args = [i, delNum]; - - if (before) { - args.push(before); - } - - var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); - - args.push(wrapped); - - if (after) { - args.push(after); - } - - Array.prototype.splice.apply(strarr, args); - } - } - } - - return strarr; - }, - - hooks: { - all: {}, - - add: function (name, callback) { - var hooks = _.hooks.all; - - hooks[name] = hooks[name] || []; - - hooks[name].push(callback); - }, - - run: function (name, env) { - var callbacks = _.hooks.all[name]; - - if (!callbacks || !callbacks.length) { - return; - } - - for (var i=0, callback; callback = callbacks[i++];) { - callback(env); - } - } - } -}; - -var Token = _.Token = function(type, content, alias, matchedStr, greedy) { - this.type = type; - this.content = content; - this.alias = alias; - // Copy of the full string this token was created from - this.length = (matchedStr || "").length|0; - this.greedy = !!greedy; -}; - -Token.stringify = function(o, language, parent) { - if (typeof o == 'string') { - return o; - } - - if (_.util.type(o) === 'Array') { - return o.map(function(element) { - return Token.stringify(element, language, o); - }).join(''); - } - - var env = { - type: o.type, - content: Token.stringify(o.content, language, parent), - tag: 'span', - classes: ['c-' + o.type], - attributes: {}, - language: language, - parent: parent - }; - - if (o.alias) { - var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; - Array.prototype.push.apply(env.classes, aliases); - } - - _.hooks.run('wrap', env); - - var attributes = Object.keys(env.attributes).map(function(name) { - return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; - }).join(' '); - - return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; - -}; - -if (!_self.document) { - if (!_self.addEventListener) { - // in Node.js - return _self.Prism; - } - // In worker - _self.addEventListener('message', function(evt) { - var message = JSON.parse(evt.data), - lang = message.language, - code = message.code, - immediateClose = message.immediateClose; - - _self.postMessage(_.highlight(code, _.languages[lang], lang)); - if (immediateClose) { - _self.close(); - } - }, false); - - return _self.Prism; -} - -//Get current script and highlight -var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); - -if (script) { - _.filename = script.src; - - if (document.addEventListener && !_.manual && !script.hasAttribute('data-manual')) { - if(document.readyState !== "loading") { - if (window.requestAnimationFrame) { - window.requestAnimationFrame(_.highlightAll); - } else { - window.setTimeout(_.highlightAll, 16); - } - } - else { - document.addEventListener('DOMContentLoaded', _.highlightAll); - } - } -} - -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 = { - 'smartyx': //, - 'comment': //, - 'prolog': /<\?[\w\W]+?\?>/, - 'doctype': //i, - 'cdata': //i, - 'tag': { - pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, - inside: { - 'tag': { - pattern: /^<\/?[^\s>\/]+/i, - inside: { - 'punctuation': /^<\/?/, - 'namespace': /^[^\s>\/:]+:/ - } - }, - 'attr-value': { - pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, - inside: { - 'punctuation': /[=>"']/ - } - }, - 'punctuation': /\/?>/, - 'attr-name': { - pattern: /[^\s>\/]+/, - inside: { - 'namespace': /^[^\s>\/:]+:/ - } - } - - } - }, - 'entity': /&#?[\da-z]{1,8};/i -}; - -// Plugin to make entity title show the real entity, idea by Roman Komarov -Prism.hooks.add('wrap', function(env) { - - if (env.type === 'entity') { - env.attributes['title'] = env.content.replace(/&/, '&'); - } -}); - -Prism.languages.xml = Prism.languages.markup; -Prism.languages.html = Prism.languages.markup; -Prism.languages.mathml = Prism.languages.markup; -Prism.languages.svg = Prism.languages.markup; - -Prism.languages.css = { - 'comment': /\/\*[\w\W]*?\*\//, - 'atrule': { - pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, - inside: { - 'rule': /@[\w-]+/ - // See rest below - } - }, - 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, - 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, - 'string': { - pattern: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'property': /(\b|\B)[\w-]+(?=\s*:)/i, - 'important': /\B!important\b/i, - 'function': /[-a-z0-9]+(?=\()/i, - 'punctuation': /[(){};:]/ -}; - -Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); - -if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - 'style': { - pattern: /()[\w\W]*?(?=<\/style>)/i, - lookbehind: true, - inside: Prism.languages.css, - alias: 'language-css' - } - }); - - Prism.languages.insertBefore('inside', 'attr-value', { - 'style-attr': { - pattern: /\s*style=("|').*?\1/i, - inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: Prism.languages.markup.tag.inside - }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, - 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' - } - }, Prism.languages.markup.tag); -}; -Prism.languages.clike = { - 'comment': [ - { - pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, - lookbehind: true - }, - { - pattern: /(^|[^\\:])\/\/.*/, - lookbehind: true - } - ], - 'string': { - pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'class-name': { - pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, - lookbehind: true, - inside: { - punctuation: /(\.|\\)/ - } - }, - 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, - 'boolean': /\b(true|false)\b/, - 'function': /[a-z0-9_]+(?=\()/i, - 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, - 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, - 'punctuation': /[{}[\];(),.:]/ -}; - -Prism.languages.javascript = Prism.languages.extend('clike', { - 'build-in': /\b(Object|Array|console|Function|String|Global|window|Buffer|Audio|Video|Date|Math|process|EventEmitter|__dirname|__filename|module|export|exports|import|require|Promise)\b/, - 'params': /(\(.*?\)|[A-Za-z$_][0-9A-Za-z$_]*)\s*=>/, - 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, - 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, - // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) - 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, - 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/, - -}); - -Prism.languages.insertBefore('javascript', 'keyword', { - 'regex': { - pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, - lookbehind: true, - greedy: true - } -}); - -Prism.languages.insertBefore('javascript', 'string', { - 'template-string': { - pattern: /`(?:\\\\|\\?[^\\])*?`/, - greedy: true, - inside: { - 'interpolation': { - pattern: /\$\{[^}]+\}/, - inside: { - 'interpolation-punctuation': { - pattern: /^\$\{|\}$/, - alias: 'punctuation' - }, - rest: Prism.languages.javascript - } - }, - 'string': /[\s\S]+/ - } - } -}); - -if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - 'script': { - pattern: /()[\w\W]*?(?=<\/script>)/i, - lookbehind: true, - inside: Prism.languages.javascript, - alias: 'language-javascript' - } - }); -} - -Prism.languages.js = Prism.languages.javascript; -(function(Prism) { - var insideString = { - variable: [ - // Arithmetic Environment - { - pattern: /\$?\(\([\w\W]+?\)\)/, - inside: { - // If there is a $ sign at the beginning highlight $(( and )) as variable - variable: [{ - pattern: /(^\$\(\([\w\W]+)\)\)/, - lookbehind: true - }, - /^\$\(\(/, - ], - number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/, - // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic - operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, - // If there is no $ sign at the beginning highlight (( and )) as punctuation - punctuation: /\(\(?|\)\)?|,|;/ - } - }, - // Command Substitution - { - pattern: /\$\([^)]+\)|`[^`]+`/, - inside: { - variable: /^\$\(|^`|\)$|`$/ - } - }, - /\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i - ], - }; - - Prism.languages.bash = { - 'important': { - pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/ - }, - 'comment': { - pattern: /(^|[^"{\\])#.*/, - lookbehind: true - }, - 'string': [ - //Support for Here-Documents https://en.wikipedia.org/wiki/Here_document - { - pattern: /((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g, - lookbehind: true, - greedy: true, - inside: insideString - }, - { - pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g, - greedy: true, - inside: insideString - } - ], - 'variable': insideString.variable, - // Originally based on http://ss64.com/bash/ - 'function': { - pattern: /(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/, - lookbehind: true - }, - 'keyword': { - pattern: /(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/, - lookbehind: true - }, - 'boolean': { - pattern: /(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/, - lookbehind: true - }, - 'operator': /&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/, - 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/ - }; - - var inside = insideString.variable[1].inside; - inside['function'] = Prism.languages.bash['function']; - inside.keyword = Prism.languages.bash.keyword; - inside.boolean = Prism.languages.bash.boolean; - inside.operator = Prism.languages.bash.operator; - inside.punctuation = Prism.languages.bash.punctuation; -})(Prism); - -Prism.languages.nginx = Prism.languages.extend('clike', { - 'comment': { + var patterns = grammar[token]; + patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns]; + + for (var j = 0; j < patterns.length; ++j) { + var pattern = patterns[j], + inside = pattern.inside, + lookbehind = !!pattern.lookbehind, + greedy = !!pattern.greedy, + lookbehindLength = 0, + alias = pattern.alias; + + if (greedy && !pattern.pattern.global) { + // Without the global flag, lastIndex won't work + var flags = pattern.pattern.toString().match(/[imuy]*$/)[0]; + pattern.pattern = RegExp(pattern.pattern.source, flags + "g"); + } + + pattern = pattern.pattern || pattern; + + // Don’t cache length as it changes during the loop + for (var i = 0, pos = 0; i < strarr.length; pos += strarr[i].length, ++i) { + + var str = strarr[i]; + + if (strarr.length > text.length) { + // Something went terribly wrong, ABORT, ABORT! + break tokenloop; + } + + if (str instanceof Token) { + continue; + } + + pattern.lastIndex = 0; + + var match = pattern.exec(str), + delNum = 1; + + // Greedy patterns can override/remove up to two previously matched tokens + if (!match && greedy && i != strarr.length - 1) { + pattern.lastIndex = pos; + match = pattern.exec(text); + if (!match) { + break; + } + + var from = match.index + (lookbehind ? match[1].length : 0), + to = match.index + match[0].length, + k = i, + p = pos; + + for (var len = strarr.length; k < len && p < to; ++k) { + p += strarr[k].length; + // Move the index i to the element in strarr that is closest to from + if (from >= p) { + ++i; + pos = p; + } + } + + if (strarr[i] instanceof Token || strarr[k - 1].greedy) { + continue; + } + + // Number of tokens to delete and replace with the new match + delNum = k - i; + str = text.slice(pos, p); + match.index -= pos; + } + + if (!match) { + continue; + } + + if (lookbehind) { + lookbehindLength = match[1].length; + } + + var from = match.index + lookbehindLength, + match = match[0].slice(lookbehindLength), + to = from + match.length, + before = str.slice(0, from), + after = str.slice(to); + + var args = [i, delNum]; + + if (before) { + args.push(before); + } + + var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias, match, greedy); + + args.push(wrapped); + + if (after) { + args.push(after); + } + + Array.prototype.splice.apply(strarr, args); + } + } + } + + return strarr; + }, + + hooks: { + all: {}, + + add: function(name, callback) { + var hooks = _.hooks.all; + + hooks[name] = hooks[name] || []; + + hooks[name].push(callback); + }, + + run: function(name, env) { + var callbacks = _.hooks.all[name]; + + if (!callbacks || !callbacks.length) { + return; + } + + for (var i = 0, callback; callback = callbacks[i++];) { + callback(env); + } + } + } + }; + + var Token = _.Token = function(type, content, alias, matchedStr, greedy) { + this.type = type; + this.content = content; + this.alias = alias; + // Copy of the full string this token was created from + this.length = (matchedStr || "").length | 0; + this.greedy = !!greedy; + }; + + Token.stringify = function(o, language, parent) { + if (typeof o == 'string') { + return o; + } + + if (_.util.type(o) === 'Array') { + return o.map(function(element) { + return Token.stringify(element, language, o); + }).join(''); + } + + var env = { + type: o.type, + content: Token.stringify(o.content, language, parent), + tag: 'span', + classes: ['c-' + o.type], + attributes: {}, + language: language, + parent: parent + }; + + if (o.alias) { + var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; + Array.prototype.push.apply(env.classes, aliases); + } + + _.hooks.run('wrap', env); + + var attributes = Object.keys(env.attributes).map(function(name) { + return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; + }).join(' '); + + return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; + + }; + + if (!_self.document) { + if (!_self.addEventListener) { + // in Node.js + return _self.Prism; + } + // In worker + _self.addEventListener('message', function(evt) { + var message = JSON.parse(evt.data), + lang = message.language, + code = message.code, + immediateClose = message.immediateClose; + + _self.postMessage(_.highlight(code, _.languages[lang], lang)); + if (immediateClose) { + _self.close(); + } + }, false); + + return _self.Prism; + } + + //Get current script and highlight + var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); + + if (script) { + _.filename = script.src; + + if (document.addEventListener && !_.manual && !script.hasAttribute('data-manual')) { + if (document.readyState !== "loading") { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(_.highlightAll); + } else { + window.setTimeout(_.highlightAll, 16); + } + } else { + document.addEventListener('DOMContentLoaded', _.highlightAll); + } + } + } + + return _self.Prism; + + })(); + + + Prism.languages.markup = { + 'smartyx': //, + 'comment': //, + 'prolog': /<\?[\w\W]+?\?>/, + 'doctype': //i, + 'cdata': //i, + 'tag': { + pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, + inside: { + 'tag': { + pattern: /^<\/?[^\s>\/]+/i, + inside: { + 'punctuation': /^<\/?/, + 'namespace': /^[^\s>\/:]+:/ + } + }, + 'attr-value': { + pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, + inside: { + 'punctuation': /[=>"']/ + } + }, + 'punctuation': /\/?>/, + 'attr-name': { + pattern: /[^\s>\/]+/, + inside: { + 'namespace': /^[^\s>\/:]+:/ + } + } + + } + }, + 'entity': /&#?[\da-z]{1,8};/i + }; + + // Plugin to make entity title show the real entity, idea by Roman Komarov + Prism.hooks.add('wrap', function(env) { + + if (env.type === 'entity') { + env.attributes['title'] = env.content.replace(/&/, '&'); + } + }); + + Prism.languages.xml = Prism.languages.markup; + Prism.languages.html = Prism.languages.markup; + Prism.languages.mathml = Prism.languages.markup; + Prism.languages.svg = Prism.languages.markup; + + Prism.languages.css = { + 'comment': /\/\*[\w\W]*?\*\//, + 'atrule': { + pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, + inside: { + 'rule': /@[\w-]+/ + // See rest below + } + }, + 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, + 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, + 'string': { + pattern: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, + greedy: true + }, + 'property': /(\b|\B)[\w-]+(?=\s*:)/i, + 'important': /\B!important\b/i, + 'function': /[-a-z0-9]+(?=\()/i, + 'punctuation': /[(){};:]/ + }; + + Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); + + if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'style': { + pattern: /()[\w\W]*?(?=<\/style>)/i, + lookbehind: true, + inside: Prism.languages.css, + alias: 'language-css' + } + }); + + Prism.languages.insertBefore('inside', 'attr-value', { + 'style-attr': { + pattern: /\s*style=("|').*?\1/i, + inside: { + 'attr-name': { + pattern: /^\s*style/i, + inside: Prism.languages.markup.tag.inside + }, + 'punctuation': /^\s*=\s*['"]|['"]\s*$/, + 'attr-value': { + pattern: /.+/i, + inside: Prism.languages.css + } + }, + alias: 'language-css' + } + }, Prism.languages.markup.tag); + }; + Prism.languages.clike = { + 'comment': [{ + pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, + lookbehind: true + }, { + pattern: /(^|[^\\:])\/\/.*/, + lookbehind: true + }], + 'string': { + pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: true + }, + 'class-name': { + pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, + lookbehind: true, + inside: { + punctuation: /(\.|\\)/ + } + }, + 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, + 'boolean': /\b(true|false)\b/, + 'function': /[a-z0-9_]+(?=\()/i, + 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, + 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, + 'punctuation': /[{}[\];(),.:]/ + }; + + Prism.languages.javascript = Prism.languages.extend('clike', { + 'build-in': /\b(Object|Array|console|Function|String|Global|window|Buffer|Audio|Video|Date|Math|process|EventEmitter|__dirname|__filename|module|export|exports|import|require|Promise)\b/, + 'params': /(\(.*?\)|[A-Za-z$_][0-9A-Za-z$_]*)\s*=>/, + 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, + 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, + // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) + 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, + 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/, + + }); + + Prism.languages.insertBefore('javascript', 'keyword', { + 'regex': { + pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, + lookbehind: true, + greedy: true + } + }); + + Prism.languages.insertBefore('javascript', 'string', { + 'template-string': { + pattern: /`(?:\\\\|\\?[^\\])*?`/, + greedy: true, + inside: { + 'interpolation': { + pattern: /\$\{[^}]+\}/, + inside: { + 'interpolation-punctuation': { + pattern: /^\$\{|\}$/, + alias: 'punctuation' + }, + rest: Prism.languages.javascript + } + }, + 'string': /[\s\S]+/ + } + } + }); + + if (Prism.languages.markup) { + Prism.languages.insertBefore('markup', 'tag', { + 'script': { + pattern: /()[\w\W]*?(?=<\/script>)/i, + lookbehind: true, + inside: Prism.languages.javascript, + alias: 'language-javascript' + } + }); + } + + Prism.languages.js = Prism.languages.javascript; + (function(Prism) { + var insideString = { + variable: [ + // Arithmetic Environment + { + pattern: /\$?\(\([\w\W]+?\)\)/, + inside: { + // If there is a $ sign at the beginning highlight $(( and )) as variable + variable: [{ + pattern: /(^\$\(\([\w\W]+)\)\)/, + lookbehind: true + }, + /^\$\(\(/, + ], + number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/, + // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic + operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, + // If there is no $ sign at the beginning highlight (( and )) as punctuation + punctuation: /\(\(?|\)\)?|,|;/ + } + }, + // Command Substitution + { + pattern: /\$\([^)]+\)|`[^`]+`/, + inside: { + variable: /^\$\(|^`|\)$|`$/ + } + }, + /\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i + ], + }; + + Prism.languages.bash = { + 'important': { + pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/ + }, + 'comment': { pattern: /(^|[^"{\\])#.*/, lookbehind: true + }, + 'string': [ + //Support for Here-Documents https://en.wikipedia.org/wiki/Here_document + { + pattern: /((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g, + lookbehind: true, + greedy: true, + inside: insideString + }, { + pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g, + greedy: true, + inside: insideString + } + ], + 'variable': insideString.variable, + // Originally based on http://ss64.com/bash/ + 'function': { + pattern: /(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'keyword': { + pattern: /(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'boolean': { + pattern: /(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/, + lookbehind: true + }, + 'operator': /&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/, + 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/ + }; + + var inside = insideString.variable[1].inside; + inside['function'] = Prism.languages.bash['function']; + inside.keyword = Prism.languages.bash.keyword; + inside.boolean = Prism.languages.bash.boolean; + inside.operator = Prism.languages.bash.operator; + inside.punctuation = Prism.languages.bash.punctuation; + })(Prism); + + Prism.languages.nginx = Prism.languages.extend('clike', { + 'comment': { + pattern: /(^|[^"{\\])#.*/, + lookbehind: true }, 'keyword': /\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|server|events|location|include|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i, -}); + }); -Prism.languages.insertBefore('nginx', 'keyword', { + Prism.languages.insertBefore('nginx', 'keyword', { 'variable': /\$[a-z_]+/i -}); -Prism.languages.yaml = { - 'scalar': { - pattern: /([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/, - lookbehind: true, - alias: 'string' - }, - 'comment': /#.*/, - 'key': { - pattern: /(\s*(?:^|[:\-,[{\r\n?])[ \t]*(![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/, - lookbehind: true, - alias: 'atrule' - }, - 'directive': { - pattern: /(^[ \t]*)%.+/m, - lookbehind: true, - alias: 'important' - }, - 'datetime': { - pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*($|,|]|}))/m, - lookbehind: true, - alias: 'number' - }, - 'boolean': { - pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=$|,|]|})/im, - lookbehind: true, - alias: 'important' - }, - 'null': { - pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=$|,|]|})/im, - lookbehind: true, - alias: 'important' - }, - 'string': { - pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=[ \t]*($|,|]|}))/m, - lookbehind: true, - greedy: true - }, - 'number': { - pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\da-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im, - lookbehind: true - }, - 'tag': /![^\s]+/, - 'important': /[&*][\w]+/, - 'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./ -}; + }); + Prism.languages.yaml = { + 'scalar': { + pattern: /([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/, + lookbehind: true, + alias: 'string' + }, + 'comment': /#.*/, + 'key': { + pattern: /(\s*(?:^|[:\-,[{\r\n?])[ \t]*(![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/, + lookbehind: true, + alias: 'atrule' + }, + 'directive': { + pattern: /(^[ \t]*)%.+/m, + lookbehind: true, + alias: 'important' + }, + 'datetime': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*($|,|]|}))/m, + lookbehind: true, + alias: 'number' + }, + 'boolean': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=$|,|]|})/im, + lookbehind: true, + alias: 'important' + }, + 'null': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=$|,|]|})/im, + lookbehind: true, + alias: 'important' + }, + 'string': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=[ \t]*($|,|]|}))/m, + lookbehind: true, + greedy: true + }, + 'number': { + pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\da-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im, + lookbehind: true + }, + 'tag': /![^\s]+/, + 'important': /[&*][\w]+/, + 'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./ + }; + Prism.languages.other = {} + window.Prism = Prism + return Prism +}) \ No newline at end of file diff --git a/js/lib/request/request.es5.js b/js/lib/request/request.es5.js index bd9da15..e778679 100644 --- a/js/lib/request/request.es5.js +++ b/js/lib/request/request.es5.js @@ -6,7 +6,7 @@ */ "use strict"; -define(function(){ +define(['yua'], function(yua){ var _request = function(url, protocol){ this.transport = true 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){ var k @@ -109,6 +79,8 @@ define(function(){ } + var Format = function(){} + Format.prototype = { parseJS: function(code){ code = (code + '').trim() @@ -141,42 +113,7 @@ define(function(){ 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>').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 + return yua.parseHTML(html) }, param: function(obj){ if(!obj || typeof obj === 'string' || typeof obj === 'number') @@ -731,9 +668,9 @@ define(function(){ }, cache: {}, cid: 0, - version: '1.0.0', - release: 'request ES5 version/1.0.0' + version: '0.0.1-es5', } + yua.ui.request = '0.0.1-es5' } return request diff --git a/js/lib/request/request.es5.normal.js b/js/lib/request/request.es5.normal.js new file mode 100644 index 0000000..bd9da15 --- /dev/null +++ b/js/lib/request/request.es5.normal.js @@ -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>').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 +}) diff --git a/js/lib/router/router.js b/js/lib/router/router.js index 1f775ee..6d6e197 100644 --- a/js/lib/router/router.js +++ b/js/lib/router/router.js @@ -159,5 +159,7 @@ define(['yua'], function(){ return false } + yua.ui.router = '0.0.1' + return yua.router = new Router; }) \ No newline at end of file diff --git a/js/lib/router/router.min.js b/js/lib/router/router.min.js index 9b21962..e69de29 100644 --- a/js/lib/router/router.min.js +++ b/js/lib/router/router.min.js @@ -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}); \ No newline at end of file diff --git a/js/lib/tree/Readme.md b/js/lib/tree/Readme.md new file mode 100644 index 0000000..089ed13 --- /dev/null +++ b/js/lib/tree/Readme.md @@ -0,0 +1,2 @@ +# Tree树型菜单 +> 顾名思义,就是 \ No newline at end of file diff --git a/js/lib/tree/main.js b/js/lib/tree/main.js new file mode 100644 index 0000000..ea5e29e --- /dev/null +++ b/js/lib/tree/main.js @@ -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 = '
    {li}
', + ul = '
    {li}
', + li = '
  • ' + + '{child}
  • '; + + + 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 + } + }) + +}) \ No newline at end of file diff --git a/js/lib/tree/skin/def.css b/js/lib/tree/skin/def.css new file mode 100644 index 0000000..b4ed7d3 --- /dev/null +++ b/js/lib/tree/skin/def.css @@ -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";} \ No newline at end of file diff --git a/js/lib/tree/skin/iconfont.eot b/js/lib/tree/skin/iconfont.eot new file mode 100644 index 0000000..44431a3 Binary files /dev/null and b/js/lib/tree/skin/iconfont.eot differ diff --git a/js/lib/tree/skin/iconfont.ttf b/js/lib/tree/skin/iconfont.ttf new file mode 100644 index 0000000..10d19ab Binary files /dev/null and b/js/lib/tree/skin/iconfont.ttf differ diff --git a/js/yua-touch.js b/js/yua-touch.js index f85eb84..0afd789 100644 --- a/js/yua-touch.js +++ b/js/yua-touch.js @@ -353,7 +353,7 @@ if(!String.prototype.splice){ Object.defineProperty(String.prototype, 'splice', { - value: function(start, len, sub){ + value: function(start, len, fill){ var length = this.length, argLen = arguments.length; @@ -497,6 +497,7 @@ yua.mix({ subscribers: subscribers, version: '1.0.0', log: log, + ui: {}, //仅用于存放组件版本信息等 slice: function (nodes, start, end) { return aslice.call(nodes, start, end) }, @@ -3349,7 +3350,7 @@ yua.component = function (name, opts) { delete elemOpts.config delete elemOpts.$id delete elemOpts.identifier - var componentDefinition = {} + var componentDefinition = {$up: host.vmodels[0], $ups: host.vmodels} yua.mix(true, componentDefinition, hooks) @@ -3384,6 +3385,14 @@ yua.component = function (name, opts) { // 组件所使用的标签是temlate,所以必须要要用子元素替换掉 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) child.msResolved = 1 var cssText = elem.style.cssText diff --git a/js/yua.js b/js/yua.js index 9e423cf..f388f26 100644 --- a/js/yua.js +++ b/js/yua.js @@ -353,7 +353,7 @@ if(!String.prototype.splice){ Object.defineProperty(String.prototype, 'splice', { - value: function(start, len, sub){ + value: function(start, len, fill){ var length = this.length, argLen = arguments.length; @@ -497,6 +497,7 @@ yua.mix({ subscribers: subscribers, version: '1.0.0', log: log, + ui: {}, //仅用于存放组件版本信息等 slice: function (nodes, start, end) { return aslice.call(nodes, start, end) }, @@ -3349,7 +3350,7 @@ yua.component = function (name, opts) { delete elemOpts.config delete elemOpts.$id delete elemOpts.identifier - var componentDefinition = {} + var componentDefinition = {$up: host.vmodels[0], $ups: host.vmodels} yua.mix(true, componentDefinition, hooks) @@ -3384,12 +3385,23 @@ yua.component = function (name, opts) { // 组件所使用的标签是temlate,所以必须要要用子元素替换掉 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) + child.msResolved = 1 var cssText = elem.style.cssText var className = elem.className elem = host.element = child elem.style.cssText += ";"+ cssText + if (className) { yua(elem).addClass(className) }