@olenbetong/appframe-core 2.0.3 → 2.1.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 (42) hide show
  1. package/dist/esm/af.common.js +115 -293
  2. package/dist/esm/af.common.legacy.js +119 -290
  3. package/dist/esm/af.common.legacy.min.js +1 -47
  4. package/dist/esm/af.common.legacy.min.js.map +4 -4
  5. package/dist/esm/af.common.min.js +1 -47
  6. package/dist/esm/af.common.min.js.map +4 -4
  7. package/dist/iife/af.common.js +118 -294
  8. package/dist/iife/af.common.legacy.js +122 -293
  9. package/dist/iife/af.common.legacy.min.js +1 -47
  10. package/dist/iife/af.common.legacy.min.js.map +4 -4
  11. package/dist/iife/af.common.min.js +1 -47
  12. package/dist/iife/af.common.min.js.map +4 -4
  13. package/es/SessionHandler.d.ts +2 -7
  14. package/es/SessionHandler.js +34 -135
  15. package/es/UserSession.d.ts +1 -2
  16. package/es/UserSession.js +1 -2
  17. package/es/downloadRequest.js +1 -4
  18. package/es/expose.d.ts +1 -1
  19. package/es/expose.js +4 -5
  20. package/es/getLocalizedString.d.ts +6 -7
  21. package/es/getLocalizedString.js +9 -82
  22. package/es/index.d.ts +3 -2
  23. package/es/index.js +4 -3
  24. package/es/localize.d.ts +14 -0
  25. package/es/localize.js +25 -0
  26. package/es/parseFunc.d.ts +1 -1
  27. package/es/parseFunc.js +1 -1
  28. package/es/requireNamespace.d.ts +1 -1
  29. package/es/requireNamespace.js +1 -7
  30. package/package.json +2 -2
  31. package/src/SessionHandler.ts +38 -156
  32. package/src/UserSession.ts +1 -2
  33. package/src/downloadRequest.ts +1 -4
  34. package/src/expose.ts +4 -5
  35. package/src/getLocalizedString.ts +22 -110
  36. package/src/index.ts +3 -2
  37. package/src/localize.ts +29 -0
  38. package/src/parseFunc.ts +1 -1
  39. package/src/requireNamespace.ts +1 -5
  40. package/es/warn.d.ts +0 -1
  41. package/es/warn.js +0 -4
  42. package/src/warn.ts +0 -4
@@ -4,24 +4,19 @@ var af;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
8
7
  var __export = (target, all) => {
9
8
  for (var name in all)
10
9
  __defProp(target, name, { get: all[name], enumerable: true });
11
10
  };
12
11
  var __copyProps = (to, from, except, desc) => {
13
12
  if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key2 of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key2) && key2 !== except)
16
- __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
16
  }
18
17
  return to;
19
18
  };
20
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
- var __publicField = (obj, key2, value) => {
22
- __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
23
- return value;
24
- };
25
20
 
26
21
  // src/index.ts
27
22
  var src_exports = {};
@@ -35,6 +30,7 @@ var af;
35
30
  getSettings: () => getSettings,
36
31
  has: () => has,
37
32
  localStorage: () => localStorage_default,
33
+ localize: () => localize,
38
34
  mitt: () => mitt_default,
39
35
  saveSettings: () => saveSettings,
40
36
  version: () => version
@@ -81,259 +77,42 @@ var af;
81
77
  } };
82
78
  }
83
79
 
84
- // src/has.ts
85
- function has(obj, key2) {
86
- return Object.prototype.hasOwnProperty.call(obj, key2);
87
- }
88
-
89
- // src/getLocalizedString.ts
90
- async function getLocalizedStringAsync(text) {
91
- try {
92
- let response = await fetch(`/api/user/localize/new/${af.article.id}`, {
93
- body: JSON.stringify({ text }),
94
- headers: {
95
- Accept: "application/json; */*",
96
- "Content-Type": "application/json",
97
- "X-Requested-With": "XMLHttpRequest"
98
- },
99
- method: "POST"
100
- });
101
- if (response.ok) {
102
- return await response.json();
103
- }
104
- } catch (error) {
105
- }
106
- return text;
107
- }
108
- function afGetLocalizedString(string, wait) {
109
- if (typeof string === "string" && string.trim().length === 0) {
110
- return string;
111
- }
112
- if (string === void 0 || string === "" || string === null) {
113
- return;
114
- }
115
- if (af?.article?.i18n !== void 0) {
116
- if (!has(af.article.i18n, string)) {
117
- af.article.i18n[string] = string;
118
- let promise = getLocalizedStringAsync(string).then((text) => {
119
- af.article.i18n[string] = text;
120
- return text;
121
- });
122
- if (wait) {
123
- return promise;
124
- }
125
- }
126
- return af.article.i18n[string];
127
- } else {
128
- return string;
129
- }
130
- }
131
- var key = "__UNLOCALIZED_STRINGS__";
132
- var localizeSet = window[key] || /* @__PURE__ */ new Set();
133
- if (!window[key]) {
134
- window[key] = localizeSet;
135
- }
136
- function handleReadyStateChange() {
137
- if (document.readyState !== "loading") {
138
- addDeveloperUtils();
139
- document.removeEventListener("readystatechange", handleReadyStateChange);
140
- }
141
- }
142
- if (document.readyState !== "loading") {
143
- addDeveloperUtils();
144
- } else {
145
- document.addEventListener("readystatechange", handleReadyStateChange);
146
- }
147
- function isDeveloper() {
148
- const { af: af2 } = window;
149
- return af2 && af2.userSession && af2.userSession.isDeveloper;
150
- }
151
- function addDeveloperUtils() {
152
- if (isDeveloper()) {
153
- if (typeof window.__doNothingWithStrings === "function") {
154
- const addedStrings = window.__doNothingWithStrings();
155
- for (let string of Object.keys(addedStrings)) {
156
- localizeSet.add(string);
157
- }
158
- }
159
- if (!window[key]) {
160
- window[key] = localizeSet;
161
- }
162
- if (!window.__getUnlocalizedStrings) {
163
- window.__getUnlocalizedStrings = function(forCustomRoute) {
164
- const strings = [];
165
- for (let string of localizeSet) {
166
- if (string) {
167
- const escaped = string.replace(/'/g, "\\'");
168
- if (forCustomRoute) {
169
- const localized = afGetLocalizedString(string).replaceAll(/'/g, "\\'");
170
- strings.push(`'${escaped}': '${localized}',`);
171
- } else {
172
- strings.push(
173
- `s['${escaped}'] = @Html(@context.AddLocalizableString("${string.replaceAll('"', '\\"')}"));`
174
- );
175
- }
176
- }
177
- }
178
- if (forCustomRoute) {
179
- return `// Localization hack, since it AddLocalizableString doesn't work properly when custom routes is used
180
- if (af.userSession.uiculture === 'nb-NO') {
181
- const strings = {
182
- ${strings.join("\n ")}
183
- };
184
- af.article.i18n = af.article.i18n || {};
185
- Object.assign(af.article.i18n, strings);
186
- }`;
187
- }
188
- return `<script type="text/javascript">
189
- function __doNothingWithStrings() {
190
- @{
191
- var context = @Appframe.Web.Context.RequestContext.Current;
192
- }
193
- let s = {};
194
- ${strings.join("\n")}
195
- return s;
196
- }
197
- <\/script>`;
198
- };
199
- }
200
- }
201
- }
202
- function getLocalizedString(string) {
203
- const localized = afGetLocalizedString(string);
204
- if (localized === string && !localizeSet.has(string)) {
205
- localizeSet.add(string);
206
- }
207
- return localized;
208
- }
209
-
210
80
  // src/SessionHandler.ts
211
- var _SessionHandler = class {
81
+ var SessionHandler = class {
212
82
  eventHandler = mitt_default();
213
- showingDialog = false;
214
- dialog = null;
215
- expired(callback) {
216
- af.userSession = af.userSession || {
217
- login: null
218
- };
219
- if (typeof callback !== "function") {
220
- throw new TypeError("Parameter pCallback passed to the expired function must be a function!");
221
- }
222
- const once = () => {
223
- this.detachEvent("onAuthenticated", once);
224
- callback();
225
- };
226
- this.attachEvent("onAuthenticated", once);
227
- if (this.showingDialog !== true) {
228
- this.showingDialog = true;
229
- const contentContainer = document.createElement("div");
230
- contentContainer.className = "session-expired-container";
231
- contentContainer.innerHTML = `
232
- <div class="session-expired-log-in" style="margin-top: 20px;">
233
- <div class="row">
234
- <div class="sessionExpired">
235
- <h4 class="message">Frakoblet - tidsavbrudd</h4>
236
- <div class="form-group">
237
- <label for="username">${getLocalizedString("Username")}</label>
238
- <input type="text" class="form-control" id="username" autofocus>
239
- </div>
240
- <div class="form-group">
241
- <label for="password">${getLocalizedString("Password")}</label>
242
- <input type="password" autocomplete="password" class="form-control" id="password" >
243
- </div>
244
- <div class="form-group">
245
- <div>
246
- <button type="submit" class="btn btn-default sign-in">
247
- ${getLocalizedString("Log in")}
248
- </button>
249
- </div>
250
- </div>
251
- </div>
252
- </div>
253
- <div class="row">
254
- <div class="" style="display:none; margin: 0px 30px;">
255
- <div class="alert alert-warning" role="alert" style="margin-top:10px;"></div>
256
- </div>
257
- </div>
258
- </div>
259
- `;
260
- const message = af.userSession.login ? _SessionHandler.messages.relog : _SessionHandler.messages.login;
261
- const messageElem = contentContainer.querySelector(".message");
262
- const statusElem = contentContainer.querySelector(".alert-warning");
263
- const userElem = contentContainer.querySelector("input[type=text]");
264
- const signInElem = contentContainer.querySelector(".sign-in");
265
- const passwordElem = contentContainer.querySelector("input[type=password]");
266
- if (messageElem !== null && userElem !== null && statusElem !== null && userElem !== null && signInElem !== null && passwordElem !== null) {
267
- messageElem.innerText = getLocalizedString(message);
268
- userElem.value = af.userSession.login || "";
269
- userElem.disabled = !!af.userSession.login;
270
- userElem.readOnly = !!af.userSession.login;
271
- document.body.appendChild(contentContainer);
272
- const doLogin = async () => {
273
- passwordElem.disabled = true;
274
- const request = new Request("/login", {
275
- body: JSON.stringify({
276
- username: userElem.value,
277
- password: passwordElem.value,
278
- remember: false
279
- }),
280
- headers: {
281
- Accept: "application/json",
282
- "Content-Type": "application/json; charset=utf-8",
283
- "X-Requested-With": "XMLHttpRequest"
284
- },
285
- method: "POST"
286
- });
287
- try {
288
- const response = await fetch(request);
289
- const json = await response.json();
290
- if (json.success) {
291
- document.body.removeChild(contentContainer);
292
- this.showingDialog = false;
293
- this.eventHandler.emit("onAuthenticated");
294
- if (statusElem.parentNode) {
295
- statusElem.parentNode.style.display = "none";
296
- }
297
- } else {
298
- throw new Error(json.error);
299
- }
300
- } catch (err) {
301
- if (err && typeof err === "object") {
302
- let error = err;
303
- passwordElem.disabled = false;
304
- passwordElem.classList.toggle("invalid", true);
305
- passwordElem.value = "";
306
- passwordElem.focus();
307
- statusElem.innerText = error.message ? error.message : String(error);
308
- if (statusElem.parentNode) {
309
- statusElem.parentNode.style.display = "initial";
310
- }
311
- }
312
- }
313
- };
314
- signInElem.addEventListener("click", doLogin);
315
- passwordElem.addEventListener("keyup", (evt) => {
316
- if (evt.key === "Enter") {
317
- doLogin();
318
- }
319
- });
320
- passwordElem.addEventListener("change", (evt) => {
321
- if (evt.key === "Enter") {
322
- doLogin();
323
- }
324
- });
325
- userElem.addEventListener("keyup", (evt) => {
326
- if (evt.key === "Enter") {
327
- doLogin();
328
- }
329
- });
330
- userElem.addEventListener("change", (evt) => {
331
- if (evt.key === "Enter") {
332
- doLogin();
333
- }
334
- });
335
- passwordElem.focus();
83
+ authenticated() {
84
+ this.eventHandler.emit("onAuthenticated");
85
+ }
86
+ async expired(callback, type) {
87
+ let authPromise = new Promise((resolve) => {
88
+ let eventHandler = () => {
89
+ this.eventHandler.off("onAuthenticated", eventHandler);
90
+ callback?.();
91
+ resolve();
92
+ };
93
+ this.eventHandler.on("onAuthenticated", eventHandler);
94
+ });
95
+ let dialog = document.querySelector("dialog.session-expired-dialog");
96
+ if (!dialog) {
97
+ dialog = document.createElement("dialog");
98
+ dialog.className = "session-expired-dialog";
99
+ dialog.style.display = "flex";
100
+ dialog.style.padding = "0";
101
+ dialog.style.left = "50%";
102
+ dialog.style.transform = "translateX(-50%)";
103
+ let link = "/login?ReturnUrl=%2fapi/sessionexpired/remove";
104
+ if (type !== "RequireTwoFactor") {
105
+ await fetch("/logout", { method: "POST" });
106
+ } else {
107
+ link = "/login?RequireTwoFactor=1&ReturnUrl=%2fapi/sessionexpired/remove";
336
108
  }
109
+ dialog.innerHTML = `<iframe sandbox="allow-same-origin allow-scripts allow-modals allow-top-navigation-by-user-activation allow-forms" src="${link}" style="border:0;width:min(500px,100vw);height:min(700px, 100vh);"></iframe>`;
110
+ document.body.append(dialog);
111
+ dialog.showModal();
112
+ await authPromise;
113
+ dialog.remove();
114
+ } else {
115
+ await authPromise;
337
116
  }
338
117
  }
339
118
  attachEvent(eventName, handler) {
@@ -343,11 +122,6 @@ return s;
343
122
  return this.eventHandler.off(eventName, handler);
344
123
  }
345
124
  };
346
- var SessionHandler = _SessionHandler;
347
- __publicField(SessionHandler, "messages", {
348
- login: "Log in",
349
- relog: "Session expired - log in"
350
- });
351
125
 
352
126
  // src/UserSession.ts
353
127
  var UserSession = class extends SessionHandler {
@@ -370,7 +144,6 @@ return s;
370
144
  shortDateFormat = "dd.MM.yyyy";
371
145
  culture = "en-GB";
372
146
  uiculture = "en-GB";
373
- expired = () => null;
374
147
  constructor(userData) {
375
148
  super();
376
149
  this.formats = {};
@@ -441,7 +214,6 @@ return s;
441
214
  });
442
215
  response = new Response(stream);
443
216
  } catch (error) {
444
- console.warn("Failed to replace response stream to log download progress.");
445
217
  }
446
218
  const blob = await response.blob();
447
219
  reportProgress({ bytesReceived, status: "downloaded" });
@@ -456,6 +228,11 @@ return s;
456
228
  }
457
229
  }
458
230
 
231
+ // src/has.ts
232
+ function has(obj, key) {
233
+ return Object.prototype.hasOwnProperty.call(obj, key);
234
+ }
235
+
459
236
  // src/parseFunc.ts
460
237
  var funcRegex = /^function(?:\s+([a-zA-Z$_][a-zA-Z0-9$_]*))?\s*\(((?:(?:\s*[a-zA-Z$_][a-zA-Z0-9$_]*)(?:\s*,\s*[a-zA-Z$_][a-zA-Z0-9$_]*)*)?)\s*\)\s*\{((?:.|\n|\r)*)\}$/;
461
238
  function parseFunc(func) {
@@ -484,19 +261,10 @@ return s;
484
261
  current = current[namespace[i]] = current[namespace[i]] || new Namespace_default();
485
262
  }
486
263
  return current;
487
- } else {
488
- throw new TypeError("Invalid type of parameter 'namespace'");
489
264
  }
490
- } else {
491
- throw new TypeError("Invalid type of parameter 'root'");
492
265
  }
493
266
  }
494
267
 
495
- // src/warn.ts
496
- function warn(message, fallbackToAlert) {
497
- console.warn(message);
498
- }
499
-
500
268
  // src/expose.ts
501
269
  function expose(name, value) {
502
270
  if (arguments.length !== 2) {
@@ -532,37 +300,93 @@ return s;
532
300
  throw new TypeError("Invalid typeof parameter 'name', or unable to parse pValue!");
533
301
  }
534
302
  if (has(namespace, keyName)) {
535
- warn([name, keyName].join(".") + " is already defined!");
303
+ console.warn([name, keyName].join(".") + " is already defined!");
536
304
  } else {
537
305
  namespace[keyName] = value;
538
306
  }
539
307
  }
540
308
  }
541
309
 
310
+ // src/getLocalizedString.ts
311
+ async function fetchLocalizedString(text) {
312
+ try {
313
+ let response = await fetch(`/api/user/localize/new/${af.article.id}`, {
314
+ body: JSON.stringify({ text }),
315
+ headers: {
316
+ Accept: "application/json; */*",
317
+ "Content-Type": "application/json",
318
+ "X-Requested-With": "XMLHttpRequest"
319
+ },
320
+ method: "POST"
321
+ });
322
+ if (response.ok) {
323
+ return await response.json();
324
+ }
325
+ } catch (error) {
326
+ }
327
+ return text;
328
+ }
329
+ function getLocalizedString(string, wait) {
330
+ if (typeof string === "string" && string.trim().length === 0) {
331
+ return string;
332
+ }
333
+ if (string === void 0 || string === "" || string === null) {
334
+ return;
335
+ }
336
+ if (af?.article?.i18n !== void 0) {
337
+ if (!has(af.article.i18n, string)) {
338
+ af.article.i18n[string] = string;
339
+ let promise = fetchLocalizedString(string).then((text) => {
340
+ af.article.i18n[string] = text;
341
+ return text;
342
+ });
343
+ if (wait) {
344
+ return promise;
345
+ }
346
+ }
347
+ return af.article.i18n[string];
348
+ } else {
349
+ return string;
350
+ }
351
+ }
352
+
353
+ // src/localize.ts
354
+ function localize(stringParts, ...args) {
355
+ if (!Array.isArray(stringParts) || stringParts?.length || stringParts.length !== args.length + 1) {
356
+ throw TypeError("Method 'localize' must be used as a tag function");
357
+ }
358
+ let stringToLocalize = stringParts.map((s, i) => i === stringParts.length - 1 ? s : `${s}$${i}`).join("");
359
+ let localized = getLocalizedString(stringToLocalize);
360
+ args.forEach((arg, index) => {
361
+ localized = localized.replace("$" + index, arg);
362
+ });
363
+ return localized;
364
+ }
365
+
542
366
  // src/localStorage.ts
543
- function getLocalKey(key2) {
544
- return [af?.article?.id || "", "common", key2].join(".");
367
+ function getLocalKey(key) {
368
+ return [af?.article?.id || "", "common", key].join(".");
545
369
  }
546
370
  var LocalStorage = class {
547
371
  isPersisted() {
548
372
  return true;
549
373
  }
550
- getLocalStorageKey(key2, global) {
551
- return global ? ["common", key2].join(".") : getLocalKey(key2);
374
+ getLocalStorageKey(key, global) {
375
+ return global ? ["common", key].join(".") : getLocalKey(key);
552
376
  }
553
- get(key2, defaultValue, global) {
554
- const lsKey = this.getLocalStorageKey(key2, global);
377
+ get(key, defaultValue, global) {
378
+ const lsKey = this.getLocalStorageKey(key, global);
555
379
  const value = localStorage.getItem(lsKey);
556
380
  return value !== null ? JSON.parse(value) : defaultValue;
557
381
  }
558
- set(key2, value, global) {
382
+ set(key, value, global) {
559
383
  localStorage.setItem(
560
- this.getLocalStorageKey(key2, global),
384
+ this.getLocalStorageKey(key, global),
561
385
  JSON.stringify(value)
562
386
  );
563
387
  }
564
- remove(key2, global) {
565
- const lsKey = this.getLocalStorageKey(key2, global);
388
+ remove(key, global) {
389
+ const lsKey = this.getLocalStorageKey(key, global);
566
390
  if (localStorage.getItem(lsKey) !== null) {
567
391
  localStorage.removeItem(lsKey);
568
392
  return true;
@@ -572,9 +396,9 @@ return s;
572
396
  }
573
397
  clear() {
574
398
  const baseKey = getLocalKey("");
575
- for (let key2 in localStorage) {
576
- if (key2.slice(0, baseKey.length) === baseKey) {
577
- localStorage.removeItem(key2);
399
+ for (let key in localStorage) {
400
+ if (key.slice(0, baseKey.length) === baseKey) {
401
+ localStorage.removeItem(key);
578
402
  }
579
403
  }
580
404
  }
@@ -589,8 +413,8 @@ return s;
589
413
  function getSettings(setting, article) {
590
414
  if (!af?.userSession)
591
415
  return null;
592
- const key2 = getKey(article);
593
- const settings = JSON.parse(localStorage.getItem(key2) || "{}");
416
+ const key = getKey(article);
417
+ const settings = JSON.parse(localStorage.getItem(key) || "{}");
594
418
  if (setting) {
595
419
  return settings[setting] || null;
596
420
  }
@@ -599,17 +423,17 @@ return s;
599
423
  function saveSettings(setting, value, article) {
600
424
  if (!af?.userSession)
601
425
  return;
602
- const key2 = getKey(article);
603
- let userSettings = JSON.parse(localStorage.getItem(key2) || "{}");
426
+ const key = getKey(article);
427
+ let userSettings = JSON.parse(localStorage.getItem(key) || "{}");
604
428
  if (typeof value !== "undefined") {
605
429
  userSettings[setting] = value;
606
430
  } else {
607
431
  userSettings = setting;
608
432
  }
609
- localStorage.setItem(key2, JSON.stringify(userSettings));
433
+ localStorage.setItem(key, JSON.stringify(userSettings));
610
434
  }
611
435
 
612
436
  // src/index.ts
613
- var version = "2.0.3";
437
+ var version = "2.1.0";
614
438
  return __toCommonJS(src_exports);
615
439
  })();