├── .gitignore
├── LICENSE
├── README.md
├── build
├── README.md
├── build.js
└── package.json
├── images
├── close.png
└── open.png
├── package.json
├── src
├── css
│ └── style.css
├── index.html
├── main.js
└── utils
│ ├── dom.js
│ ├── drag.js
│ ├── fetch.js
│ ├── type.js
│ └── xhr.js
├── tests
├── index.html
└── simple.html
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | .idea
8 | build
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 |
15 | # Directory for instrumented libs generated by jscoverage/JSCover
16 | lib-cov
17 |
18 | # Coverage directory used by tools like istanbul
19 | coverage
20 |
21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22 | .grunt
23 |
24 | # node-waf configuration
25 | .lock-wscript
26 |
27 | # Compiled binary addons (http://nodejs.org/api/addons.html)
28 | build/Release
29 |
30 | # Dependency directories
31 | node_modules
32 | jspm_packages
33 |
34 | # Optional npm cache directory
35 | .npm
36 |
37 | # Optional REPL history
38 | .node_repl_history
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 DuJia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # a better console tool https://github.com/Tencent/vConsole
2 |
3 | # console.js
4 |
5 | [](https://www.npmjs.com/package/mobile-console.js)
6 | [](https://www.npmjs.com/package/mobile-console.js)
7 |
8 | a console panel for mobile phone, replace alert.
9 | https://www.npmjs.com/package/mobile-console.js
10 |
11 | Preview
12 | -------
13 |
14 | ### close status
15 |
16 |

17 |
18 |
19 | ### open status
20 |
21 |

22 |
23 |
24 | ### build
25 |
26 | ``` bash
27 | npm run build
28 | ```
29 |
30 | ### install
31 |
32 | ``` bash
33 | npm i mobile-console.js --save-dev
34 | ```
35 |
36 | ### ES6
37 |
38 | ```
39 | import 'mobile-console.js';
40 | new MobileConsole();
41 | ```
42 |
43 | ### demo
44 |
45 | open `tests/index.html`
46 |
47 | ### feature
48 |
49 | - support to show console.log api output. (info, warn, error, debug)
50 | - support to show js error.
51 | - support to show xhr and fetch's request and response information. (default off)
52 |
--------------------------------------------------------------------------------
/build/README.md:
--------------------------------------------------------------------------------
1 | # console.js
2 |
3 | a console panel for mobile phone, replace alert.
4 | https://www.npmjs.com/package/mobile-console.js
5 |
6 | Preview
7 | -------
8 |
9 | ### close status
10 |
11 |

12 |
13 |
14 | ### open status
15 |
16 |

17 |
18 |
19 | ### Build
20 |
21 | ``` bash
22 | npm run build
23 | ```
24 |
25 | ### Install
26 |
27 | ``` bash
28 | npm i mobile-console.js --save-dev
29 | ```
30 |
31 | ### ES6
32 |
33 | ```
34 | import 'mobile-console.js';
35 | new MobileConsole();
36 | ```
37 |
38 | ### Demo
39 |
40 | open `tests/index.html`
41 |
42 | ### Feature
43 |
44 | - Support showing console.log api output. (info, warn, error, debug)
45 | - Support showing js error.
46 | - Support showing xhr and fetch's request and response info. (default off)
47 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 |
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 |
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId])
10 | /******/ return installedModules[moduleId].exports;
11 |
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ exports: {},
15 | /******/ id: moduleId,
16 | /******/ loaded: false
17 | /******/ };
18 |
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 |
22 | /******/ // Flag the module as loaded
23 | /******/ module.loaded = true;
24 |
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 |
29 |
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 |
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 |
36 | /******/ // __webpack_public_path__
37 | /******/ __webpack_require__.p = "";
38 |
39 | /******/ // Load entry module and return exports
40 | /******/ return __webpack_require__(0);
41 | /******/ })
42 | /************************************************************************/
43 | /******/ ([
44 | /* 0 */
45 | /***/ (function(module, exports, __webpack_require__) {
46 |
47 | 'use strict';
48 |
49 | Object.defineProperty(exports, "__esModule", {
50 | value: true
51 | });
52 |
53 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
54 |
55 | __webpack_require__(1);
56 |
57 | var _index = __webpack_require__(5);
58 |
59 | var _index2 = _interopRequireDefault(_index);
60 |
61 | var _dom = __webpack_require__(6);
62 |
63 | var _dom2 = _interopRequireDefault(_dom);
64 |
65 | var _drag = __webpack_require__(7);
66 |
67 | var _drag2 = _interopRequireDefault(_drag);
68 |
69 | var _xhr = __webpack_require__(8);
70 |
71 | var _xhr2 = _interopRequireDefault(_xhr);
72 |
73 | var _fetch = __webpack_require__(9);
74 |
75 | var _fetch2 = _interopRequireDefault(_fetch);
76 |
77 | var _type = __webpack_require__(10);
78 |
79 | var _type2 = _interopRequireDefault(_type);
80 |
81 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
82 |
83 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
84 |
85 | var logBoxSelector = '.-c-content';
86 | var switchBtnSelector = '.-c-switch';
87 | var toolBarSelector = '.-c-toolbar';
88 | var clearClass = '-c-clear';
89 | var hideClass = '-c-hide';
90 | var ajaxClass = '-c-ajax';
91 | var logItemClass = '-c-log';
92 | var consoleMethods = ['debug', 'error', 'info', 'log', 'warn'];
93 |
94 | var Console = function () {
95 | function Console() {
96 | _classCallCheck(this, Console);
97 |
98 | this.render();
99 | this.prepareProperty();
100 | this.bindEvent();
101 | this.catchAjax();
102 | this.core();
103 | }
104 |
105 | _createClass(Console, [{
106 | key: 'render',
107 | value: function render() {
108 | var ele = _dom2.default.createElement('div', null, _index2.default);
109 | _dom2.default.append(_dom2.default.$('body'), ele);
110 | }
111 | }, {
112 | key: 'prepareProperty',
113 | value: function prepareProperty() {
114 | this.ajaxEnable = false;
115 | this.switchBtn = _dom2.default.$(switchBtnSelector);
116 | // 设置 Switch Button 初始位置, 并使其可以 Drag
117 | this.switchBtn.style.left = document.documentElement.clientWidth - this.switchBtn.offsetWidth - 10 + "px";
118 | this.switchBtn.style.top = document.documentElement.clientHeight - this.switchBtn.offsetHeight - 10 + "px";
119 | (0, _drag2.default)(this.switchBtn);
120 | this.toolBar = _dom2.default.$(toolBarSelector);
121 | this.logBox = _dom2.default.$(logBoxSelector);
122 | }
123 | }, {
124 | key: 'bindEvent',
125 | value: function bindEvent() {
126 | var _this2 = this;
127 |
128 | this.toolBar.addEventListener('click', function (e) {
129 | var target = e.target;
130 | if (target.classList.contains(clearClass)) {
131 | _dom2.default.html(_this2.logBox, '');
132 | } else if (target.classList.contains(hideClass)) {
133 | _dom2.default.hide(_this2.logBox, _this2.toolBar).show(_this2.switchBtn);
134 | }
135 | if (target.classList.contains(ajaxClass)) {
136 | _this2.ajaxEnable = !_this2.ajaxEnable;
137 | if (_this2.ajaxEnable) {
138 | target.innerText = 'AJAX(ON)';
139 | } else {
140 | target.innerText = 'AJAX(OFF)';
141 | }
142 | }
143 | });
144 |
145 | this.switchBtn.addEventListener('click', function () {
146 | _dom2.default.hide(_this2.switchBtn).show(_this2.logBox, _this2.toolBar);
147 | });
148 |
149 | // 捕获页面错误
150 | var _onerror = window.onerror || function noop() {};
151 |
152 | window.onerror = function (msg, url, lineNo, columnNo, error) {
153 | _onerror();
154 | var message = ['Message: ' + msg, 'URL: ' + url, 'Line: ' + lineNo, 'Column: ' + columnNo, 'Error object: ' + error].join('
');
155 |
156 | _this2.pushLog([message], 'Exception');
157 | };
158 | }
159 | }, {
160 | key: 'catchAjax',
161 | value: function catchAjax() {
162 | // 捕获 xhr 错误
163 | // TODO 添加 REQUEST BODY 和 RESPONSE DATA
164 | var _this = this;
165 | _xhr2.default.fn = function (xhr) {
166 | if (!_this.ajaxEnable) return;
167 | if (xhr.readyState === XMLHttpRequest.DONE) {
168 | if (xhr.status >= 200 && xhr.status <= 299) {
169 | _this.pushLog(['[AJAX] ' + xhr.open_fn_parmas.method + ' ' + xhr.open_fn_parmas.url + ' ' + xhr.status + ' (' + xhr.statusText + ')'], 'AJAXSUCCESS');
170 | xhr.send_fn_params.data && _this.pushLog(['[REQUEST BODY] ' + xhr.send_fn_params.data], 'AJAXSUCCESS');
171 | xhr.responseText && _this.pushLog(['[RESPONSE DATA] ' + xhr.responseText], 'AJAXSUCCESS');
172 | } else {
173 | _this.pushLog(['[AJAX] ' + xhr.open_fn_parmas.method + ' ' + xhr.open_fn_parmas.url + ' ' + xhr.status + ' (' + xhr.statusText + ')'], 'AJAXFAILURE');
174 | xhr.send_fn_params.data && _this.pushLog(['[REQUEST BODY] ' + xhr.send_fn_params.data], 'AJAXFAILURE');
175 | xhr.responseText && _this.pushLog(['[RESPONSE DATA] ' + xhr.responseText], 'AJAXFAILURE');
176 | }
177 | }
178 | };
179 |
180 | window.XMLHttpRequest = _xhr2.default;
181 | // 捕获 fetch 错误
182 | var unregister = _fetch2.default.register({
183 | response: function response(_ref) {
184 | var request = _ref.request,
185 | _response = _ref.response;
186 |
187 | if (_this.ajaxEnable) {
188 | if (_response.status >= 200 && _response.status <= 299) {
189 | _this.pushFetchLog(request, _response, 'AJAXSUCCESS');
190 | } else {
191 | _this.pushFetchLog(request, _response, 'AJAXFAILURE');
192 | }
193 | }
194 | return _response;
195 | },
196 | responseError: function responseError(_ref2) {
197 | var request = _ref2.request,
198 | _responseError = _ref2.responseError;
199 |
200 | // TODO 待确定
201 | if (_this.ajaxEnable) {
202 | _this.pushLog(['[AJAX] ' + request.method + ' ' + request.url + ' ' + _responseError.status + ' (' + _responseError.statusText + ')'], 'AJAXFAILURE');
203 | }
204 | return Promise.reject(_responseError);
205 | }
206 | });
207 | }
208 | }, {
209 | key: 'pushFetchLog',
210 | value: function pushFetchLog(request, response, type) {
211 | var _this3 = this;
212 |
213 | try {
214 | request = request.clone();
215 | response = response.clone();
216 | Promise.all([request.text(), response.text()]).then(function (data) {
217 | _this3.pushLog(['[AJAX] ' + request.method + ' ' + request.url + ' ' + response.status + ' (' + response.statusText + ')'], type);
218 | data[0] && _this3.pushLog(['[REQUEST BODY] ' + data[0]], type);
219 | data[1] && _this3.pushLog(['[RESPONSE DATA] ' + data[1]], type);
220 | }).catch(function (err) {
221 | _this3.pushLog(['[AJAX] ' + request.method + ' ' + request.url + ' ' + response.status + ' (' + response.statusText + ')'], type);
222 | });
223 | } catch (err) {
224 | this.pushLog(['[AJAX] ' + request.method + ' ' + request.url + ' ' + response.status + ' (' + response.statusText + ')'], type);
225 | }
226 | }
227 | }, {
228 | key: 'pushLog',
229 | value: function pushLog(msg, type) {
230 | var text = msg.map(function (val) {
231 | return (0, _type2.default)(val) ? '' + val.stack : JSON.stringify(val);
232 | }).join(' '),
233 | log = _dom2.default.createElement('div', { class: logItemClass + ' ' + type }, text);
234 | _dom2.default.append(this.logBox, log);
235 | this.logBox.scrollTop = this.logBox.scrollHeight;
236 | }
237 | }, {
238 | key: 'core',
239 | value: function core() {
240 | var _this4 = this;
241 |
242 | consoleMethods.forEach(function (method) {
243 | var original = window.console[method];
244 | window.console[method] = function () {
245 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
246 | args[_key] = arguments[_key];
247 | }
248 |
249 | _this4.pushLog(args, method);
250 | original.apply(console, args);
251 | };
252 | });
253 | }
254 | }]);
255 |
256 | return Console;
257 | }();
258 |
259 | exports.default = Console;
260 |
261 |
262 | window.MobileConsole = Console;
263 |
264 | /***/ }),
265 | /* 1 */
266 | /***/ (function(module, exports, __webpack_require__) {
267 |
268 | // style-loader: Adds some css to the DOM by adding a -->
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
166 |
167 |