fwtoolkit 0.1.0-alpha.3 → 0.1.0-alpha.6

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 (135) hide show
  1. package/README.md +56 -8
  2. package/css/add_remove_dialog.css +18 -0
  3. package/css/alerts.css +69 -0
  4. package/css/buttons.css +373 -0
  5. package/css/colors.css +118 -0
  6. package/css/common.css +183 -0
  7. package/css/content_menu.css +105 -0
  8. package/css/data_table.css +191 -0
  9. package/css/dialog.css +151 -0
  10. package/css/dialog_table.css +125 -0
  11. package/css/faq_dialog.css +16 -0
  12. package/css/file_selector.css +25 -0
  13. package/css/forms.css +112 -0
  14. package/css/loader.css +38 -0
  15. package/css/overview_menu.css +187 -0
  16. package/css/pulldown.css +114 -0
  17. package/css/ui_dialogs.css +144 -0
  18. package/css/ui_tabs.css +61 -0
  19. package/dist/basic.d.ts +70 -0
  20. package/dist/basic.d.ts.map +1 -0
  21. package/dist/basic.js +447 -0
  22. package/dist/basic.js.map +1 -0
  23. package/dist/blob.d.ts +2 -0
  24. package/dist/blob.d.ts.map +1 -0
  25. package/dist/blob.js +12 -0
  26. package/dist/blob.js.map +1 -0
  27. package/dist/content_menu.d.ts +31 -0
  28. package/dist/content_menu.d.ts.map +1 -0
  29. package/dist/content_menu.js +360 -0
  30. package/dist/content_menu.js.map +1 -0
  31. package/dist/datatable_bulk.d.ts +14 -0
  32. package/dist/datatable_bulk.d.ts.map +1 -0
  33. package/dist/datatable_bulk.js +176 -0
  34. package/dist/datatable_bulk.js.map +1 -0
  35. package/dist/dialog.d.ts +18 -0
  36. package/dist/dialog.d.ts.map +1 -0
  37. package/dist/dialog.js +395 -0
  38. package/dist/dialog.js.map +1 -0
  39. package/dist/events.d.ts +2 -0
  40. package/dist/events.d.ts.map +1 -0
  41. package/dist/events.js +11 -0
  42. package/dist/events.js.map +1 -0
  43. package/dist/faq_dialog.d.ts +8 -0
  44. package/dist/faq_dialog.d.ts.map +1 -0
  45. package/dist/faq_dialog.js +63 -0
  46. package/dist/faq_dialog.js.map +1 -0
  47. package/dist/file/dialog.d.ts +27 -0
  48. package/dist/file/dialog.d.ts.map +1 -0
  49. package/dist/file/dialog.js +125 -0
  50. package/dist/file/dialog.js.map +1 -0
  51. package/dist/file/index.d.ts +5 -0
  52. package/dist/file/index.d.ts.map +1 -0
  53. package/dist/file/index.js +6 -0
  54. package/dist/file/index.js.map +1 -0
  55. package/dist/file/new_folder_dialog.d.ts +5 -0
  56. package/dist/file/new_folder_dialog.d.ts.map +1 -0
  57. package/dist/file/new_folder_dialog.js +34 -0
  58. package/dist/file/new_folder_dialog.js.map +1 -0
  59. package/dist/file/selector.d.ts +22 -0
  60. package/dist/file/selector.d.ts.map +1 -0
  61. package/dist/file/selector.js +239 -0
  62. package/dist/file/selector.js.map +1 -0
  63. package/dist/file/templates.d.ts +5 -0
  64. package/dist/file/templates.d.ts.map +1 -0
  65. package/dist/file/templates.js +9 -0
  66. package/dist/file/templates.js.map +1 -0
  67. package/dist/file/tools.d.ts +5 -0
  68. package/dist/file/tools.d.ts.map +1 -0
  69. package/dist/file/tools.js +51 -0
  70. package/dist/file/tools.js.map +1 -0
  71. package/dist/focus.d.ts +3 -0
  72. package/dist/focus.d.ts.map +1 -0
  73. package/dist/focus.js +12 -0
  74. package/dist/focus.js.map +1 -0
  75. package/dist/index.d.ts +18 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +19 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/network.d.ts +11 -0
  80. package/dist/network.d.ts.map +1 -0
  81. package/dist/network.js +113 -0
  82. package/dist/network.js.map +1 -0
  83. package/dist/overview_menu.d.ts +27 -0
  84. package/dist/overview_menu.d.ts.map +1 -0
  85. package/dist/overview_menu.js +536 -0
  86. package/dist/overview_menu.js.map +1 -0
  87. package/dist/settings.d.ts +3 -0
  88. package/dist/settings.d.ts.map +1 -0
  89. package/dist/settings.js +16 -0
  90. package/dist/settings.js.map +1 -0
  91. package/dist/templates.d.ts +7 -0
  92. package/dist/templates.d.ts.map +1 -0
  93. package/dist/templates.js +43 -0
  94. package/dist/templates.js.map +1 -0
  95. package/dist/user.d.ts +6 -0
  96. package/dist/user.d.ts.map +1 -0
  97. package/dist/user.js +45 -0
  98. package/dist/user.js.map +1 -0
  99. package/dist/user_util.d.ts +7 -0
  100. package/dist/user_util.d.ts.map +1 -0
  101. package/dist/user_util.js +19 -0
  102. package/dist/user_util.js.map +1 -0
  103. package/dist/worker.d.ts +2 -0
  104. package/dist/worker.d.ts.map +1 -0
  105. package/dist/worker.js +12 -0
  106. package/dist/worker.js.map +1 -0
  107. package/dist/ws.d.ts +46 -0
  108. package/dist/ws.d.ts.map +1 -0
  109. package/dist/ws.js +329 -0
  110. package/dist/ws.js.map +1 -0
  111. package/package.json +26 -4
  112. package/src/{basic.js → basic.ts} +1 -0
  113. package/src/{blob.js → blob.ts} +1 -0
  114. package/src/{content_menu.js → content_menu.ts} +1 -0
  115. package/src/{datatable_bulk.js → datatable_bulk.ts} +1 -0
  116. package/src/{dialog.js → dialog.ts} +1 -0
  117. package/src/{events.js → events.ts} +1 -0
  118. package/src/{faq_dialog.js → faq_dialog.ts} +1 -0
  119. package/src/file/{dialog.js → dialog.ts} +1 -0
  120. package/src/file/{index.js → index.ts} +1 -0
  121. package/src/file/{new_folder_dialog.js → new_folder_dialog.ts} +1 -0
  122. package/src/file/{selector.js → selector.ts} +1 -0
  123. package/src/file/{templates.js → templates.ts} +1 -0
  124. package/src/file/{tools.js → tools.ts} +1 -0
  125. package/src/{focus.js → focus.ts} +1 -0
  126. package/src/global.d.ts +11 -0
  127. package/src/{index.js → index.ts} +1 -0
  128. package/src/{network.js → network.ts} +1 -0
  129. package/src/{overview_menu.js → overview_menu.ts} +1 -0
  130. package/src/{settings.js → settings.ts} +1 -0
  131. package/src/{templates.js → templates.ts} +1 -0
  132. package/src/{user.js → user.ts} +1 -0
  133. package/src/{user_util.js → user_util.ts} +1 -0
  134. package/src/{worker.js → worker.ts} +1 -0
  135. package/src/{ws.js → ws.ts} +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,GAAI,YAAO,EAAE,aAAQ,kBAUvC,CAAA;AAwBN,oDAAoD;AACpD,eAAO,MAAM,cAAc,GAAI;;CAAM,WAQpC,CAAA"}
package/dist/user.js ADDED
@@ -0,0 +1,45 @@
1
+ // @ts-nocheck
2
+ import { post } from "./network.js";
3
+ export const setLanguage = (_config, language) => post("/api/i18n/setlang/", { language }).then(() => {
4
+ // We delete the network cache as this contains the JS
5
+ // translations.
6
+ caches.keys().then(names => {
7
+ for (const name of names) {
8
+ caches.delete(name);
9
+ }
10
+ window.location.reload();
11
+ });
12
+ });
13
+ const COLOR_CACHE = {};
14
+ const userColor = string => {
15
+ // Source https://gist.github.com/0x263b/2bdd90886c2036a1ad5bcf06d6e6fb37
16
+ if (string.length === 0) {
17
+ return "rgb(0,0,0)";
18
+ }
19
+ else if (COLOR_CACHE[string]) {
20
+ return COLOR_CACHE[string];
21
+ }
22
+ let hash = 0;
23
+ for (let i = 0; i < string.length; i++) {
24
+ hash = string.charCodeAt(i) + ((hash << 5) - hash);
25
+ hash = hash & hash;
26
+ }
27
+ const rgb = [0, 0, 0];
28
+ for (let i = 0; i < 3; i++) {
29
+ rgb[i] = (hash >> (i * 8)) & 255;
30
+ }
31
+ COLOR_CACHE[string] = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
32
+ return COLOR_CACHE[string];
33
+ };
34
+ /** A template for the default round avatar view. */
35
+ export const avatarTemplate = ({ user }) => {
36
+ const name = user.username || user.name || "A";
37
+ if (user.avatar) {
38
+ return `<img class="fw-avatar" src="${user.avatar}" alt="${name}">`;
39
+ }
40
+ else {
41
+ const color = userColor(name);
42
+ return `<span class="fw-string-avatar" style="background-color: ${color};"><span>${name[0]}</span></span>`;
43
+ }
44
+ };
45
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAC,IAAI,EAAC,MAAM,cAAc,CAAA;AAEjC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAC7C,IAAI,CAAC,oBAAoB,EAAE,EAAC,QAAQ,EAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IAC7C,sDAAsD;IACtD,gBAAgB;IAChB,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;IAC5B,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA;AAEN,MAAM,WAAW,GAAG,EAAE,CAAA;AAEtB,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE;IACvB,yEAAyE;IACzE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,YAAY,CAAA;IACvB,CAAC;SAAM,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,WAAW,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QAClD,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACtB,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAA;IACpC,CAAC;IACD,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IAC5D,OAAO,WAAW,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC,CAAA;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAA;IAC9C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,+BAA+B,IAAI,CAAC,MAAM,UAAU,IAAI,IAAI,CAAA;IACvE,CAAC;SAAM,CAAC;QACJ,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC7B,OAAO,2DAA2D,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAA;IAC9G,CAAC;AACL,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ /** Creates a dropdown box.
2
+ * @param btn The button to open and close the dropdown box.
3
+ * @param box The node containing the contents of the dropdown box.
4
+ * @param preopen An optional function to be called before opening the dropdown box. Used to position dropdown box.
5
+ */
6
+ export declare const filterPrimaryEmail: (emails: any) => any;
7
+ //# sourceMappingURL=user_util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user_util.d.ts","sourceRoot":"","sources":["../src/user_util.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAG,WAAM,QAUvC,CAAA"}
@@ -0,0 +1,19 @@
1
+ // @ts-nocheck
2
+ /** Creates a dropdown box.
3
+ * @param btn The button to open and close the dropdown box.
4
+ * @param box The node containing the contents of the dropdown box.
5
+ * @param preopen An optional function to be called before opening the dropdown box. Used to position dropdown box.
6
+ */
7
+ export const filterPrimaryEmail = emails => {
8
+ const primaryEmails = emails.filter(email => email.primary);
9
+ if (!primaryEmails.length) {
10
+ if (emails.length) {
11
+ return emails[0].address;
12
+ }
13
+ else {
14
+ return "";
15
+ }
16
+ }
17
+ return primaryEmails[0].address;
18
+ };
19
+ //# sourceMappingURL=user_util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user_util.js","sourceRoot":"","sources":["../src/user_util.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE;IACvC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3D,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QAC5B,CAAC;aAAM,CAAC;YACJ,OAAO,EAAE,CAAA;QACb,CAAC;IACL,CAAC;IACD,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACnC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const makeWorker: (workerUrl: any) => Worker;
2
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,GAAG,cAAS,WASlC,CAAA"}
package/dist/worker.js ADDED
@@ -0,0 +1,12 @@
1
+ // @ts-nocheck
2
+ /* allows cross domain web workers */
3
+ /* Taken from https://benohead.com/cross-domain-cross-browser-web-workers/ */
4
+ export const makeWorker = workerUrl => {
5
+ const a = document.createElement("a");
6
+ a.href = workerUrl; // turn into absolute URL if needed.
7
+ const blob = new Blob([`importScripts("${a.href}")`], {
8
+ type: "application/javascript"
9
+ }), blobUrl = window.URL.createObjectURL(blob), worker = new Worker(blobUrl);
10
+ return worker;
11
+ };
12
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,qCAAqC;AACrC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE;IAClC,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACrC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAA,CAAC,oCAAoC;IACvD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE;QAC9C,IAAI,EAAE,wBAAwB;KACjC,CAAC,EACF,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,EAC1C,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;IAChC,OAAO,MAAM,CAAA;AACjB,CAAC,CAAA"}
package/dist/ws.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ export declare class WebSocketConnector {
2
+ constructor({ base, // needs to be specified
3
+ path, // needs to be specified
4
+ appLoaded, // required argument
5
+ anythingToSend, // required argument
6
+ messagesElement, // element in which to show connection messages
7
+ initialMessage, resubScribed, // Cleanup when the client connects a second or subsequent time
8
+ restartMessage, // Too many messages have been lost and we need to restart
9
+ warningNotAllSent, // Info to show while disconnected WITH unsaved data
10
+ infoDisconnected, // Info to show while disconnected WITHOUT unsaved data
11
+ receiveData, failedAuth }: {
12
+ base?: string;
13
+ path?: string;
14
+ appLoaded?: () => boolean;
15
+ anythingToSend?: () => boolean;
16
+ messagesElement?: () => boolean;
17
+ initialMessage?: () => {
18
+ type: string;
19
+ };
20
+ resubScribed?: () => void;
21
+ restartMessage?: () => {
22
+ type: string;
23
+ };
24
+ warningNotAllSent?: string;
25
+ infoDisconnected?: string;
26
+ receiveData?: (_data: any) => void;
27
+ failedAuth?: () => void;
28
+ });
29
+ init(): void;
30
+ goOffline(): void;
31
+ goOnline(): void;
32
+ close(): void;
33
+ createWSConnection(): void;
34
+ waitForWS(): Promise<unknown>;
35
+ onmessage(event: any): void;
36
+ onclose(): void;
37
+ open(): void;
38
+ subscribed(): void;
39
+ /** Sends data to server or keeps it in a list if currently offline. */
40
+ send(getData: any, timer?: number): void;
41
+ setRecentlySentTimer(timer: any): void;
42
+ resend_messages(from: any): Promise<void>;
43
+ receive(data: any): void;
44
+ heartbeat(): void;
45
+ }
46
+ //# sourceMappingURL=ws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"AAGA,qBAAa,kBAAkB;gBACf,EACR,IAAS,EAAE,wBAAwB;IACnC,IAAS,EAAE,wBAAwB;IACnC,SAAuB,EAAE,oBAAoB;IAC7C,cAA4B,EAAE,oBAAoB;IAClD,eAA6B,EAAE,+CAA+C;IAC9E,cAA4C,EAC5C,YAAuB,EAAE,+DAA+D;IACxF,cAA0C,EAAE,0DAA0D;IACtG,iBAA4D,EAAE,oDAAoD;IAClH,gBAAsE,EAAE,uDAAuD;IAC/H,WAAyB,EACzB,UAEC,EACJ;;;;;;;;;;;;;;;;;KAAA;IAiCD,IAAI;IAQJ,SAAS;IAST,QAAQ;IAKR,KAAK;IAQL,kBAAkB;IAiClB,SAAS;IAyBT,SAAS,CAAC,KAAK,KAAA;IAyDf,OAAO;IAoBP,IAAI;IAeJ,UAAU;IASV,uEAAuE;IACvE,IAAI,CAAC,OAAO,KAAA,EAAE,KAAK,SAAK;IAmCxB,oBAAoB,CAAC,KAAK,KAAA;IAa1B,eAAe,CAAC,IAAI,KAAA;IAuBpB,OAAO,CAAC,IAAI,KAAA;IAqBZ,SAAS;CAaZ"}
package/dist/ws.js ADDED
@@ -0,0 +1,329 @@
1
+ // @ts-nocheck
2
+ /* Sets up communicating with server (retrieving document, saving, collaboration, etc.).
3
+ */
4
+ export class WebSocketConnector {
5
+ constructor({ base = "", // needs to be specified
6
+ path = "", // needs to be specified
7
+ appLoaded = () => false, // required argument
8
+ anythingToSend = () => false, // required argument
9
+ messagesElement = () => false, // element in which to show connection messages
10
+ initialMessage = () => ({ type: "subscribe" }), resubScribed = () => { }, // Cleanup when the client connects a second or subsequent time
11
+ restartMessage = () => ({ type: "restart" }), // Too many messages have been lost and we need to restart
12
+ warningNotAllSent = gettext("Warning! Some data is unsaved"), // Info to show while disconnected WITH unsaved data
13
+ infoDisconnected = gettext("Disconnected. Attempting to reconnect..."), // Info to show while disconnected WITHOUT unsaved data
14
+ receiveData = _data => { }, failedAuth = () => {
15
+ window.location.href = "/";
16
+ } }) {
17
+ this.base = base;
18
+ this.path = path;
19
+ this.appLoaded = appLoaded;
20
+ this.anythingToSend = anythingToSend;
21
+ this.messagesElement = messagesElement;
22
+ this.initialMessage = initialMessage;
23
+ this.resubScribed = resubScribed;
24
+ this.restartMessage = restartMessage;
25
+ this.warningNotAllSent = warningNotAllSent;
26
+ this.infoDisconnected = infoDisconnected;
27
+ this.receiveData = receiveData;
28
+ this.failedAuth = failedAuth;
29
+ /* A list of messages to be sent. Only used when temporarily offline.
30
+ Messages will be sent when returning back online. */
31
+ this.messagesToSend = [];
32
+ /* A list of messages from a previous connection */
33
+ this.oldMessages = [];
34
+ this.online = true;
35
+ this.connected = false;
36
+ /* Increases when connection has to be reestablished */
37
+ /* 0 = before first connection. */
38
+ /* 1 = first connection established, etc. */
39
+ this.connectionCount = 0;
40
+ this.recentlySent = false;
41
+ this.listeners = {};
42
+ //heartbeat
43
+ this.pingTimer = false;
44
+ this.pongTimer = false;
45
+ }
46
+ init() {
47
+ this.createWSConnection();
48
+ // Close the socket manually for now when the connection is lost. Sometimes the socket isn't closed on disconnection.
49
+ this.listeners.onOffline = _event => this.ws.close();
50
+ window.addEventListener("offline", this.listeners.onOffline);
51
+ }
52
+ goOffline() {
53
+ // Simulate offline mode due to lack of ways of doing this in Chrome/Firefox
54
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1421357
55
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=423246
56
+ this.online = false;
57
+ this.connected = false;
58
+ this.ws.close();
59
+ }
60
+ goOnline() {
61
+ // Reconnect from offline mode
62
+ this.online = true;
63
+ }
64
+ close() {
65
+ if (this.ws) {
66
+ this.ws.onclose = () => { };
67
+ this.ws.close();
68
+ }
69
+ window.removeEventListener("offline", this.listeners.onOffline);
70
+ }
71
+ createWSConnection() {
72
+ // Messages object used to ensure that data is received in right order.
73
+ this.messages = {
74
+ server: 0,
75
+ client: 0,
76
+ lastTen: []
77
+ };
78
+ let url;
79
+ if (this.online) {
80
+ if (this.base.startsWith("/")) {
81
+ url = this.base + this.path;
82
+ }
83
+ else if (location.protocol === "https:") {
84
+ url = `wss://${this.base}${this.path}`;
85
+ }
86
+ else {
87
+ url = `ws://${this.base}${this.path}`;
88
+ }
89
+ }
90
+ else {
91
+ if (location.protocol === "https:") {
92
+ url = "wss://offline";
93
+ }
94
+ else {
95
+ url = "ws://offline";
96
+ }
97
+ }
98
+ if (this.ws) {
99
+ this.ws.onmessage = () => { };
100
+ this.ws.onclose = () => { };
101
+ this.ws.close();
102
+ }
103
+ this.ws = new window.WebSocket(url);
104
+ this.ws.onmessage = event => this.onmessage(event);
105
+ this.ws.onclose = () => this.onclose();
106
+ }
107
+ waitForWS() {
108
+ return new Promise((resolve, reject) => {
109
+ const checkState = () => {
110
+ if (!this.ws) {
111
+ // WebSocket doesn't exist
112
+ return setTimeout(() => checkState(), 100);
113
+ }
114
+ if (this.ws.readyState === this.ws.OPEN) {
115
+ // WebSocket is open and ready
116
+ return resolve();
117
+ }
118
+ else if (this.ws.readyState === this.ws.CONNECTING) {
119
+ // WebSocket is still connecting, wait
120
+ return setTimeout(() => checkState(), 100);
121
+ }
122
+ else {
123
+ // WebSocket is in CLOSING or CLOSED state
124
+ // We should not try to send on this socket
125
+ return reject(new Error("WebSocket is not in OPEN state"));
126
+ }
127
+ };
128
+ checkState();
129
+ });
130
+ }
131
+ onmessage(event) {
132
+ const data = JSON.parse(event.data);
133
+ const expectedServer = this.messages.server + 1;
134
+ if (data.type === "request_resend") {
135
+ this.resend_messages(data.from);
136
+ }
137
+ else if (data.type === "pong") {
138
+ this.heartbeat();
139
+ }
140
+ else if (data.s < expectedServer) {
141
+ // Receive a message already received at least once. Ignore.
142
+ return;
143
+ }
144
+ else if (data.s > expectedServer) {
145
+ // Messages from the server have been lost.
146
+ // Request resend.
147
+ this.waitForWS()
148
+ .then(() => this.ws.send(JSON.stringify({
149
+ type: "request_resend",
150
+ from: this.messages.server
151
+ })))
152
+ .catch(() => {
153
+ // Connection not ready, we will handle this on reconnection
154
+ });
155
+ }
156
+ else {
157
+ this.messages.server = expectedServer;
158
+ if (data.c === this.messages.client) {
159
+ this.receive(data);
160
+ }
161
+ else if (data.c < this.messages.client) {
162
+ // We have received all server messages, but the server seems
163
+ // to have missed some of the client's messages. They could
164
+ // have been sent simultaneously.
165
+ // The server wins over the client in this case.
166
+ this.waitForWS().then(() => {
167
+ const clientDifference = this.messages.client - data.c;
168
+ this.messages.client = data.c;
169
+ if (clientDifference > this.messages.lastTen.length) {
170
+ // We cannot fix the situation
171
+ this.send(this.restartMessage);
172
+ return;
173
+ }
174
+ this.messages["lastTen"]
175
+ .slice(0 - clientDifference)
176
+ .forEach(data => {
177
+ this.messages.client += 1;
178
+ data.c = this.messages.client;
179
+ data.s = this.messages.server;
180
+ this.ws.send(JSON.stringify(data));
181
+ });
182
+ this.receive(data);
183
+ });
184
+ }
185
+ }
186
+ }
187
+ onclose() {
188
+ this.connected = false;
189
+ window.setTimeout(() => {
190
+ this.createWSConnection();
191
+ }, 2000);
192
+ if (!this.appLoaded()) {
193
+ // doc not initiated
194
+ return;
195
+ }
196
+ const messagesElement = this.messagesElement();
197
+ if (messagesElement) {
198
+ if (this.anythingToSend()) {
199
+ messagesElement.innerHTML = `<span class="warn">${this.warningNotAllSent}</span>`;
200
+ }
201
+ else {
202
+ messagesElement.innerHTML = this.infoDisconnected;
203
+ }
204
+ }
205
+ }
206
+ open() {
207
+ const messagesElement = this.messagesElement();
208
+ if (messagesElement) {
209
+ messagesElement.innerHTML = "";
210
+ }
211
+ this.connected = true;
212
+ const message = this.initialMessage();
213
+ this.connectionCount++;
214
+ this.oldMessages = this.messagesToSend;
215
+ this.messagesToSend = [];
216
+ this.send(() => message);
217
+ }
218
+ subscribed() {
219
+ if (this.connectionCount > 1) {
220
+ this.resubScribed();
221
+ }
222
+ while (this.oldMessages.length > 0) {
223
+ this.send(this.oldMessages.shift());
224
+ }
225
+ }
226
+ /** Sends data to server or keeps it in a list if currently offline. */
227
+ send(getData, timer = 80) {
228
+ if (this.connected && this.ws.readyState !== this.ws.OPEN) {
229
+ this.ws.close();
230
+ return;
231
+ }
232
+ if (this.connected && !this.recentlySent) {
233
+ const data = getData();
234
+ if (!data) {
235
+ // message is empty
236
+ return;
237
+ }
238
+ this.messages.client += 1;
239
+ data.c = this.messages.client;
240
+ data.s = this.messages.server;
241
+ this.messages.lastTen.push(data);
242
+ this.messages.lastTen = this.messages["lastTen"].slice(-10);
243
+ this.waitForWS()
244
+ .then(() => {
245
+ this.ws.send(JSON.stringify(data));
246
+ this.setRecentlySentTimer(timer);
247
+ })
248
+ .catch(() => {
249
+ // Failed to send - likely WebSocket is not open
250
+ // Put the message back into the queue
251
+ this.messages.client -= 1;
252
+ this.messagesToSend.unshift(getData);
253
+ // Remove from lastTen to avoid duplicates
254
+ this.messages.lastTen = this.messages.lastTen.slice(0, -1);
255
+ });
256
+ }
257
+ else {
258
+ this.messagesToSend.push(getData);
259
+ }
260
+ }
261
+ setRecentlySentTimer(timer) {
262
+ this.recentlySent = true;
263
+ window.setTimeout(() => {
264
+ this.recentlySent = false;
265
+ const oldMessages = this.messagesToSend;
266
+ this.messagesToSend = [];
267
+ while (oldMessages.length > 0) {
268
+ const getData = oldMessages.shift();
269
+ this.send(getData, Math.min(timer * 1.2, 10000));
270
+ }
271
+ }, timer);
272
+ }
273
+ resend_messages(from) {
274
+ return this.waitForWS()
275
+ .then(() => {
276
+ const toSend = this.messages.client - from;
277
+ this.messages.client = from;
278
+ if (toSend > this.messages.lastTen.length) {
279
+ // Too many messages requested. Abort.
280
+ this.send(this.restartMessage);
281
+ return;
282
+ }
283
+ this.messages.lastTen.slice(0 - toSend).forEach(data => {
284
+ this.messages.client += 1;
285
+ data.c = this.messages.client;
286
+ data.s = this.messages.server;
287
+ this.ws.send(JSON.stringify(data));
288
+ });
289
+ })
290
+ .catch(() => {
291
+ // Could not send messages - WebSocket not ready
292
+ // Will try again when WebSocket is ready
293
+ });
294
+ }
295
+ receive(data) {
296
+ switch (data.type) {
297
+ case "redirect":
298
+ this.base = data.base;
299
+ break;
300
+ case "welcome":
301
+ this.open();
302
+ break;
303
+ case "subscribed":
304
+ this.subscribed();
305
+ this.heartbeat();
306
+ break;
307
+ case "access_denied":
308
+ this.failedAuth();
309
+ break;
310
+ default:
311
+ this.receiveData(data);
312
+ break;
313
+ }
314
+ }
315
+ heartbeat() {
316
+ clearTimeout(this.pingTimer);
317
+ clearTimeout(this.pongTimer);
318
+ this.pingTimer = setTimeout(() => {
319
+ // Don't send ping if WebSocket is not open
320
+ if (this.ws.readyState === this.ws.OPEN) {
321
+ this.ws.send('{"type": "ping"}');
322
+ this.pongTimer = setTimeout(() => {
323
+ this.listeners.onOffline();
324
+ }, 10000);
325
+ }
326
+ }, 60000);
327
+ }
328
+ }
329
+ //# sourceMappingURL=ws.js.map
package/dist/ws.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws.js","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fwtoolkit",
3
- "version": "0.1.0-alpha.3",
4
- "description": "Fidus Writer Toolkit — reusable utilities and UI helpers for Fidus Writer and other applications",
3
+ "version": "0.1.0-alpha.6",
4
+ "description": "Fidus Writer Toolkit — reusable TypeScript utilities, UI helpers and styles for Fidus Writer and other applications",
5
5
  "type": "module",
6
6
  "license": "LGPL-3.0-or-later",
7
7
  "repository": {
@@ -9,17 +9,39 @@
9
9
  "url": "https://codeberg.org/fiduswriter/fwtoolkit.git"
10
10
  },
11
11
  "author": "Johannes Wilm",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
12
14
  "files": [
13
15
  "src/",
16
+ "dist/",
17
+ "css/",
14
18
  "README.md",
15
19
  "LICENSE"
16
20
  ],
17
21
  "exports": {
18
- ".": "./src/index.js",
19
- "./*": "./src/*"
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./*": {
27
+ "types": "./dist/*.d.ts",
28
+ "default": "./dist/*.js"
29
+ }
30
+ },
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "prepublishOnly": "npm run build && npm test",
34
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.config.js"
20
35
  },
21
36
  "dependencies": {
22
37
  "diff-dom": "^5.2.1",
23
38
  "w3c-keyname": "^2.2.8"
39
+ },
40
+ "devDependencies": {
41
+ "@types/jest": "^29.5.14",
42
+ "jest": "^29.7.0",
43
+ "jest-environment-jsdom": "^29.7.0",
44
+ "ts-jest": "^29.2.5",
45
+ "typescript": "^5.8.2"
24
46
  }
25
47
  }
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {keyName} from "w3c-keyname"
2
3
 
3
4
  import {ContentMenu} from "./content_menu.js"
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  export function convertDataURIToBlob(dataURI) {
2
3
  const byteString = atob(dataURI.split(",")[1])
3
4
  const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  const menuTemplate = ({
2
3
  id,
3
4
  classes,
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {keyName} from "w3c-keyname"
2
3
 
3
4
  import {whenReady} from "./basic.js"
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {keyName} from "w3c-keyname"
2
3
 
3
4
  import {findTarget} from "./basic.js"
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  export const isActivationEvent = event => {
2
3
  if (event.type === "click") {
3
4
  return true
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {escapeText} from "./basic.js"
2
3
  import {Dialog} from "./dialog.js"
3
4
  import {ensureCSS} from "./network.js"
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {Dialog} from "../dialog.js"
2
3
  import {FileSelector} from "./selector.js"
3
4
  import {addAlert} from "../basic.js"
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  export {FileDialog} from "./dialog.js"
2
3
  export {FileSelector} from "./selector.js"
3
4
  export {
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {Dialog} from "../dialog.js"
2
3
  import {newFolderTemplate} from "./templates.js"
3
4
 
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {escapeText, findTarget} from "../basic.js"
2
3
  import {ensureCSS} from "../network.js"
3
4
 
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {escapeText} from "../index.js"
2
3
 
3
4
  export const moveTemplate = ({path}) =>
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import {escapeText} from "../basic.js"
2
3
  import {postJson} from "../network.js"
3
4
 
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  // Get the index number of currently focused selement. This it to set tyhe focus close by after doing some dom changes.
2
3
 
3
4
  export const getFocusIndex = () => {