UNPKG

7.12 kBJavaScriptView Raw
1import keyString from '@yelloxing/core.js/tools/keyString';
2import xhtml from '../xhtml';
3
4// 绑定键盘和鼠标等交互事件处理
5
6export default function () {
7
8 // 点击编辑界面
9 xhtml.bind(this._el, 'click', event => {
10
11 let position = xhtml.position(this._el, event);
12 let topIndex = Math.round((position.y - 20.5) / 21);
13
14 // 如果超过了内容区域
15 if (topIndex < 0 || topIndex >= this._contentArray.length) return;
16
17 this.__lineNum = topIndex;
18 this.__leftNum = this.$$bestLeftNum(position.x);
19
20 this.$$updateCursorPosition();
21 this.$$updateView();
22 });
23
24 let update = text => {
25
26 // 获取输入内容
27 text = text || this.__focusDOM.value;
28
29 this.__focusDOM.value = "";
30
31 // 如果输入的是回车,切割文本
32 if (/^\n$/.test(text)) {
33
34 if (this.__leftNum >= this._contentArray[this.__lineNum].length) {
35 this._contentArray.splice(this.__lineNum + 1, 0, "");
36 } else {
37 this._contentArray.splice(this.__lineNum + 1, 0, this._contentArray[this.__lineNum].substring(this.__leftNum));
38 this._contentArray[this.__lineNum] = this._contentArray[this.__lineNum].substring(0, this.__leftNum);
39 }
40 this.__lineNum += 1;
41 this.__leftNum = 0;
42
43 }
44
45 // 否则就是一堆文本(包括复制来的)
46 else {
47
48 let textArray = text.split(/\n/);
49
50 // 如果只有一行文本(分开是为了加速)
51 if (textArray.length <= 1) {
52 this._contentArray[this.__lineNum] = this._contentArray[this.__lineNum].substring(0, this.__leftNum) + text + this._contentArray[this.__lineNum].substring(this.__leftNum);
53 this.__leftNum += text.length;
54 }
55
56 // 如果是复制的多行文本
57 else {
58
59 // 需要切割的行两边文本
60 let leftText = this._contentArray[this.__lineNum].substring(0, this.__leftNum);
61 let rightText = this._contentArray[this.__lineNum].substring(this.__leftNum);
62
63 // 旧行文本拼接进来
64 textArray[0] = leftText + textArray[0];
65 textArray[textArray.length - 1] += rightText;
66
67 // 新内容记录下来
68 this._contentArray.splice(this.__lineNum, 1, ...textArray);
69
70 this.__lineNum += (textArray.length - 1);
71 this.__leftNum = textArray[textArray.length - 1].length - rightText.length;
72
73 }
74
75 }
76
77 // 着色并更新视图
78
79 this.__formatData = this.$shader(this._contentArray.join('\n'));
80 this.$$updateCursorPosition();
81 this.$$updateView();
82
83 };
84
85 // 中文输入开始
86 xhtml.bind(this.__focusDOM, 'compositionstart', () => {
87 this.__needUpdate = false;
88 this.__focusDOM.style.color = "rgba(0,0,0,0)";
89 this.__focusDOM.style.borderLeft = '1px solid ' + this._colorCursor;
90 });
91
92 // 中文输入结束
93 xhtml.bind(this.__focusDOM, 'compositionend', () => {
94 this.__needUpdate = true;
95 this.__focusDOM.style.color = this._colorCursor;
96 this.__focusDOM.style.borderLeft = "none";
97 update();
98 });
99
100 // 输入
101 xhtml.bind(this.__focusDOM, 'input', () => {
102 // 如果是中文输入开始,不应该更新
103 if (this.__needUpdate) update();
104 });
105
106 // 处理键盘控制
107 xhtml.bind(this._el, 'keydown', event => {
108
109 // console.log(keyString(event));
110
111 switch (keyString(event)) {
112
113 case "tab": {
114
115 // tab用来控制输入多个空格,默认事件需要禁止
116 xhtml.stopPropagation(event);
117 xhtml.preventDefault(event);
118
119 // 计算空格
120 let blanks = "";
121 for (let i = 0; i < this._tabSpace; i++) blanks += " ";
122
123 update(blanks);
124
125 break;
126 }
127
128 case "up": {
129
130 // 如果是第一行不需要任何处理
131 if (this.__lineNum <= 0) return;
132
133 this.__leftNum = this.$$bestLeftNum(this.$$textWidth("", true) + 40);
134
135 // 向上一行
136 this.__lineNum -= 1;
137
138 this.$$updateCursorPosition();
139 this.$$updateView();
140
141 this._el.scrollTop -= 21;
142
143 break;
144 }
145
146 case "down": {
147
148 if (this.__lineNum >= this._contentArray.length - 1) return;
149
150 this.__leftNum = this.$$bestLeftNum(this.$$textWidth("", true) + 40);
151
152 // 向下一行
153 this.__lineNum += 1;
154
155 this.$$updateCursorPosition();
156 this.$$updateView();
157
158 this._el.scrollTop += 21;
159
160 break;
161 }
162
163 case "left": {
164
165 if (this.__leftNum <= 0) {
166 if (this.__lineNum <= 0) return;
167 this.__lineNum -= 1;
168 this.__leftNum = this._contentArray[this.__lineNum].length;
169 } else {
170 this.__leftNum -= 1;
171 }
172
173 this.$$updateCursorPosition();
174
175 break;
176 }
177
178 case "right": {
179
180 if (this.__leftNum >= this._contentArray[this.__lineNum].length) {
181 if (this.__lineNum >= this._contentArray.length - 1) return;
182 this.__lineNum += 1;
183 this.__leftNum = 0;
184 } else {
185 this.__leftNum += 1;
186 }
187
188 this.$$updateCursorPosition();
189
190 break;
191 }
192
193 case "backspace": {
194
195 if (this.__leftNum <= 0) {
196 if (this.__lineNum <= 0) return;
197
198 this.__lineNum -= 1;
199 this.__leftNum = this._contentArray[this.__lineNum].length;
200
201 // 一行的开头应该删除本行(合并到前一行)
202 this._contentArray[this.__lineNum] += this._contentArray[this.__lineNum + 1];
203 this._contentArray.splice(this.__lineNum + 1, 1);
204
205 } else {
206 this.__leftNum -= 1;
207 this._contentArray[this.__lineNum] = this._contentArray[this.__lineNum].substring(0, this.__leftNum) + this._contentArray[this.__lineNum].substring(this.__leftNum + 1);
208 }
209
210 // 由于内容改变,需要重新调用着色
211 this.__formatData = this.$shader(this._contentArray.join('\n'));
212
213 // 更新视图
214 this.$$updateCursorPosition();
215 this.$$updateView();
216
217 break;
218 }
219 }
220
221 });
222
223};
\No newline at end of file