UNPKG

22 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="zh-cn">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="X-UA-Compatible" content="ie=edge">
8 <link rel="shortcut icon" href="./logo.png">
9
10 <style>
11 body {
12 margin: 0;
13 }
14
15 div#wscode {
16 width: 100vw;
17 height: 100vh;
18 }
19
20 .github {
21 position: fixed;
22 transform: rotate(45deg);
23 top: 60px;
24 line-height: 1.6em;
25 right: -60px;
26 background-color: #9e9695;
27 outline: 4px solid #9e9695;
28 transform-origin: 150px 23px;
29 border: 2px dashed #faf6f5;
30 width: 300px;
31 text-align: center;
32 color: #f7f3f2;
33 z-index: 2;
34 font-family: sans-serif;
35 text-decoration: none;
36 }
37 </style>
38
39 <!-- 本地最新 -->
40 <script src="./dist/wscode.js"></script>
41
42 <!-- CDN最新 -->
43 <!-- <script src="https://cdn.jsdelivr.net/npm/wscode"></script> -->
44
45 <title>Example | Web Studio Code</title>
46
47 <script>
48
49 // 合并内容
50
51 var toShaderReult = function (words) {
52
53 var resultData = [[]], lineNum = 0;
54
55 words.forEach(word => {
56
57 var codeArray = word.content.split(/\n/);
58
59 resultData[lineNum].push({
60 color: word.color,
61 content: codeArray[0]
62 });
63
64 for (var index = 1; index < codeArray.length; index++) {
65 lineNum += 1;
66 resultData.push([]);
67
68 resultData[lineNum].push({
69 color: word.color,
70 content: codeArray[index]
71 });
72
73 }
74
75 });
76
77 return resultData;
78 };
79
80 // JS关键字
81 var keyWords = [
82 "abstract", "arguments", "boolean", "break", "byte",
83 "case", "catch", "char", "class", "const",
84 "continue", "debugger", "default", "delete", "do",
85 "double", "else", "enum", "eval", "export",
86 "extends", "false", "final", "finally", "float",
87 "for", "function", "goto", "if", "implements",
88 "import", "in", "instanceof", "int", "interface",
89 "let", "long", "native", "new", "null",
90 "package", "private", "protected", "public", "return",
91 "short", "static", "super", "switch", "synchronized",
92 "this", "throw", "throws", "transient", "true",
93 "try", "typeof", "var", "void", "volatile",
94 "while", "with", "yield"
95 ];
96
97 function _inner_CSS_shader(textString, colors) {
98 var shaderArray = [];
99
100 // 当前面对的
101 var i = 0;
102
103 // 获取往后n个值
104 var nextNValue = function (n) {
105 return textString.substring(i, n + i > textString.length ? textString.length : n + i);
106 };
107
108 var template = "";
109
110 // 1:选择器 tag
111 // 2:属性名 attr
112 // 3:属性值 string
113 var state = "tag";
114
115 // 初始化模板,开始文本捕获
116 var initTemplate = function () {
117 if (template != "") {
118 shaderArray.push({
119 color: colors[state],
120 content: template
121 });
122 }
123
124 template = "";
125 };
126
127 while (true) {
128
129 /* 1.注释 */
130
131 if (nextNValue(2) == '/*') {
132
133 initTemplate();
134 while (nextNValue(2) !== '*/' && i < textString.length) {
135 template += textString[i++];
136 }
137
138 shaderArray.push({
139 color: colors.annotation,
140 content: template + nextNValue(2)
141 });
142 i += 2;
143 template = "";
144
145 }
146
147 /* 2.字符串 */
148
149 else if (["'", '"'].indexOf(nextNValue(1)) > -1) {
150
151 var strBorder = nextNValue(1);
152 initTemplate();
153
154 do {
155 template += textString[i++];
156 } while (nextNValue(1) != strBorder && i < textString.length)
157
158 // 因为可能是没有字符导致的结束
159 if (nextNValue(1) != strBorder) {
160 strBorder = "";
161 } else {
162 i += 1;
163 }
164
165 shaderArray.push({
166 color: colors.string,
167 content: template + strBorder
168 });
169 template = "";
170
171 }
172
173 /* 3.边界 */
174
175 else if ([":", '{', '}', ";"].indexOf(nextNValue(1)) > -1) {
176
177 initTemplate();
178 shaderArray.push({
179 color: colors.border,
180 content: nextNValue(1)
181 });
182 template = "";
183
184 if (nextNValue(1) == '{' || nextNValue(1) == ';') {
185 state = 'attr';
186 } else if (nextNValue(1) == '}') {
187 state = 'tag';
188 } else {
189 state = 'string';
190 }
191
192 i += 1;
193 }
194
195 /* 追加字符 */
196
197 else {
198 if (i >= textString.length) {
199 initTemplate();
200 break;
201 } else {
202 template += textString[i++];
203 }
204 }
205
206 }
207 return shaderArray;
208 }
209
210 function _inner_ES_shader(textString, colors) {
211 var shaderArray = [];
212
213 // 当前面对的
214 var i = 0;
215
216 // 获取往后n个值
217 var nextNValue = function (n) {
218 return textString.substring(i, n + i > textString.length ? textString.length : n + i);
219 };
220
221 var template = "";
222
223 // 初始化模板,开始文本捕获
224 var initTemplate = function () {
225 if (template != "") {
226
227 // 考虑开始的(s
228 if (template[0] == '(') {
229 shaderArray.push({
230 color: colors.border,
231 content: "("
232 });
233 template = template.substr(1);
234 }
235
236 shaderArray.push({
237 color: colors.text,
238 content: template
239 });
240 }
241
242 template = "";
243 };
244
245 while (true) {
246
247 /* 1.注释1 */
248
249 if (nextNValue(2) == '/*') {
250
251 initTemplate();
252 while (nextNValue(2) !== '*/' && i < textString.length) {
253 template += textString[i++];
254 }
255
256 shaderArray.push({
257 color: colors.annotation,
258 content: template + nextNValue(2)
259 });
260 i += 2;
261 template = "";
262
263 }
264
265 /* 2.注释2 */
266
267 else if (nextNValue(2) == '//') {
268 initTemplate();
269 while (nextNValue(1) !== '\n' && i < textString.length) {
270 template += textString[i++];
271 }
272 shaderArray.push({
273 color: colors.annotation,
274 content: template
275 });
276 template = "";
277 }
278
279 /* 3.字符串 */
280
281 else if (["'", '"', '`'].indexOf(nextNValue(1)) > -1) {
282
283
284
285 var strBorder = nextNValue(1);
286 initTemplate();
287
288 do {
289 template += textString[i++];
290 } while (nextNValue(1) != strBorder && i < textString.length)
291
292 // 因为可能是没有字符导致的结束
293 if (nextNValue(1) != strBorder) {
294 strBorder = "";
295 } else {
296 i += 1;
297 }
298
299 shaderArray.push({
300 color: colors.string,
301 content: template + strBorder
302 });
303 template = "";
304
305 }
306
307
308 /* 4.函数定义 */
309
310 else if (nextNValue(1) == '(' && (template[0] == ' ' || (i - template.length - 1 >= 0 && textString[i - template.length - 1] == " "))) {
311 shaderArray.push({
312 color: colors.tag,
313 content: template
314 });
315 i += 1;
316 template = "(";
317
318 }
319
320 /* 5.方法调用 */
321
322 else if (nextNValue(1) == '(') {
323
324 shaderArray.push({
325 color: colors.attr,
326 content: template
327 });
328 i += 1;
329 template = "(";
330 }
331
332 /* 6.边界 */
333
334 else if ([";", '{', '}', '(', ')', '.', '\n', '=', '+', '>', '<', '[', ']', '-', '*', '/', '^', '*', '!'].indexOf(nextNValue(1)) > -1) {
335
336 initTemplate();
337 shaderArray.push({
338 color: colors.border,
339 content: nextNValue(1)
340 });
341 template = "";
342 i += 1;
343 }
344
345 /* 7.关键字 */
346
347 else if (nextNValue(1) == ' ' && keyWords.indexOf(template.trim()) > -1) {
348
349 shaderArray.push({
350 color: colors.key,
351 content: template + " "
352 });
353 template = "";
354 i += 1;
355
356 }
357
358 /* 追加字符 */
359
360 else {
361 if (i >= textString.length) {
362 initTemplate();
363 break;
364 } else {
365 template += textString[i++];
366 }
367 }
368
369 }
370
371 return shaderArray;
372 }
373
374
375 /**
376 * HTML着色器
377 */
378
379 function HTML_shader(textString) {
380
381 var colors = {
382 "annotation": "#6a9955",/*注释颜色*/
383 "border": "#ffffff",/*边界颜色*/
384 "tag": "#1e50b3",/*结点颜色*/
385 "attr": "#1e83b1",/*属性颜色*/
386 "string": "#ac4c1e",/*字符串颜色*/
387 "key": "#ff0000"/*关键字颜色*/
388 };
389
390 var shaderArray = [];
391
392 // 当前面对的
393 var i = 0;
394
395 // 获取往后n个值
396 var nextNValue = function (n) {
397 return textString.substring(i, n + i > textString.length ? textString.length : n + i);
398 };
399
400 var template = "";
401
402 // 初始化模板,开始文本捕获
403 var initTemplate = function () {
404 if (template != "") {
405 shaderArray.push({
406 color: colors.text,
407 content: template
408 });
409 }
410
411 template = "";
412 };
413
414 // 匹配属性值模板
415 var getAttrValueTemplate = function () {
416 var endStr = " ";
417 // 寻找属性值边界
418 if (nextNValue(1) == '"') endStr = '"';
419 if (nextNValue(1) == "'") endStr = "'";
420
421 // 到达边界前一直寻找下一个
422 do {
423 template += textString[i++];
424 } while (nextNValue(1) != endStr && i < textString.length);
425
426 // 如果是匹配成功而不是匹配到末尾
427 if (endStr != " " && i < textString.length) {
428 template += endStr;
429 i += 1;
430 }
431
432 shaderArray.push({
433 color: colors.string,
434 content: template
435 });
436 template = "";
437 };
438
439 while (true) {
440
441 /* 1.注释 */
442
443 if (nextNValue(4) == '<!--') {
444
445 initTemplate();
446 while (nextNValue(3) !== '-->' && i < textString.length) {
447 template += textString[i++];
448 }
449
450 shaderArray.push({
451 color: colors.annotation,
452 content: template + nextNValue(3)
453 });
454 i += 3;
455 template = "";
456
457 }
458
459 /* 2.</ */
460
461 else if (nextNValue(2) == '</') {
462
463 initTemplate();
464 shaderArray.push({
465 color: colors.border,
466 content: "</"
467 });
468 i += 2;
469
470 while (nextNValue(1) !== '>' && i < textString.length) {
471 template += textString[i++];
472 }
473
474 if (template != "") {
475 shaderArray.push({
476 color: colors.tag,
477 content: template
478 });
479 template = "";
480
481 if (i < textString.length) {
482 shaderArray.push({
483 color: colors.border,
484 content: ">"
485 });
486 i += 1;
487 }
488
489 }
490 }
491
492 /* 3.< */
493
494 else if (nextNValue(1) == '<' && nextNValue(2) != '< ') {
495
496 var specialTag = "";
497
498 initTemplate();
499 shaderArray.push({
500 color: colors.border,
501 content: "<"
502 });
503 i += 1;
504
505 // 寻找标签名称
506 while (nextNValue(1) != '>' && nextNValue(1) != ' ' && i < textString.length) {
507 template += textString[i++];
508 }
509 if (template != '') {
510
511 // 针对style和script这样特殊的标签,内部需要调用对应的着色器着色
512 if (template == "style" || template == 'script') {
513 specialTag = "</" + template + ">";
514 }
515
516 shaderArray.push({
517 color: colors.tag,
518 content: template
519 });
520
521 template = '';
522 if (i < textString.length) {
523
524 // 寻找标签属性
525 while (i < textString.length) {
526
527 // 遇到这个表示标签结束了
528 // 也就意味着标签匹配结束
529 if (nextNValue(1) == ">") {
530
531 initTemplate();
532 shaderArray.push({
533 color: colors.border,
534 content: ">"
535 });
536 i += 1;
537 break;
538 }
539
540 // 如果是空格,表示是属性之间,接着查看下一个即可
541 else if (nextNValue(1) != ' ') {
542
543 initTemplate();
544
545 // 匹配属性名称
546 if (nextNValue(1) != '"' && nextNValue(1) != "'") {
547
548 // 如果不是=或>和空格就继续
549 while (nextNValue(1) != "=" && nextNValue(1) != '>' && i < textString.length && nextNValue(1) != " ") {
550 template += textString[i++];
551 }
552 if (template != "") {
553 shaderArray.push({
554 color: colors.attr,
555 content: template
556 });
557 template = "";
558
559 // 如果下一个是=,就接着找属性值
560 if (nextNValue(1) == '=') {
561 shaderArray.push({
562 color: colors.text,
563 content: "="
564 });
565 i += 1;
566
567
568 if (i < textString.length && nextNValue(1) != " " && nextNValue(1) != '>') {
569 // 寻找属性值
570 getAttrValueTemplate();
571
572 }
573 }
574 } else {
575 template += textString[i++];
576 }
577 } else if (nextNValue(1) == '=') {
578 shaderArray.push({
579 color: colors.text,
580 content: "="
581 });
582 i += 1;
583 } else {
584 if (i < textString.length && nextNValue(1) != " " && nextNValue(1) != '>') {
585
586 getAttrValueTemplate();
587
588 }
589 }
590
591 } else {
592 template += textString[i++];
593 }
594
595 }
596
597 }
598
599 }
600
601 if (specialTag != "") {
602
603 var oldI = i, oldTemplate = template;
604 while (nextNValue(specialTag.length) != specialTag && i < textString.length) {
605 template += textString[i++];
606 }
607
608 if (i < textString.length) {
609
610 var innerShaderArray = {
611 "style>": _inner_CSS_shader,
612 "script>": _inner_ES_shader
613 }[specialTag.replace(/<\//, '')](template, colors);
614
615 innerShaderArray.forEach(innerShader => {
616 shaderArray.push(innerShader);
617 });
618
619 template = "";
620 } else {
621 template = oldTemplate;
622 i = oldI;
623 }
624
625 }
626
627 }
628
629 /* 追加字符 */
630
631 else {
632 if (i >= textString.length) {
633 initTemplate();
634 break;
635 } else {
636 template += textString[i++];
637 }
638 }
639
640 }
641
642 return toShaderReult(shaderArray);
643
644 }
645 </script>
646
647</head>
648
649<body>
650
651 <a href="https://github.com/yelloxing/Web-Studio-Code" class='github' target="_blank">Fork me on Github</a>
652
653 <div id="wscode"></div>
654
655 <script>
656 window.wscode = new WSCode({
657
658 // 编辑器挂载点
659 el: document.getElementById('wscode'),
660
661 // 设置字体
662 "font-family": "serif",
663
664 // 设置字重
665 "font-weight": 800,
666
667 // 设置tab代表多少空格
668 tabSpace: 2,
669
670 // 着色器
671 shader: HTML_shader,
672
673 // 初始化文本
674 content: "<html lang=\"zh-cn\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Example | Web Studio Code</title>\n <style>\n /*css样式*/\n body {\n margin: 0px;\n }\n </style>\n</head>\n<body>\n <script>\n\n /*js代码*/\n function doit() {\n console.log('你好,世界!');\n }\n\n \</script\>\n</body>\n</html>\n\n<!-- Developed by 心叶(yelloxing@gmail.com) -->"
675 });
676
677 console.log(wscode);
678
679 // 通过这个钩子,可以监听编辑器数据的改变
680 wscode.updated(function(){
681 console.log('数据更新了'+new Date());
682 });
683
684 </script>
685
686</body>
687
688</html>