cx 24.3.7 → 24.3.9

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.
package/src/ui/Culture.js CHANGED
@@ -1,76 +1,132 @@
1
- import { NumberCulture, DateTimeCulture } from "intl-io";
2
- import { Localization } from "./Localization";
3
- import { GlobalCacheIdentifier } from "../util/GlobalCacheIdentifier";
4
- import { invalidateExpressionCache } from "../data/Expression";
5
- import { invalidateStringTemplateCache } from "../data/StringTemplate";
6
- import { defaultCompare } from "../data/defaultCompare";
7
-
8
- let culture = "en";
9
- let numberCulture = null;
10
- let dateTimeCulture = null;
11
- let cultureCache = {};
12
- let defaultCurrency = "USD";
13
- let dateEncoding = (date) => date.toISOString();
14
-
15
- export class Culture {
16
- static setCulture(cultureCode) {
17
- culture = cultureCode;
18
- cultureCache = {};
19
- Localization.setCulture(cultureCode);
20
- this.invalidateCache();
21
- }
22
-
23
- static setNumberCulture(cultureCode) {
24
- numberCulture = cultureCode;
25
- delete cultureCache.numberCulture;
26
- this.invalidateCache();
27
- }
28
-
29
- static setDateTimeCulture(cultureCode) {
30
- dateTimeCulture = cultureCode;
31
- delete cultureCache.dateTimeCulture;
32
- this.invalidateCache();
33
- }
34
-
35
- static setDefaultCurrency(currencyCode) {
36
- defaultCurrency = currencyCode;
37
- this.invalidateCache();
38
- }
39
-
40
- static invalidateCache() {
41
- GlobalCacheIdentifier.change();
42
- invalidateExpressionCache();
43
- invalidateStringTemplateCache();
44
- }
45
-
46
- static get defaultCurrency() {
47
- return defaultCurrency;
48
- }
49
-
50
- static get culture() {
51
- return culture;
52
- }
53
-
54
- static getNumberCulture() {
55
- if (!cultureCache.numberCulture) cultureCache.numberCulture = new NumberCulture(numberCulture ?? culture);
56
- return cultureCache.numberCulture;
57
- }
58
-
59
- static getDateTimeCulture() {
60
- if (!cultureCache.dateTimeCulture) cultureCache.dateTimeCulture = new DateTimeCulture(dateTimeCulture ?? culture);
61
- return cultureCache.dateTimeCulture;
62
- }
63
-
64
- static getDefaultDateEncoding() {
65
- return dateEncoding;
66
- }
67
-
68
- static setDefaultDateEncoding(encoding) {
69
- dateEncoding = encoding;
70
- }
71
-
72
- static getComparer(options) {
73
- if (typeof Intl.Collator != "undefined") return new Intl.Collator(culture, options).compare;
74
- return defaultCompare;
75
- }
76
- }
1
+ import { NumberCulture, DateTimeCulture } from "intl-io";
2
+ import { Localization } from "./Localization";
3
+ import { GlobalCacheIdentifier } from "../util/GlobalCacheIdentifier";
4
+ import { invalidateExpressionCache } from "../data/Expression";
5
+ import { invalidateStringTemplateCache } from "../data/StringTemplate";
6
+ import { defaultCompare } from "../data/defaultCompare";
7
+
8
+ // let culture = "en";
9
+ // let numberCulture = null;
10
+ // let dateTimeCulture = null;
11
+ // let cache = {};
12
+ // let defaultCurrency = "USD";
13
+ // let dateEncoding = (date) => date.toISOString();
14
+
15
+ let stack = [
16
+ {
17
+ culture: "en",
18
+ numberCulture: null,
19
+ dateTimeCulture: null,
20
+ cache: {},
21
+ defaultCurrency: "USD",
22
+ dateEncoding: (date) => date.toISOString(),
23
+ },
24
+ ];
25
+
26
+ function getRootCultureSpecs() {
27
+ return stack[0];
28
+ }
29
+
30
+ function getCurrentCultureSpecs() {
31
+ return stack[stack.length - 1];
32
+ }
33
+
34
+ export function getCurrentCultureCache() {
35
+ return getCurrentCultureSpecs().cache;
36
+ }
37
+
38
+ export function pushCulture(cultureInfo) {
39
+ stack.push(cultureInfo);
40
+ }
41
+
42
+ export function createCulture(cultureSpecs) {
43
+ let current = getCurrentCultureSpecs();
44
+ let info = {
45
+ culture: current.culture,
46
+ dateEncoding: current.dateEncoding,
47
+ defaultCurrency: current.defaultCurrency,
48
+ cache: {},
49
+ };
50
+ for (let key in cultureSpecs) {
51
+ if (!cultureSpecs[key]) continue;
52
+ info[key] = cultureSpecs[key];
53
+ }
54
+ return info;
55
+ }
56
+
57
+ export function popCulture() {
58
+ if (stack.length == 1) throw new Error("Cannot pop the last culture object.");
59
+ return stack.pop();
60
+ }
61
+
62
+ export class Culture {
63
+ static setCulture(cultureCode) {
64
+ let cultureSpecs = getRootCultureSpecs();
65
+ cultureSpecs.culture = cultureCode;
66
+ cultureSpecs.cache = {};
67
+ Localization.setCulture(cultureCode);
68
+ this.invalidateCache();
69
+ }
70
+
71
+ static setNumberCulture(cultureCode) {
72
+ let cultureSpecs = getRootCultureSpecs();
73
+ cultureSpecs.numberCulture = cultureCode;
74
+ delete cultureSpecs.cache.numberCulture;
75
+ this.invalidateCache();
76
+ }
77
+
78
+ static setDateTimeCulture(cultureCode) {
79
+ let cultureSpecs = getRootCultureSpecs();
80
+ cultureSpecs.dateTimeCulture = cultureCode;
81
+ delete cultureSpecs.cache.dateTimeCulture;
82
+ this.invalidateCache();
83
+ }
84
+
85
+ static setDefaultCurrency(currencyCode) {
86
+ let cultureSpecs = getRootCultureSpecs();
87
+ cultureSpecs.defaultCurrency = currencyCode;
88
+ this.invalidateCache();
89
+ }
90
+
91
+ static setDefaultDateEncoding(encoding) {
92
+ let cultureSpecs = getRootCultureSpecs();
93
+ cultureSpecs.dateEncoding = encoding;
94
+ this.invalidateCache();
95
+ }
96
+
97
+ static invalidateCache() {
98
+ GlobalCacheIdentifier.change();
99
+ invalidateExpressionCache();
100
+ invalidateStringTemplateCache();
101
+ }
102
+
103
+ static get defaultCurrency() {
104
+ return getCurrentCultureSpecs().defaultCurrency;
105
+ }
106
+
107
+ static get culture() {
108
+ return getCurrentCultureSpecs().culture;
109
+ }
110
+
111
+ static getNumberCulture() {
112
+ let { cache, numberCulture, culture } = getCurrentCultureSpecs();
113
+ if (!cache.numberCulture) cache.numberCulture = new NumberCulture(numberCulture ?? culture);
114
+ return cache.numberCulture;
115
+ }
116
+
117
+ static getDateTimeCulture() {
118
+ let { cache, dateTimeCulture, culture } = getCurrentCultureSpecs();
119
+ if (!cache.dateTimeCulture) cache.dateTimeCulture = new DateTimeCulture(dateTimeCulture ?? culture);
120
+ return cache.dateTimeCulture;
121
+ }
122
+
123
+ static getDefaultDateEncoding() {
124
+ return getCurrentCultureSpecs().dateEncoding;
125
+ }
126
+
127
+ static getComparer(options) {
128
+ let { culture } = getCurrentCultureSpecs();
129
+ if (typeof Intl.Collator != "undefined") return new Intl.Collator(culture, options).compare;
130
+ return defaultCompare;
131
+ }
132
+ }
@@ -0,0 +1,10 @@
1
+ import * as Cx from "../core";
2
+
3
+ interface CultureScopeProps extends Cx.PureContainerProps {
4
+ culture: Cx.StringProp;
5
+ numberCulture: Cx.StringProp;
6
+ dateTimeCulture: Cx.StringProp;
7
+ defaultCurrency: Cx.StringProp;
8
+ }
9
+
10
+ export class CultureScope extends Cx.Widget<CultureScopeProps> {}
@@ -0,0 +1,53 @@
1
+ import { createCulture, popCulture, pushCulture } from "./Culture";
2
+ import { PureContainer } from "./PureContainer";
3
+
4
+ export class CultureScope extends PureContainer {
5
+ init() {
6
+ this.initialItems = this.items ?? this.children;
7
+ delete this.items;
8
+ delete this.children;
9
+ super.init();
10
+ }
11
+
12
+ declareData(...args) {
13
+ super.declareData(...args, {
14
+ culture: undefined,
15
+ numberCulture: undefined,
16
+ dateTimeCulture: undefined,
17
+ defaultCurrency: undefined,
18
+ });
19
+ }
20
+
21
+ prepareData(context, instance) {
22
+ super.prepareData(context, instance);
23
+ this.clear();
24
+ let { data } = instance;
25
+
26
+ if (this.onCreateCulture) instance.culture = instance.invoke("onCreateCulture", data, instance);
27
+ else
28
+ instance.culture = createCulture({
29
+ culture: data.culture,
30
+ numberCulture: data.numberCulture,
31
+ dateTimeCulture: data.dateTimeCulture,
32
+ defaultCurrency: data.defaultCurrency,
33
+ dateEncoding: this.dateEncoding,
34
+ });
35
+ }
36
+
37
+ explore(context, instance) {
38
+ let { culture } = instance;
39
+ pushCulture(culture);
40
+ if (this.items.length == 0 && this.initialItems) this.add(this.initialItems);
41
+ super.explore(context, instance);
42
+ }
43
+
44
+ exploreCleanup(context, instance) {
45
+ popCulture();
46
+ }
47
+ }
48
+
49
+ CultureScope.prototype.culture = null;
50
+ CultureScope.prototype.numberCulture = null;
51
+ CultureScope.prototype.dateTimeCulture = null;
52
+ CultureScope.prototype.defaultCurrency = null;
53
+ CultureScope.prototype.dateEncoding = null;
package/src/ui/Format.js CHANGED
@@ -1,87 +1,107 @@
1
- import { Culture } from "./Culture";
2
- import { Format as Fmt, resolveMinMaxFractionDigits } from "../util/Format";
3
- import { GlobalCacheIdentifier } from "../util/GlobalCacheIdentifier";
4
-
5
- export const Format = Fmt;
6
-
7
- let cultureSensitiveFormatsRegistered = false;
8
-
9
- export function resolveNumberFormattingFlags(flags) {
10
- if (!flags) return null;
11
- let result = {};
12
- if (flags.indexOf("+") >= 0) result.signDisplay = "exceptZero";
13
- if (flags.indexOf("c") >= 0) result.notation = "compact";
14
- if (flags.indexOf("a") >= 0) result.currencySign = "accounting";
15
- return result;
16
- }
17
-
18
- export function enableCultureSensitiveFormatting() {
19
- if (cultureSensitiveFormatsRegistered) return;
20
-
21
- cultureSensitiveFormatsRegistered = true;
22
-
23
- Fmt.registerFactory(["number", "n"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
24
- let culture = Culture.getNumberCulture();
25
-
26
- let formatter = culture.getFormatter({
27
- ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
28
- ...resolveNumberFormattingFlags(flags),
29
- });
30
-
31
- return (value) => formatter.format(value);
32
- });
33
-
34
- Fmt.registerFactory("currency", (format, currency, minimumFractionDigits, maximumFractionDigits, flags) => {
35
- let culture = Culture.getNumberCulture();
36
- currency = currency || Culture.defaultCurrency;
37
-
38
- let formatter = culture.getFormatter({
39
- style: "currency",
40
- currency: currency,
41
- ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
42
- ...resolveNumberFormattingFlags(flags),
43
- });
44
-
45
- return (value) => formatter.format(value);
46
- });
47
-
48
- Fmt.registerFactory(["percentage", "p", "%"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
49
- let culture = Culture.getNumberCulture();
50
- let formatter = culture.getFormatter({
51
- style: "percent",
52
- ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
53
- ...resolveNumberFormattingFlags(flags),
54
- });
55
- return (value) => formatter.format(value);
56
- });
57
-
58
- Fmt.registerFactory(["percentSign", "ps"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
59
- let culture = Culture.getNumberCulture();
60
- let formatter = culture.getFormatter({
61
- style: "percent",
62
- ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
63
- ...resolveNumberFormattingFlags(flags),
64
- });
65
- return (value) => formatter.format(value / 100);
66
- });
67
-
68
- Fmt.registerFactory(["date", "d"], (fmt, format = "yyyyMMdd") => {
69
- let culture = Culture.getDateTimeCulture();
70
- let formatter = culture.getFormatter(format);
71
- return (value) => formatter.format(new Date(value));
72
- });
73
-
74
- Fmt.registerFactory(["time", "t"], (fmt, format = "hhmmss") => {
75
- let culture = Culture.getDateTimeCulture();
76
- let formatter = culture.getFormatter(format);
77
- return (value) => formatter.format(new Date(value));
78
- });
79
-
80
- Fmt.registerFactory(["datetime", "dt"], (fmt, format = "yyyyMd hhmm") => {
81
- let culture = Culture.getDateTimeCulture();
82
- let formatter = culture.getFormatter(format);
83
- return (value) => formatter.format(new Date(value));
84
- });
85
-
86
- GlobalCacheIdentifier.change();
87
- }
1
+ import { Culture, getCurrentCultureCache } from "./Culture";
2
+ import { Format as Fmt, resolveMinMaxFractionDigits, setGetFormatCacheCallback } from "../util/Format";
3
+ import { GlobalCacheIdentifier } from "../util/GlobalCacheIdentifier";
4
+ import { setGetExpressionCacheCallback } from "../data/Expression";
5
+ import { setGetStringTemplateCacheCallback } from "../data/StringTemplate";
6
+
7
+ export const Format = Fmt;
8
+
9
+ let cultureSensitiveFormatsRegistered = false;
10
+
11
+ export function resolveNumberFormattingFlags(flags) {
12
+ if (!flags) return null;
13
+ let result = {};
14
+ if (flags.indexOf("+") >= 0) result.signDisplay = "exceptZero";
15
+ if (flags.indexOf("c") >= 0) result.notation = "compact";
16
+ if (flags.indexOf("a") >= 0) result.currencySign = "accounting";
17
+ return result;
18
+ }
19
+
20
+ export function enableCultureSensitiveFormatting() {
21
+ if (cultureSensitiveFormatsRegistered) return;
22
+
23
+ cultureSensitiveFormatsRegistered = true;
24
+
25
+ Fmt.registerFactory(["number", "n"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
26
+ let culture = Culture.getNumberCulture();
27
+
28
+ let formatter = culture.getFormatter({
29
+ ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
30
+ ...resolveNumberFormattingFlags(flags),
31
+ });
32
+
33
+ return (value) => formatter.format(value);
34
+ });
35
+
36
+ Fmt.registerFactory("currency", (format, currency, minimumFractionDigits, maximumFractionDigits, flags) => {
37
+ let culture = Culture.getNumberCulture();
38
+ currency = currency || Culture.defaultCurrency;
39
+
40
+ let formatter = culture.getFormatter({
41
+ style: "currency",
42
+ currency: currency,
43
+ ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
44
+ ...resolveNumberFormattingFlags(flags),
45
+ });
46
+
47
+ return (value) => formatter.format(value);
48
+ });
49
+
50
+ Fmt.registerFactory(["percentage", "p", "%"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
51
+ let culture = Culture.getNumberCulture();
52
+ let formatter = culture.getFormatter({
53
+ style: "percent",
54
+ ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
55
+ ...resolveNumberFormattingFlags(flags),
56
+ });
57
+ return (value) => formatter.format(value);
58
+ });
59
+
60
+ Fmt.registerFactory(["percentSign", "ps"], (format, minimumFractionDigits, maximumFractionDigits, flags) => {
61
+ let culture = Culture.getNumberCulture();
62
+ let formatter = culture.getFormatter({
63
+ style: "percent",
64
+ ...resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits),
65
+ ...resolveNumberFormattingFlags(flags),
66
+ });
67
+ return (value) => formatter.format(value / 100);
68
+ });
69
+
70
+ Fmt.registerFactory(["date", "d"], (fmt, format = "yyyyMMdd") => {
71
+ let culture = Culture.getDateTimeCulture();
72
+ let formatter = culture.getFormatter(format);
73
+ return (value) => formatter.format(new Date(value));
74
+ });
75
+
76
+ Fmt.registerFactory(["time", "t"], (fmt, format = "hhmmss") => {
77
+ let culture = Culture.getDateTimeCulture();
78
+ let formatter = culture.getFormatter(format);
79
+ return (value) => formatter.format(new Date(value));
80
+ });
81
+
82
+ Fmt.registerFactory(["datetime", "dt"], (fmt, format = "yyyyMd hhmm") => {
83
+ let culture = Culture.getDateTimeCulture();
84
+ let formatter = culture.getFormatter(format);
85
+ return (value) => formatter.format(new Date(value));
86
+ });
87
+
88
+ setGetFormatCacheCallback(() => {
89
+ let cache = getCurrentCultureCache();
90
+ if (!cache.formatCache) cache.formatCache = {};
91
+ return cache.formatCache;
92
+ });
93
+
94
+ setGetExpressionCacheCallback(() => {
95
+ let cache = getCurrentCultureCache();
96
+ if (!cache.exprCache) cache.exprCache = {};
97
+ return cache.exprCache;
98
+ });
99
+
100
+ setGetStringTemplateCacheCallback(() => {
101
+ let cache = getCurrentCultureCache();
102
+ if (!cache.strTplCache) cache.strTplCache = {};
103
+ return cache.strTplCache;
104
+ });
105
+
106
+ GlobalCacheIdentifier.change();
107
+ }