UNPKG

45.1 kBJavaScriptView Raw
1/*!
2* web Studio Code - 🎉 An Editor Used on the Browser Side.
3* git+https://github.com/yelloxing/Web-Studio-Code.git
4*
5* author 心叶
6*
7* version 2.0.4
8*
9* build Fri May 08 2020
10*
11* Copyright yelloxing
12* Released under the MIT license
13*
14* Date:Fri Oct 09 2020 13:07:46 GMT+0800 (GMT+08:00)
15*/
16
17"use strict";
18
19function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
20
21function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
22
23function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
24
25function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
26
27function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
28
29function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
30
31function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
32
33function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
34
35(function () {
36 'use strict';
37
38 var _dictionary;
39
40 var toString = Object.prototype.toString;
41 /**
42 * 获取一个值的类型字符串[object type]
43 *
44 * @private
45 * @param {*} value 需要返回类型的值
46 * @returns {string} 返回类型字符串
47 */
48
49 function getType(value) {
50 if (value == null) {
51 return value === undefined ? '[object Undefined]' : '[object Null]';
52 }
53
54 return toString.call(value);
55 }
56 /**
57 * 判断一个值是不是一个朴素的'对象'
58 *
59 * @private
60 * @param {*} value 需要判断类型的值
61 * @returns {boolean} 如果是朴素的'对象'返回true,否则返回false
62 */
63
64
65 function isPlainObject(value) {
66 if (value === null || _typeof(value) !== 'object' || getType(value) != '[object Object]') {
67 return false;
68 } // 如果原型为null
69
70
71 if (Object.getPrototypeOf(value) === null) {
72 return true;
73 }
74
75 var proto = value;
76
77 while (Object.getPrototypeOf(proto) !== null) {
78 proto = Object.getPrototypeOf(proto);
79 }
80
81 return Object.getPrototypeOf(value) === proto;
82 }
83 /**
84 * 判断一个值是不是结点元素。
85 *
86 * @since V0.1.2
87 * @public
88 * @param {*} value 需要判断类型的值
89 * @returns {boolean} 如果是结点元素返回true,否则返回false
90 */
91
92
93 function isElement(value) {
94 return value !== null && _typeof(value) === 'object' && (value.nodeType === 1 || value.nodeType === 9 || value.nodeType === 11) && !isPlainObject(value);
95 }
96
97 var xhtml = {
98 // 阻止冒泡
99 "stopPropagation": function stopPropagation(event) {
100 event = event || window.event;
101
102 if (event.stopPropagation) {
103 //这是其他非IE浏览器
104 event.stopPropagation();
105 } else {
106 event.cancelBubble = true;
107 }
108 },
109 // 阻止默认事件
110 "preventDefault": function preventDefault(event) {
111 event = event || window.event;
112
113 if (event.preventDefault) {
114 event.preventDefault();
115 } else {
116 event.returnValue = false;
117 }
118 },
119 // 绑定事件
120 "bind": function bind(el, eventType, callback) {
121 if (window.attachEvent) {
122 el.attachEvent("on" + eventType, callback); // 后绑定的先执行
123 } else {
124 el.addEventListener(eventType, callback, false); // 捕获
125 }
126 },
127 // 触发事件
128 "trigger": function trigger(dom, eventType) {
129 var event; //创建event的对象实例。
130
131 if (document.createEventObject) {
132 // IE浏览器支持fireEvent方法
133 event = document.createEventObject();
134 dom.fireEvent('on' + eventType, event);
135 } // 其他标准浏览器使用dispatchEvent方法
136 else {
137 event = document.createEvent('HTMLEvents'); // 3个参数:事件类型,是否冒泡,是否阻止浏览器的默认行为
138
139 event.initEvent(eventType, true, false);
140 dom.dispatchEvent(event);
141 }
142 },
143 // 变成结点
144 "toNode": function toNode(template) {
145 var frame = document.createElement("div");
146 frame.innerHTML = template;
147 var childNodes = frame.childNodes;
148
149 for (var i = 0; i < childNodes.length; i++) {
150 if (isElement(childNodes[i])) return childNodes[i];
151 }
152
153 return null;
154 },
155 // 追加结点
156 "appendTo": function appendTo(el, template) {
157 var node = isElement(template) ? template : this.toNode(template);
158 el.appendChild(node);
159 return node;
160 },
161 // 删除结点
162 "remove": function remove(el) {
163 el.parentNode.removeChild(el);
164 },
165 // 在被指定元素之后插入结点
166 "after": function after(el, template) {
167 var node = isElement(template) ? template : this.toNode(template);
168 el.parentNode.insertBefore(node, el.nextSibling);
169 return node;
170 },
171 // 修改样式
172 "css": function css(el, styles) {
173 for (var key in styles) {
174 el.style[key] = styles[key];
175 }
176 },
177 // 修改属性
178 "attr": function attr(el, attrs) {
179 for (var key in attrs) {
180 el.setAttribute(key, attrs[key]);
181 }
182 },
183 // 获取鼠标相对特定元素左上角位置
184 "position": function position(el, event) {
185 event = event || window.event; // 返回元素的大小及其相对于视口的位置
186
187 var bounding = el.getBoundingClientRect();
188 if (!event || !event.clientX) throw new Error('Event is necessary!');
189 var temp = {
190 // 鼠标相对元素位置 = 鼠标相对窗口坐标 - 元素相对窗口坐标
191 "x": event.clientX - bounding.left + el.scrollLeft,
192 "y": event.clientY - bounding.top + el.scrollTop
193 };
194 return temp;
195 },
196 // 复制到剪切板
197 "copy": function copy(text) {
198 var el = this.appendTo(document.body, '<textarea>' + text + '</textarea>'); // 执行复制
199
200 el.select();
201
202 try {
203 var result = window.document.execCommand("copy", false, null);
204
205 if (result) {// console.log('已经复制到剪切板!');
206 } else {// console.log('复制到剪切板失败!');
207 }
208 } catch (e) {
209 console.error(e); // console.log('复制到剪切板失败!');
210 }
211
212 document.body.removeChild(el);
213 }
214 };
215 /**
216 * 判断一个值是不是String。
217 *
218 * @since V0.1.2
219 * @public
220 * @param {*} value 需要判断类型的值
221 * @returns {boolean} 如果是String返回true,否则返回false
222 */
223
224 function isString(value) {
225 var type = _typeof(value);
226
227 return type === 'string' || type === 'object' && value != null && !Array.isArray(value) && getType(value) === '[object String]';
228 }
229 /**
230 * 判断一个值是不是Object。
231 *
232 * @since V0.1.2
233 * @public
234 * @param {*} value 需要判断类型的值
235 * @returns {boolean} 如果是Object返回true,否则返回false
236 */
237
238
239 function isObject(value) {
240 var type = _typeof(value);
241
242 return value != null && (type === 'object' || type === 'function');
243 }
244 /**
245 * 判断一个值是不是Function。
246 *
247 * @since V0.1.2
248 * @public
249 * @param {*} value 需要判断类型的值
250 * @returns {boolean} 如果是Function返回true,否则返回false
251 */
252
253
254 function isFunction(value) {
255 if (!isObject(value)) {
256 return false;
257 }
258
259 var type = getType(value);
260 return type === '[object Function]' || type === '[object AsyncFunction]' || type === '[object GeneratorFunction]' || type === '[object Proxy]';
261 } // 计算文字长度
262
263
264 function textWidth(text) {
265 this.__helpCalcDOM.innerText = text;
266 return this.__helpCalcDOM.offsetWidth;
267 } // 计算最佳光标左边位置
268
269
270 function bestLeftNum(x, lineNum) {
271 if (arguments.length < 2) lineNum = lineNum || this.__lineNum;
272 var text = this._contentArray[lineNum];
273 if (x <= 40) return 0;
274 if (x - 40 >= this.$$textWidth(text)) return text.length;
275 var dist = x - 40,
276 i = 1;
277
278 for (; i < text.length; i++) {
279 var tempDist = Math.abs(x - 40 - this.$$textWidth(text.substr(0, i)));
280 if (tempDist > dist) break;
281 dist = tempDist;
282 }
283
284 return i - 1;
285 } // 计算光标对应的x,y值
286
287
288 function calcCanvasXY(leftNum, lineNum) {
289 return {
290 x: this.$$textWidth(this._contentArray[lineNum].substr(0, leftNum)),
291 y: lineNum * 21
292 };
293 } // 判断选区是否为空
294
295
296 function selectIsNotBlank() {
297 return this.__cursor1.lineNum != this.__cursor2.lineNum || this.__cursor1.leftNum != this.__cursor2.leftNum;
298 } // 根据内容生成模板
299
300
301 function toTemplate(line, index, noLineNumber) {
302 var _this = this;
303
304 var template = "";
305 template += "<div style='min-width: fit-content;white-space: nowrap;line-height:21px;height:21px;'>";
306 var lineStyle = noLineNumber ? "font-size:0;" : "";
307 template += "<em style='" + lineStyle + "color:" + this._colorNumber + ";user-select: none;display:inline-block;font-style:normal;width:35px;text-align:right;margin-right:5px;'>" + (index + 1) + "</em>";
308 line.forEach(function (text) {
309 var contentText = text.content; // 提前对特殊字符进行处理
310
311 contentText = contentText.replace(/\&/g, "&amp;");
312 /*[&]*/
313
314 contentText = contentText.replace(/</g, "&lt;");
315 contentText = contentText.replace(/>/g, "&gt;");
316 /*[<,>]*/
317
318 template += "<span style='user-select: none;font-weight:" + _this._fontWeight + ";white-space: pre;color:" + text.color + "'>" + contentText + "</span>";
319 });
320 return template + "</div>";
321 } // 整理当前输入框信息
322
323
324 function getInputMessage(wscode) {
325 return {
326 // 光标前面有多少个字符
327 leftNum: wscode.__leftNum,
328 // 当前行之前有多少行
329 lineNum: wscode.__lineNum,
330 // 光标left坐标
331 x: wscode.__cursorLeft,
332 // 光标top坐标
333 y: wscode.__cursorTop,
334 // 一行文本的高
335 lineHeight: 21
336 };
337 } // 初始化结点
338
339
340 function initDom() {
341 var _this2 = this;
342
343 this._el.innerHTML = "";
344 xhtml.css(this._el, {
345 "font-size": "12px",
346 position: "relative",
347 cursor: "text",
348 "font-family": this._fontFamily,
349 "background": this._colorBackground,
350 overflow: "auto"
351 });
352 xhtml.bind(this._el, 'click', function () {
353 // 由于有时候点击屏幕的时候,是滚动导致的,因此位置可能没有计算好前聚焦了,导致光标错位
354 setTimeout(function () {
355 _this2.__focusDOM.focus();
356 });
357 }); // 辅助计算标签
358
359 this.__helpCalcDOM = xhtml.appendTo(this._el, "<span></span>");
360 xhtml.css(this.__helpCalcDOM, {
361 position: "absolute",
362 "z-index": "-1",
363 "white-space": "pre",
364 "top": 0,
365 "left": 0,
366 "color": "rgba(0,0,0,0)",
367 "font-weight": this._fontWeight
368 }); // 辅助输入标签
369
370 this.__helpInputDOM = xhtml.appendTo(this._el, "<div></div>");
371 xhtml.css(this.__helpInputDOM, {
372 position: "absolute",
373 "z-index": 1
374 });
375 xhtml.bind(this.__helpInputDOM, 'click', function (event) {
376 xhtml.stopPropagation(event);
377 xhtml.preventDefault(event);
378
379 _this2.__focusDOM.focus();
380 }); // 光标
381
382 this.__focusDOM = xhtml.appendTo(this._el, "<textarea></textarea>");
383 xhtml.css(this.__focusDOM, {
384 position: "absolute",
385 width: "6px",
386 "margin-top": "3px",
387 height: "15px",
388 "line-height": "15px",
389 resize: "none",
390 overflow: "hidden",
391 padding: "0",
392 outline: "none",
393 border: "none",
394 background: "rgba(0,0,0,0)",
395 color: this._colorCursor
396 });
397 xhtml.attr(this.__focusDOM, {
398 wrap: "off",
399 autocorrect: "off",
400 autocapitalize: "off",
401 spellcheck: "false"
402 });
403
404 if (this._readonly) {
405 xhtml.attr(this.__focusDOM, {
406 readonly: true
407 });
408 } // 显示区域
409
410
411 this.__showDOM = xhtml.appendTo(this._el, "<div></div>");
412 xhtml.css(this.__showDOM, {
413 padding: "10px 0"
414 }); // 选中区域
415
416 this.__selectCanvas = xhtml.appendTo(this._el, "<canvas></canvas>");
417 xhtml.css(this.__selectCanvas, {
418 position: "absolute",
419 left: "40px",
420 top: "10px",
421 opacity: "0.5"
422 });
423 this.$$updateCanvasSize(1, 1);
424 } // 初始化视图
425
426
427 function initView() {
428 // 初始化定位光标位置
429 xhtml.css(this.__focusDOM, {
430 left: 40 + this.$$textWidth(this._contentArray[this.__lineNum]) + "px",
431 top: 10 + this.__lineNum * 21 + "px"
432 });
433 } // 更新编辑器内容视图
434
435
436 function updateView() {
437 var _this3 = this;
438
439 // 如果有重复利用的行(可复用的过少就不选择这种方法了)
440 if (this.__diff && this.__diff.beginNum + this.__diff.endNum > 10) {
441 var lineDoms = this.__showDOM.childNodes;
442 var lineDoms_length = lineDoms.length; // 先删除无用的行
443
444 /**
445 * 这里的删除需要稍微注意一下
446 * 因为结点删除以后就没有了,这会导致lineDoms的更新,这也是为什么备份数组长度的原因
447 * 倒着删除同样是因为这个原因
448 */
449
450 for (var i = lineDoms_length - this.__diff.endNum - 1; i >= this.__diff.beginNum; i--) {
451 xhtml.remove(lineDoms[i]);
452 } // 追加不足的行
453
454
455 if (this.__diff.beginNum > 0) {
456 for (var _i = this.__formatData.length - 1 - this.__diff.endNum; _i >= this.__diff.beginNum; _i--) {
457 xhtml.after(lineDoms[this.__diff.beginNum - 1], this.$$toTemplate(this.__formatData[_i], _i, this._noLineNumber));
458 }
459 } else {
460 // 如果开头没有结点保留,为了简单,我们直接采用append方法追加
461 for (var _i2 = 0; _i2 < this.__formatData.length - this.__diff.endNum; _i2++) {
462 xhtml.appendTo(this.__showDOM, this.$$toTemplate(this.__formatData[_i2], _i2, this._noLineNumber));
463 }
464 } // 更新行号
465
466
467 lineDoms = this.__showDOM.childNodes;
468
469 for (var _i3 = this.__diff.beginNum; _i3 < this.__formatData.length; _i3++) {
470 lineDoms[_i3].getElementsByTagName('em')[0].innerText = _i3 + 1;
471 }
472 } // 有时候,可能直接替换更快
473 else if (this.__diff != "not update") {
474 var template = "";
475
476 this.__formatData.forEach(function (line, index) {
477 template += _this3.$$toTemplate(line, index, _this3._noLineNumber);
478 });
479
480 this.__showDOM.innerHTML = template;
481 }
482
483 this.__diff = "not update";
484 var tempLineDom = this.__showDOM.childNodes[this.__lineNum]; // 修改当前编辑的行
485
486 if (!this._readonly && this.__lineDom) {
487 this.__lineDom.style.backgroundColor = "rgba(0, 0, 0, 0)";
488 tempLineDom.style.backgroundColor = this._colorEdit;
489 }
490
491 this.__lineDom = tempLineDom;
492 } // 更新编辑器选中视图
493
494
495 function updateSelectView() {
496 var _this4 = this;
497
498 var ctx = this.__selectCanvas.getContext('2d');
499
500 ctx.fillStyle = this._colorSelect;
501 ctx.clearRect(0, 0, this.__selectCanvas.scrollWidth, this.__selectCanvas.scrollHeight); // 绘制二个区间
502
503 var drawerSelect = function drawerSelect(beginLeftNum, endLeftNum, lineNum) {
504 var xy1 = _this4.$$calcCanvasXY(beginLeftNum, lineNum);
505
506 var xy2 = _this4.$$calcCanvasXY(endLeftNum, lineNum); // 如何一行过少,前置一点点选中显示
507
508
509 if (beginLeftNum == endLeftNum && beginLeftNum == 0) {
510 ctx.fillRect(xy1.x, xy1.y, 5, 21);
511 } else {
512 ctx.fillRect(xy1.x, xy1.y, xy2.x - xy1.x, 21);
513 }
514 }; // 如果选中区域为空,不用绘制
515
516
517 if (this.__cursor1.lineNum == this.__cursor2.lineNum && this.__cursor1.leftNum == this.__cursor2.leftNum) return;
518 ctx.beginPath(); // 如果在一行
519
520 if (this.__cursor1.lineNum == this.__cursor2.lineNum) {
521 drawerSelect(this.__cursor1.leftNum, this.__cursor2.leftNum, this.__cursor1.lineNum);
522 } // 如果选中的多于一行
523 else {
524 var beginCursor, endCursor;
525
526 if (this.__cursor1.lineNum < this.__cursor2.lineNum) {
527 beginCursor = this.__cursor1;
528 endCursor = this.__cursor2;
529 } else {
530 beginCursor = this.__cursor2;
531 endCursor = this.__cursor1;
532 } // 绘制开始的结尾
533
534
535 drawerSelect(beginCursor.leftNum, this._contentArray[beginCursor.lineNum].length, beginCursor.lineNum); // 绘制结束的开头
536
537 drawerSelect(0, endCursor.leftNum, endCursor.lineNum); // 绘制两行之间
538
539 for (var lineNum = beginCursor.lineNum + 1; lineNum < endCursor.lineNum; lineNum++) {
540 drawerSelect(0, this._contentArray[lineNum].length, lineNum);
541 }
542 }
543 } // 输入的时候更新光标位置
544
545
546 function updateCursorPosition() {
547 this.__cursorTop = this.__lineNum * 21 + 10;
548 this.__cursorLeft = 40 + this.$$textWidth(this._contentArray[this.__lineNum].substring(0, this.__leftNum));
549 xhtml.css(this.__focusDOM, {
550 top: this.__cursorTop + "px",
551 left: this.__cursorLeft + "px"
552 });
553 } // 更新画布尺寸
554
555
556 function updateCanvasSize(width, height) {
557 if (arguments.length < 2) {
558 width = this._el.scrollWidth - 40;
559 height = this._el.scrollHeight - 10;
560 }
561
562 xhtml.css(this.__selectCanvas, {
563 width: width + "px",
564 height: height + "px"
565 });
566 xhtml.attr(this.__selectCanvas, {
567 width: width,
568 height: height
569 });
570 } // 取消选区
571
572
573 function cancelSelect() {
574 this.$$updateCanvasSize(1, 1);
575 this.__cursor1 = {
576 leftNum: 0,
577 lineNum: 0
578 };
579 this.__cursor2 = {
580 leftNum: 0,
581 lineNum: 0
582 };
583 } // 删除选区
584
585
586 function deleteSelect() {
587 // 假定cursor2是结束光标
588 var beginCursor = this.__cursor2,
589 endCursor = this.__cursor1; // 根据行号来校对
590
591 if (this.__cursor1.lineNum < this.__cursor2.lineNum) {
592 beginCursor = this.__cursor1;
593 endCursor = this.__cursor2;
594 } else if (this.__cursor1.lineNum == this.__cursor2.lineNum) {
595 // 根据列号来校对
596 if (this.__cursor1.leftNum < this.__cursor2.leftNum) {
597 beginCursor = this.__cursor1;
598 endCursor = this.__cursor2;
599 }
600 }
601
602 var newLineText = this._contentArray[beginCursor.lineNum].substr(0, beginCursor.leftNum) + this._contentArray[endCursor.lineNum].substr(endCursor.leftNum);
603
604 this._contentArray.splice(beginCursor.lineNum, endCursor.lineNum - beginCursor.lineNum + 1, newLineText); // 校对光标和选区
605
606
607 this.__leftNum = this.__cursor1.leftNum = this.__cursor2.leftNum = beginCursor.leftNum;
608 this.__lineNum = this.__cursor1.lineNum = this.__cursor2.lineNum = beginCursor.lineNum;
609 this.$$cancelSelect();
610 } // 字典表
611
612
613 var dictionary = (_dictionary = {
614 // 数字
615 48: [0, ')'],
616 49: [1, '!'],
617 50: [2, '@'],
618 51: [3, '#'],
619 52: [4, '$'],
620 53: [5, '%'],
621 54: [6, '^'],
622 55: [7, '&'],
623 56: [8, '*'],
624 57: [9, '('],
625 96: [0, 0],
626 97: 1,
627 98: 2,
628 99: 3,
629 100: 4,
630 101: 5,
631 102: 6,
632 103: 7,
633 104: 8,
634 105: 9,
635 106: "*",
636 107: "+",
637 109: "-",
638 110: ".",
639 111: "/",
640 // 字母
641 65: ["a", "A"],
642 66: ["b", "B"],
643 67: ["c", "C"],
644 68: ["d", "D"],
645 69: ["e", "E"],
646 70: ["f", "F"],
647 71: ["g", "G"],
648 72: ["h", "H"],
649 73: ["i", "I"],
650 74: ["j", "J"],
651 75: ["k", "K"],
652 76: ["l", "L"],
653 77: ["m", "M"],
654 78: ["n", "N"],
655 79: ["o", "O"],
656 80: ["p", "P"],
657 81: ["q", "Q"],
658 82: ["r", "R"],
659 83: ["s", "S"],
660 84: ["t", "T"],
661 85: ["u", "U"],
662 86: ["v", "V"],
663 87: ["w", "W"],
664 88: ["x", "X"],
665 89: ["y", "Y"],
666 90: ["z", "Z"],
667 // 方向
668 37: "left",
669 38: "up",
670 39: "right",
671 40: "down",
672 33: "page up",
673 34: "page down",
674 35: "end",
675 36: "home",
676 // 控制键
677 16: "shift",
678 17: "ctrl",
679 18: "alt",
680 91: "command",
681 92: "command",
682 93: "command",
683 9: "tab",
684 20: "caps lock",
685 32: "spacebar",
686 8: "backspace",
687 13: "enter",
688 27: "esc",
689 46: "delete",
690 45: "insert",
691 144: "number lock",
692 145: "scroll lock",
693 12: "clear"
694 }, _defineProperty(_dictionary, "45", "insert"), _defineProperty(_dictionary, 19, "pause"), _defineProperty(_dictionary, 112, "f1"), _defineProperty(_dictionary, 113, "f2"), _defineProperty(_dictionary, 114, "f3"), _defineProperty(_dictionary, 115, "f4"), _defineProperty(_dictionary, 116, "f5"), _defineProperty(_dictionary, 117, "f6"), _defineProperty(_dictionary, 118, "f7"), _defineProperty(_dictionary, 119, "f8"), _defineProperty(_dictionary, 120, "f9"), _defineProperty(_dictionary, 121, "f10"), _defineProperty(_dictionary, 122, "f11"), _defineProperty(_dictionary, 123, "f12"), _defineProperty(_dictionary, 189, ["-", "_"]), _defineProperty(_dictionary, 187, ["=", "+"]), _defineProperty(_dictionary, 219, ["[", "{"]), _defineProperty(_dictionary, 221, ["]", "}"]), _defineProperty(_dictionary, 220, ["\\", "|"]), _defineProperty(_dictionary, 186, [";", ":"]), _defineProperty(_dictionary, 222, ["'", '"']), _defineProperty(_dictionary, 188, [",", "<"]), _defineProperty(_dictionary, 190, [".", ">"]), _defineProperty(_dictionary, 191, ["/", "?"]), _defineProperty(_dictionary, 192, ["`", "~"]), _dictionary); // 非独立键字典
695
696 var help_key = ["shift", "ctrl", "alt"];
697 /**
698 * 键盘按键
699 * 返回键盘此时按下的键的组合结果
700 * @since V0.2.5
701 * @public
702 */
703
704 function keyString(event) {
705 event = event || window.event;
706 var keycode = event.keyCode || event.which;
707 var key = dictionary[keycode] || keycode;
708 if (!key) return;
709 if (key.constructor !== Array) key = [key, key];
710 var shift = event.shiftKey ? "shift+" : "",
711 alt = event.altKey ? "alt+" : "",
712 ctrl = event.ctrlKey ? "ctrl+" : "";
713 var resultKey = "",
714 preKey = ctrl + shift + alt;
715
716 if (help_key.indexOf(key[0]) >= 0) {
717 key[0] = key[1] = "";
718 } // 判断是否按下了caps lock
719
720
721 var lockPress = event.code == "Key" + event.key && !shift; // 只有字母(且没有按下功能Ctrl、shift或alt)区分大小写
722
723 resultKey = preKey + (preKey == '' && lockPress ? key[1] : key[0]);
724
725 if (key[0] == "") {
726 resultKey = resultKey.replace(/\+$/, '');
727 }
728
729 return resultKey;
730 } // 绑定键盘和鼠标等交互事件处理
731
732
733 function bindEvent() {
734 var _this5 = this;
735
736 var mouseDown = false; // 辅助计算选择光标位置
737
738 var calcCursor = function calcCursor(event) {
739 var position = xhtml.position(_this5._el, event);
740 var topIndex = Math.round((position.y - 20.5) / 21);
741 if (topIndex < 0) topIndex = 0;
742 if (topIndex >= _this5._contentArray.length) topIndex = _this5._contentArray.length - 1;
743 return {
744 leftNum: _this5.$$bestLeftNum(position.x, topIndex),
745 lineNum: topIndex
746 };
747 }; // 获取光标之间的内容
748
749
750 var calcTwoCursor = function calcTwoCursor() {
751 // 假定cursor2是结束光标
752 var beginCursor = _this5.__cursor2,
753 endCursor = _this5.__cursor1; // 根据行号来校对
754
755 if (_this5.__cursor1.lineNum < _this5.__cursor2.lineNum) {
756 beginCursor = _this5.__cursor1;
757 endCursor = _this5.__cursor2;
758 } else if (_this5.__cursor1.lineNum == _this5.__cursor2.lineNum) {
759 // 根据列号来校对
760 if (_this5.__cursor1.leftNum < _this5.__cursor2.leftNum) {
761 beginCursor = _this5.__cursor1;
762 endCursor = _this5.__cursor2;
763 }
764
765 return _this5._contentArray[beginCursor.lineNum].substring(beginCursor.leftNum, endCursor.leftNum);
766 } // 余下的一定是多行
767
768
769 var resultData = "";
770 resultData += _this5._contentArray[beginCursor.lineNum].substr(beginCursor.leftNum) + "\n";
771
772 for (var lineNum = beginCursor.lineNum + 1; lineNum < endCursor.lineNum; lineNum++) {
773 resultData += _this5._contentArray[lineNum] + "\n";
774 }
775
776 resultData += _this5._contentArray[endCursor.lineNum].substr(0, endCursor.leftNum);
777 return resultData;
778 }; // 鼠标按下的时候,记录开始光标位置并标记鼠标按下动作
779
780
781 xhtml.bind(this._el, 'mousedown', function (event) {
782 mouseDown = true;
783 _this5.__cursor2 = _this5.__cursor1 = calcCursor(event);
784
785 _this5.$$updateCanvasSize(); // 绘制选中效果
786
787
788 _this5.$$updateSelectView();
789 }); // 移动的时候不停的同步结束光标位置
790
791 xhtml.bind(this._el, 'mousemove', function (event) {
792 if (!mouseDown) return;
793 _this5.__cursor2 = calcCursor(event); // 绘制选中效果
794
795 _this5.$$updateSelectView();
796 }); // 鼠标分开或移出的时候,标记鼠标放开
797
798 xhtml.bind(this._el, 'mouseup', function () {
799 return mouseDown = false;
800 });
801 xhtml.bind(this._el, 'mouseout', function () {
802 return mouseDown = false;
803 }); // 点击编辑界面
804
805 xhtml.bind(this._el, 'click', function (event) {
806 _this5.__helpInputDOM.innerHTML = '';
807 var position = xhtml.position(_this5._el, event);
808 var topIndex = Math.round((position.y - 20.5) / 21); // 如果超过了内容区域
809
810 if (topIndex < 0 || topIndex >= _this5._contentArray.length) return;
811 _this5.__lineNum = topIndex;
812 _this5.__leftNum = _this5.$$bestLeftNum(position.x);
813
814 _this5.$$updateCursorPosition();
815
816 _this5.$$updateView();
817 });
818
819 var update = function update(text) {
820 // 获取输入内容
821 text = text || _this5.__focusDOM.value;
822 text = _this5.$$filterText(text);
823 _this5.__focusDOM.value = ""; // 如果有选区,先删除选区
824
825 if (_this5.$$selectIsNotBlank()) _this5.$$deleteSelect(); // 如果输入的是回车,切割文本
826
827 if (/^\n$/.test(text)) {
828 if (_this5.__leftNum >= _this5._contentArray[_this5.__lineNum].length) {
829 _this5._contentArray.splice(_this5.__lineNum + 1, 0, "");
830 } else {
831 _this5._contentArray.splice(_this5.__lineNum + 1, 0, _this5._contentArray[_this5.__lineNum].substring(_this5.__leftNum));
832
833 _this5._contentArray[_this5.__lineNum] = _this5._contentArray[_this5.__lineNum].substring(0, _this5.__leftNum);
834 }
835
836 _this5.__lineNum += 1;
837 _this5.__leftNum = 0;
838 } // 否则就是一堆文本(包括复制来的)
839 else {
840 var textArray = text.split(/\n/); // 如果只有一行文本(分开是为了加速)
841
842 if (textArray.length <= 1) {
843 _this5._contentArray[_this5.__lineNum] = _this5._contentArray[_this5.__lineNum].substring(0, _this5.__leftNum) + text + _this5._contentArray[_this5.__lineNum].substring(_this5.__leftNum);
844 _this5.__leftNum += text.length;
845 } // 如果是复制的多行文本
846 else {
847 var _this5$_contentArray;
848
849 // 需要切割的行两边文本
850 var leftText = _this5._contentArray[_this5.__lineNum].substring(0, _this5.__leftNum);
851
852 var rightText = _this5._contentArray[_this5.__lineNum].substring(_this5.__leftNum); // 旧行文本拼接进来
853
854
855 textArray[0] = leftText + textArray[0];
856 textArray[textArray.length - 1] += rightText; // 新内容记录下来
857
858 (_this5$_contentArray = _this5._contentArray).splice.apply(_this5$_contentArray, [_this5.__lineNum, 1].concat(_toConsumableArray(textArray)));
859
860 _this5.__lineNum += textArray.length - 1;
861 _this5.__leftNum = textArray[textArray.length - 1].length - rightText.length;
862 }
863 } // 着色并更新视图
864
865
866 _this5.__formatData = _this5.$$diff(_this5.$shader(_this5._contentArray.join('\n')));
867
868 _this5.$$updateCursorPosition();
869
870 _this5.$$updateView(); // 通知文本改动
871
872
873 _this5.__updated__();
874 }; // 中文输入开始
875
876
877 xhtml.bind(this.__focusDOM, 'compositionstart', function () {
878 _this5.__needUpdate = false;
879 _this5.__focusDOM.style.color = "rgba(0,0,0,0)";
880 _this5.__focusDOM.style.borderLeft = '1px solid ' + _this5._colorCursor;
881 }); // 中文输入结束
882
883 xhtml.bind(this.__focusDOM, 'compositionend', function () {
884 _this5.__needUpdate = true;
885 _this5.__focusDOM.style.color = _this5._colorCursor;
886 _this5.__focusDOM.style.borderLeft = "none";
887 update(); // 辅助输入
888
889 if (_this5.$input != null) _this5.__helpInputEvent = _this5.$input(_this5.__helpInputDOM, getInputMessage(_this5), _this5._contentArray) || {};
890 }); // 输入
891
892 xhtml.bind(this.__focusDOM, 'input', function () {
893 // 如果是中文输入开始,不应该更新
894 if (_this5.__needUpdate) {
895 update(); // 辅助输入
896
897 if (_this5.$input != null) _this5.__helpInputEvent = _this5.$input(_this5.__helpInputDOM, getInputMessage(_this5), _this5._contentArray) || {};
898 }
899 }); // 处理键盘控制
900
901 xhtml.bind(this._el, 'keydown', function (event) {
902 var keyStringCode = keyString(event); // 辅助输入前置拦截
903
904 if (_this5.__helpInputDOM.innerHTML != '') {
905 var __helpInputEvent = _this5.__helpInputEvent[keyStringCode];
906
907 if (isFunction(__helpInputEvent)) {
908 // 如果返回true表示继续调用,否则此快捷键结束
909 if (!__helpInputEvent()) return;
910 } else {
911 _this5.__helpInputDOM.innerHTML = '';
912 }
913 } // 只读模式需要拦截部分快捷键
914
915
916 if (_this5._readonly && ['ctrl+a', 'ctrl+c'].indexOf(keyStringCode) < 0) return; // 进入常规快捷键
917
918 switch (keyStringCode) {
919 // 全选
920 case "ctrl+a":
921 {
922 // 修改选区范围
923 _this5.__cursor1 = {
924 leftNum: 0,
925 lineNum: 0
926 };
927 _this5.__cursor2 = {
928 lineNum: _this5._contentArray.length - 1,
929 leftNum: _this5._contentArray[_this5._contentArray.length - 1].length
930 }; // 绘制选中效果
931
932 _this5.$$updateSelectView();
933
934 break;
935 }
936 // 复制
937
938 case "ctrl+c":
939 {
940 if (_this5.$$selectIsNotBlank()) {
941 xhtml.copy(calcTwoCursor());
942
943 _this5.__focusDOM.focus();
944 }
945
946 break;
947 }
948 // 剪切
949
950 case "ctrl+x":
951 {
952 if (_this5.$$selectIsNotBlank()) {
953 xhtml.copy(calcTwoCursor());
954
955 _this5.__focusDOM.focus();
956
957 _this5.$$deleteSelect(); // 由于内容改变,需要重新调用着色
958
959
960 _this5.__formatData = _this5.$$diff(_this5.$shader(_this5._contentArray.join('\n'))); // 更新视图
961
962 _this5.$$updateCursorPosition();
963
964 _this5.$$updateView();
965
966 _this5.$$cancelSelect(); // 通知文本改动
967
968
969 _this5.__updated__();
970 }
971
972 break;
973 }
974 // 多空格输入或多行移位
975
976 case "tab":
977 {
978 // tab用来控制输入多个空格,默认事件需要禁止
979 xhtml.stopPropagation(event);
980 xhtml.preventDefault(event); // 计算空格
981
982 var blanks = "";
983
984 for (var i = 0; i < _this5._tabSpace; i++) {
985 blanks += " ";
986 } // 如果有选区,特殊处理
987
988
989 if (_this5.$$selectIsNotBlank()) {
990 var beginLineNum = _this5.__cursor1.lineNum,
991 endLineNum = _this5.__cursor2.lineNum;
992
993 if (beginLineNum > endLineNum) {
994 beginLineNum = _this5.__cursor2.lineNum;
995 endLineNum = _this5.__cursor1.lineNum;
996 } // 在开头追究tab
997
998
999 for (var lineNum = beginLineNum; lineNum <= endLineNum; lineNum++) {
1000 _this5._contentArray[lineNum] = blanks + _this5._contentArray[lineNum];
1001 } // 校对选择区域
1002
1003
1004 _this5.__cursor1.leftNum += _this5._tabSpace;
1005 _this5.__cursor2.leftNum += _this5._tabSpace; // 校对光标
1006
1007 _this5.__leftNum += _this5._tabSpace;
1008 _this5.__formatData = _this5.$$diff(_this5.$shader(_this5._contentArray.join('\n')));
1009
1010 _this5.$$updateCursorPosition();
1011
1012 _this5.$$updateView();
1013
1014 _this5.$$updateCanvasSize();
1015
1016 _this5.$$updateSelectView(); // 通知文本改动
1017
1018
1019 _this5.__updated__();
1020 } else {
1021 update(blanks);
1022 }
1023
1024 break;
1025 }
1026 // 光标向上
1027
1028 case "up":
1029 {
1030 // 如果是第一行不需要任何处理
1031 if (_this5.__lineNum <= 0) return; // 向上一行
1032
1033 _this5.__lineNum -= 1;
1034 _this5.__leftNum = _this5.$$bestLeftNum(_this5.$$textWidth(_this5._contentArray[_this5.__lineNum + 1].substr(0, _this5.__leftNum)) + 40);
1035
1036 _this5.$$updateCursorPosition();
1037
1038 _this5.$$updateView();
1039
1040 _this5.$$cancelSelect();
1041
1042 _this5._el.scrollTop -= 21;
1043 break;
1044 }
1045 // 光标向下
1046
1047 case "down":
1048 {
1049 if (_this5.__lineNum >= _this5._contentArray.length - 1) return; // 向下一行
1050
1051 _this5.__lineNum += 1;
1052 _this5.__leftNum = _this5.$$bestLeftNum(_this5.$$textWidth(_this5._contentArray[_this5.__lineNum - 1].substr(0, _this5.__leftNum)) + 40);
1053
1054 _this5.$$updateCursorPosition();
1055
1056 _this5.$$updateView();
1057
1058 _this5.$$cancelSelect();
1059
1060 _this5._el.scrollTop += 21;
1061 break;
1062 }
1063 // 光标向左
1064
1065 case "left":
1066 {
1067 if (_this5.__leftNum <= 0) {
1068 if (_this5.__lineNum <= 0) return;
1069 _this5.__lineNum -= 1;
1070 _this5.__leftNum = _this5._contentArray[_this5.__lineNum].length;
1071 } else {
1072 _this5.__leftNum -= 1;
1073 }
1074
1075 _this5.$$updateCursorPosition();
1076
1077 _this5.$$cancelSelect();
1078
1079 break;
1080 }
1081 // 光标向右
1082
1083 case "right":
1084 {
1085 if (_this5.__leftNum >= _this5._contentArray[_this5.__lineNum].length) {
1086 if (_this5.__lineNum >= _this5._contentArray.length - 1) return;
1087 _this5.__lineNum += 1;
1088 _this5.__leftNum = 0;
1089 } else {
1090 _this5.__leftNum += 1;
1091 }
1092
1093 _this5.$$updateCursorPosition();
1094
1095 _this5.$$cancelSelect();
1096
1097 break;
1098 }
1099 // 删除
1100
1101 case "backspace":
1102 {
1103 // 如果有选区
1104 if (_this5.$$selectIsNotBlank()) {
1105 // 删除选区
1106 _this5.$$deleteSelect();
1107 } // 无选区的常规操作
1108 else {
1109 if (_this5.__leftNum <= 0) {
1110 if (_this5.__lineNum <= 0) return;
1111 _this5.__lineNum -= 1;
1112 _this5.__leftNum = _this5._contentArray[_this5.__lineNum].length; // 一行的开头应该删除本行(合并到前一行)
1113
1114 _this5._contentArray[_this5.__lineNum] += _this5._contentArray[_this5.__lineNum + 1];
1115
1116 _this5._contentArray.splice(_this5.__lineNum + 1, 1);
1117 } else {
1118 _this5.__leftNum -= 1;
1119 _this5._contentArray[_this5.__lineNum] = _this5._contentArray[_this5.__lineNum].substring(0, _this5.__leftNum) + _this5._contentArray[_this5.__lineNum].substring(_this5.__leftNum + 1);
1120 }
1121 } // 由于内容改变,需要重新调用着色
1122
1123
1124 _this5.__formatData = _this5.$$diff(_this5.$shader(_this5._contentArray.join('\n'))); // 更新视图
1125
1126 _this5.$$updateCursorPosition();
1127
1128 _this5.$$updateView();
1129
1130 _this5.$$cancelSelect(); // 通知文本改动
1131
1132
1133 _this5.__updated__();
1134
1135 break;
1136 }
1137 }
1138 });
1139 } // 判断一行是否匹配
1140
1141
1142 var euqalLine = function euqalLine(line1, line2) {
1143 if (line1.length != line2.length) return false;
1144
1145 for (var i = 0; i < line1.length; i++) {
1146 if (line1[i].content != line2[i].content || line1[i].color != line2[i].color) return false;
1147 }
1148
1149 return true;
1150 };
1151 /**
1152 * 为了加速页面渲染,我们引入差异对比
1153 * 简单的理解就是:
1154 * 原本在数据改变的时候直接更新整个DOM的方式替换成只功能必要的DOM
1155 */
1156
1157
1158 function diff(newFormatData) {
1159 /**
1160 * 思路:
1161 *
1162 * 从开始匹配无法匹配的,匹配条个数记作beginNum
1163 * 再从结尾匹配无法匹配的,匹配条个数记作endNum
1164 * 只有begin和end之间的数据需要更新DOM
1165 *
1166 * 当然,也有特殊情况,因此在进行回归前,先把特殊情况提取处理
1167 *
1168 */
1169 var oldFormatData = this.__formatData;
1170
1171 if (oldFormatData) {
1172 // 寻找开始匹配行数
1173 var beginNum = 0;
1174
1175 for (var i = 0; i < oldFormatData.length && i < newFormatData.length; i++) {
1176 if (!euqalLine(oldFormatData[i], newFormatData[i])) {
1177 break;
1178 }
1179
1180 beginNum += 1;
1181 } // 寻找结束匹配行数
1182
1183
1184 var endNum = 0;
1185
1186 for (var _i4 = 1; _i4 <= oldFormatData.length && _i4 <= newFormatData.length; _i4++) {
1187 if (!euqalLine(oldFormatData[oldFormatData.length - _i4], newFormatData[newFormatData.length - _i4])) {
1188 break;
1189 }
1190
1191 endNum += 1;
1192 }
1193
1194 var minLength = Math.min(oldFormatData.length, newFormatData.length); // 校对(如果复用重叠了)
1195
1196 if (beginNum + endNum >= minLength) {
1197 endNum = minLength - beginNum - 1; // 由于不知道是删除还是增加,因此可能出现负数
1198
1199 if (endNum < 0) endNum = 0;
1200 } // 对比以后的差异信息
1201
1202
1203 this.__diff = {
1204 beginNum: beginNum,
1205 endNum: endNum
1206 };
1207 }
1208
1209 return newFormatData;
1210 } // 外来文本统一过滤处理
1211
1212
1213 function filterText(oralStr) {
1214 // 把tab统一变成空格
1215 var tab = "";
1216
1217 for (var i = 0; i < this._tabSpace; i++) {
1218 tab += " ";
1219 }
1220
1221 return oralStr.replace(/\t/g, tab);
1222 }
1223
1224 var wscode = function wscode(options) {
1225 var _this6 = this;
1226
1227 if (!(this instanceof wscode)) {
1228 throw new Error('WSCode is a constructor and should be called with the `new` keyword');
1229 }
1230 /**
1231 *
1232 * [格式化配置]
1233 *
1234 * 所有的配置校验和默认值设置等都应该在这里进行
1235 * 经过这里处理以后,后续不需要再进行校验了
1236 * 因此这里的内容的更改一定要慎重
1237 *
1238 */
1239 // 编辑器挂载点
1240
1241
1242 if (isElement(options.el)) {
1243 // 着色器
1244 var shader = function shader() {
1245 var resultData = [];
1246
1247 _this6._contentArray.forEach(function (text) {
1248 resultData.push([{
1249 content: text,
1250 color: _this6._colorText
1251 }]);
1252 });
1253
1254 return resultData;
1255 }; // 格式化
1256
1257
1258 var format = function format(textString) {
1259 return textString;
1260 };
1261
1262 this._el = options.el; // 公共配置
1263
1264 options.color = options.color || {};
1265 this._colorBackground = options.color.background || "#d6d6e4";
1266 /*编辑器背景*/
1267
1268 this._colorText = options.color.text || "#000000";
1269 /*普通文本颜色*/
1270
1271 this._colorNumber = options.color.number || "#888484";
1272 /*行号颜色*/
1273
1274 this._colorEdit = options.color.edit || "#eaeaf1";
1275 /*编辑行颜色*/
1276
1277 this._colorCursor = options.color.cursor || "#ff0000";
1278 /*光标颜色*/
1279
1280 this._colorSelect = options.color.select || "#6c6cf1";
1281 /*选择背景*/
1282
1283 this._fontFamily = options["font-family"] || "新宋体";
1284 /*字体*/
1285
1286 this._fontWeight = options["font-weight"] || 600;
1287 /*字重*/
1288
1289 this._tabSpace = options.tabSpace || 4;
1290 /*设置一个tab表示多少个空格*/
1291
1292 this._readonly = options.readonly || false;
1293 /*是否只读*/
1294
1295 this._noLineNumber = options.noLineNumber || false;
1296 /*是否隐藏行号*/
1297 // 文本
1298
1299 this._contentArray = isString(options.content) ? (this.$$filterText(options.content) + "").split("\n") : [""]; // 着色方法
1300
1301 this.$shader = isFunction(options.shader) ? options.shader : shader; // 格式化方法
1302
1303 this.$format = isFunction(options.format) ? options.format : format; // 辅助输入
1304
1305 this.$input = isFunction(options.input) ? options.input : null;
1306 } else {
1307 // 挂载点是必须的,一定要有
1308 throw new Error('options.el is not a element!');
1309 } // 先初始化DOM
1310
1311
1312 this.$$initDom(); // 初始化控制变量
1313
1314 this.__needUpdate = true;
1315 this.__lineNum = this._contentArray.length - 1;
1316 this.__leftNum = this._contentArray[this.__lineNum].length;
1317 this.__cursor1 = this.__cursor2 = {
1318 leftNum: 0,
1319 lineNum: 0
1320 };
1321 this.__formatData = this.$$diff(this.$shader(this._contentArray.join('\n'))); // 初始化视图
1322
1323 this.$$initView(); // 更新视图
1324
1325 this.$$updateView(); // 绑定操作
1326
1327 this.$$bindEvent();
1328
1329 this.__updated__ = function () {}; // 编辑器管理的文本发生改变后会主动触发callback方法
1330
1331
1332 this.updated = function (callback) {
1333 _this6.__updated__ = callback;
1334 }; // 获取当前编辑器代码
1335
1336
1337 this.valueOf = function () {
1338 return _this6._contentArray.join('\n');
1339 }; // 在当前光标位置输入新的内容
1340
1341
1342 this.input = function () {
1343 var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
1344 var cursor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1345 var number = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
1346
1347 // 先删除多余的内容
1348 if (cursor != 0) {
1349 if (number != 0) {
1350 _this6._contentArray[_this6.__lineNum] = _this6._contentArray[_this6.__lineNum].substring(0, _this6.__leftNum + cursor) + _this6._contentArray[_this6.__lineNum].substring(_this6.__leftNum + cursor + number);
1351 } // 修改光标位置
1352
1353
1354 _this6.__leftNum += cursor;
1355 } // 输入以触发更新
1356
1357
1358 _this6.__focusDOM.value = content;
1359 xhtml.trigger(_this6.__focusDOM, 'input');
1360
1361 _this6.__focusDOM.focus();
1362 }; // 格式化代码
1363
1364
1365 this.format = function () {
1366 // 格式化内容
1367 _this6._contentArray = _this6.$format(_this6._contentArray.join('\n'), _this6._tabSpace).split('\n');
1368 _this6.__lineNum = _this6._contentArray.length - 1;
1369 _this6.__leftNum = _this6._contentArray[_this6.__lineNum].length; // 着色
1370
1371 _this6.__formatData = _this6.$$diff(_this6.$shader(_this6._contentArray.join('\n'))); // 更新视图
1372
1373 _this6.$$updateView(); // 更新光标位置
1374
1375
1376 _this6.$$initView();
1377 };
1378 }; // 挂载辅助方法
1379
1380
1381 wscode.prototype.$$textWidth = textWidth;
1382 wscode.prototype.$$bestLeftNum = bestLeftNum;
1383 wscode.prototype.$$calcCanvasXY = calcCanvasXY;
1384 wscode.prototype.$$selectIsNotBlank = selectIsNotBlank;
1385 wscode.prototype.$$filterText = filterText;
1386 wscode.prototype.$$toTemplate = toTemplate; // 挂载核心方法
1387
1388 wscode.prototype.$$initDom = initDom;
1389 wscode.prototype.$$initView = initView;
1390 wscode.prototype.$$updateView = updateView;
1391 wscode.prototype.$$updateSelectView = updateSelectView;
1392 wscode.prototype.$$updateCursorPosition = updateCursorPosition;
1393 wscode.prototype.$$updateCanvasSize = updateCanvasSize;
1394 wscode.prototype.$$cancelSelect = cancelSelect;
1395 wscode.prototype.$$deleteSelect = deleteSelect;
1396 wscode.prototype.$$bindEvent = bindEvent; // 性能优化系列方法
1397
1398 wscode.prototype.$$diff = diff;
1399 wscode.author = '心叶(yelloxing@gmail.com)';
1400
1401 if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") {
1402 module.exports = wscode;
1403 } else {
1404 window.WSCode = wscode;
1405 }
1406})();
\No newline at end of file