pinokiod 3.51.0 → 3.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/kernel/gitconfig_template +3 -1
  2. package/kernel/index.js +65 -43
  3. package/kernel/peer.js +21 -8
  4. package/kernel/router/index.js +10 -10
  5. package/kernel/router/localhost_static_router.js +3 -0
  6. package/kernel/router/peer_static_router.js +1 -0
  7. package/kernel/scripts/git/create +1 -2
  8. package/kernel/scripts/git/push +1 -1
  9. package/package.json +6 -2
  10. package/server/index.js +178 -87
  11. package/server/public/common.js +0 -13
  12. package/server/public/serve/directory.html +106 -0
  13. package/server/public/serve/icons/application_xp.png +0 -0
  14. package/server/public/serve/icons/application_xp_terminal.png +0 -0
  15. package/server/public/serve/icons/box.png +0 -0
  16. package/server/public/serve/icons/cd.png +0 -0
  17. package/server/public/serve/icons/controller.png +0 -0
  18. package/server/public/serve/icons/drive.png +0 -0
  19. package/server/public/serve/icons/film.png +0 -0
  20. package/server/public/serve/icons/folder.png +0 -0
  21. package/server/public/serve/icons/font.png +0 -0
  22. package/server/public/serve/icons/image.png +0 -0
  23. package/server/public/serve/icons/map.png +0 -0
  24. package/server/public/serve/icons/page.png +0 -0
  25. package/server/public/serve/icons/page_add.png +0 -0
  26. package/server/public/serve/icons/page_attach.png +0 -0
  27. package/server/public/serve/icons/page_code.png +0 -0
  28. package/server/public/serve/icons/page_copy.png +0 -0
  29. package/server/public/serve/icons/page_delete.png +0 -0
  30. package/server/public/serve/icons/page_edit.png +0 -0
  31. package/server/public/serve/icons/page_error.png +0 -0
  32. package/server/public/serve/icons/page_excel.png +0 -0
  33. package/server/public/serve/icons/page_find.png +0 -0
  34. package/server/public/serve/icons/page_gear.png +0 -0
  35. package/server/public/serve/icons/page_go.png +0 -0
  36. package/server/public/serve/icons/page_green.png +0 -0
  37. package/server/public/serve/icons/page_key.png +0 -0
  38. package/server/public/serve/icons/page_lightning.png +0 -0
  39. package/server/public/serve/icons/page_link.png +0 -0
  40. package/server/public/serve/icons/page_paintbrush.png +0 -0
  41. package/server/public/serve/icons/page_paste.png +0 -0
  42. package/server/public/serve/icons/page_red.png +0 -0
  43. package/server/public/serve/icons/page_refresh.png +0 -0
  44. package/server/public/serve/icons/page_save.png +0 -0
  45. package/server/public/serve/icons/page_white.png +0 -0
  46. package/server/public/serve/icons/page_white_acrobat.png +0 -0
  47. package/server/public/serve/icons/page_white_actionscript.png +0 -0
  48. package/server/public/serve/icons/page_white_add.png +0 -0
  49. package/server/public/serve/icons/page_white_c.png +0 -0
  50. package/server/public/serve/icons/page_white_camera.png +0 -0
  51. package/server/public/serve/icons/page_white_cd.png +0 -0
  52. package/server/public/serve/icons/page_white_code.png +0 -0
  53. package/server/public/serve/icons/page_white_code_red.png +0 -0
  54. package/server/public/serve/icons/page_white_coldfusion.png +0 -0
  55. package/server/public/serve/icons/page_white_compressed.png +0 -0
  56. package/server/public/serve/icons/page_white_copy.png +0 -0
  57. package/server/public/serve/icons/page_white_cplusplus.png +0 -0
  58. package/server/public/serve/icons/page_white_csharp.png +0 -0
  59. package/server/public/serve/icons/page_white_cup.png +0 -0
  60. package/server/public/serve/icons/page_white_database.png +0 -0
  61. package/server/public/serve/icons/page_white_delete.png +0 -0
  62. package/server/public/serve/icons/page_white_dvd.png +0 -0
  63. package/server/public/serve/icons/page_white_edit.png +0 -0
  64. package/server/public/serve/icons/page_white_error.png +0 -0
  65. package/server/public/serve/icons/page_white_excel.png +0 -0
  66. package/server/public/serve/icons/page_white_find.png +0 -0
  67. package/server/public/serve/icons/page_white_flash.png +0 -0
  68. package/server/public/serve/icons/page_white_freehand.png +0 -0
  69. package/server/public/serve/icons/page_white_gear.png +0 -0
  70. package/server/public/serve/icons/page_white_get.png +0 -0
  71. package/server/public/serve/icons/page_white_go.png +0 -0
  72. package/server/public/serve/icons/page_white_h.png +0 -0
  73. package/server/public/serve/icons/page_white_horizontal.png +0 -0
  74. package/server/public/serve/icons/page_white_key.png +0 -0
  75. package/server/public/serve/icons/page_white_lightning.png +0 -0
  76. package/server/public/serve/icons/page_white_link.png +0 -0
  77. package/server/public/serve/icons/page_white_magnify.png +0 -0
  78. package/server/public/serve/icons/page_white_medal.png +0 -0
  79. package/server/public/serve/icons/page_white_office.png +0 -0
  80. package/server/public/serve/icons/page_white_paint.png +0 -0
  81. package/server/public/serve/icons/page_white_paintbrush.png +0 -0
  82. package/server/public/serve/icons/page_white_paste.png +0 -0
  83. package/server/public/serve/icons/page_white_php.png +0 -0
  84. package/server/public/serve/icons/page_white_picture.png +0 -0
  85. package/server/public/serve/icons/page_white_powerpoint.png +0 -0
  86. package/server/public/serve/icons/page_white_put.png +0 -0
  87. package/server/public/serve/icons/page_white_ruby.png +0 -0
  88. package/server/public/serve/icons/page_white_stack.png +0 -0
  89. package/server/public/serve/icons/page_white_star.png +0 -0
  90. package/server/public/serve/icons/page_white_swoosh.png +0 -0
  91. package/server/public/serve/icons/page_white_text.png +0 -0
  92. package/server/public/serve/icons/page_white_text_width.png +0 -0
  93. package/server/public/serve/icons/page_white_tux.png +0 -0
  94. package/server/public/serve/icons/page_white_vector.png +0 -0
  95. package/server/public/serve/icons/page_white_visualstudio.png +0 -0
  96. package/server/public/serve/icons/page_white_width.png +0 -0
  97. package/server/public/serve/icons/page_white_word.png +0 -0
  98. package/server/public/serve/icons/page_white_world.png +0 -0
  99. package/server/public/serve/icons/page_white_wrench.png +0 -0
  100. package/server/public/serve/icons/page_white_zip.png +0 -0
  101. package/server/public/serve/icons/page_word.png +0 -0
  102. package/server/public/serve/icons/page_world.png +0 -0
  103. package/server/public/serve/style.css +308 -0
  104. package/server/public/style.css +13 -5
  105. package/server/public/urldropdown.css +95 -3
  106. package/server/public/urldropdown.js +245 -23
  107. package/server/serveIndex.js +691 -0
  108. package/server/views/app.ejs +305 -89
  109. package/server/views/connect.ejs +3 -0
  110. package/server/views/container.ejs +2 -1
  111. package/server/views/index.ejs +3 -0
  112. package/server/views/init/index.ejs +3 -0
  113. package/server/views/net.ejs +30 -27
  114. package/server/views/network.ejs +23 -70
  115. package/server/views/screenshots.ejs +3 -0
  116. package/server/views/settings.ejs +3 -0
  117. package/server/views/tools.ejs +3 -0
package/server/index.js CHANGED
@@ -23,7 +23,7 @@ const fse = require('fs-extra')
23
23
  const QRCode = require('qrcode')
24
24
  const axios = require('axios')
25
25
  const crypto = require('crypto')
26
- const serveIndex = require('serve-index')
26
+ const serveIndex = require('./serveIndex')
27
27
 
28
28
  const git = require('isomorphic-git')
29
29
  const http = require('isomorphic-git/http/node')
@@ -280,6 +280,52 @@ class Server {
280
280
  }
281
281
  })
282
282
  }
283
+ async processMenu(name, config) {
284
+ let cfg = config
285
+ if (cfg) {
286
+ if (cfg.menu) {
287
+ if (typeof cfg.menu === "function") {
288
+ if (cfg.menu.constructor.name === "AsyncFunction") {
289
+ cfg.menu = await cfg.menu(this.kernel, this.kernel.info)
290
+ } else {
291
+ cfg.menu = cfg.menu(this.kernel, this.kernel.info)
292
+ }
293
+ }
294
+ } else {
295
+ cfg = await this.renderIndex(name)
296
+ }
297
+ } else {
298
+ cfg = await this.renderIndex(name)
299
+ }
300
+ return cfg
301
+ }
302
+ async renderIndex(name) {
303
+ let p = this.kernel.path("api", name)
304
+ let html_path = path.resolve(p, "index.html")
305
+ let html_exists = await this.kernel.exists(html_path)
306
+ console.log({ html_path, html_exists })
307
+ if (html_exists) {
308
+ return {
309
+ title: name,
310
+ menu: [{
311
+ default: true,
312
+ icon: "fa-solid fa-link",
313
+ text: "index.html",
314
+ href: "index.html?raw=true",
315
+ }]
316
+ }
317
+ } else {
318
+ return {
319
+ title: name,
320
+ menu: [{
321
+ default: true,
322
+ icon: "fa-solid fa-link",
323
+ text: "Project Files",
324
+ href: `/files/api/${name}`,
325
+ }]
326
+ }
327
+ }
328
+ }
283
329
  async getGit(ref, filepath) {
284
330
  let dir = this.kernel.path("api", filepath)
285
331
  let branches = await git.listBranches({ fs, dir });
@@ -310,6 +356,14 @@ class Server {
310
356
  remote = config["remote \"origin\""].url
311
357
  }
312
358
 
359
+ // Get all remotes
360
+ let remotes = []
361
+ try {
362
+ remotes = await git.listRemotes({ fs, dir, verbose: true })
363
+ } catch (e) {
364
+ console.log("Remotes error", e)
365
+ }
366
+
313
367
  let branch = await git.currentBranch({ fs, dir, fullname: false });
314
368
 
315
369
  const remote2 = await git.getConfig({
@@ -350,7 +404,7 @@ class Server {
350
404
  }
351
405
  })
352
406
  }
353
- return { ref, config, remote, connected, log, branch, branches, dir }
407
+ return { ref, config, remote, remotes, connected, log, branch, branches, dir }
354
408
  }
355
409
  async init_env(env_dir_path, options) {
356
410
  let current = this.kernel.path(env_dir_path, "ENVIRONMENT")
@@ -455,31 +509,21 @@ class Server {
455
509
  }
456
510
  }
457
511
 
458
- let menu = config.menu || []
459
- try {
460
- if (typeof config.menu === "function") {
461
- if (config.menu.constructor.name === "AsyncFunction") {
462
- config.menu = await config.menu(this.kernel, this.kernel.info)
463
- } else {
464
- config.menu = config.menu(this.kernel, this.kernel.info)
465
- }
466
- }
467
- } catch (e) {
468
- err = e.stack
469
- config.menu = []
470
- }
471
-
472
512
 
473
513
  let uri = this.kernel.path("api")
474
514
  try {
475
515
  let launcher = await this.kernel.api.launcher(name)
476
516
  req.launcher_root = launcher.launcher_root
477
- await this.renderMenu(req, uri, name, config, [])
517
+ config = await this.processMenu(name, config)
478
518
  } catch(e) {
479
519
  config.menu = []
480
520
  err = e.stack
481
521
  }
482
522
 
523
+ console.log("renderMenu before", config)
524
+ await this.renderMenu(req, uri, name, config, [])
525
+ console.log("renderMenu after", config)
526
+
483
527
  let platform = os.platform()
484
528
 
485
529
  await Environment.init({ name }, this.kernel)
@@ -612,11 +656,14 @@ class Server {
612
656
  theme: this.theme,
613
657
  agent: this.agent,
614
658
  src: "/_api/" + name,
615
- asset: "/asset/api/" + name,
659
+ //asset: "/asset/api/" + name,
660
+ asset: "/files/api/" + name,
616
661
  logs: "/_api/" + name + "/logs",
617
662
  execUrl: "/api/" + name,
618
663
  git_monitor_url: `/gitcommit/HEAD/${name}`,
619
664
  git_history_url: `/info/git/HEAD/${name}`,
665
+ git_push_url: `/run/scripts/git/push.json?cwd=${encodeURIComponent(this.kernel.path('api', name))}`,
666
+ git_create_url: `/run/scripts/git/create.json?cwd=${encodeURIComponent(this.kernel.path('api', name))}`
620
667
  // rawpath,
621
668
  }
622
669
  // if (!this.kernel.proto.config) {
@@ -2620,10 +2667,10 @@ class Server {
2620
2667
  getPeers() {
2621
2668
  let list = []
2622
2669
  for(let key in this.kernel.peer.info) {
2623
- if (key !== this.kernel.peer.host) {
2670
+ // if (key !== this.kernel.peer.host) {
2624
2671
  let info = this.kernel.peer.info[key]
2625
2672
  list.push(info)
2626
- }
2673
+ // }
2627
2674
  }
2628
2675
  return list
2629
2676
  }
@@ -2916,14 +2963,26 @@ class Server {
2916
2963
  this.kernel.path("web/views"),
2917
2964
  path.resolve(__dirname, "views")
2918
2965
  ])
2919
- let serve = express.static(this.kernel.homedir, { fallthrough: true })
2966
+ let serve = express.static(this.kernel.homedir, { fallthrough: true, })
2967
+ let serve2 = express.static(this.kernel.homedir, { index: false, fallthrough: true, })
2920
2968
  let http_serve = express.static(this.kernel.homedir, {
2921
2969
  redirect: true,
2922
2970
  })
2923
2971
  let https_serve = express.static(this.kernel.homedir, {
2924
2972
  redirect: false,
2925
2973
  })
2926
- this.app.use('/asset', serve, serveIndex(this.kernel.homedir, {icons: true, hidden: true}))
2974
+ this.app.use('/asset', serve, serveIndex(this.kernel.homedir, {icons: true, hidden: true, theme: this.theme }))
2975
+ // this.app.use("/asset", async (req, res, next) => {
2976
+ // let asset_path = this.kernel.path(req.path.slice(1), "index.html")
2977
+ // let exists = await this.exists(asset_path)
2978
+ // if (exists) {
2979
+ // return res.sendFile(asset_path)
2980
+ // } else {
2981
+ // let chunks = req.path.slice(1).split("/")
2982
+ // let parent_path = chunks.slice(0, -1).join("/")
2983
+ // res.redirect("/asset/" + parent_path)
2984
+ // }
2985
+ // })
2927
2986
  this.app.use('/asset', (req, res, next) => {
2928
2987
  if (req.path.match(/\.(png|jpg|jpeg|gif|ico|svg)$/)) {
2929
2988
  res.sendFile(path.resolve(__dirname, 'public', 'pinokio-black.png'));
@@ -2931,17 +2990,7 @@ class Server {
2931
2990
  next();
2932
2991
  }
2933
2992
  });
2934
- this.app.use("/asset", async (req, res, next) => {
2935
- let asset_path = this.kernel.path(req.path.slice(1), "index.html")
2936
- let exists = await this.exists(asset_path)
2937
- if (exists) {
2938
- return res.sendFile(asset_path)
2939
- } else {
2940
- let chunks = req.path.slice(1).split("/")
2941
- let parent_path = chunks.slice(0, -1).join("/")
2942
- res.redirect("/asset/" + parent_path)
2943
- }
2944
- })
2993
+ this.app.use('/files', serve2, serveIndex(this.kernel.homedir, {icons: true, hidden: true, theme: this.theme }))
2945
2994
  } else {
2946
2995
  this.app.set("views", [
2947
2996
  path.resolve(__dirname, "views")
@@ -3617,7 +3666,19 @@ class Server {
3617
3666
  }))
3618
3667
  this.app.post("/openfs", ex(async (req, res) => {
3619
3668
  //Util.openfs(req.body.path, req.body.mode)
3620
- Util.openfs(req.body.path, req.body, this.kernel)
3669
+ if (req.body.name) {
3670
+ let filepath = this.kernel.path("api", req.body.name)
3671
+ Util.openfs(filepath, req.body, this.kernel)
3672
+ } else if (req.body.asset_path) {
3673
+ // asset_path : /asset/...
3674
+ // relpath : ...
3675
+ let relpath = req.body.asset_path.split("/").filter((x) => { return x }).slice(1).join("/")
3676
+ let filepath = this.kernel.path(relpath)
3677
+ console.log({ filepath, relpath })
3678
+ Util.openfs(filepath, req.body, this.kernel)
3679
+ } else if (req.body.path) {
3680
+ Util.openfs(req.body.path, req.body, this.kernel)
3681
+ }
3621
3682
  res.json({ success: true })
3622
3683
  }))
3623
3684
  this.app.post("/keys", ex(async (req, res) => {
@@ -5442,60 +5503,20 @@ class Server {
5442
5503
  res.send(html)
5443
5504
  }))
5444
5505
  this.app.get("/pinokio/sidebar/:name", ex(async (req, res) => {
5506
+
5507
+ let uri = this.kernel.path("api")
5445
5508
  let name = req.params.name
5446
5509
  let launcher = await this.kernel.api.launcher(name)
5447
- let rawpath = "/api/" + name
5448
5510
  let config = launcher.script
5449
- req.launcher_root = launcher.launcher_root
5450
- if (config && config.menu) {
5451
- if (typeof config.menu === "function") {
5452
- if (config.menu.constructor.name === "AsyncFunction") {
5453
- config.menu = await config.menu(this.kernel, this.kernel.info)
5454
- } else {
5455
- config.menu = config.menu(this.kernel, this.kernel.info)
5456
- }
5457
- }
5458
-
5459
- let uri = this.kernel.path("api")
5460
- await this.renderMenu(req, uri, name, config, [])
5461
- } else {
5462
- // if there is no menu, display all files
5463
- let p = this.kernel.path("api", name)
5464
-
5465
- let html_path = path.resolve(p, "index.html")
5466
- let html_exists = await this.kernel.exists(html_path)
5467
- if (html_exists) {
5468
- config = {
5469
- title: name,
5470
- menu: [{
5471
- default: true,
5472
- icon: "fa-solid fa-link",
5473
- text: "index.html",
5474
- href: "index.html?raw=true",
5475
- }]
5476
- }
5477
- } else {
5478
- let files = await fs.promises.readdir(p, { withFileTypes: true })
5479
- files = files.filter((file) => {
5480
- return file.name.endsWith(".json") || file.name.endsWith(".js")
5481
- }).filter((file) => {
5482
- return file.name !== "pinokio.js" && file.name !== "pinokio.json" && file.name !== "pinokio_meta.json"
5483
- })
5484
- config = {
5485
- title: name,
5486
- menu: files.map((file) => {
5487
- return {
5488
- text: file.name,
5489
- href: file.name
5490
- }
5491
- })
5492
- }
5493
- }
5494
-
5495
- let uri = this.kernel.path("api")
5496
- await this.renderMenu(req, uri, name, config, [])
5511
+ try {
5512
+ let rawpath = "/api/" + name
5513
+ req.launcher_root = launcher.launcher_root
5514
+ config = await this.processMenu(name, config)
5515
+ } catch(e) {
5516
+ config.menu = []
5517
+ err = e.stack
5497
5518
  }
5498
-
5519
+ await this.renderMenu(req, uri, name, config, [])
5499
5520
 
5500
5521
  ejs.renderFile(path.resolve(__dirname, "views/partials/menu.ejs"), { menu: config.menu }, (err, html) => {
5501
5522
  res.send(html)
@@ -5542,11 +5563,81 @@ class Server {
5542
5563
  // }))
5543
5564
 
5544
5565
  this.app.get("/info/procs", ex(async (req, res) => {
5545
- console.time("Refresh")
5546
5566
  await this.kernel.processes.refresh()
5547
- console.timeEnd("Refresh")
5567
+
5568
+ let info = []
5569
+ for(let item of this.kernel.processes.info) {
5570
+ info.push({
5571
+ online: true,
5572
+ host: {
5573
+ ip: this.kernel.peer.host,
5574
+ local: true,
5575
+ name: this.kernel.peer.name,
5576
+ platform: this.kernel.platform,
5577
+ arch: this.kernel.arch,
5578
+ },
5579
+ ...item,
5580
+ })
5581
+ }
5582
+ // get only the parts not from this peer
5583
+ for(let host in this.kernel.peer.info) {
5584
+ let host_info = this.kernel.peer.info[host]
5585
+ let host_rewrites = host_info.rewrite_mapping
5586
+ for(let key in host_rewrites) {
5587
+ info.push({
5588
+ online: true,
5589
+ host: {
5590
+ ip: host,
5591
+ local: this.kernel.peer.host === host,
5592
+ name: host_info.name,
5593
+ platform: host_info.platform,
5594
+ arch: host_info.arch
5595
+ },
5596
+ name: `[Files] ${host_rewrites[key].name}`,
5597
+ ip: host_rewrites[key].external_ip
5598
+ })
5599
+ }
5600
+ if (this.kernel.peer.host !== host) {
5601
+ let host_routers = host_info.router_info
5602
+ for(let host_router of host_routers) {
5603
+ let ip
5604
+ // the peer sharing works only if external_ip is available (caddy is installed)
5605
+ if (host_router.external_ip) {
5606
+ ip = host_router.external_ip
5607
+ } else {
5608
+ // if caddy is not turned on, set ip as null, so that it suggests turning on peer sharing
5609
+ ip = null
5610
+ }
5611
+ info.push({
5612
+ online: true,
5613
+ host: {
5614
+ ip: host,
5615
+ name: host_info.name,
5616
+ platform: host_info.platform,
5617
+ arch: host_info.arch
5618
+ },
5619
+ name: host_router.title || host_router.name,
5620
+ ip
5621
+ })
5622
+ }
5623
+ }
5624
+
5625
+ for(let app of host_info.installed) {
5626
+ info.push({
5627
+ host: {
5628
+ ip: host,
5629
+ local: this.kernel.peer.host === host,
5630
+ name: host_info.name,
5631
+ platform: host_info.platform,
5632
+ arch: host_info.arch
5633
+ },
5634
+ name: app.title || app.folder,
5635
+ ip: app.http_href.replace("http://", "")
5636
+ })
5637
+ }
5638
+ }
5548
5639
  res.json({
5549
- info: this.kernel.processes.info
5640
+ info
5550
5641
  })
5551
5642
  }))
5552
5643
 
@@ -319,7 +319,6 @@ function initTippy() {
319
319
  }
320
320
  });
321
321
  } catch(e) {
322
- console.log(e);
323
322
  }
324
323
  }
325
324
 
@@ -331,13 +330,10 @@ function updateTippyPlacement(instance) {
331
330
 
332
331
  //if (isHeaderElement && isMobileOrMinimized) {
333
332
  if (isMinimized) {
334
- console.log(">1")
335
333
  instance.setProps({ placement: 'right' });
336
334
  } else if (isSidebarTab) {
337
- console.log(">2")
338
335
  instance.setProps({ placement: 'left' });
339
336
  } else {
340
- console.log(">3")
341
337
  instance.setProps({ placement: 'top' });
342
338
  }
343
339
  }
@@ -481,15 +477,6 @@ document.addEventListener("DOMContentLoaded", () => {
481
477
  }
482
478
 
483
479
 
484
- if (document.querySelector(".urlbar")) {
485
- document.querySelector(".urlbar").addEventListener("submit", (e) => {
486
- debugger
487
- e.preventDefault()
488
- e.stopPropagation()
489
- location.href = "/container?url=" + e.target.querySelector("input[type=url]").value
490
- })
491
- }
492
-
493
480
  if (document.querySelector("#genlog")) {
494
481
  document.querySelector("#genlog").addEventListener("click", (e) => {
495
482
  e.preventDefault()
@@ -0,0 +1,106 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6
+ <title>listing directory {directory}</title>
7
+ <style>{style}</style>
8
+ <script>
9
+ function $(id){
10
+ var el = 'string' == typeof id
11
+ ? document.getElementById(id)
12
+ : id;
13
+
14
+ el.on = function(event, fn){
15
+ if ('content loaded' == event) {
16
+ event = window.attachEvent ? "load" : "DOMContentLoaded";
17
+ }
18
+ el.addEventListener
19
+ ? el.addEventListener(event, fn, false)
20
+ : el.attachEvent("on" + event, fn);
21
+ };
22
+
23
+ el.all = function(selector){
24
+ return $(el.querySelectorAll(selector));
25
+ };
26
+
27
+ el.each = function(fn){
28
+ for (var i = 0, len = el.length; i < len; ++i) {
29
+ fn($(el[i]), i);
30
+ }
31
+ };
32
+
33
+ el.getClasses = function(){
34
+ return this.getAttribute('class').split(/\s+/);
35
+ };
36
+
37
+ el.addClass = function(name){
38
+ var classes = this.getAttribute('class');
39
+ el.setAttribute('class', classes
40
+ ? classes + ' ' + name
41
+ : name);
42
+ };
43
+
44
+ el.removeClass = function(name){
45
+ var classes = this.getClasses().filter(function(curr){
46
+ return curr != name;
47
+ });
48
+ this.setAttribute('class', classes.join(' '));
49
+ };
50
+
51
+ return el;
52
+ }
53
+
54
+ function search() {
55
+ var str = $('search').value.toLowerCase();
56
+ var links = $('files').all('a');
57
+
58
+ if (str.length > 0) {
59
+ $('files').addClass("searching")
60
+ } else {
61
+ $('files').removeClass("searching")
62
+ }
63
+
64
+ links.each(function(link){
65
+ var text = link.textContent.toLowerCase();
66
+
67
+ if ('..' == text) return;
68
+ if (str.length && ~text.indexOf(str)) {
69
+ link.addClass('highlight');
70
+ } else {
71
+ link.removeClass('highlight');
72
+ }
73
+ });
74
+ }
75
+
76
+ $(window).on('content loaded', function(){
77
+ $('search').on('keyup', search);
78
+ $("open").on("click", async (e) => {
79
+ console.log("location", location)
80
+ await fetch("/openfs", {
81
+ method: "post",
82
+ headers: {
83
+ "Content-Type": "application/json"
84
+ },
85
+ body: JSON.stringify({
86
+ asset_path: location.pathname,
87
+ mode: "open",
88
+ })
89
+ }).then((res) => {
90
+ return res.json()
91
+ })
92
+ })
93
+ });
94
+
95
+
96
+ </script>
97
+ </head>
98
+ <body class="directory {theme}">
99
+ <button id='open'>Open File Explorer</button>
100
+ <input id="search" type="text" placeholder="Search" autocomplete="off" />
101
+ <div id="wrapper">
102
+ <h1><a href="/">~</a>{linked-path}</h1>
103
+ {files}
104
+ </div>
105
+ </body>
106
+ </html>
Binary file