Comparing version 1.1.0 to 1.2.0
@@ -0,5 +1,17 @@ | ||
English | [简体中文](./CHANGELOG_CN.md) | ||
#### v1.2.0 (2016-05-11) | ||
- [ADD] Add network panel | ||
- [DELELE] Deprecate `vConsole.ready()` method | ||
- [IMPROVE] Display formatted Object & Array variable | ||
- [IMPROVE] Add English README and CHANGELOG | ||
- [IMPROVE] Improve UI | ||
#### v1.1.0 (2016-05-06) | ||
- 【特性】支持 window.onerror() 的异常信息捕获 | ||
- 【特性】支持 [default|system|...] 日志格式,将 log 输出到指定面板 | ||
- [ADD] Support `window.onerror()` to catch exceptions and errors | ||
- [ADD] Support `[default|system|...]` string to print logs to specific panel | ||
@@ -9,4 +21,4 @@ | ||
- 【修复】修复 webpack 编译失败的问题 | ||
- 【修复】修复打印 HTML 字符串可能导致的 XSS 问题 | ||
- [FIX] Fix webpack compilation | ||
- [FIX] Fix XSS when printing HTML string | ||
@@ -16,4 +28,4 @@ | ||
- 【修复】修复 package.json 的 main 路径 | ||
- 【优化】优化 example 的 demo 页面 | ||
- [FIX] Fix the `main` path in `package.json` | ||
- [IMPROVE] Update demo pages | ||
@@ -23,2 +35,2 @@ | ||
初始发布 | ||
- Initial release |
/*! | ||
* vconsole v1.1.0 (https://github.com/WechatFE/vConsole) | ||
* vconsole v1.2.0 (https://github.com/WechatFE/vConsole) | ||
* Copyright 2016, WechatFE Team | ||
* MIT license | ||
*/ | ||
!function(o,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.vConsole=t():o.vConsole=t()}(this,function(){return function(o){function t(n){if(e[n])return e[n].exports;var i=e[n]={exports:{},id:n,loaded:!1};return o[n].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var e={};return t.m=o,t.c=e,t.p="",t(0)}([function(o,t,e){"use strict";function n(o){return o&&o.__esModule?o:{"default":o}}function i(){this.html=u["default"],this.$dom=null,this.activedTab="default",this.tabList=["default","system"],this.console={},this.isReady=!1,this.readyCallback=[];var o=this;l(window,"load",function(){o._render(),o._bindEvent(),o._mokeConsole(),o._autoRun()})}function r(o,t){return t?t.querySelector(o):document.querySelector(o)}function c(o,t){var e,n=[];return e=t?t.querySelectorAll(o):document.querySelectorAll(o),e&&e.length>0&&(n=Array.prototype.slice.call(e)),n}function a(o,t){if(o){"[object Array]"!=Object.prototype.toString.call(o)&&(o=[o]);for(var e=0;e<o.length;e++)o[e].className+=" "+t}}function s(o,t){if(o){"[object Array]"!=Object.prototype.toString.call(o)&&(o=[o]);for(var e=0;e<o.length;e++){for(var n=o[e].className.split(" "),i=0;i<n.length;i++)n[i]==t&&(n[i]="");o[e].className=n.join(" ")}}}function l(o,t,e,n){if(o){void 0===n&&(n=!1),"[object Array]"!=Object.prototype.toString.call(o)&&(o=[o]);for(var i=0;i<o.length;i++)o[i].addEventListener(t,e,n)}}function d(o){var t=o>0?new Date(o):new Date,e=t.getDay()<10?"0"+t.getDay():t.getDay(),n=t.getMonth()<9?"0"+(t.getMonth()+1):t.getMonth()+1,i=t.getFullYear(),r=t.getHours()<10?"0"+t.getHours():t.getHours(),c=t.getMinutes()<10?"0"+t.getMinutes():t.getMinutes(),a=t.getSeconds()<10?"0"+t.getSeconds():t.getSeconds(),s=t.getMilliseconds()<10?"0"+t.getMilliseconds():t.getMilliseconds();return 100>s&&(s="0"+s),{time:+t,year:i,month:n,day:e,hour:r,minute:c,second:a,millisecond:s}}function f(o){return document.createElement("a").appendChild(document.createTextNode(o)).parentNode.innerHTML}Object.defineProperty(t,"__esModule",{value:!0});var v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol?"symbol":typeof o};e(1);var p=e(5),u=n(p);i.prototype._render=function(){var o="#__vconsole";if(!r(o)){var t=document.createElement("div");t.innerHTML=this.html,document.body.appendChild(t.children[0])}this.$dom=r(o)},i.prototype._bindEvent=function(){var o=this;l(r(".vc-show"),"click",function(){o.show()}),l(r(".vc-hide"),"click",function(){o.hide()}),l(r(".vc-mask"),"click",function(t){return t.target!=r(".vc-mask")?!1:void o.hide()}),l(r(".vc-clear"),"click",function(){o.clearLog(o.activedTab)}),l(c(".vc-tab"),"click",function(t){var e=t.target.dataset.tab;e!=o.activedTab&&o.showTab(e)})},i.prototype._mokeConsole=function(){if(window.console){var o=this;this.console.log=window.console.log,this.console.info=window.console.info,this.console.warn=window.console.warn,this.console.debug=window.console.debug,this.console.error=window.console.error,window.console.log=function(){o._printLog("auto","log",arguments)},window.console.info=function(){o._printLog("auto","info",arguments)},window.console.warn=function(){o._printLog("auto","warn",arguments)},window.console.debug=function(){o._printLog("auto","debug",arguments)},window.console.error=function(){o._printLog("auto","error",arguments)},window.onerror=function(o,t,e,n,i){var r=i.stack.split("at");r=r[0]+" "+r[1],r=r.replace(location.origin,""),console.error(r)}}},i.prototype._autoRun=function(){var o=navigator.userAgent,t=[],e=d();this._printLog("system","info",["日志时间:",e.year+"-"+e.month+"-"+e.day+" "+e.hour+":"+e.minute+":"+e.second+" "+e.millisecond]),t=["系统版本:","不明"];var n=o.match(/(ipod).*\s([\d_]+)/i),i=o.match(/(ipad).*\s([\d_]+)/i),r=o.match(/(iphone)\sos\s([\d_]+)/i),c=o.match(/(android)\s([\d\.]+)/i);c?t[1]="Android "+c[2]:r?t[1]="iPhone, iOS "+r[2].replace(/_/g,"."):i?t[1]="iPad, iOS "+i[2].replace(/_/g,"."):n&&(t[1]="iPod, iOS "+n[2].replace(/_/g,".")),this._printLog("system","info",t);var a=o.match(/MicroMessenger\/([\d\.]+)/i);t=["微信版本:","不明"],a&&a[1]&&(t[1]=a[1],this._printLog("system","info",t));var s=o.toLowerCase().match(/ nettype\/([^ ]+)/g);for(t=["网络类型:","不明"],s&&s[0]&&(s=s[0].split("/"),t[1]=s[1],this._printLog("system","info",t)),t=["网址协议:","不明"],"https:"==location.protocol?t[1]="HTTPS":"http:"==location.protocol?t[1]="HTTP":t[1]=location.protocol.replace(":",""),this._printLog("system","info",t),window.addEventListener("load",function(o){var t=window.performance||window.msPerformance||window.webkitPerformance;if(t&&t.timing){var e=t.timing,n=e.navigationStart;this._printLog("system","info",["连接结束点:",e.connectEnd-n+"ms"]),this._printLog("system","info",["回包结束点:",e.responseEnd-n+"ms"]),e.secureConnectionStart>0&&this._printLog("system","info",["ssl耗时:",e.connectEnd-e.secureConnectionStart+"ms"]),this._printLog("system","info",["dom渲染耗时:",e.domComplete-e.domLoading+"ms"])}});this.readyCallback.length>0;){var l=this.readyCallback.shift();l&&l.call(this)}this.isReady=!0},i.prototype._printLog=function(o,t,e){if(e.length){for(var n="",i=0;i<e.length;i++)try{n+="function"==typeof e[i]?" "+e[i].toString():"object"==v(e[i])?" "+JSON.stringify(e[i]):" "+f(e[i]).replace(/\n/g,"<br/>")}catch(c){n+=" ["+v(e[i])+"]"}if("auto"==o){var a=/^ \[(\w+)\]/i,s=n.match(a);null!==s&&s.length>0&&this.tabList.indexOf(s[1])>-1&&(o=s[1],n=n.replace(a,""))}"auto"==o&&(o="default");var l=r("#__vc_log_"+o),d=document.createElement("p");d.className="vc-item vc-item-"+t,d.innerHTML=n,r(".vc-log",l).appendChild(d),r(".vc-content").scrollTop=r(".vc-content").scrollHeight,this.console[t].apply(window.console,e)}},i.prototype.showTab=function(o){var t=r("#__vc_log_"+o);s(c(".vc-tab",this.$dom),"vc-actived"),a(r("#__vc_tab_"+o),"vc-actived"),s(c(".vc-logbox"),"vc-actived"),a(t,"vc-actived"),r(".vc-content").scrollTop=r(".vc-content").scrollHeight,this.activedTab=o},i.prototype.clearLog=function(o){var t=r("#__vc_log_"+o);r(".vc-log",t).innerHTML=""},i.prototype.show=function(){a(this.$dom,"vc-toggle")},i.prototype.hide=function(){s(this.$dom,"vc-toggle")},i.prototype.ready=function(o){this.isReady?o.call(this):this.readyCallback.push(o)},t["default"]=new i,o.exports=t["default"]},function(o,t,e){var n=e(2);"string"==typeof n&&(n=[[o.id,n,""]]);e(4)(n,{});n.locals&&(o.exports=n.locals)},function(o,t,e){t=o.exports=e(3)(),t.push([o.id,'#__vconsole{font-size:13px}#__vconsole .vc-show{display:block;position:fixed;right:10px;bottom:10px;color:#fff;background-color:#04be02;line-height:1;font-size:14px;padding:8px 16px;z-index:10000;border-radius:4px;box-shadow:0 0 8px rgba(0,0,0,.4)}#__vconsole .vc-mask{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background-color:transparent;z-index:10001;transition:background .3s}#__vconsole .vc-panel{position:fixed;min-height:80%;left:0;right:0;bottom:0;z-index:10002;background-color:#efeff4;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:translateY(100%);transform:translateY(100%)}#__vconsole .vc-tabbar{border-bottom:1px solid #d9d9d9;overflow:hidden}#__vconsole .vc-tabbar .vc-tab{float:left;line-height:39px;padding:0 15px;border-right:1px solid #d9d9d9;text-decoration:none;color:#000}#__vconsole .vc-tabbar .vc-tab.vc-actived{background-color:#fff}#__vconsole .vc-content{background-color:#fff;overflow-x:hidden;overflow-y:scroll;position:absolute;top:40px;left:0;right:0;bottom:40px;-webkit-overflow-scrolling:touch}#__vconsole .vc-logbox{display:none;position:relative;height:100%}#__vconsole .vc-logbox .vc-log:empty:before{content:"No log";color:#999;position:absolute;top:45%;left:0;right:0;bottom:0;font-size:15px;text-align:center}#__vconsole .vc-logbox .vc-item{margin:0;padding:6px 8px;line-height:1.3;border-bottom:1px solid #eee;word-break:break-word}#__vconsole .vc-logbox .vc-item-info{color:#6a5acd}#__vconsole .vc-logbox .vc-item-debug{color:#daa520}#__vconsole .vc-logbox .vc-item-warn{color:orange;border-color:#ffb930;background-color:#fffacd}#__vconsole .vc-logbox .vc-item-error{color:#dc143c;border-color:#f4a0ab;background-color:#ffe4e1}#__vconsole .vc-logbox.vc-actived{display:block}#__vconsole .vc-toolbar{border-top:1px solid #d9d9d9;line-height:39px;position:absolute;left:0;right:0;bottom:0;overflow:hidden}#__vconsole .vc-toolbar .vc-tool{text-decoration:none;color:#000;width:50%;float:left;text-align:center;position:relative}#__vconsole .vc-toolbar .vc-tool:after{content:" ";position:absolute;top:7px;bottom:7px;right:0;border-left:1px solid #d9d9d9}#__vconsole .vc-toolbar .vc-tool-last:after{border:none}#__vconsole.vc-toggle .vc-show{display:none}#__vconsole.vc-toggle .vc-mask{background:rgba(0,0,0,.6);display:block}#__vconsole.vc-toggle .vc-panel{-webkit-transform:translate(0);transform:translate(0)}',""])},function(o,t){"use strict";o.exports=function(){var o=[];return o.toString=function(){for(var o=[],t=0;t<this.length;t++){var e=this[t];e[2]?o.push("@media "+e[2]+"{"+e[1]+"}"):o.push(e[1])}return o.join("")},o.i=function(t,e){"string"==typeof t&&(t=[[null,t,""]]);for(var n={},i=0;i<this.length;i++){var r=this[i][0];"number"==typeof r&&(n[r]=!0)}for(i=0;i<t.length;i++){var c=t[i];"number"==typeof c[0]&&n[c[0]]||(e&&!c[2]?c[2]=e:e&&(c[2]="("+c[2]+") and ("+e+")"),o.push(c))}},o}},function(o,t,e){function n(o,t){for(var e=0;e<o.length;e++){var n=o[e],i=p[n.id];if(i){i.refs++;for(var r=0;r<i.parts.length;r++)i.parts[r](n.parts[r]);for(;r<n.parts.length;r++)i.parts.push(l(n.parts[r],t))}else{for(var c=[],r=0;r<n.parts.length;r++)c.push(l(n.parts[r],t));p[n.id]={id:n.id,refs:1,parts:c}}}}function i(o){for(var t=[],e={},n=0;n<o.length;n++){var i=o[n],r=i[0],c=i[1],a=i[2],s=i[3],l={css:c,media:a,sourceMap:s};e[r]?e[r].parts.push(l):t.push(e[r]={id:r,parts:[l]})}return t}function r(o,t){var e=g(),n=_[_.length-1];if("top"===o.insertAt)n?n.nextSibling?e.insertBefore(t,n.nextSibling):e.appendChild(t):e.insertBefore(t,e.firstChild),_.push(t);else{if("bottom"!==o.insertAt)throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");e.appendChild(t)}}function c(o){o.parentNode.removeChild(o);var t=_.indexOf(o);t>=0&&_.splice(t,1)}function a(o){var t=document.createElement("style");return t.type="text/css",r(o,t),t}function s(o){var t=document.createElement("link");return t.rel="stylesheet",r(o,t),t}function l(o,t){var e,n,i;if(t.singleton){var r=m++;e=b||(b=a(t)),n=d.bind(null,e,r,!1),i=d.bind(null,e,r,!0)}else o.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(e=s(t),n=v.bind(null,e),i=function(){c(e),e.href&&URL.revokeObjectURL(e.href)}):(e=a(t),n=f.bind(null,e),i=function(){c(e)});return n(o),function(t){if(t){if(t.css===o.css&&t.media===o.media&&t.sourceMap===o.sourceMap)return;n(o=t)}else i()}}function d(o,t,e,n){var i=e?"":n.css;if(o.styleSheet)o.styleSheet.cssText=y(t,i);else{var r=document.createTextNode(i),c=o.childNodes;c[t]&&o.removeChild(c[t]),c.length?o.insertBefore(r,c[t]):o.appendChild(r)}}function f(o,t){var e=t.css,n=t.media;if(n&&o.setAttribute("media",n),o.styleSheet)o.styleSheet.cssText=e;else{for(;o.firstChild;)o.removeChild(o.firstChild);o.appendChild(document.createTextNode(e))}}function v(o,t){var e=t.css,n=t.sourceMap;n&&(e+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */");var i=new Blob([e],{type:"text/css"}),r=o.href;o.href=URL.createObjectURL(i),r&&URL.revokeObjectURL(r)}var p={},u=function(o){var t;return function(){return"undefined"==typeof t&&(t=o.apply(this,arguments)),t}},h=u(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),g=u(function(){return document.head||document.getElementsByTagName("head")[0]}),b=null,m=0,_=[];o.exports=function(o,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=h()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var e=i(o);return n(e,t),function(o){for(var r=[],c=0;c<e.length;c++){var a=e[c],s=p[a.id];s.refs--,r.push(s)}if(o){var l=i(o);n(l,t)}for(var c=0;c<r.length;c++){var s=r[c];if(0===s.refs){for(var d=0;d<s.parts.length;d++)s.parts[d]();delete p[s.id]}}}};var y=function(){var o=[];return function(t,e){return o[t]=e,o.filter(Boolean).join("\n")}}()},function(o,t){o.exports='<div id=__vconsole class=""> <div class=vc-show>面板</div> <div class=vc-mask> </div> <div class=vc-panel> <div class=vc-tabbar> <a class="vc-tab vc-actived" data-tab=default id=__vc_tab_default href=javascript:;>日志</a> <a class=vc-tab data-tab=system id=__vc_tab_system href=javascript:;>系统</a> </div> <div class=vc-content> <div class="vc-logbox vc-actived" id=__vc_log_default> <div class=vc-log></div> </div> <div class=vc-logbox id=__vc_log_system> <div class=vc-log></div> </div> </div> <div class=vc-toolbar> <a href=javascript:; class="vc-tool vc-clear">清空</a> <a href=javascript:; class="vc-tool vc-tool-last vc-hide">隐藏</a> </div> </div> </div>'}])}); | ||
!function(o,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.vConsole=t():o.vConsole=t()}(this,function(){return function(o){function t(n){if(e[n])return e[n].exports;var r=e[n]={exports:{},id:n,loaded:!1};return o[n].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var e={};return t.m=o,t.c=e,t.p="",t(0)}([function(o,t,e){"use strict";function n(o){return o&&o.__esModule?o:{"default":o}}function r(){var o=this;this.html=w["default"],this.$dom=null,this.activedTab="default",this.tabList=["default","system","network"],this.console={},this.logList=[],this.isReady=!1,o._mokeConsole(),o._mokeAjax(),d(window,"load",function(){o._render(),o._bindEvent(),o._autoRun()})}function i(o,t){return t?t.querySelector(o):document.querySelector(o)}function c(o,t){var e,n=[];return e=t?t.querySelectorAll(o):document.querySelectorAll(o),e&&e.length>0&&(n=Array.prototype.slice.call(e)),n}function l(o,t){if(o){b(o)||(o=[o]);for(var e=0;e<o.length;e++)o[e].className+=" "+t}}function a(o,t){if(o){b(o)||(o=[o]);for(var e=0;e<o.length;e++){for(var n=o[e].className.split(" "),r=0;r<n.length;r++)n[r]==t&&(n[r]="");o[e].className=n.join(" ")}}}function s(o,t){if(!o)return!1;for(var e=o.className.split(" "),n=0;n<e.length;n++)if(e[n]==t)return!0;return!1}function d(o,t,e,n){if(o){void 0===n&&(n=!1),b(o)||(o=[o]);for(var r=0;r<o.length;r++)o[r].addEventListener(t,e,n)}}function v(o){var t=o>0?new Date(o):new Date,e=t.getDay()<10?"0"+t.getDay():t.getDay(),n=t.getMonth()<9?"0"+(t.getMonth()+1):t.getMonth()+1,r=t.getFullYear(),i=t.getHours()<10?"0"+t.getHours():t.getHours(),c=t.getMinutes()<10?"0"+t.getMinutes():t.getMinutes(),l=t.getSeconds()<10?"0"+t.getSeconds():t.getSeconds(),a=t.getMilliseconds()<10?"0"+t.getMilliseconds():t.getMilliseconds();return 100>a&&(a="0"+a),{time:+t,year:r,month:n,day:e,hour:i,minute:c,second:l,millisecond:a}}function f(o){return document.createElement("a").appendChild(document.createTextNode(o)).parentNode.innerHTML}function p(o,t){var e=o;for(var n in t)e=e.replace("{"+n+"}",t[n]);return e}function u(o){return"[object Number]"==Object.prototype.toString.call(o)}function g(o){return"[object String]"==Object.prototype.toString.call(o)}function b(o){return"[object Array]"==Object.prototype.toString.call(o)}function h(o){return"[object Object]"==Object.prototype.toString.call(o)}function m(o){return"[object Function]"==Object.prototype.toString.call(o)}Object.defineProperty(t,"__esModule",{value:!0});var _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol?"symbol":typeof o};e(1);var y=e(5),w=n(y),x=e(6),k=n(x);r.prototype._render=function(){var o="#__vconsole";if(!i(o)){var t=document.createElement("div");t.innerHTML=this.html,document.body.appendChild(t.children[0])}this.$dom=i(o)},r.prototype._bindEvent=function(){var o=this;d(i(".vc-show"),"click",function(){o.show()}),d(i(".vc-hide"),"click",function(){o.hide()}),d(i(".vc-mask"),"click",function(t){return t.target!=i(".vc-mask")?!1:void o.hide()}),d(i(".vc-clear"),"click",function(){o.clearLog(o.activedTab)}),d(c(".vc-tab"),"click",function(t){var e=t.target.dataset.tab;e!=o.activedTab&&o.showTab(e)}),d(c(".vc-log"),"click",function(o){var t=o.target;s(t,"vc-fold-outer")&&(s(t.parentElement,"vc-toggle")?a(t.parentElement,"vc-toggle"):l(t.parentElement,"vc-toggle"),o.preventDefault())})},r.prototype._mokeConsole=function(){if(window.console){var o=this;this.console.log=window.console.log,this.console.info=window.console.info,this.console.warn=window.console.warn,this.console.debug=window.console.debug,this.console.error=window.console.error,window.console.log=function(){o._printLog("auto","log",arguments)},window.console.info=function(){o._printLog("auto","info",arguments)},window.console.warn=function(){o._printLog("auto","warn",arguments)},window.console.debug=function(){o._printLog("auto","debug",arguments)},window.console.error=function(){o._printLog("auto","error",arguments)},window.onerror=function(o,t,e,n,r){var i=r.stack.split("at");i=i[0]+" "+i[1],i=i.replace(location.origin,""),console.error(i)}}},r.prototype._mokeAjax=function(){var o=window.XMLHttpRequest;if(o){var t=window.XMLHttpRequest.prototype.open,e=window.XMLHttpRequest.prototype.send;window.XMLHttpRequest.prototype.open=function(){var o=this,e=arguments;return setTimeout(function(){var t=o.onreadystatechange||function(){};o.onreadystatechange=function(){if(4==o.readyState){o._endTime=+new Date;var n=e[1]||"unknow URL",r=o._endTime-(o._startTime||o._endTime),i="[network]["+o.status+"] ["+r+"ms] "+n;o.status>=200&&o.status<400?console.log(i):console.error(i)}return t.apply(o,arguments)}},0),t.apply(o,e)},window.XMLHttpRequest.prototype.send=function(){var o=this;o._startTime=+new Date,setTimeout(function(){e.apply(o,arguments)},1)}}},r.prototype._autoRun=function(){for(this.isReady=!0;this.logList.length>0;){var o=this.logList.shift();this._printLog(o.tabName,o.logType,o.logs)}var t=navigator.userAgent,e=[],n=v();this._printLog("system","info",["日志时间:",n.year+"-"+n.month+"-"+n.day+" "+n.hour+":"+n.minute+":"+n.second+" "+n.millisecond]),e=["系统版本:","不明"];var r=t.match(/(ipod).*\s([\d_]+)/i),i=t.match(/(ipad).*\s([\d_]+)/i),c=t.match(/(iphone)\sos\s([\d_]+)/i),l=t.match(/(android)\s([\d\.]+)/i);l?e[1]="Android "+l[2]:c?e[1]="iPhone, iOS "+c[2].replace(/_/g,"."):i?e[1]="iPad, iOS "+i[2].replace(/_/g,"."):r&&(e[1]="iPod, iOS "+r[2].replace(/_/g,".")),this._printLog("system","info",e);var a=t.match(/MicroMessenger\/([\d\.]+)/i);e=["微信版本:","不明"],a&&a[1]&&(e[1]=a[1],this._printLog("system","info",e));var s=t.toLowerCase().match(/ nettype\/([^ ]+)/g);e=["网络类型:","不明"],s&&s[0]&&(s=s[0].split("/"),e[1]=s[1],this._printLog("system","info",e)),e=["网址协议:","不明"],"https:"==location.protocol?e[1]="HTTPS":"http:"==location.protocol?e[1]="HTTP":e[1]=location.protocol.replace(":",""),this._printLog("system","info",e),window.addEventListener("load",function(o){var t=window.performance||window.msPerformance||window.webkitPerformance;if(t&&t.timing){var e=t.timing,n=e.navigationStart;this._printLog("system","info",["连接结束点:",e.connectEnd-n+"ms"]),this._printLog("system","info",["回包结束点:",e.responseEnd-n+"ms"]),e.secureConnectionStart>0&&this._printLog("system","info",["ssl耗时:",e.connectEnd-e.secureConnectionStart+"ms"]),this._printLog("system","info",["dom渲染耗时:",e.domComplete-e.domLoading+"ms"])}})},r.prototype._printLog=function(o,t,e){if(e.length){if(!this.isReady)return void this.logList.push({tabName:o,logType:t,logs:e});for(var n="",r=0;r<e.length;r++)try{n+=m(e[r])?" "+e[r].toString():h(e[r])||b(e[r])?" "+this._getFoldedLine(e[r]):" "+f(e[r]).replace(/\n/g,"<br/>")}catch(c){n+=" ["+_(e[r])+"]"}if("auto"==o){var l=/^ \[(\w+)\]/i,a=n.match(l);null!==a&&a.length>0&&this.tabList.indexOf(a[1])>-1&&(o=a[1],n=n.replace(l,""))}"auto"==o&&(o="default");var s=i("#__vc_log_"+o),d=document.createElement("p");d.className="vc-item vc-item-"+t,d.innerHTML=n,i(".vc-log",s).appendChild(d),i(".vc-content").scrollTop=i(".vc-content").scrollHeight,this.console[t].apply(window.console,e)}},r.prototype._getFoldedLine=function(o,t){function e(o){if(h(o)){var t=Object.keys(o);i+="{\n",l++;for(var n=0;n<t.length;n++){var r=t[n];o.hasOwnProperty(r)&&(i+=Array(l+1).join(a)+'<i class="vc-code-key">'+r+"</i>: ",e(o[r]),n<t.length-1&&(i+=",\n"))}l--,i+="\n"+Array(l+1).join(a)+"}"}else if(b(o)){i+="[\n",l++;for(var n=0;n<o.length;n++)i+=Array(l+1).join(a)+'<i class="vc-code-key">'+n+"</i>: ",e(o[n]),n<o.length-1&&(i+=",\n");l--,i+="\n"+Array(l+1).join(a)+"]"}else i+=g(o)?'<i class="vc-code-string">"'+o+'"</i>':u(o)?'<i class="vc-code-number">'+o+"</i>":JSON.stringify(o)}var n=JSON.stringify(o),r="",i="",c="",l=0,a=" ";c=n.substr(0,30),n.length>30&&(c+="..."),r=Object.prototype.toString.call(o).replace("[object ","").replace("]",""),r+=" "+c,e(o);var s=p(k["default"],{outer:r,inner:i});return s},r.prototype.showTab=function(o){var t=i("#__vc_log_"+o);a(c(".vc-tab",this.$dom),"vc-actived"),l(i("#__vc_tab_"+o),"vc-actived"),a(c(".vc-logbox"),"vc-actived"),l(t,"vc-actived"),i(".vc-content").scrollTop=i(".vc-content").scrollHeight,this.activedTab=o},r.prototype.clearLog=function(o){var t=i("#__vc_log_"+o);i(".vc-log",t).innerHTML=""},r.prototype.show=function(){l(this.$dom,"vc-toggle")},r.prototype.hide=function(){a(this.$dom,"vc-toggle")},r.prototype.ready=function(o){console.warn("vConsole.ready() is deprecated, console.log() can be called at anytime without waiting for ready. This method will be removed at v2.0.0 and later"),o&&o.call(this)},t["default"]=new r,o.exports=t["default"]},function(o,t,e){var n=e(2);"string"==typeof n&&(n=[[o.id,n,""]]);e(4)(n,{});n.locals&&(o.exports=n.locals)},function(o,t,e){t=o.exports=e(3)(),t.push([o.id,'#__vconsole{font-size:13px}#__vconsole .vc-show{display:block;position:fixed;right:10px;bottom:10px;color:#fff;background-color:#04be02;line-height:1;font-size:14px;padding:8px 16px;z-index:10000;border-radius:4px;box-shadow:0 0 8px rgba(0,0,0,.4)}#__vconsole .vc-mask{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background-color:transparent;z-index:10001;transition:background .3s;-webkit-tap-highlight-color:transparent}#__vconsole .vc-panel{position:fixed;min-height:80%;left:0;right:0;bottom:0;z-index:10002;background-color:#efeff4;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:translateY(100%);transform:translateY(100%)}#__vconsole .vc-tabbar{border-bottom:1px solid #d9d9d9;overflow:hidden}#__vconsole .vc-tabbar .vc-tab{float:left;line-height:39px;padding:0 15px;border-right:1px solid #d9d9d9;text-decoration:none;color:#000;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}#__vconsole .vc-tabbar .vc-tab:active{background-color:rgba(0,0,0,.15)}#__vconsole .vc-tabbar .vc-tab.vc-actived{background-color:#fff}#__vconsole .vc-content{background-color:#fff;overflow-x:hidden;overflow-y:scroll;position:absolute;top:40px;left:0;right:0;bottom:40px;-webkit-overflow-scrolling:touch}#__vconsole .vc-logbox{display:none;position:relative;height:100%}#__vconsole .vc-logbox i{font-style:normal}#__vconsole .vc-logbox .vc-log{-webkit-tap-highlight-color:transparent}#__vconsole .vc-logbox .vc-log:empty:before{content:"No log";color:#999;position:absolute;top:45%;left:0;right:0;bottom:0;font-size:15px;text-align:center}#__vconsole .vc-logbox .vc-item{margin:0;padding:6px 8px;line-height:1.3;border-bottom:1px solid #eee;word-break:break-word}#__vconsole .vc-logbox .vc-item-info{color:#6a5acd}#__vconsole .vc-logbox .vc-item-debug{color:#daa520}#__vconsole .vc-logbox .vc-item-warn{color:orange;border-color:#ffb930;background-color:#fffacd}#__vconsole .vc-logbox .vc-item-error{color:#dc143c;border-color:#f4a0ab;background-color:#ffe4e1}#__vconsole .vc-logbox .vc-item .vc-fold{display:block;max-height:300px;overflow:scroll;-webkit-overflow-scrolling:touch}#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer{display:block;font-style:italic}#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer:active{background-color:rgba(0,0,0,.15)}#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer{padding-left:10px;position:relative}#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer:before{content:"";position:absolute;top:4px;left:2px;width:0;height:0;border:4px solid transparent;border-left-color:#000}#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-inner{display:none}#__vconsole .vc-logbox .vc-item .vc-fold.vc-toggle .vc-fold-outer:before{top:6px;left:0;border-top-color:#000;border-left-color:transparent}#__vconsole .vc-logbox .vc-item .vc-fold.vc-toggle .vc-fold-inner{display:block}#__vconsole .vc-logbox .vc-code-key{color:#905}#__vconsole .vc-logbox .vc-code-number{color:#0086b3}#__vconsole .vc-logbox .vc-code-string{color:#183691}#__vconsole .vc-logbox.vc-actived{display:block}#__vconsole .vc-toolbar{border-top:1px solid #d9d9d9;line-height:39px;position:absolute;left:0;right:0;bottom:0;overflow:hidden}#__vconsole .vc-toolbar .vc-tool{text-decoration:none;color:#000;width:50%;float:left;text-align:center;position:relative;-webkit-touch-callout:none}#__vconsole .vc-toolbar .vc-tool:after{content:" ";position:absolute;top:7px;bottom:7px;right:0;border-left:1px solid #d9d9d9}#__vconsole .vc-toolbar .vc-tool-last:after{border:none}#__vconsole.vc-toggle .vc-show{display:none}#__vconsole.vc-toggle .vc-mask{background:rgba(0,0,0,.6);display:block}#__vconsole.vc-toggle .vc-panel{-webkit-transform:translate(0);transform:translate(0)}',""])},function(o,t){"use strict";o.exports=function(){var o=[];return o.toString=function(){for(var o=[],t=0;t<this.length;t++){var e=this[t];e[2]?o.push("@media "+e[2]+"{"+e[1]+"}"):o.push(e[1])}return o.join("")},o.i=function(t,e){"string"==typeof t&&(t=[[null,t,""]]);for(var n={},r=0;r<this.length;r++){var i=this[r][0];"number"==typeof i&&(n[i]=!0)}for(r=0;r<t.length;r++){var c=t[r];"number"==typeof c[0]&&n[c[0]]||(e&&!c[2]?c[2]=e:e&&(c[2]="("+c[2]+") and ("+e+")"),o.push(c))}},o}},function(o,t,e){function n(o,t){for(var e=0;e<o.length;e++){var n=o[e],r=p[n.id];if(r){r.refs++;for(var i=0;i<r.parts.length;i++)r.parts[i](n.parts[i]);for(;i<n.parts.length;i++)r.parts.push(s(n.parts[i],t))}else{for(var c=[],i=0;i<n.parts.length;i++)c.push(s(n.parts[i],t));p[n.id]={id:n.id,refs:1,parts:c}}}}function r(o){for(var t=[],e={},n=0;n<o.length;n++){var r=o[n],i=r[0],c=r[1],l=r[2],a=r[3],s={css:c,media:l,sourceMap:a};e[i]?e[i].parts.push(s):t.push(e[i]={id:i,parts:[s]})}return t}function i(o,t){var e=b(),n=_[_.length-1];if("top"===o.insertAt)n?n.nextSibling?e.insertBefore(t,n.nextSibling):e.appendChild(t):e.insertBefore(t,e.firstChild),_.push(t);else{if("bottom"!==o.insertAt)throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");e.appendChild(t)}}function c(o){o.parentNode.removeChild(o);var t=_.indexOf(o);t>=0&&_.splice(t,1)}function l(o){var t=document.createElement("style");return t.type="text/css",i(o,t),t}function a(o){var t=document.createElement("link");return t.rel="stylesheet",i(o,t),t}function s(o,t){var e,n,r;if(t.singleton){var i=m++;e=h||(h=l(t)),n=d.bind(null,e,i,!1),r=d.bind(null,e,i,!0)}else o.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(e=a(t),n=f.bind(null,e),r=function(){c(e),e.href&&URL.revokeObjectURL(e.href)}):(e=l(t),n=v.bind(null,e),r=function(){c(e)});return n(o),function(t){if(t){if(t.css===o.css&&t.media===o.media&&t.sourceMap===o.sourceMap)return;n(o=t)}else r()}}function d(o,t,e,n){var r=e?"":n.css;if(o.styleSheet)o.styleSheet.cssText=y(t,r);else{var i=document.createTextNode(r),c=o.childNodes;c[t]&&o.removeChild(c[t]),c.length?o.insertBefore(i,c[t]):o.appendChild(i)}}function v(o,t){var e=t.css,n=t.media;if(n&&o.setAttribute("media",n),o.styleSheet)o.styleSheet.cssText=e;else{for(;o.firstChild;)o.removeChild(o.firstChild);o.appendChild(document.createTextNode(e))}}function f(o,t){var e=t.css,n=t.sourceMap;n&&(e+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */");var r=new Blob([e],{type:"text/css"}),i=o.href;o.href=URL.createObjectURL(r),i&&URL.revokeObjectURL(i)}var p={},u=function(o){var t;return function(){return"undefined"==typeof t&&(t=o.apply(this,arguments)),t}},g=u(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),b=u(function(){return document.head||document.getElementsByTagName("head")[0]}),h=null,m=0,_=[];o.exports=function(o,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=g()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var e=r(o);return n(e,t),function(o){for(var i=[],c=0;c<e.length;c++){var l=e[c],a=p[l.id];a.refs--,i.push(a)}if(o){var s=r(o);n(s,t)}for(var c=0;c<i.length;c++){var a=i[c];if(0===a.refs){for(var d=0;d<a.parts.length;d++)a.parts[d]();delete p[a.id]}}}};var y=function(){var o=[];return function(t,e){return o[t]=e,o.filter(Boolean).join("\n")}}()},function(o,t){o.exports='<div id=__vconsole class=""> <div class=vc-show>vConsole</div> <div class=vc-mask> </div> <div class=vc-panel> <div class=vc-tabbar> <a class="vc-tab vc-actived" data-tab=default id=__vc_tab_default>Log</a> <a class=vc-tab data-tab=system id=__vc_tab_system>System</a> <a class=vc-tab data-tab=network id=__vc_tab_network>Network</a> </div> <div class=vc-content> <div class="vc-logbox vc-actived" id=__vc_log_default> <div class=vc-log></div> </div> <div class=vc-logbox id=__vc_log_system> <div class=vc-log></div> </div> <div class=vc-logbox id=__vc_log_network> <div class=vc-log></div> </div> </div> <div class=vc-toolbar> <a class="vc-tool vc-clear">Clear</a> <a class="vc-tool vc-tool-last vc-hide">Hide</a> </div> </div> </div>'},function(o,t){o.exports="<span class=vc-fold> <i class=vc-fold-outer>{outer}</i> <pre class=vc-fold-inner>{inner}</pre> </span>"}])}); |
{ | ||
"name": "vconsole", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "A virtual console panel for mobile page", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/WechatFE/vConsole", |
@@ -0,1 +1,3 @@ | ||
English | [简体中文](./README_CN.md) | ||
vConsole | ||
@@ -5,11 +7,11 @@ ============================== | ||
一个针对手机网页的前端 console 调试面板。 | ||
A front-end developer tool for mobile web page. | ||
## 简介 | ||
## Introduction | ||
vConsole 是一个网页前端调试面板,专为手机 web 页面量身设计,帮助开发者更为便捷地进行开发调试工作。 | ||
vConsole is a mobile front-end developer tool which can be very helpful for debug and development. | ||
## 手机预览 | ||
## Preview | ||
@@ -23,13 +25,18 @@ ![](./example/snapshot/qrcode.png) | ||
## 使用方法 | ||
## Installation | ||
### 1.下载模块 | ||
### 1. Download | ||
checkout 文件 `dist/vconsole.min.js` 到本地。 | ||
Download file `dist/vconsole.min.js` to your project's directory. | ||
Or, install via `npm` : | ||
### 2.引入模块 | ||
``` | ||
npm install vconsole | ||
``` | ||
(1) 如果未使用 AMD/CMD 规范,可直接在 HTML 中引入 vConsole 模块。为了便于后续扩展,建议在 `<head>` 中引入: | ||
### 2. Import | ||
(1) Under non-AMD/CMD rule, insert vConsole into `<head>`. To support further features, insert vConsole into `<head>` rather than `</body>` is a better choice. | ||
```html | ||
@@ -41,3 +48,3 @@ <head> | ||
(2) 如果使用了 AMD/CMD 规范,可在 module 内使用 `require()` 引入模块: | ||
(2) Under AMD/CMD rule, use `require()` to import vConsole. | ||
@@ -49,5 +56,5 @@ ```javascript | ||
### 3.打印 log 日志 | ||
### 3. Usage | ||
(1) 与 PC 端打印 log 一致,可直接使用 `console.log()` 等方法直接打印日志: | ||
(1) Use the methods of `console` to print logs, just like what you do at desktop browsers: | ||
@@ -58,65 +65,68 @@ ```javascript | ||
未加载 vConsole 模块时,`console.log()` 会直接打印到原生控制台中;加载 vConsole 后,日志会打印到页面前端+原生控制台。 | ||
When vConsole is not loaded, logs will be printed to native console. After importing vConsole, logs will be printed to both front-end console and native console. | ||
(2) 引入模块后,vConsole 会有一段很小的延迟来用于初始化工作。此时若需打印日志,请使用 `vConsole.ready()` 方法: | ||
(2) 5 types of log method are supported, with different styles: | ||
```javascript | ||
// 若未通过 AMD/CMD 方式加载模块, | ||
// vConsole 会自动挂载在全局 window 对象中,即 window.vConsole | ||
vConsole.ready(function() { | ||
console.log('Hello World'); | ||
}); | ||
console.log('foo'); // black word, white bakcground | ||
console.info('bar'); // purple word, white background | ||
console.debug('oh'); // orange word, white background | ||
console.warn('foo'); // orange word, yellow background | ||
console.error('bar'); // red word, pink background | ||
``` | ||
(3) 支持 4 种不同类型的日志,会以不同的颜色输出到前端面板: | ||
```javascript | ||
console.log('foo'); // 白底黑字 | ||
console.info('bar'); // 白底紫字 | ||
console.debug('oh'); // 白底黄字 | ||
console.warn('foo'); // 黄底黄字 | ||
console.error('bar'); // 红底红字 | ||
``` | ||
(3) Object or Array variable will be printed as formatted JSON: | ||
(4) 支持打印 Object 对象,会以 JSON 字符串格式输出: | ||
```javascript | ||
var obj = {}; | ||
obj.foo = 'bar'; | ||
console.log(obj); // 打印出 {foo: 'bar'} | ||
console.log(obj); | ||
/* | ||
Object | ||
{ | ||
foo: "bar" | ||
} | ||
*/ | ||
``` | ||
(5) 支持传入多个参数,会以空格隔开: | ||
(4) Multiple arguments are supported, each variable will be divided by a space: | ||
```javascript | ||
var uid = 233; | ||
console.log('UserID:', uid); // 打印出 UserID: 233 | ||
console.log('UserID:', uid); // UserID: 233 | ||
``` | ||
(6) 支持使用 `[default|system|...]` 的格式将 log 输出到指定面板: | ||
(5) Use `[default|system|...]` string to print logs to specific panel: | ||
```javascript | ||
// [xxx] 须写在 log 的最开始 | ||
// [xxx] must be at the beginning of a log | ||
console.log('[system]', 'foo'); | ||
console.log('[system] bar'); | ||
// 系统面板将打印出两行,分别为 foo 和 bar | ||
// foo & bar will be printed to system panel | ||
``` | ||
目前支持的面板有: | ||
Supported panels: | ||
``` | ||
[default] 日志(默认) | ||
[system] 系统 | ||
[default] Log panel (default) | ||
[system] System panel | ||
[network] Network panel | ||
``` | ||
## 注意事项 | ||
## Notice | ||
引入 vConsole 模块后,页面前端将会在右下角出现 vConsole 的悬停按钮,可展开/收起面板。 | ||
(1) After importing vConsole, a button, which can show/hide panel, will be displayed at the right bottom of the page. | ||
若不希望普通用户看到面板,请不要在生产环境中引入 vConsole 模块。动态引入模块的方法可参考 `example/demo2.php` 示例。 | ||
Under production environment, DO NOT import vConsole to your page, unless you want to let your users help you to debug. Demo `example/demo2.php` shows how to import vConsole dynamicly. | ||
(2) After v1.2.0, `vConsole.ready()` is deprecated. You can directly use `console.log()` after importing vConsole without waiting for its ready. This method will be removed at v2.0.0 and later. | ||
## 更新记录 | ||
## Changelog | ||
[CHANGELOG.md](./CHANGELOG.md) | ||
@@ -123,0 +133,0 @@ |
@@ -9,2 +9,3 @@ /** | ||
import tpl from './tpl.html'; | ||
import tplFold from './tpl_fold.html'; | ||
@@ -16,15 +17,18 @@ /** | ||
function vConsole() { | ||
var that = this; | ||
this.html = tpl; | ||
this.$dom = null; | ||
this.activedTab = 'default'; | ||
this.tabList = ['default', 'system']; | ||
this.tabList = ['default', 'system', 'network']; | ||
this.console = {}; // store native console methods | ||
this.logList = []; // store logs when vConsole is not ready | ||
this.isReady = false; | ||
this.readyCallback = []; | ||
var that = this; | ||
that._mokeConsole(); | ||
that._mokeAjax(); | ||
bind(window, 'load', function() { | ||
that._render(); | ||
that._bindEvent(); | ||
that._mokeConsole(); | ||
that._autoRun(); | ||
@@ -86,2 +90,16 @@ }); | ||
}); | ||
// log-related actions | ||
bind($$('.vc-log'), 'click', function(e) { | ||
var target = e.target; | ||
// expand a line | ||
if (hasClass(target, 'vc-fold-outer')) { | ||
if (hasClass(target.parentElement, 'vc-toggle')) { | ||
removeClass(target.parentElement, 'vc-toggle'); | ||
} else { | ||
addClass(target.parentElement, 'vc-toggle'); | ||
} | ||
e.preventDefault(); | ||
} | ||
}); | ||
}; | ||
@@ -118,2 +136,50 @@ | ||
/** | ||
* moke ajax requst | ||
* @private | ||
*/ | ||
vConsole.prototype._mokeAjax = function() { | ||
var _XMLHttpRequest = window.XMLHttpRequest; | ||
if (!_XMLHttpRequest) { return; } | ||
var _open = window.XMLHttpRequest.prototype.open; | ||
var _send = window.XMLHttpRequest.prototype.send; | ||
window.XMLHttpRequest.prototype.open = function() { | ||
var that = this; | ||
var _arguments = arguments; | ||
// lazy assign onreadystatechange | ||
setTimeout(function() { | ||
var _onreadystatechange = that.onreadystatechange || function(){}; | ||
that.onreadystatechange = function() { | ||
if (that.readyState == 4) { | ||
that._endTime = +new Date(); | ||
var url = _arguments[1] || 'unknow URL', | ||
costTime = that._endTime - (that._startTime || that._endTime); | ||
var log = '[network][' + that.status + '] [' + costTime + 'ms] ' + url; | ||
if (that.status >= 200 && that.status < 400) { | ||
console.log(log); | ||
} else { | ||
console.error(log); | ||
} | ||
} | ||
return _onreadystatechange.apply(that, arguments); | ||
}; | ||
}, 0); | ||
return _open.apply(that, _arguments); | ||
}; | ||
window.XMLHttpRequest.prototype.send = function() { | ||
var that = this; | ||
that._startTime = +new Date(); | ||
setTimeout(function() { | ||
_send.apply(that, arguments); | ||
}, 1); | ||
}; | ||
}; | ||
/** | ||
* auto run after initialization | ||
@@ -123,2 +189,10 @@ * @private | ||
vConsole.prototype._autoRun = function() { | ||
this.isReady = true; | ||
// print logList | ||
while (this.logList.length > 0) { | ||
var log = this.logList.shift(); | ||
this._printLog(log.tabName, log.logType, log.logs); | ||
} | ||
// print system info | ||
@@ -197,8 +271,2 @@ var ua = navigator.userAgent, | ||
}); | ||
while (this.readyCallback.length > 0) { | ||
var callback = this.readyCallback.shift(); | ||
callback && callback.call(this); | ||
} | ||
this.isReady = true; | ||
}; | ||
@@ -218,2 +286,12 @@ | ||
// if vConsole is not ready, save current log to logList | ||
if (!this.isReady) { | ||
this.logList.push({ | ||
tabName: tabName, | ||
logType: logType, | ||
logs: logs | ||
}); | ||
return; | ||
} | ||
// generate plain text for a line | ||
@@ -223,6 +301,6 @@ var line = ''; | ||
try { | ||
if (typeof logs[i] == 'function') { | ||
if (isFunction(logs[i])) { | ||
line += ' ' + logs[i].toString(); | ||
} else if (typeof logs[i] == 'object') { | ||
line += ' ' + JSON.stringify(logs[i]); | ||
} else if (isObject(logs[i]) || isArray(logs[i])) { | ||
line += ' ' + this._getFoldedLine(logs[i]); | ||
} else { | ||
@@ -261,2 +339,66 @@ line += ' ' + htmlEncode(logs[i]).replace(/\n/g, '<br/>'); | ||
/** | ||
* generate the HTML of a folded line | ||
* @private | ||
*/ | ||
vConsole.prototype._getFoldedLine = function(obj, outerText) { | ||
var json = JSON.stringify(obj); | ||
var outer = '', | ||
inner = '', | ||
preview = ''; | ||
var lv = 0, | ||
p = ' '; | ||
preview = json.substr(0, 30); | ||
if (json.length > 30) { | ||
preview += '...'; | ||
} | ||
outer = Object.prototype.toString.call(obj).replace('[object ', '').replace(']', ''); | ||
outer += ' ' + preview; | ||
function _iterateObj(val) { | ||
if (isObject(val)) { | ||
var keys = Object.keys(val); | ||
inner += "{\n"; | ||
lv++; | ||
for (var i=0; i<keys.length; i++) { | ||
var k = keys[i]; | ||
if (!val.hasOwnProperty(k)) { continue; } | ||
inner += Array(lv+1).join(p) + '<i class="vc-code-key">' + k + "</i>: "; | ||
_iterateObj(val[k]); | ||
if (i < keys.length - 1) { | ||
inner += ",\n"; | ||
} | ||
} | ||
lv--; | ||
inner += "\n" + Array(lv+1).join(p) + "}"; | ||
} else if (isArray(val)) { | ||
inner += "[\n"; | ||
lv++; | ||
for (var i=0; i<val.length; i++) { | ||
inner += Array(lv+1).join(p) + '<i class="vc-code-key">' + i + "</i>: "; | ||
_iterateObj(val[i]); | ||
if (i < val.length - 1) { | ||
inner += ",\n"; | ||
} | ||
} | ||
lv--; | ||
inner += "\n" + Array(lv+1).join(p) + "]"; | ||
} else { | ||
if (isString(val)) { | ||
inner += '<i class="vc-code-string">"' + val + '"</i>'; | ||
} else if (isNumber(val)) { | ||
inner += '<i class="vc-code-number">' + val + "</i>"; | ||
} else { | ||
inner += JSON.stringify(val); | ||
} | ||
} | ||
} | ||
_iterateObj(obj); | ||
var line = render(tplFold, {outer: outer, inner: inner}); | ||
return line; | ||
}; | ||
/** | ||
* show a log box by tab name | ||
@@ -303,3 +445,4 @@ * @public | ||
/** | ||
* when vConsole is ready, callback() will be called | ||
* !!! this method is deprecated, callback will always be called !!! | ||
* @deprecated | ||
* @public | ||
@@ -309,7 +452,4 @@ * @param function callback | ||
vConsole.prototype.ready = function(callback) { | ||
if (!this.isReady) { | ||
this.readyCallback.push(callback); | ||
} else { | ||
callback.call(this); | ||
} | ||
console.warn('vConsole.ready() is deprecated, console.log() can be called at anytime without waiting for ready. This method will be removed at v2.0.0 and later'); | ||
callback && callback.call(this); | ||
}; | ||
@@ -359,3 +499,3 @@ | ||
} | ||
if (Object.prototype.toString.call($el) != '[object Array]') { | ||
if (!isArray($el)) { | ||
$el = [$el]; | ||
@@ -376,3 +516,3 @@ } | ||
} | ||
if (Object.prototype.toString.call($el) != '[object Array]') { | ||
if (!isArray($el)) { | ||
$el = [$el]; | ||
@@ -392,2 +532,19 @@ } | ||
/** | ||
* see whether an element contains a className | ||
* @private | ||
*/ | ||
function hasClass($el, className) { | ||
if (!$el) { | ||
return false; | ||
} | ||
var arr = $el.className.split(' '); | ||
for (var i=0; i<arr.length; i++) { | ||
if (arr[i] == className) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* bind an event to element(s) | ||
@@ -407,3 +564,3 @@ * @private | ||
} | ||
if (Object.prototype.toString.call($el) != '[object Array]') { | ||
if (!isArray($el)) { | ||
$el = [$el]; | ||
@@ -453,4 +610,35 @@ } | ||
/** | ||
* simply render a HTML template | ||
* @param string tpl | ||
* @param object key-value data | ||
* @return string | ||
*/ | ||
function render(tpl, data) { | ||
var html = tpl; | ||
for (var k in data) { | ||
html = html.replace('{' + k + '}', data[k]); | ||
} | ||
return html; | ||
} | ||
function isNumber(value) { | ||
return Object.prototype.toString.call(value) == '[object Number]'; | ||
} | ||
function isString(value) { | ||
return Object.prototype.toString.call(value) == '[object String]'; | ||
} | ||
function isArray(value) { | ||
return Object.prototype.toString.call(value) == '[object Array]'; | ||
} | ||
function isObject(value) { | ||
return Object.prototype.toString.call(value) == '[object Object]'; | ||
} | ||
function isFunction(value) { | ||
return Object.prototype.toString.call(value) == '[object Function]'; | ||
} | ||
/** | ||
* export | ||
*/ | ||
export default new vConsole(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
215552
23
656
133