utils.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Indexable Types
  2. interface Dict {
  3. [index: string]: any;
  4. }
  5. export class LRUMap {
  6. keys: string[] = [];
  7. map: Dict = {};
  8. push(key: string, value: any) {
  9. if (key in this.map)
  10. return console.error("LRUMap: key:%s already in map", key);
  11. this.keys.push(key);
  12. this.map[key] = value;
  13. };
  14. get_value(key: string) {
  15. return this.map[key];
  16. };
  17. get_top() {
  18. let top_key = this.keys[this.keys.length - 1];
  19. return this.map[top_key];
  20. };
  21. set_value(key: string, value: any) {
  22. if (!(key in this.map))
  23. return console.error("LRUMap: key:%s not in map when call `set_value`", key);
  24. this.map[key] = value;
  25. };
  26. move_to_top(key: string) {
  27. const index = this.keys.indexOf(key);
  28. if (index > -1) {
  29. this.keys.splice(index, 1);
  30. this.keys.push(key);
  31. } else {
  32. return console.error("LRUMap: key:%s not in map when call `move_to_top`", key);
  33. }
  34. };
  35. remove(key: string) {
  36. if (key in this.map) {
  37. delete this.map[key];
  38. this.keys.splice(this.keys.indexOf(key), 1);
  39. } else {
  40. return console.error("LRUMap: key:%s not in map when call `remove`", key);
  41. }
  42. };
  43. }
  44. export function b64toBlob(b64Data: string, contentType = 'application/octet-stream', sliceSize = 512) {
  45. const byteCharacters = atob(b64Data);
  46. const byteArrays = [];
  47. for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
  48. const slice = byteCharacters.slice(offset, offset + sliceSize);
  49. const byteNumbers = new Array(slice.length);
  50. for (let i = 0; i < slice.length; i++) {
  51. byteNumbers[i] = slice.charCodeAt(i);
  52. }
  53. const byteArray = new Uint8Array(byteNumbers);
  54. byteArrays.push(byteArray);
  55. }
  56. const blob = new Blob(byteArrays, {type: contentType});
  57. return blob;
  58. }
  59. export function make_set(arr: string[]) {
  60. let set: { [i: string]: string } = {};
  61. for (let val of arr)
  62. set[val] = '';
  63. return set;
  64. }
  65. export function deep_copy(obj: any): any {
  66. return JSON.parse(JSON.stringify(obj));
  67. }
  68. // container 为带有滚动条的元素
  69. export function body_scroll_to(target: JQuery, position = 'top', complete?: (this: HTMLElement) => void, offset = 0) {
  70. let scrollTop = null;
  71. if (position === 'top')
  72. scrollTop = target.offset().top;
  73. else if (position === 'middle')
  74. scrollTop = target.offset().top + 0.5 * target[0].clientHeight - 0.5 * $(window).height();
  75. else if (position === 'bottom')
  76. scrollTop = target[0].clientHeight + target.offset().top - $(window).height();
  77. let container = $('body,html');
  78. let speed = Math.abs(container.scrollTop() - scrollTop - offset);
  79. if (scrollTop !== null)
  80. container.stop().animate({scrollTop: scrollTop + offset}, Math.min(speed, 500) + 100, complete);
  81. }
  82. // container 为带有滚动条的元素
  83. export function box_scroll_to(target: JQuery, container: JQuery, position = 'top', complete?: (this: HTMLElement) => void, offset = 0) {
  84. let scrollTopOffset = null;
  85. if (position === 'top')
  86. scrollTopOffset = target[0].getBoundingClientRect().top - container[0].getBoundingClientRect().top;
  87. else if (position === 'middle')
  88. scrollTopOffset = target[0].getBoundingClientRect().top - container[0].getBoundingClientRect().top - container.height() * 0.5 + target.height() * 0.5;
  89. else if (position === 'bottom')
  90. scrollTopOffset = target[0].getBoundingClientRect().bottom - container[0].getBoundingClientRect().bottom;
  91. let speed = Math.min(Math.abs(scrollTopOffset + offset), 500) + 100;
  92. if (scrollTopOffset !== null)
  93. container.stop().animate({scrollTop: container.scrollTop() + scrollTopOffset + offset}, speed, complete);
  94. }
  95. export function randomid(length: number) {
  96. let result = '';
  97. let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  98. let charactersLength = characters.length;
  99. for (let i = 0; i < length; i++) {
  100. result += characters.charAt(Math.floor(Math.random() * charactersLength));
  101. }
  102. return result;
  103. }
  104. // 跳转PyWebIO Application
  105. // name: app名称
  106. // new_window: 是否在新窗口打开
  107. export function openApp(name: string, new_window: boolean) {
  108. let url = new URL(window.location.href);
  109. url.searchParams.set("app", name);
  110. if (new_window)
  111. window.open(url.href);
  112. else
  113. window.location.href = url.href;
  114. }
  115. export function error_alert(text: string, duration: number = 1.5) {
  116. Toastify({
  117. text: Mustache.escape(text),
  118. duration: duration * 1000,
  119. gravity: "top",
  120. position: 'center',
  121. backgroundColor: '#e53935',
  122. }).showToast();
  123. }