| @@ -0,0 +1,8 | |||||
| 
             | 
        1 | import { bundle } from "../i18n"; | |||
| 
             | 
        2 | ||||
| 
             | 
        3 | export default bundle({ | |||
| 
             | 
        4 | greeting: (name: string) => `Hello, ${name}!`, | |||
| 
             | 
        5 | goodbye: (name: string) => `Bye, ${name}!` | |||
| 
             | 
        6 | }, { | |||
| 
             | 
        7 | ru: () => import("./ru/foo") | |||
| 
             | 
        8 | }); | |||
| @@ -0,0 +1,6 | |||||
| 
             | 
        1 | import foo from "../foo"; | |||
| 
             | 
        2 | ||||
| 
             | 
        3 | export default foo.define({ | |||
| 
             | 
        4 | greeting: (name: string) => `Привет, ${name}`, | |||
| 
             | 
        5 | goodbye: (name: string) => `Пока, ${name}` | |||
| 
             | 
        6 | }); | |||
| 1 | NO CONTENT: new file 100644 | 
             | 
        NO CONTENT: new file 100644 | 
| @@ -60,26 +60,26 export class MyWidget extends djbase( | |||||
| 60 | 
             | 
        60 | |||
| 61 | ## DESCRIPTION | 
             | 
        61 | ## DESCRIPTION | |
| 62 | 
             | 
        62 | |||
| 63 | This package provides you with tools to glue your good-fellow dojo with modern | 
             | 
        63 | This package provides you with the tools to glue your good-fellow dojo with modern | |
| 64 | techniques of building the webapp. The core concept is built around widgets and | 
             | 
        64 | techniques of building the webapp. The core concept is to built around widgets and | |
| 65 | using .tsx to write it. Here some features: | 
             | 
        65 | using .tsx to write it. Here are some features: | |
| 66 | 
             | 
        66 | |||
| 67 | * `djbase()`, `@djaclass` - traits to declare your classes with `dojo/_base/declare` | 
             | 
        67 | * `djbase()`, `@djaclass` - traits to declare your classes with `dojo/_base/declare` | |
| 68 | * `@implab/djx/tsx` - traits to build the rendering of your widgets with tsx | 
             | 
        68 | * `@implab/djx/tsx` - traits to build the rendering of your widgets with tsx | |
| 69 | * `DjxWidgetBase` - abstract class which supports tsx markup and | 
             | 
        69 | * `DjxWidgetBase` - abstract class which supports tsx markup and | |
| 70 | `data-dojo-attach-*` attributes. | 
             | 
        70 | `data-dojo-attach-*` attributes. | |
| 71 | 
            
            * `@bind(...)` - annotations provide | 
        
             | 
        71 | * `@bind(...)` - annotations provide an easy way of using standard dojo widget | |
| 72 | attribute bindings. | 
             | 
        72 | attribute bindings. | |
| 73 | 
             | 
        73 | |||
| 74 | ### djbase, @djclass | 
             | 
        74 | ### djbase, @djclass | |
| 75 | 
             | 
        75 | |||
| 76 | 
            
            These two traits provide | 
        
             | 
        76 | These two traits provide convenient way of using `dojo/_base/declare` in Typescript | |
| 77 | for declaring your classes. | 
             | 
        77 | for declaring your classes. | |
| 78 | 
             | 
        78 | |||
| 79 | `djbase(...constructors)` - this method accepts a list of constructors in its | 
             | 
        79 | `djbase(...constructors)` - this method accepts a list of constructors in its | |
| 80 | parameters and returns the **fake** base type which then can be used to derive | 
             | 
        80 | parameters and returns the **fake** base type which then can be used to derive | |
| 81 | your own class. This allows you to provide the Typescript with the correct | 
             | 
        81 | your own class. This allows you to provide the Typescript with the correct | |
| 82 | 
            
            information about the base type and even use `super`!. The only  | 
        
             | 
        82 | information about the base type and even use `super`!. The only caveat of | |
| 83 | this approach is that you **MUST** decorate your class with `@djclass` annotation. | 
             | 
        83 | this approach is that you **MUST** decorate your class with `@djclass` annotation. | |
| 84 | 
             | 
        84 | |||
| 85 | Consider the following example: | 
             | 
        85 | Consider the following example: | |
| @@ -150,11 +150,11 you will get the following output: | |||||
| 150 | <- Baz | 
             | 
        150 | <- Baz | |
| 151 | ``` | 
             | 
        151 | ``` | |
| 152 | 
             | 
        152 | |||
| 153 | 
            
            Let's take a closer look t | 
        
             | 
        153 | Let's take a closer look at the `Baz` declaration it uses `djbase` to derive | |
| 154 | from three mixins and the class is decorated with `@djclass` to accomplish the | 
             | 
        154 | from three mixins and the class is decorated with `@djclass` to accomplish the | |
| 155 | declaration and make a real constructor. | 
             | 
        155 | declaration and make a real constructor. | |
| 156 | 
             | 
        156 | |||
| 157 | 
            
            To allow | 
        
             | 
        157 | To allow access to the next sibling method (in terms of multiple inheritance) | |
| 158 | Dojo provides `this.inherited(arguments)` method but this approach leads to the | 
             | 
        158 | Dojo provides `this.inherited(arguments)` method but this approach leads to the | |
| 159 | problem with 'strict' mode of ES5 and eliminates the type information about a | 
             | 
        159 | problem with 'strict' mode of ES5 and eliminates the type information about a | |
| 160 | calling method. This library solves the problem calling inherited/next method by | 
             | 
        160 | calling method. This library solves the problem calling inherited/next method by | |
| @@ -162,9 +162,9 utilizing `super` keyword. Under the hoo | |||||
| 162 | the prototype of the declared class which make calls to `this.inherited(...)` | 
             | 
        162 | the prototype of the declared class which make calls to `this.inherited(...)` | |
| 163 | method. This technique is compatible with 'strict' mode. | 
             | 
        163 | method. This technique is compatible with 'strict' mode. | |
| 164 | 
             | 
        164 | |||
| 165 | 
            
            Mixins are declared  | 
        
             | 
        165 | Mixins are declared similar, they also may have the base types although | |
| 166 | the most common case is declaring the mixin without any base classes. To allow | 
             | 
        166 | the most common case is declaring the mixin without any base classes. To allow | |
| 167 | 
            
            the mixin to access the next method  | 
        
             | 
        167 | the mixin to access the next method declare the interface with | |
| 168 | desired methods and use the special form of `djbase<Super>()` without arguments. | 
             | 
        168 | desired methods and use the special form of `djbase<Super>()` without arguments. | |
| 169 | 
             | 
        169 | |||
| 170 | ### DjxWidgetBase<Attrs, Events> | 
             | 
        170 | ### DjxWidgetBase<Attrs, Events> | |
| @@ -21,6 +21,10 function isCallback<T>(v: ResolveCallbac | |||||
| 21 | return typeof v === "function"; | 
             | 
        21 | return typeof v === "function"; | |
| 22 | } | 
             | 
        22 | } | |
| 23 | 
             | 
        23 | |||
| 
             | 
        24 | function defaultResolver(module: string) { | |||
| 
             | 
        25 | return import(module).then(x => x && x.default ? x.default : x); | |||
| 
             | 
        26 | } | |||
| 
             | 
        27 | ||||
| 24 | function chainObjects<T extends object>(o1: T, o2: T) { | 
             | 
        28 | function chainObjects<T extends object>(o1: T, o2: T) { | |
| 25 | if (!o1) | 
             | 
        29 | if (!o1) | |
| 26 | return o2; | 
             | 
        30 | return o2; | |
| @@ -31,51 +35,48 function chainObjects<T extends object>( | |||||
| 31 | } | 
             | 
        35 | } | |
| 32 | 
             | 
        36 | |||
| 33 | export class NlsBundle<T extends object> { | 
             | 
        37 | export class NlsBundle<T extends object> { | |
| 34 | _locales: MapOf<ResolveCallback<T> | PromiseOrValue<T>>; | 
             | 
        38 | private _locales: MapOf<ResolveCallback<T> | PromiseOrValue<T>>; | |
| 35 | default: T; | 
             | 
        |||
| 36 | 
             | 
        39 | |||
| 37 | _cache: MapOf<PromiseOrValue<T>>; | 
             | 
        40 | private _default: T; | |
| 
             | 
        41 | ||||
| 
             | 
        42 | private _cache: MapOf<PromiseOrValue<T>>; | |||
| 38 | 
             | 
        43 | |||
| 39 | constructor(defNls: T, locales?: MapOf<any>) { | 
             | 
        44 | constructor(defNls: T, locales?: MapOf<any>) { | |
| 40 | this.default = defNls; | 
             | 
        45 | this._default = defNls; | |
| 41 | this._locales = locales || {}; | 
             | 
        46 | this._locales = locales || {}; | |
| 42 | this._cache = {}; | 
             | 
        47 | this._cache = {}; | |
| 43 | } | 
             | 
        48 | } | |
| 44 | 
             | 
        49 | |||
| 45 | getLocale(locale: string) { | 
             | 
        50 | getLocale(locale?: string) { | |
| 46 | 
            
                    const _loc = locale  | 
        
             | 
        51 | const _loc = locale ?? sysLocale; | |
| 47 | 
             | 
        ||||
| 48 | const locales = new Array<string>(); | 
             | 
        |||
| 49 | 
             | 
        52 | |||
| 50 | _loc.split("-").reduce((a, x) => { | 
             | 
        53 | // en-US => ["en", "en-US"] | |
| 51 | a.push(x); | 
             | 
        54 | const locales = _loc.split(/-|_/).map((x, i, a) => a.slice(0, i + 1).join("-")); | |
| 52 | locales.unshift(a.join("-")); | 
             | 
        |||
| 53 | return a; | 
             | 
        |||
| 54 | }, new Array<string>()); | 
             | 
        |||
| 55 | 
             | 
        ||||
| 56 | return this._resolveLocale(locales); | 
             | 
        55 | return this._resolveLocale(locales); | |
| 57 | } | 
             | 
        56 | } | |
| 58 | 
             | 
        57 | |||
| 59 | _resolveLocale(locales: string[]): PromiseOrValue<T> { | 
             | 
        58 | _resolveLocale(locales: string[]): PromiseOrValue<T> { | |
| 60 | if (!locales.length) | 
             | 
        59 | if (!locales.length) | |
| 61 | return this.default; | 
             | 
        60 | return this._default; | |
| 62 | 
             | 
        61 | |||
| 63 | 
            
                    const locale = locales. | 
        
             | 
        62 | const locale = locales.pop(); | |
| 64 | 
             | 
        ||||
| 65 | if (!locale) | 
             | 
        63 | if (!locale) | |
| 66 | return this._resolveLocale(locales); | 
             | 
        64 | throw new Error("The locale can't be empty"); | |
| 67 | 
             | 
        65 | |||
| 68 | if (this._cache[locale]) | 
             | 
        66 | if (this._cache[locale]) | |
| 69 | return this._cache[locale]; | 
             | 
        67 | return this._cache[locale]; | |
| 70 | 
             | 
        68 | |||
| 71 | 
            
                     | 
        
             | 
        69 | const data = this._loadPackage(this._locales[locale]); | |
| 72 | if (isCallback(data)) | 
             | 
        |||
| 73 | data = data(); | 
             | 
        |||
| 74 | 
             | 
        ||||
| 75 | const parent = this._resolveLocale(locales); | 
             | 
        70 | const parent = this._resolveLocale(locales); | |
| 76 | 
             | 
        71 | |||
| 77 | return this._cache[locale] = when(data, x => { | 
             | 
        72 | return this._cache[locale] = when(data, x => { | |
| 78 | return when(parent, y => this._cache[locale] = chainObjects(y, x)); | 
             | 
        73 | return when(parent, y => this._cache[locale] = chainObjects(y, x)); | |
| 79 | }); | 
             | 
        74 | }); | |
| 80 | } | 
             | 
        75 | } | |
| 
             | 
        76 | ||||
| 
             | 
        77 | _loadPackage(localeData: any) { | |||
| 
             | 
        78 | if (isCallback(localeData)) | |||
| 
             | 
        79 | return when(localeData(), data => data && "default" in data ? data.default : data); | |||
| 
             | 
        80 | return localeData; | |||
| 
             | 
        81 | } | |||
| 81 | } | 
             | 
        82 | } | |
| @@ -7,7 +7,7 interface OnLoad { | |||||
| 7 | 
             | 
        7 | |||
| 8 | const plugin = { | 
             | 
        8 | const plugin = { | |
| 9 | load: (id: string, require: Require, cb: OnLoad, config: { isBuild?: boolean }) => { | 
             | 
        9 | load: (id: string, require: Require, cb: OnLoad, config: { isBuild?: boolean }) => { | |
| 10 | if (config.isBuild) { | 
             | 
        10 | if (config && config.isBuild) { | |
| 11 | cb(); | 
             | 
        11 | cb(); | |
| 12 | } else { | 
             | 
        12 | } else { | |
| 13 | const url = require.toUrl(id); | 
             | 
        13 | const url = require.toUrl(id); | |
| @@ -11,7 +11,7 export function bundle<T extends object> | |||||
| 11 | const nlsBundle = new NlsBundle(nls, locales); | 
             | 
        11 | const nlsBundle = new NlsBundle(nls, locales); | |
| 12 | 
             | 
        12 | |||
| 13 | const fn = (locale?: string) => { | 
             | 
        13 | const fn = (locale?: string) => { | |
| 14 | 
            
                    const result =  | 
        
             | 
        14 | const result = nlsBundle.getLocale(locale); | |
| 15 | 
             | 
        15 | |||
| 16 | if (isPromise(result)) | 
             | 
        16 | if (isPromise(result)) | |
| 17 | throw new Error(`The bundle '${locale}' isn't loaded`); | 
             | 
        17 | throw new Error(`The bundle '${locale}' isn't loaded`); | |
| @@ -20,7 +20,6 export function bundle<T extends object> | |||||
| 20 | }; | 
             | 
        20 | }; | |
| 21 | 
             | 
        21 | |||
| 22 | fn.define = (pack: Partial<T>) => pack; | 
             | 
        22 | fn.define = (pack: Partial<T>) => pack; | |
| 23 | fn.default = nlsBundle.default; | 
             | 
        |||
| 24 | fn.load = async (id: string, require: Require, cb: OnLoad, config: any) => { | 
             | 
        23 | fn.load = async (id: string, require: Require, cb: OnLoad, config: any) => { | |
| 25 | if (config && config.isBuild) { | 
             | 
        24 | if (config && config.isBuild) { | |
| 26 | cb(); | 
             | 
        25 | cb(); | |
| @@ -29,7 +28,8 export function bundle<T extends object> | |||||
| 29 | await nlsBundle.getLocale(id); | 
             | 
        28 | await nlsBundle.getLocale(id); | |
| 30 | cb(); | 
             | 
        29 | cb(); | |
| 31 | } catch (e) { | 
             | 
        30 | } catch (e) { | |
| 32 | 
            
                            cb.error | 
        
             | 
        31 | if(cb.error) | |
| 
             | 
        32 | cb.error(e); | |||
| 33 | } | 
             | 
        33 | } | |
| 34 | } | 
             | 
        34 | } | |
| 35 | }; | 
             | 
        35 | }; | |
        
        General Comments 0
    
    
  
  
                      You need to be logged in to leave comments.
                      Login now
                    
                