-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
572 lines (547 loc) · 21.9 KB
/
Copy pathmain.js
File metadata and controls
572 lines (547 loc) · 21.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
"ui";
//这是最后一个测试版。
importClass(android.view.KeyEvent);
importClass(android.webkit.WebView);
importClass(android.webkit.WebChromeClient);
importClass(android.webkit.WebResourceResponse);
importClass(android.webkit.WebViewClient);
importClass(android.widget.EditText);
importClass(android.text.InputType);
var info_size = 35;
var pack_size = 2;
var color = "#009688";
var running = false;
var path = "/storage/emulated/0/HTMLcodeedit/";
var htmlcode, csscode, jscode, pj; //pj: project
var not_enabled = false;
var seted1 = false,
seted2 = false;
var storage = storages.create("html_code_edit");
ui.statusBarColor(color);
var scroll_to_where = 0;
function mainui(html, css, js, pjname) {
ui.layout(
<frame bg="{{color}}">
<vertical gravity="bottom" id="info">
<linear bg="#000000" h="{{info_size}}" id="_info">
<text text="" id="info_text" color="#ffffff" h="{{info_size}}" textSize="20sp" gravity="center"/>
</linear>
</vertical>
<scroll margin="8 {{info_size}}" id="scroll">
<vertical bg="#ffffff" padding="8">
<linear>
<text text="项目名称:" id="pjname_text" textSize="20sp"/>
<input text="pj" id="pjname" w="*" singleLine="true"/>
</linear>
<linear>
<text text="HTML代码区:" textSize="20sp" color="{{color}}"/>
</linear>
<linear>
<EditText hint="HTML" w="*" id="htmlcode" layout_width="match_parent"/>
</linear>
<linear>
<text text="CSS代码区:" textSize="20sp" color="{{color}}"/>
</linear>
<linear>
<EditText hint="CSS" w="*" id="csscode"/>
</linear>
<linear>
<text text="JavaScript代码区:" textSize="20sp" color="{{color}}"/>
</linear>
<linear>
<EditText hint="JavaScript" w="*" id="jscode"/>
</linear>
</vertical>
</scroll>
<vertical gravity="top" margin="8 0">
<linear bg="{{color}}" gravity="right">
<img text="运行代码" bg="?selectableItemBackground" h="35" tint="#ffffff" src="@drawable/ic_play_arrow_black_48dp" id="runcode"/>
<img text="保存代码" bg="?selectableItemBackground" h="35" tint="#ffffff" src="@drawable/ic_save_black_48dp" id="savecode"/>
<img text="新建代码" bg="?selectableItemBackground" h="35" tint="#ffffff" src="@drawable/ic_note_add_black_48dp" id="newcode"/>
<img text="打开代码" bg="?selectableItemBackground" h="35" tint="#ffffff" src="@drawable/ic_folder_open_black_48dp" id="opencode"/>
<img text="字体" bg="?selectableItemBackground" h="35" tint="#ffffff" src="@drawable/ic_text_fields_black_48dp" id="ttf_set"/>
<img text="关于" h="35" bg="?selectableItemBackground" tint="#ffffff" src="@drawable/ic_help_outline_black_48dp" id="about"/>
</linear>
</vertical>
<vertical gravity="top" margin="16 0">
<linear gravity="left">
<text text="HTML Code Edit" h="35" gravity="center" color="#ffffff" textSize="20sp"/>
</linear>
</vertical>
</frame>
);
function setFont_(i) {
var tf;
switch (i) {
case 0:
tf = android.graphics.Typeface.createFromFile(java.io.File(files.path("./consolas.ttf")));
break;
case 1:
tf = android.graphics.Typeface.createFromFile(java.io.File(files.path("./intel-one-mono.ttf")));
break;
}
if (tf == undefined) {
return;
}
ui.htmlcode.setTypeface(tf);
ui.jscode.setTypeface(tf);
ui.csscode.setTypeface(tf);
fontId = i;
storage.put("fontId", i);
}
ui.info.visibility = 8;
ui.htmlcode.setText(html);
ui.csscode.setText(css);
ui.jscode.setText(js);
ui.pjname.setText(pjname);
ui.pjname.setEnabled(!not_enabled);
pj = pjname;
//禁用底部横线
ui.htmlcode.setBackgroundColor(android.graphics.Color.TRANSPARENT);
ui.csscode.setBackgroundColor(android.graphics.Color.TRANSPARENT);
ui.jscode.setBackgroundColor(android.graphics.Color.TRANSPARENT);
ui.pjname.setBackgroundColor(android.graphics.Color.TRANSPARENT);
//禁用自动换行
ui.htmlcode.setHorizontallyScrolling(true);
ui.jscode.setHorizontallyScrolling(true);
ui.csscode.setHorizontallyScrolling(true);
//设置字体
var fontId = storage.get("fontId");
if (fontId == null) {
fontId = 0;
}
setFont_(fontId);
//添加事件
ui.runcode.on("click", () => {
if (isValidFolderName(ui.pjname.getText())) {
scroll_to_where = ui.scroll.getScrollY();
log(scroll_to_where.toString());
running = true;
savecode(ui);
not_enabled = true;
ui.pjname.setEnabled(false);
htmlcode = ui.htmlcode.getText() + "";
csscode = ui.csscode.getText() + "";
jscode = ui.jscode.getText() + "";
pj = ui.pjname.getText() + "";
view_html(htmlcode, csscode, jscode);
show_info("开始运行(已保存代码)");
} else {
alert("项目名称不合法,不能保存并运行", "目前支持大小写字母、数字,下划线和汉字")
}
});
ui.savecode.on("click", () => {
if (isValidFolderName(ui.pjname.getText())) {
savecode(ui);
not_enabled = true;
ui.pjname.setEnabled(false);
toast("文件保存成功!\n\nHTML文件已保存到" + path + ui.pjname.getText() + "/main.html\n\nCSS文件已保存到" + path + ui.pjname.getText() + "/css.css\n\nJS文件已保存到" + path + ui.pjname.getText() + "/js.js");
if (storage.get("do_not_show_save_dialog") == true) {
return;
}
dialogs.build({
title: "养成好习惯",
content: "勤于手动保存代码,以避免意外导致代码丢失。\n\n虽然自动保存也能为您保存代码,但遇到非正常退出(被一键加速清理掉、没电关机、程序卡死等),那就无能为力了。",
positive: "知道了",
checkBoxPrompt: "不再提示"
}).on("positive", (win) => {
win.dismiss();
}).on("check", (checked) => {
storage.put("do_not_show_save_dialog", checked)
}).show();
} else {
alert("保存失败:项目名称不合法", "目前支持大小写字母、数字,下划线和汉字")
}
});
ui.newcode.on("click", () => {
if (!is_save()) {
dialogs.confirm("提示", "您的代码还未保存,确定创建新的项目?", function(b) {
if (b) {
new_code();
not_enabled = false;
ui.pjname.setEnabled(true);
show_info("创建项目成功,但没有保存到本地")
}
});
} else {
new_code();
not_enabled = false;
ui.pjname.setEnabled(true);
show_info("创建项目成功,但没有保存到本地");
}
});
ui.opencode.on("click", () => {
if (!is_save()) {
dialogs.confirm("提示", "您的代码还未保存,确定打开以前的项目?", function(b) {
if (!b) {
return;
} else {
open_pj();
}
});
} else {
open_pj();
}
});
ui.ttf_set.click(function() {
var ttf_list = ["Consolas", "Inter One Mono"];
dialogs.singleChoice("更改字体", ttf_list, fontId, setFont_)
});
if (!seted1) {
seted1 = true;
ui.emitter.on("back_pressed", (event) => {
if (running || is_save()) {
return;
}
event.consumed = true;
confirm("HTML Code Edit", "提示:您的代码还未保存,确定要退出吗?", function(b) {
if (b) {
ui.finish();
}
});
//savecode(ui);
//toast("即将退出。已经保存代码。");
});
}
ui.about.on("click", () => {
alert("关于", "HTML Code Edit\n v0.1.0 beta(测试版)\n 基于Auto.js开发\n\n因为是测试版,bug也是有的。\n遇到bug请联系开发者。");
});
ui.pjname_text.on("click", () => {
if (!ui.pjname.isEnabled()) {
alert("提示", "为了您代码的安全,以及避免HTML Code Edit读取代码文件夹出问题,所以代码一经保存,不可修改项目名称。\n\n如要修改项目名称,请在创建项目后、第一次保存代码之前进行修改。\n\n为您带来不便,请谅解!")
}
});
ui.pjname.addTextChangedListener({
onTextChanged: function(text) {
if (!isValidFolderName(text)) {
ui.pjname.setError("项目名称不合法");
}
}
});
ui.scroll.setScrollY(scroll_to_where);
return text;
}
function isValidFolderName(folderName) {
// 判断文件夹名是否为空
if (folderName + "" === "") {
return false;
}
// 定义合法文件夹名的正则表达式
var regex = /^[a-zA-Z0-9\u4E00-\u9FA5_-_]+$/;
// 使用正则表达式进行匹配
var isMatch = regex.test(folderName);
// 返回匹配结果
return isMatch;
}
function getpj(name) {
let data = [];
try {
var p = files.join(path, name);
var f = open(files.join(p, "data.json"), "r")
var data = JSON.parse(f.read());
f.close();
var html = files.join(p, data.html);
var css = files.join(p, data.css);
var js = files.join(p, data.js);
var name = data.name;
var hc, cc, jc;
f = open(html, "r");
hc = f.read();
f.close();
f = open(css, "r");
cc = f.read();
f.close();
f = open(js, "r");
jc = f.read();
f.close();
data[0] = hc;
data[1] = cc;
data[2] = jc;
data[3] = name;
return data;
} catch (err) {
log(err);
return null;
}
}
function open_pj() {
let alldir = files.listDir(path);
let pjs = ["取消"];
var j = 1;
if (alldir.length == 0) {
alert("还没有项目!请创建一个!");
return;
}
for (var i = 0; i < alldir.length; i++) {
var p = files.join(path, alldir[i]);
if (files.isDir(p)) {
if (files.exists(files.join(p, "data.json"))) {
var f = open(files.join(p, "data.json"), "r")
try {
var data = JSON.parse(f.read());
var html = files.join(p, data.html);
var css = files.join(p, data.css);
var js = files.join(p, data.js);
var name = data.name;
} catch (err) {
f.close();
log(err);
continue;
}
//log(html);
if (files.exists(html) && files.exists(css) && files.exists(css)) {
pjs[j] = name;
j++;
}
}
}
}
if (pjs.length == 1) {
alert("还没有项目!请创建一个!");
return;
}
dialogs.singleChoice("打开项目", pjs).then(pjn => {
if (pjn == 0 || pjn == -1) {
return;
}
show_info("正在打开“" + pjs[pjn] + "”,请稍后……");
threads.start(function() {
let data = getpj(pjs[pjn]);
if (data == null || pjs[pjn] != data[3]) {
show_info("无法打开项目“" + pjs[pjn] + "”,项目配置文件损坏!");
return;
}
htmlcode = data[0];
csscode = data[1];
jscode = data[2];
pj = data[3];
ui.run(() => {
ui.htmlcode.setText(htmlcode);
ui.csscode.setText(csscode);
ui.jscode.setText(jscode);
ui.pjname.setText(data[3]);
ui.pjname.setEnabled(false);
});
storage.put("open_pj_name", data[3]);
show_info("打开“" + pjs[pjn] + "”完成");
});
});
}
function new_code() {
var t = new Date().getTime();
htc = "<!--TODO:请在这里写上您的HTML代码。-->\n<!--这里提供了一些HTML的基本框架,您可以在此基础上加以修改。-->\n\n<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<title>hello</title>\n\t</head>\n\t<body>\n\t\t<p>hello</p>\n\t</body>\n</html>";
csc = "/*TODO:请在这里写上您的CSS代码。*/\n\n";
jsc = "/*TODO:请在这里写上您的JavaScript代码。*/\n\n";
mainui(htc, csc, jsc, "html_project_" + t); //"HELLO_HTML_Code_Edit");
htmlcode = htc, csscode = csc, jscode = jsc;
}
function is_save() {
return (ui.htmlcode.getText() + "") == htmlcode && (ui.csscode.getText() + "") == csscode && (ui.jscode.getText() + "") == jscode && (ui.pjname.getText() + "") == pj;
}
function savemycode(html, css, js, name) {
var p = path + name + "/";
files.ensureDir(p);
var f = open(p + "main.html", "w");
f.write(html);
f.close();
f = open(p + "css.css", "w");
f.write(css);
f.close();
f = open(p + "js.js", "w");
f.write(js);
f.close();
f = open(p + "data.json", "w");
data = {
html: "main.html",
css: "css.css",
js: "js.js",
name: name
}
f.write(JSON.stringify(data));
f.close();
storage.put("open_pj_name", name);
htmlcode = html, csscode = css, jscode = js;
}
function savecode(ui) {
try {
savemycode(ui.htmlcode.getText() + "", ui.csscode.getText() + "", ui.jscode.getText() + "", ui.pjname.getText() + "");
} catch (err) {
log(err);
savemycode(htmlcode, csscode, jscode, pj)
}
}
//log(JSON.parse('{"hello":"6"}').hello);
//log(JSON.stringify({hello:"6"}));
function show_info(s) {
threads.start(function() {
ui.run(() => {
ui.info_text.setText(" " + s);
ui.info.visibility = 0;
});
sleep(1000);
ui.run(() => {
ui.info.visibility = 8;
});
});
}
var htc, csc, jsc;
var open_pj_name = storage.get("open_pj_name");
if (open_pj_name == null) {
new_code();
} else {
var data = getpj(open_pj_name);
if (data == null) {
new_code();
} else {
mainui(data[0], data[1], data[2], data[3]);
ui.pjname.setEnabled(false);
}
}
show_info("欢迎使用");
function view_html(h, c, j) { //h:html,c:css,j:JavaScript
var code = "";
//code = '<meta name="viewport" content="minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,initial-scale=1.0" /><script>document.documentElement.style.overflow=\'hidden\'; document.body.style.overflow=\'hidden\';</script><style>html{overflow-x:hidden;/* 隐藏滚动条 */}</style>';
code = '<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">';
//var s = code + h + '<style>' + c + '</style><script>' + j + '</script>';
p = path + pj + "/run_temp.html";
f = open(p, "w")
f.writeline(code);
f.writeline(h);
f.writeline("<style>" + c + "</style>");
f.writeline("<script>" + j + "</script>");
f.close()
runui(); //启动运行界面
ui.run_view.loadUrl("file://" + p);
}
function runui() {
ui.layout(
<frame bg="{{color}}" id="f">
<horizontal gravity="center">
<webview id="run_view" h="*" margin="16 {{info_size}}"/>
</horizontal>
<vertical margin="16 {{info_size}}" layout_gravity="top" bg="#ffffff" w="*" h="*" id="ui_console_box">
<ScrollView padding="8">
<text text="" id="ui_console" color="#000000" textSize="16sp"/>
</ScrollView>
</vertical>
<vertical gravity="bottom" id="info">
<linear bg="#000000" h="{{info_size}}">
<text text="" id="info_text" color="#ffffff" h="{{info_size}}" textSize="20sp" gravity="center"/>
</linear>
</vertical>
<vertical margin="16 0">
<linear>
<img text="返回" bg="?selectableItemBackground" margin="{{pack_size}} 0" id="back" tint="#ffffff" src="@drawable/ic_arrow_back_black_48dp" w="{{info_size}}" h="{{info_size}}"/>
<img text="刷新" bg="?selectableItemBackground" margin="{{pack_size}} 0" id="refresh" tint="#ffffff" src="@drawable/ic_replay_black_48dp" w="{{info_size}}" h="{{info_size}}"/>
<img text="清空" bg="?selectableItemBackground" margin="{{pack_size}} 0" id="del_all_msg" tint="#ffffff" src="@drawable/ic_delete_black_48dp" w="{{info_size}}" h="{{info_size}}"/>
<img text="复制" bg="?selectableItemBackground" margin="{{pack_size}} 0" id="copy_msg" tint="#ffffff" src="@drawable/ic_content_copy_black_48dp" w="{{info_size}}" h="{{info_size}}"/>
</linear>
</vertical>
<vertical margin="16 0">
<linear>
<text text="无标题" gravity="center" id="view_title" color="#ffffff" w="*" textSize="{{info_size-10}}sp" h="{{info_size}}"/>
</linear>
</vertical>
<vertical margin="16 0">
<linear gravity="right">
<img text="终端" bg="?selectableItemBackground" margin="{{pack_size}} 0" id="show_console" tint="#ffffff" src="@drawable/ic_personal_video_black_48dp" w="{{info_size}}" h="{{info_size}}"/>
</linear>
</vertical>
</frame>
);
var console_mode = false;
var web_title = "无标题";
ui.info.visibility = 8;
ui.ui_console_box.visibility = 8;
ui.del_all_msg.visibility = 8;
ui.copy_msg.visibility = 8;
function show_console_func() {
console_mode = !console_mode;
ui.ui_console_box.visibility = 8 - ui.ui_console_box.visibility;
ui.del_all_msg.visibility = ui.ui_console_box.visibility;
ui.copy_msg.visibility = ui.del_all_msg.visibility;
ui.run_view.visibility = 8 - ui.ui_console_box.visibility;
ui.refresh.visibility = ui.run_view.visibility;
ui.back.visibility = ui.run_view.visibility;
if (console_mode) {
ui.view_title.setText("终端");
show_info("打开终端");
} else {
ui.view_title.setText("页面:" + web_title);
show_info("关闭终端");
}
}
var webcc = new JavaAdapter(WebChromeClient, {
onConsoleMessage: function(consoleMessage) {
function timestampToTime(timestamp) {
var date = new Date(timestamp);
var Y = date.getFullYear() + '/';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '/';
var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()) + ".";
var ms = date.getMilliseconds() < 100 ? ((date.getMilliseconds() < 10) ? ('00' + date.getMilliseconds()) : ('0' + date.getMilliseconds())) : date.getMilliseconds();
return Y + M + D + h + m + s + ms;
}
ui.ui_console.setText(ui.ui_console.getText() + timestampToTime(Date.parse(new Date()) + ((new Date().getTime()) % 1000)) + ": " + consoleMessage.message() + "\n");
},
onReceivedTitle: function(view, title) {
if (title != null) {
web_title = title;
if (!console_mode) {
ui.view_title.setText("页面:" + title);
}
} else {
web_title = "无标题";
if (!console_mode) {
ui.view_title.setText("无标题");
}
}
},
});
ui.run_view.setWebChromeClient(webcc);
ui.back.on("click", () => {
running = false;
mainui(htmlcode, csscode, jscode, pj);
show_info("运行结束");
});
ui.refresh.on("click", () => {
//dialogs.confirm("确认", "要刷新页面吗?", function(b) {
// if (b) {
view_html(htmlcode, csscode, jscode);
show_info("刷新页面");
// }
//});
});
ui.del_all_msg.on("click", () => {
ui.ui_console.setText("");
show_info("清空终端");
});
ui.copy_msg.on("click", () => {
setClip(ui.ui_console.getText() + "");
show_info("已复制");
});
ui.show_console.on("click", show_console_func);
if (!seted2) {
seted2 = true;
ui.emitter.on("back_pressed", (event) => {
if (!running) {
return;
}
event.consumed = true;
if (ui.ui_console_box.visibility == 0) {
show_console_func();
return;
}
if (ui.run_view.canGoBack()) {
ui.run_view.goBack()
return;
} else {
running = false;
mainui(htmlcode, csscode, jscode, pj);
show_info("运行结束");
}
});
}
}