### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\crypto-js.d.ts // Type definitions for crypto-js v4.0.0 // Project: https://github.com/brix/crypto-js // Definitions by: Michael Zabka // Max Lysenko // Brendan Early // Doma // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped type WordArray = CryptoJS.lib.WordArray; type CipherParams = CryptoJS.lib.CipherParams; type X64Word = CryptoJS.x64.Word; /** * Encoding strategy. */ interface Encoder { /** * Converts a word array to a hex string. * * @param wordArray The word array. * * @return The hex string. * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify(wordArray: WordArray): string; /** * Converts a hex string to a word array. * * @param hexStr The hex string. * * @return The word array. * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse(str: string): WordArray; } /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. */ interface BufferedBlockAlgorithm { /** * The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ _minBufferSize: number; /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset(): void; /** * Adds new data to this block algorithm's buffer. * * @param data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append(data: WordArray | string): void; /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param doFlush Whether all blocks and partial blocks should be processed. * * @return The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process(doFlush?: boolean): WordArray; /** * Creates a copy of this object. * * @return The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone(): BufferedBlockAlgorithm; } /** * Abstract hasher template. */ interface Hasher { /** * The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ blockSize: number; /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset(): void; /** * Updates this hasher with a message. * * @param messageUpdate The message to append. * * @return This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update(messageUpdate: WordArray | string): this; /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param messageUpdate (Optional) A final message update. * * @return The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize(messaegUpdate?: WordArray | string): WordArray; } interface HasherStatic { /** * Initializes a newly created hasher. * * @param cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ create(cfg?: object): Hasher; } interface HasherHelper { (message: WordArray | string, cfg?: object): WordArray; } interface HmacHasherHelper { (message: WordArray | string, key: WordArray | string): WordArray; } /** * Abstract base cipher template. */ interface Cipher { /** * This cipher's key size. Default: 4 (128 bits) */ keySize: number; /** * This cipher's IV size. Default: 4 (128 bits) */ ivSize: number; /** * A constant representing encryption mode. */ readonly _ENC_XFORM_MODE: number; /** * A constant representing decryption mode. */ readonly _DEV_XFORM_MODE: number; /** * Resets this cipher to its initial state. * * @example * * cipher.reset(); */ reset(): void; /** * Adds data to be encrypted or decrypted. * * @param dataUpdate The data to encrypt or decrypt. * * @return The data after processing. * * @example * * var encrypted = cipher.process('data'); * var encrypted = cipher.process(wordArray); */ process(dataUpdate: WordArray | string): WordArray; /** * Finalizes the encryption or decryption process. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param dataUpdate The final data to encrypt or decrypt. * * @return The data after final processing. * * @example * * var encrypted = cipher.finalize(); * var encrypted = cipher.finalize('data'); * var encrypted = cipher.finalize(wordArray); */ finalize(dataUpdate?: WordArray | string): WordArray; } interface CipherStatic { /** * Creates this cipher in encryption mode. * * @param key The key. * @param cfg (Optional) The configuration options to use for this operation. * * @return A cipher instance. * * @example * * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); */ createEncryptor(key: WordArray, cfg?: CipherOption): Cipher; /** * Creates this cipher in decryption mode. * * @param key The key. * @param cfg (Optional) The configuration options to use for this operation. * * @return A cipher instance. * * @example * * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); */ createDecryptor(key: WordArray, cfg?: CipherOption): Cipher; /** * Initializes a newly created cipher. * * @param xformMode Either the encryption or decryption transormation mode constant. * @param key The key. * @param cfg (Optional) The configuration options to use for this operation. * * @example * * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); */ create(xformMode: number, key: WordArray, cfg?: CipherOption): Cipher; } interface CipherHelper { encrypt( message: WordArray | string, key: WordArray | string, cfg?: CipherOption ): CipherParams; decrypt( ciphertext: CipherParams | string, key: WordArray | string, cfg?: CipherOption ): WordArray; } /** * Configuration options. */ interface CipherOption { /** * The IV to use for this operation. */ iv?: WordArray | undefined; format?: Format | undefined; [key: string]: any; } interface Mode { /** * Processes the data block at offset. * * @param words The data words to operate on. * @param offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock(words: number[], offset: number): void; } interface ModeStatic { /** * Initializes a newly created mode. * * @param cipher A block cipher instance. * @param iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); */ create(cipher: Cipher, iv: number[]): Mode; } /** * Abstract base block cipher mode template. */ interface BlockCipherMode { Encryptor: ModeStatic; Decryptor: ModeStatic; /** * Creates this mode for encryption. * * @param cipher A block cipher instance. * @param iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); */ createEncryptor(cipher: Cipher, iv: number[]): Mode; /** * Creates this mode for decryption. * * @param cipher A block cipher instance. * @param iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); */ createDecryptor(cipher: Cipher, iv: number[]): Mode; } /** * Abstract base block cipher mode template. */ interface BlockCipherMode { /** * Creates this mode for encryption. * * @param cipher A block cipher instance. * @param iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); */ createEncryptor(cipher: Cipher): Mode; } /** * Padding strategy. */ interface Padding { /** * Pads data using the algorithm defined in PKCS #5/7. * * @param data The data to pad. * @param blockSize The multiple that the data should be padded to. * * @example * * CryptoJS.pad.Pkcs7.pad(wordArray, 4); */ pad(data: WordArray, blockSize: number): void; /** * Unpads data that had been padded using the algorithm defined in PKCS #5/7. * * @param data The data to unpad. * * @example * * CryptoJS.pad.Pkcs7.unpad(wordArray); */ unpad(data: WordArray): void; } /** * Abstract base block cipher template. */ interface BlockCipher { /** * The number of 32-bit words this cipher operates on. Default: 4 (128 bits) */ blockSize: number; } /** * Configuration options. */ interface BlockCipherOption { /** * The block mode to use. Default: CBC */ mode: Mode; /** * The padding strategy to use. Default: Pkcs7 */ padding: Padding; } /** * Formatting strategy. */ interface Format { /** * Converts a cipher params object to an OpenSSL-compatible string. * * @param cipherParams The cipher params object. * * @return The OpenSSL-compatible string. * * @example * * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); */ stringify(cipherParams: CipherParams): string; /** * Converts an OpenSSL-compatible string to a cipher params object. * * @param openSSLStr The OpenSSL-compatible string. * * @return The cipher params object. * * @example * * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); */ parse(str: string): CipherParams; } /** * An array of 64-bit words. */ interface X64WordArray { /** * The array of CryptoJS.x64.Word objects. */ words: number[]; /** * The number of significant bytes in this word array. */ sigBytes: number; /** * Converts this 64-bit word array to a 32-bit word array. * * @return This word array's data as a 32-bit word array. * * @example * * var x32WordArray = x64WordArray.toX32(); */ toX32(): WordArray; /** * Creates a copy of this word array. * * @return The clone. * * @example * * var clone = x64WordArray.clone(); */ clone(): X64WordArray; } /** * Base object for prototypal inheritance. */ interface Base { /** * Creates a copy of this object. * * @return The clone. * * @example * * var clone = instance.clone(); */ clone(): this; } /** * Configuration options. */ interface KDFOption { /** * The key size in words to generate. */ keySize?: number | undefined; /** * The hasher to use. */ hasher?: HasherStatic | undefined; /** * The number of iterations to perform. */ iterations?: number | undefined; } declare namespace CryptoJS { /** * Library namespace. */ export namespace lib { /** * Base object for prototypal inheritance. */ const Base: { /** * Creates a new object that inherits from this object. * * @param overrides Properties to copy into the new object. * * @return The new object. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend(overrides: object): any; /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return The new object. * * @example * * var instance = MyType.create(); */ create(...args: any[]): any; /** * Copies properties into this object. * * @param properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn(properties: object): any; }; /** * An array of 32-bit words. */ interface WordArray { /** * The array of 32-bit words. */ words: number[]; /** * The number of significant bytes in this word array. */ sigBytes: number; /** * Converts this word array to a string. * * @param encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString(encoder?: Encoder): string; /** * Concatenates a word array to this word array. * * @param wordArray The word array to append. * * @return This word array. * * @example * * wordArray1.concat(wordArray2); */ concat(wordArray: WordArray): this; /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp(): void; /** * Creates a copy of this word array. * * @return The clone. * * @example * * var clone = wordArray.clone(); */ clone(): WordArray; } const WordArray: { /** * Initializes a newly created word array. * * @param words (Optional) An array of 32-bit words. * @param sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ create(words?: number[], sigBytes?: number): WordArray; /** * Creates a word array filled with random bytes. * * @param nBytes The number of random bytes to generate. * * @return The random word array. * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random(nBytes: number): WordArray; }; const BufferedBlockAlgorithm: any; const Hasher: { /** * Creates a shortcut function to a hasher's object interface. * * @param hasher The hasher to create a helper for. * * @return The shortcut function. * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper(hasher: HasherStatic): HasherHelper; /** * Creates a shortcut function to the HMAC's object interface. * * @param hasher The hasher to use in this HMAC helper. * * @return The shortcut function. * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper(hasher: HasherStatic): HmacHasherHelper; }; const Cipher: { /** * Creates shortcut functions to a cipher's object interface. * * @param cipher The cipher to create a helper for. * * @return An object with encrypt and decrypt shortcut functions. * * @example * * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); */ _createHelper(cipher: Cipher): CipherHelper; }; interface CipherOption { /** * The IV to use for this operation. */ iv?: WordArray | undefined; format?: Format | undefined; [key: string]: any; } /** * A collection of cipher parameters. */ interface CipherParams { /** * The raw ciphertext. */ ciphertext: WordArray; /** * The key to this ciphertext. */ key: WordArray; /** * The IV used in the ciphering operation. */ iv: WordArray; /** * The salt used with a key derivation function. */ salt: WordArray; /** * The cipher algorithm. */ algorithm: CipherStatic; /** * The block mode used in the ciphering operation. */ mode: Mode; /** * The padding scheme used in the ciphering operation. */ padding: Padding; /** * The block size of the cipher. */ blockSize: number; /** * The default formatting strategy to convert this cipher params object to a string. */ formatter: Format; /** * Converts this cipher params object to a string. * * @param formatter (Optional) The formatting strategy to use. * * @return The stringified cipher params. * * @throws Error If neither the formatter nor the default formatter is set. * * @example * * var string = cipherParams + ''; * var string = cipherParams.toString(); * var string = cipherParams.toString(CryptoJS.format.OpenSSL); */ toString(formatter?: Format): string; } const CipherParams: { /** * Initializes a newly created cipher params object. * * @param cipherParams An object with any of the possible cipher parameters. * * @example * * var cipherParams = CryptoJS.lib.CipherParams.create({ * ciphertext: ciphertextWordArray, * key: keyWordArray, * iv: ivWordArray, * salt: saltWordArray, * algorithm: CryptoJS.algo.AES, * mode: CryptoJS.mode.CBC, * padding: CryptoJS.pad.PKCS7, * blockSize: 4, * formatter: CryptoJS.format.OpenSSL * }); */ create(cipherParams: Partial): CipherParams; }; /** * Abstract base stream cipher template. */ interface StreamCipher extends Cipher { /** * The number of 32-bit words this cipher operates on. Default: 1 (32 bits) */ blockSize: number; } /** * Abstract base block cipher mode template. */ const BlockCipherMode: any; /** * A cipher wrapper that returns ciphertext as a serializable cipher params object. */ const SerializableCipher: { /** * Encrypts a message. * * @param cipher The cipher algorithm to use. * @param message The message to encrypt. * @param key The key. * @param cfg (Optional) The configuration options to use for this operation. * * @return A cipher params object. * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ encrypt( cipher: CipherStatic, message: WordArray | string, key: WordArray, cfg?: CipherOption ): CipherParams; /** * Decrypts serialized ciphertext. * * @param cipher The cipher algorithm to use. * @param ciphertext The ciphertext to decrypt. * @param key The key. * @param cfg (Optional) The configuration options to use for this operation. * * @return The plaintext. * * @example * * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ decrypt( cipher: CipherStatic, ciphertext: WordArray | string, key: WordArray, cfg?: CipherOption ): CipherParams; /** * Converts serialized ciphertext to CipherParams, * else assumed CipherParams already and returns ciphertext unchanged. * * @param ciphertext The ciphertext. * @param format The formatting strategy to use to parse serialized ciphertext. * * @return The unserialized ciphertext. * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); */ _parse(ciphertext: CipherParams | string, format: Format): CipherParams; }; /** * A serializable cipher wrapper that derives the key from a password, * and returns ciphertext as a serializable cipher params object. */ const PasswordBasedCipher: { /** * Encrypts a message using a password. * * @param cipher The cipher algorithm to use. * @param message The message to encrypt. * @param password The password. * @param cfg (Optional) The configuration options to use for this operation. * * @return A cipher params object. * * @example * * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); */ encrypt( cipher: CipherStatic, message: WordArray | string, password: string, cfg?: CipherOption ): CipherParams; /** * Decrypts serialized ciphertext using a password. * * @param cipher The cipher algorithm to use. * @param ciphertext The ciphertext to decrypt. * @param password The password. * @param cfg (Optional) The configuration options to use for this operation. * * @return The plaintext. * * @example * * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); */ decrypt( cipher: CipherStatic, ciphertext: CipherParams | string, password: string, cfg?: CipherOption ): WordArray; }; } /** * Padding namespace. */ export namespace pad { /** * PKCS #5/7 padding strategy. */ const Pkcs7: Padding; /** * ANSI X.923 padding strategy. */ const AnsiX923: Padding; /** * ISO 10126 padding strategy. */ const Iso10126: Padding; /** * ISO/IEC 9797-1 Padding Method 2. */ const Iso97971: Padding; /** * Zero padding strategy. */ const ZeroPadding: Padding; /** * A noop padding strategy. */ const NoPadding: Padding; } /** * Key derivation function namespace. */ export namespace kdf { /** * OpenSSL key derivation function. */ const OpenSSL: { /** * Derives a key and IV from a password. * * @param password The password to derive from. * @param keySize The size in words of the key to generate. * @param ivSize The size in words of the IV to generate. * @param salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. * * @return A cipher params object with the key, IV, and salt. * * @example * * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); */ execute( password: string, keySize: number, ivSize: number, salt?: WordArray | string ): CipherParams; }; } /** * Mode namespace. */ export namespace mode { /** * Cipher Block Chaining mode. */ const CBC: BlockCipherMode; /** * Cipher Feedback block mode. */ const CFB: BlockCipherMode; /** * Counter block mode. */ const CTR: BlockCipherMode; /** * @preserve * Counter block mode compatible with Dr Brian Gladman fileenc.c * derived from CryptoJS.mode.CTR * Jan Hruby jhruby.web@gmail.com */ const CTRGladman: BlockCipherMode; /** * Output Feedback block mode. */ const OFB: BlockCipherMode; /** * Electronic Codebook block mode. */ const ECB: BlockCipherMode; } /** * Format namespace. */ export namespace format { /** * OpenSSL formatting strategy. */ const OpenSSL: Format; const Hex: Format; } /** * Encoder namespace. */ export namespace enc { /** * Hex encoding strategy. */ const Hex: Encoder; /** * Latin1 encoding strategy. */ const Latin1: Encoder; /** * UTF-8 encoding strategy. */ const Utf8: Encoder; /** * UTF-16 BE encoding strategy. */ const Utf16: Encoder; const Utf16BE: Encoder; /** * UTF-16 LE encoding strategy. */ const Utf16LE: Encoder; /** * Base64 encoding strategy. */ const Base64: Encoder; } /** * Algorithm namespace. */ export namespace algo { /** * MD5 hash algorithm. */ const MD5: HasherStatic; /** * SHA-1 hash algorithm. */ const SHA1: HasherStatic; /** * SHA-256 hash algorithm. */ const SHA256: HasherStatic; /** * SHA-224 hash algorithm. */ const SHA224: HasherStatic; /** * SHA-512 hash algorithm. */ const SHA512: HasherStatic; /** * SHA-384 hash algorithm. */ const SHA384: HasherStatic; /** * SHA-3 hash algorithm. */ const SHA3: HasherStatic; /** * RIPEMD160 hash algorithm. */ const RIPEMD160: HasherStatic; /** * HMAC algorithm. */ abstract class HMAC { /** * Initializes a newly created HMAC. * * @param hasher The hash algorithm to use. * @param key The secret key. * * @example * * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); */ static create(hasher: HasherStatic, key: WordArray | string): HMAC; /** * Resets this HMAC to its initial state. * * @example * * hmacHasher.reset(); */ reset(): void; /** * Updates this HMAC with a message. * * @param messageUpdate The message to append. * * @return This HMAC instance. * * @example * * hmacHasher.update('message'); * hmacHasher.update(wordArray); */ update(messageUpdate: WordArray | string): this; /** * Finalizes the HMAC computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param messageUpdate (Optional) A final message update. * * @return The HMAC. * * @example * * var hmac = hmacHasher.finalize(); * var hmac = hmacHasher.finalize('message'); * var hmac = hmacHasher.finalize(wordArray); */ finalize(messageUpdate?: WordArray | string): WordArray; } /** * Password-Based Key Derivation Function 2 algorithm. */ abstract class PBKDF2 { /** * Initializes a newly created key derivation function. * * @param cfg (Optional) The configuration options to use for the derivation. * * @example * * var kdf = CryptoJS.algo.PBKDF2.create(); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 }); */ static create(cfg?: KDFOption): PBKDF2; /** * Computes the Password-Based Key Derivation Function 2. * * @param password The password. * @param salt A salt. * * @return The derived key. * * @example * * var key = kdf.compute(password, salt); */ compute(password: WordArray | string, salt: WordArray): WordArray; } /** * This key derivation function is meant to conform with EVP_BytesToKey. * www.openssl.org/docs/crypto/EVP_BytesToKey.html */ abstract class EvpKDF { /** * Initializes a newly created key derivation function. * * @param cfg (Optional) The configuration options to use for the derivation. * * @example * * var kdf = CryptoJS.algo.EvpKDF.create(); * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); */ static create(cfg?: { keySize: number; hasher?: HasherStatic | undefined; iterations: number; }): EvpKDF; /** * Derives a key from a password. * * @param password The password. * @param salt A salt. * * @return The derived key. * * @example * * var key = kdf.compute(password, salt); */ compute(password: WordArray | string, salt: WordArray): WordArray; } /** * AES block cipher algorithm. */ const AES: CipherStatic; /** * DES block cipher algorithm. */ const DES: CipherStatic; /** * Triple-DES block cipher algorithm. */ const TripleDES: CipherStatic; /** * RC4 stream cipher algorithm. */ const RC4: CipherStatic; /** * Modified RC4 stream cipher algorithm. */ const RC4Drop: CipherStatic; /** * Rabbit stream cipher algorithm */ const Rabbit: CipherStatic; /** * Rabbit stream cipher algorithm. * * This is a legacy version that neglected to convert the key to little-endian. * This error doesn't affect the cipher's security, * but it does affect its compatibility with other implementations. */ const RabbitLegacy: CipherStatic; } /** * x64 namespace. */ export namespace x64 { /** * A 64-bit word. */ interface Word { /** * Bitwise NOTs this word. * * @return A new x64-Word object after negating. * * @example * * var negated = x64Word.not(); */ not(): X64Word; /** * Bitwise ANDs this word with the passed word. * * @param word The x64-Word to AND with this word. * * @return A new x64-Word object after ANDing. * * @example * * var anded = x64Word.and(anotherX64Word); */ and(word: X64Word): X64Word; /** * Bitwise ORs this word with the passed word. * * @param word The x64-Word to OR with this word. * * @return A new x64-Word object after ORing. * * @example * * var ored = x64Word.or(anotherX64Word); */ or(word: X64Word): X64Word; /** * Bitwise XORs this word with the passed word. * * @param word The x64-Word to XOR with this word. * * @return A new x64-Word object after XORing. * * @example * * var xored = x64Word.xor(anotherX64Word); */ xor(word: X64Word): X64Word; /** * Shifts this word n bits to the left. * * @param n The number of bits to shift. * * @return A new x64-Word object after shifting. * * @example * * var shifted = x64Word.shiftL(25); */ shiftL(n: number): X64Word; /** * Shifts this word n bits to the right. * * @param n The number of bits to shift. * * @return A new x64-Word object after shifting. * * @example * * var shifted = x64Word.shiftR(7); */ shiftR(n: number): X64Word; /** * Rotates this word n bits to the left. * * @param n The number of bits to rotate. * * @return A new x64-Word object after rotating. * * @example * * var rotated = x64Word.rotL(25); */ rotL(n: number): X64Word; /** * Rotates this word n bits to the right. * * @param n The number of bits to rotate. * * @return A new x64-Word object after rotating. * * @example * * var rotated = x64Word.rotR(7); */ rotR(n: number): X64Word; /** * Adds this word with the passed word. * * @param word The x64-Word to add with this word. * * @return A new x64-Word object after adding. * * @example * * var added = x64Word.add(anotherX64Word); */ add(word: X64Word): X64Word; } const Word: { /** * Initializes a newly created 64-bit word. * * @param high The high 32 bits. * @param low The low 32 bits. * * @example * * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); */ create(high: number, low: number): X64Word; }; /** * Initializes a newly created word array. * * @param words (Optional) An array of CryptoJS.x64.Word objects. * @param sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.x64.WordArray.create(); * * var wordArray = CryptoJS.x64.WordArray.create([ * CryptoJS.x64.Word.create(0x00010203, 0x04050607), * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) * ]); * * var wordArray = CryptoJS.x64.WordArray.create([ * CryptoJS.x64.Word.create(0x00010203, 0x04050607), * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) * ], 10); */ const WordArray: { create(words?: X64WordArray[], sigBytes?: number): X64WordArray; }; } /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.MD5('message'); * var hash = CryptoJS.MD5(wordArray); */ export const MD5: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMA'C. * * @example * * var hmac = CryptoJS.HmacMD5(message, key); */ export const HmacMD5: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA1('message'); * var hash = CryptoJS.SHA1(wordArray); */ export const SHA1: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA1(message, key); */ export const HmacSHA1: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA256('message'); * var hash = CryptoJS.SHA256(wordArray); */ export const SHA256: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA256(message, key); */ export const HmacSHA256: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA224('message'); * var hash = CryptoJS.SHA224(wordArray); */ export const SHA224: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA224(message, key); */ export const HmacSHA224: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA512('message'); * var hash = CryptoJS.SHA512(wordArray); */ export const SHA512: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA512(message, key); */ export const HmacSHA512: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA384('message'); * var hash = CryptoJS.SHA384(wordArray); */ export const SHA384: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA384(message, key); */ export const HmacSHA384: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.SHA3('message'); * var hash = CryptoJS.SHA3(wordArray); */ export const SHA3: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacSHA3(message, key); */ export const HmacSHA3: HmacHasherHelper; /** * Shortcut function to the hasher's object interface. * * @param message The message to hash. * * @return The hash. * * @example * * var hash = CryptoJS.RIPEMD160('message'); * var hash = CryptoJS.RIPEMD160(wordArray); */ export const RIPEMD160: HasherHelper; /** * Shortcut function to the HMAC's object interface. * * @param message The message to hash. * @param key The secret key. * * @return The HMAC. * * @example * * var hmac = CryptoJS.HmacRIPEMD160(message, key); */ export const HmacRIPEMD160: HmacHasherHelper; /** * Computes the Password-Based Key Derivation Function 2. * * @param password The password. * @param salt A salt. * @param cfg (Optional) The configuration options to use for this computation. * * @return The derived key. * * @example * * var key = CryptoJS.PBKDF2(password, salt); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); */ export function PBKDF2( password: WordArray | string, salt: WordArray | string, cfg?: KDFOption ): WordArray; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); */ export const AES: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.DES.encrypt(message, key, cfg); * var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg); */ export const DES: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg); * var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg); */ export const TripleDES: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg); */ export const RC4: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg); */ export const RC4Drop: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg); * var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg); */ export const Rabbit: CipherHelper; /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg); * var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg); */ export const RabbitLegacy: CipherHelper; /** * Derives a key from a password. * * @param password The password. * @param salt A salt. * @param cfg (Optional) The configuration options to use for this computation. * * @return The derived key. * * @example * * var key = CryptoJS.EvpKDF(password, salt); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); */ export function EvpKDF( password: WordArray | string, salt: WordArray | string, cfg?: { keySize: number; hasher?: HasherStatic | undefined; iterations: number; } ): WordArray; } export = CryptoJS; ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\public-api.ts /* * Public API Surface of x-framework-services */ // //#region Export Services ... export * from './lib/x-dialog.service'; export * from './lib/x-manager.service'; export * from './lib/x-storage.service'; export * from './lib/x-security.service'; export * from './lib/x-settings.service'; export * from './lib/x-identifier.service'; export * from './lib/x-geolocation.service'; export * from './lib/x-localization.service'; export * from './lib/x-notification.service'; export * from './lib/x-task-manager.service'; export * from './lib/x-theme-manager.service'; export * from './lib/x-secure-storage.service'; export * from './lib/x-http-interceptor.service'; //#endregion // //#region Export Directives ... export * from './lib/directives/x-swipable.directive'; export * from './lib/directives/x-date-presenter.directive'; export * from './lib/directives/x-currency-formatter.directive'; export * from './lib/directives/x-from-input-formatter.directive'; export * from './lib/directives/x-locale-input-formatter.directive'; //#endregion // //#region Export Pipes ... export * from './lib/pipes/x-translate.pipe'; //#endregion // //#region Tokens ... export * from './lib/tokens/x-injectable-tokens'; //#endregion // //#region Export Config ... export * from './lib/config/x-framework-services.config'; //#endregion // //#region Export Modules ... export * from './lib/modules/x-directives.module'; export * from './lib/x-framework-services.module'; //#endregion ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\test.ts // This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js'; import 'zone.js/testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-dialog.service.ts import { NavController, AlertController, ModalController, PickerController, PopoverController, LoadingController, ActionSheetController, } from '@ionic/angular'; import { toArray, hasChild, XActionType, XModalInput, XBaseService, XResourceIDs, XModalButton, XPickerColumn, XAlertOptions, XModalOptions, XPickerOptions, XPopoverOptions, XLoadingOptions, XModalButtonRole, XActionModalOptions, XPickerColumnOption, XModalButtonRoleIdentifier, } from 'x-framework-core'; import { Observable, of } from 'rxjs'; import { Injectable, Inject } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { XLocalizationService } from './x-localization.service'; import { XNotificationService } from './x-notification.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XDialogService extends XBaseService { // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, public matDialogService: MatDialog, public modalController: ModalController, public alertController: AlertController, public pickerController: PickerController, public navigationController: NavController, public popoverController: PopoverController, public loadingController: LoadingController, private notificationService: XNotificationService, private localizationService: XLocalizationService, public actionSheetController: ActionSheetController ) { super(config); } // //#region Service Actions ... nativeAlert(message?: string | XResourceIDs): Observable { // message = !message ? XResourceIDs.are_you_sure : message; // const mMessage = this.localizationService.getValue(message); const confirmation = window.alert(mMessage); // return of(confirmation); } nativeConfirm(message?: string | XResourceIDs): Observable { // message = !message ? XResourceIDs.are_you_sure : message; // const mMessage = this.localizationService.getValue(message); const confirmation = window.confirm(mMessage); // return of(confirmation); } async presentActionModal(props: XActionModalOptions) { // const options = await this.toActionSheetOptions(props); const actionModal = await this.actionSheetController.create(options); // if (props.playSound) { this.notificationService.playSound(props.type || XActionType.System); } // await actionModal.present(); return actionModal; } async presentModal(props: XModalOptions) { // if (props.fullScreen) { // const mFullscreen = 'fullscreen'; if (hasChild(props.cssClass)) { props.cssClass = [...toArray(props.cssClass), mFullscreen]; } else { props.cssClass = [mFullscreen]; } } else if (props.autoHeight) { // const mAutoHeight = 'autoHeight'; if (hasChild(props.cssClass)) { props.cssClass = [...toArray(props.cssClass), mAutoHeight]; } else { props.cssClass = [mAutoHeight]; } } // const modal = await this.modalController.create(props); await modal.present(); return modal; } async presentPopover(props: XPopoverOptions) { // const popover = await this.popoverController.create(props); await popover.present(); return popover; } async presentLoading(props: XLoadingOptions) { // const loading = await this.loadingController.create(props); await loading.present(); return loading; } async presentAlert(props: XAlertOptions) { // const options = await this.prepareAlertOptions(props); const alert = await this.alertController.create(options); // await alert.present(); return alert; } async presentPicker(props: XPickerOptions) { // const options = await this.preparePickerOptions(props); const picker = await this.pickerController.create(options); // await picker.present(); return picker; } //#endregion // //#region Commonly Used dialogs ... async presentAreYouSureOkCancleDialog( okHandler: () => void, okRole?: XModalButtonRoleIdentifier, cancelHandler?: () => void, cancelRole?: XModalButtonRoleIdentifier ) { await this.presentActionModal({ header: XResourceIDs.are_you_sure, buttons: [], keyboardClose: true, backdropDismiss: true, hasOk: true, okRole, okHandler, hasCancel: true, cancelRole, cancelHandler, }); } async presentAreYouSureYesNoDialog( yesHandler: () => void, yesRole?: XModalButtonRoleIdentifier, noHandler?: () => void, noRole?: XModalButtonRoleIdentifier ) { await this.presentActionModal({ header: XResourceIDs.are_you_sure, buttons: [], keyboardClose: true, backdropDismiss: true, hasNo: true, noRole, noHandler, hasYes: true, yesRole, yesHandler, }); } //#endregion // //#region Private ... // //#region Button Preparer ... getButton( text?: XResourceIDs | string, icon?: string, role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(text); return { text: mText, icon, role, handler, }; } getYesButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.yes); const mIcon = 'checkmark'; return { text: mText, icon: mIcon, role, handler, }; } getNoButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.no); const mIcon = 'close'; return { text: mText, icon: mIcon, role, handler, }; } getOkButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.ok); const mIcon = 'checkmark'; return { text: mText, icon: mIcon, role, handler, }; } getCancelButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.cancel); const mIcon = 'close'; return { text: mText, icon: mIcon, role, handler, }; } getAcceptButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.accept); const mIcon = 'checkmark'; return { text: mText, icon: mIcon, role, handler, }; } getRetryButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Selected; } // const mText = this.getPreparedMessage(XResourceIDs.retry); const mIcon = 'refresh'; return { text: mText, icon: mIcon, role, handler, }; } getDismissButton( role?: XModalButtonRoleIdentifier, handler?: () => boolean | void | Promise ) { // if (!role) { role = XModalButtonRole.Destructive; } // const mText = this.getPreparedMessage(XResourceIDs.dismiss); const mIcon = 'remove-circle-outline'; return { text: mText, icon: mIcon, role, handler, }; } //#endregion private prepareModalButton(button?: XModalButton) { // const alertButton = { ...button, text: button.text ? this.getPreparedMessage(button.text) : '', }; // return alertButton; } private async prepareModalButtons(buttons?: XModalButton[]) { // if (!hasChild(buttons)) { return []; } // return buttons.map((b) => this.prepareModalButton(b)); } private prepareModalInput(input?: XModalInput) { // const alertInput = { ...input, label: input.label ? this.getPreparedMessage(input.label) : '', placeholder: input.placeholder ? this.getPreparedMessage(input.placeholder) : '', }; // return alertInput; } private async prepareModalInputs(inputs?: XModalInput[]) { // if (!hasChild(inputs)) { return []; } // return inputs.map((i) => this.prepareModalInput(i)); } private async prepareAlertOptions(options?: XAlertOptions) { // const alertOptions = { ...options, header: options.header ? this.getPreparedMessage(options.header) : '', subHeader: options.subHeader ? this.getPreparedMessage(options.subHeader) : '', message: options.message ? this.getPreparedMessage(options.message) : '', inputs: hasChild(options.inputs) ? await this.prepareModalInputs(options.inputs) : [], buttons: hasChild(options.buttons) ? await this.prepareModalButtons(options.buttons) : [], }; // return alertOptions; } private preparePickerColumnOption(columnOption?: XPickerColumnOption) { // const pickerColumnOption = { ...columnOption, text: this.getPreparedMessage(columnOption.text), }; // return pickerColumnOption; } private async preparePickerColumnOptions( columnOptions?: XPickerColumnOption[] ) { // if (!hasChild(columnOptions)) { return []; } // return columnOptions.map((co) => this.preparePickerColumnOption(co)); } private async preparePickerColumn(column?: XPickerColumn) { // const pickerColumn = { ...column, options: await this.preparePickerColumnOptions(column.options), }; // return pickerColumn; } private async preparePickerColumns(columns: XPickerColumn[]) { // if (!hasChild(columns)) { return []; } // return columns.map((c) => this.preparePickerColumn(c)); } private async preparePickerOptions(options?: XPickerOptions) { // const pickerOptions = { ...options, buttons: (await this.prepareModalButtons(options.buttons)) || [], columns: (await Promise.all(await this.preparePickerColumns(options.columns))) || [], }; // return pickerOptions; } private async toActionSheetOptions(options?: XActionModalOptions) { // let buttons: any[] = []; // const optButtons = (await this.prepareModalButtons(options.buttons)) || []; buttons = [...buttons, ...optButtons]; // //#region Handle Preserved Buttons ... if (options.hasRetry) { buttons.push( this.getRetryButton(options.retryRole, options.retryHandler) ); } // if (options.hasAccept) { buttons.push( this.getAcceptButton(options.acceptRole, options.acceptHandler) ); } // if (options.hasOk) { buttons.push(this.getOkButton(options.okRole, options.okHandler)); } // if (options.hasCancel) { buttons.push( this.getCancelButton(options.cancelRole, options.cancelHandler) ); } // if (options.hasYes) { buttons.push(this.getYesButton(options.yesRole, options.yesHandler)); } // if (options.hasNo) { buttons.push(this.getNoButton(options.noRole, options.noHandler)); } // if (options.hasDismiss) { buttons.push( this.getDismissButton(options.dismissRole, options.dismissHandler) ); } //#endregion // const actionModalOptions = { ...options, header: options.header ? this.getPreparedMessage(options.header) : '', subHeader: options.subHeader ? this.getPreparedMessage(options.subHeader) : '', backdropDismiss: options.backdropDismiss || true, buttons, }; // return actionModalOptions; } private getPreparedMessage(key: string | number) { return this.localizationService.isExistsId(key) ? this.localizationService.getValue(key) : key ? key.toString() : ''; } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-framework-services.module.ts import { NgModule } from '@angular/core'; import { IonicModule } from '@ionic/angular'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { XDialogService } from './x-dialog.service'; import { XHistoryService } from './x-history.service'; import { XManagerService } from './x-manager.service'; import { XStorageService } from './x-storage.service'; import { HttpClientModule } from '@angular/common/http'; import { XSecurityService } from './x-security.service'; import { XSettingsService } from './x-settings.service'; import { XGeolocationService } from './x-geolocation.service'; import { XTaskManagerService } from './x-task-manager.service'; import { XLocalizationService } from './x-localization.service'; import { XNotificationService } from './x-notification.service'; import { XThemeManagerService } from './x-theme-manager.service'; import { XDirectivesModule } from './modules/x-directives.module'; import { XSecureStorageService } from './x-secure-storage.service'; @NgModule({ declarations: [], imports: [ IonicModule, CommonModule, RouterModule, HttpClientModule, XDirectivesModule, ], exports: [ CommonModule, HttpClientModule, XDirectivesModule, ], providers: [ // XDialogService, XStorageService, XManagerService, XHistoryService, XSettingsService, XSecurityService, XGeolocationService, XTaskManagerService, XLocalizationService, XNotificationService, XThemeManagerService, XSecureStorageService, ] }) export class XFrameworkServicesModule {} ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-geolocation.service.ts import { getError, Exceptions, XException, XBaseService, } from 'x-framework-core'; import { Observable } from 'rxjs'; import { Injectable, Output, EventEmitter, Inject } from '@angular/core'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XGeolocationService extends XBaseService { // private IS_SUPPORT = false; private NAVIGATION_WATCHER: any; // options: PositionOptions; // @Output() changeLoading: EventEmitter = new EventEmitter(); // isLoading = false; // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig ) { super(config); // // Check Service is Supported or not ... if (navigator.geolocation) { this.IS_SUPPORT = true; } // this.options = { ...config.geoLocationConfig, }; } /** * determines service is Supported or not */ get isSupport() { return this.IS_SUPPORT; } /** * get given position link for open on Google Maps ... */ getGoogleMapLink(position: GeolocationPosition) { return `https://maps.google.com/?q=${position.coords.latitude},${position.coords.longitude}`; } /** * get given position Lat,Long string ... */ getLatLong(position: GeolocationPosition) { return `${position.coords.latitude},${position.coords.longitude}`; } /** * get current location ... */ getCurrentLocation(): Observable { // this.startLoading(); return new Observable((observer) => { // if (!this.IS_SUPPORT) { // this.stopLoading(); observer.error(getError(Exceptions.UnsupportedBrowser)); } // navigator.geolocation.getCurrentPosition( (position) => { // this.stopLoading(); // observer.next(position); observer.complete(); }, (error) => { // this.stopLoading(); // let exception: XException; switch (error.code) { case 1: exception = Exceptions.PermissionDenied; break; case 2: exception = Exceptions.PositionUnavailable; break; case 3: default: exception = Exceptions.Timeout; break; } // observer.error(getError(exception)); }, { ...this.options, } ); }); } /** * start Watching Location Changes ... */ watchLocation(): Observable { // this.startLoading(); // return new Observable((observer) => { this.NAVIGATION_WATCHER = navigator.geolocation.watchPosition( (position) => { // if (!this.IS_SUPPORT) { // this.stopLoading(); observer.error(getError(Exceptions.UnsupportedBrowser)); observer.complete(); } // observer.next(position); }, (error) => { // this.stopLoading(); let exception: XException; switch (error.code) { case 1: exception = Exceptions.PermissionDenied; break; case 2: exception = Exceptions.PositionUnavailable; break; case 3: default: exception = Exceptions.Timeout; break; } // observer.error(getError(exception)); } ); }); } /** * Stop Watching Location Changes ... */ stopWatchingLocation() { // this.stopLoading(); navigator.geolocation.clearWatch(this.NAVIGATION_WATCHER); } private startLoading() { // this.isLoading = true; this.changeLoading.emit(true); } private stopLoading() { // this.isLoading = false; this.changeLoading.emit(false); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-history.service.ts import { Subject } from 'rxjs'; import { Injectable } from '@angular/core'; import { Location, PlatformLocation } from '@angular/common'; @Injectable({ providedIn: 'root', }) export class XHistoryService { // //#region Props ... // public readonly backHandler = new Subject(); // //#region Getters ... // get href() { return this.platformLocation.href; } get protocol() { return this.platformLocation.protocol; } get hostname() { return this.platformLocation.hostname; } get port() { return this.platformLocation.port; } get pathname() { return this.platformLocation.pathname; } get search() { return this.platformLocation.search; } get hash() { return this.platformLocation.hash; } //#endregion //#endregion // //#region Constructor ... constructor( public location: Location, public platformLocation: PlatformLocation ) { // // Prevent from Back Button ... this.platformLocation.onPopState(() => { this.backHandler.next(); }); } //#endregion // //#region Actions ... pushEmptyState() { this.pushState(null, null, this.platformLocation.href); } replaceEmptyState() { this.replaceState(null, null, this.platformLocation.href); } getBaseHrefFromDOM() { return this.platformLocation.getBaseHrefFromDOM(); } getState() { return this.platformLocation.getState(); } replaceState(state: any, title: string, url: string) { this.platformLocation.replaceState(state, title, url); } pushState(state: any, title: string, url: string) { this.platformLocation.pushState(state, title, url); } forward() { this.location.forward(); } back() { this.location.back(); } //#endregion // //#region Private ... //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-http-interceptor.service.ts import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse, } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { Injectable, Inject } from '@angular/core'; import { finalize, catchError } from 'rxjs/operators'; import { XManagerService } from './x-manager.service'; import { XBaseService, getErrorException } from 'x-framework-core'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XHttpInterceptorService extends XBaseService implements HttpInterceptor { // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, private managerService: XManagerService ) { super(config); } intercept( req: HttpRequest, next: HttpHandler ): Observable> { return this.handleInterceptRequest(req, next); } handleInterceptRequest( req: HttpRequest, next: HttpHandler ): Observable> { // // Apply Error Handler ... const handledErrors = this.applyErrorHandler(next.handle(req)); // // Apply Finally Handler ... const handledFinally = this.applyFinally(handledErrors); // // Final Level ... const result = handledFinally; // return result; } // //#region Actions / Handlers ... applyFinally(current: Observable>) { // return current.pipe( finalize(() => { // // Collection of instructions after finish or error ... this.managerService.loading = false; }) ); } applyErrorHandler(current: Observable>) { return current.pipe( catchError((error: HttpErrorResponse) => { // this.managerService.loading = true; const mException = getErrorException(error.error); // this.managerService.error = mException; // return throwError(error); }) ); } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-identifier.service.ts import { Injectable } from '@angular/core'; import { XBaseService } from 'x-framework-core'; @Injectable({ providedIn: 'root', }) export class XIdentifierService extends XBaseService { // //#region Props ... private readonly idStartKey = '_['; private readonly idEndKey = ']'; //#endregion /** * check if task name contains id ... * * @param key the task name ... */ hasIdentifier(key: string | any, forceAppName = false) { // if (!key) { return false; } // const mKey = key.toString() as string; const result = mKey.includes(this.idStartKey) && mKey.includes(this.idEndKey); // return forceAppName ? result && mKey.includes(this.config.appInstanceName) : result; } /** * retrieve and extract the raw task name from a task name ... * * @param key the task name ... */ getName(key: string | any) { // if (!key) { return ''; } // const mKey = key.toString() as string; // if (!this.hasIdentifier(mKey)) { return mKey; } // const startIndex = mKey.indexOf(this.idStartKey); let result = mKey.substr(0, startIndex); result = result.replace(this.idStartKey, ''); // return result; } /** * retrieve and extract the id inside a task name ... * * @param key the task name ... */ getIdentifier(key: string | any, cleanAppName = true) { // // Validate Args ... if (!key || !this.hasIdentifier(key)) { return ''; } // // Task Id ... let result = key.toString() as string; // // Validating Info ... let index = result.indexOf(this.idStartKey); // result = result.substr(index, result.length); result = result.replace(this.idStartKey, ''); // index = result.indexOf(this.idEndKey); result = result.substring(0, index); // if (cleanAppName) { result = result.replace(this.config.appInstanceName, ''); } // // Return Result ... return result; } /** * prepare a Task With ID and return ... * * @param key the Task Name ... * @param id th ID ... */ setIdentifier(key: string | any, id: string | any, containsAppName = false) { return `${key.toString()}${this.idStartKey}${ containsAppName ? this.config.appInstanceName : '' }${id.toString()}${this.idEndKey}`; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-localization.service.ts import { XParam, getVal, XLocale, isNumber, formatDate, XException, Exceptions, fromUtcDate, XBaseService, XResourceIDs, GetDateProps, XExceptionIDs, throwException, isValidException, XTranslationItem, isNullOrUndefined, getErrorException, XLanguageDirection, XResourceIdentifier, XLanguageDescriptor, getErrorDateFormatString, getDateOfBirthDateFormatString, } from 'x-framework-core'; import { Injectable, Inject } from '@angular/core'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XLocalizationService extends XBaseService { // private LANGUAGEDESCRIPTOR: XLanguageDescriptor; private AVAILABLELANGUAGES: XLanguageDescriptor[]; // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig ) { super(config); // // Inject Loacle and set Application Locale and Direction based on it ... this.AVAILABLELANGUAGES = config.availableLanguages; this.LANGUAGEDESCRIPTOR = config.availableLanguages.find( (al) => al.locale === config.defaultLanguage ); window[XParam.Language] = this.LANGUAGEDESCRIPTOR.locale; } // //#region Properties ... /** * Current System Locale ... */ get locale() { return this.languageDescriptor.locale; } /** * Current Locale UI Direction ... */ get direction(): XLanguageDirection { return this.languageDescriptor.direction; } /** * current available language */ get language() { return this.languageDescriptor.language; } /** * get Current Locale Name ... */ get name() { return this.languageDescriptor.name; } /** * get Current Locale Language Descriptor Object ... */ get languageDescriptor() { return this.LANGUAGEDESCRIPTOR; } /** * get Available Languages ... */ get availableLanguages() { return this.AVAILABLELANGUAGES; } //#endregion /** * change current language ... * * @param locale name of available language */ changeLocale(locale: XLocale) { // const languageDescriptor = this.languageDescriptorOfLocale(locale); if (!languageDescriptor) { throwException(XExceptionIDs.InvalidConfiguration); } // window[XParam.Language] = locale; this.LANGUAGEDESCRIPTOR = languageDescriptor; } /** * Find specific Language Descriptor ... */ languageDescriptorOfLocale(locale: XLocale) { // return this.availableLanguages.find((al) => al.locale === locale); } /** * check an id exists in resources or not */ isExistsId(id: XResourceIdentifier) { // const key = getVal(XResourceIDs, id) || id; // return ( this.languageDescriptor.resources.findIndex((tr) => tr.id === key) > -1 ); } /** * check an id exists in resources of specific locale or not */ isExistsIdOfLocale(locale: XLocale, id: XResourceIdentifier) { // const key = getVal(XResourceIDs, id) || id; // return ( this.languageDescriptorOfLocale(locale).resources.findIndex( (tr) => tr.id === key ) > -1 ); } /** * get translation item of current language */ getTranslationItem(id: XResourceIdentifier): XTranslationItem { // const key = getVal(XResourceIDs, id) || id; // return this.languageDescriptor.resources.find((tr) => tr.id === key); } /** * get translation item of specific language */ getTranslationItemOfLocale(locale: XLocale, id: XResourceIdentifier) { // const key = getVal(XResourceIDs, id) || id; // const selectedLocale = this.languageDescriptorOfLocale(locale); // if (!selectedLocale || !this.isExistsIdOfLocale(locale, key)) { throwException(XExceptionIDs.NotFound); } // return selectedLocale.resources.find((tr) => tr.id === key); } /** * get Value of specific id in Current Locale */ getValue(id: XResourceIdentifier) { // if (!this.isExistsId(id)) { return null; } // return this.getTranslationItem(id).value; } /** * get Value of specific id in specific Locale */ getValueOfLocale(locale: XLocale, id: XResourceIdentifier) { // if (!this.isExistsIdOfLocale(locale, id)) { return null; } // return this.getTranslationItemOfLocale(locale, id).value; } /** * get coresponding translated value of errors */ getErrorMessage(err: any, locale?: XLocale) { // if (!locale) { locale = this.locale; } // let exception: XException; // if (isValidException(err)) { exception = err as XException; } else { exception = getErrorException(err); } // if (exception.id && isNumber(exception.id)) { // const exceptionID = `ex_${exception.id}`; return this.getValueOfLocale(locale, exceptionID); } // return this.getValueOfLocale(locale, 'general_error'); } /** * get and format date */ getDate(props?: GetDateProps): string { // if (!props) { props = {}; } // if (!props.locale) { props.locale = this.locale; } // if (!props.date) { props.date = new Date(); } // if (!props.dateFormat) { props.dateFormat = getDateOfBirthDateFormatString(props.locale); } // if (!props.toUtc) { props.toUtc = false; } // return formatDate(props.date, props.locale, props.dateFormat, props.toUtc); } /** * combine some resources and represent single joined string ... * * @param locale translated dest locale ... * @param joinString the string which used to join translated parts ... * @param resources an array of translation resources ... */ combine( locale?: XLocale, joinString: string = ' ', ...resources: XResourceIdentifier[] ) { // if (isNullOrUndefined(locale)) { locale = this.locale; } // const result = resources .map((r) => this.getValueOfLocale(locale, r)) .join(joinString); // return result; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager.service.ts import { Location } from '@angular/common'; import { Platform } from '@angular/cdk/platform'; import { HttpClient } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { XDialogService } from './x-dialog.service'; import { XStorageService } from './x-storage.service'; import { XHistoryService } from './x-history.service'; import { XSecurityService } from './x-security.service'; import { XSettingsService } from './x-settings.service'; import { Router, ActivatedRoute } from '@angular/router'; import { XIdentifierService } from './x-identifier.service'; import { XGeolocationService } from './x-geolocation.service'; import { XTaskManagerService } from './x-task-manager.service'; import { MenuController, NavController } from '@ionic/angular'; import { XNotificationService } from './x-notification.service'; import { XLocalizationService } from './x-localization.service'; import { XThemeManagerService } from './x-theme-manager.service'; import { XSecureStorageService } from './x-secure-storage.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; import { XManagerFinalService } from './x-manager-service-partial/x-manager-final.service'; @Injectable({ providedIn: 'root', }) export class XManagerService extends XManagerFinalService { constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) public config: XFrameworkServicesConfig, public router: Router, public platform: Platform, public location: Location, public httpClient: HttpClient, public dialogService: XDialogService, public menuController: MenuController, public activatedRoute: ActivatedRoute, public historyService: XHistoryService, public storageService: XStorageService, public securityService: XSecurityService, public settingsService: XSettingsService, public navigationController: NavController, public identifierService: XIdentifierService, public geoLocationService: XGeolocationService, public taskManagerService: XTaskManagerService, public themeManagerService: XThemeManagerService, public notificationService: XNotificationService, public localizationService: XLocalizationService, public secureStorageService: XSecureStorageService ) { super( config, router, platform, location, httpClient, dialogService, menuController, activatedRoute, historyService, storageService, securityService, settingsService, navigationController, geoLocationService, taskManagerService, themeManagerService, notificationService, localizationService, secureStorageService ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-notification.service.ts import { XColor, isNumber, XActionType, XValidators, XResourceIDs, XBaseService, XNotificationParams, XTypedNotificationParams, XErrorNotificationParams, } from 'x-framework-core'; import { Howl } from 'howler'; import { ToastOptions } from '@ionic/core'; import { ToastController } from '@ionic/angular'; import { Injectable, Inject } from '@angular/core'; import { XLocalizationService } from './x-localization.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XNotificationService extends XBaseService { // private NOTIFICATION_IDS: string[] = []; // private userNotifiCationSound: Howl; private captureNotifiCationSound: Howl; private systemNotifiCationSound: Howl; // public notificationDelay: number; constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, private localizationService: XLocalizationService, private toastController: ToastController ) { // super(config); // const userActionConfig = config.notificationAudioSources.find( (as) => as.type === XActionType.User ); const systemActionConfig = config.notificationAudioSources.find( (as) => as.type === XActionType.System ); const captureActionConfig = config.notificationAudioSources.find( (as) => as.type === XActionType.Capture ); // this.notificationDelay = config.defaultNotificationDelay; // this.userNotifiCationSound = new Howl({ src: [userActionConfig.resourcePath], }); this.captureNotifiCationSound = new Howl({ src: [captureActionConfig.resourcePath], }); this.systemNotifiCationSound = new Howl({ src: [systemActionConfig.resourcePath], }); } /** * play sound based on type */ playSound(type: XActionType = XActionType.System) { // switch (type) { // case XActionType.Capture: this.playCaptureNotification(); break; // case XActionType.User: this.playUserNotification(); break; // default: case XActionType.System: this.playSystemNotification(); break; } } /** * play system sound */ playSystemNotification() { // if (this.systemNotifiCationSound.playing()) { return; } // this.systemNotifiCationSound.play(); } /** * play user sound */ playUserNotification() { // if (this.userNotifiCationSound.playing()) { return; } // this.userNotifiCationSound.play(); } /** * play Capture sound */ playCaptureNotification() { // if (this.captureNotifiCationSound.playing()) { return; } // this.captureNotifiCationSound.play(); } // //#region Toas Related ... /** * create a notification object ... * * @param opt notification options */ createNotification(props?: XNotificationParams) { const toastOpt = this.prepareToastOptions(props); return this.toastController.create(toastOpt); } /** * create and present notification ... * * @param opt notification options */ async presentNotification(props?: XNotificationParams) { // const mProps = props ? props : this.getDefaultNotificationOptions(); // const notification = await this.createNotification(mProps); this.NOTIFICATION_IDS.push(notification.id); // notification.onDidDismiss().then(() => { if (mProps.onDidDismiss) { mProps.onDidDismiss(); this.NOTIFICATION_IDS = this.NOTIFICATION_IDS.filter( (id) => id === notification.id ); } }); // notification.onWillDismiss().then(() => { if (mProps.onWillDismiss) { mProps.onWillDismiss(); } }); // notification.present(); // if (props && props.playSound) { this.playSound(props.type); } } async presentXNotification(props: XTypedNotificationParams) { // // Validate Args ... XValidators.validateNotNull(props); // const isResourceID = isNumber(props.message); const mMessage = isResourceID ? this.localizationService.getValue(props.message as XResourceIDs) : (props.message as string); const defOpts = this.getDefaultNotificationOptions(); const mProps = { ...defOpts, ...props, opt: { ...defOpts.opt, ...props.opt, message: mMessage, }, }; // await this.presentNotification(mProps); } /** * present Info notification * * @param props Notification Properties */ async presentInfoNotification( props: XTypedNotificationParams ): Promise { await this.presentXNotification({ ...props, opt: { ...props.opt, color: XColor.Tertiary, }, }); } /** * present Success Notification * * @param props Notification Properties */ async presentSuccessNotification( props: XTypedNotificationParams ): Promise { await this.presentXNotification({ ...props, opt: { ...props.opt, color: XColor.Success, }, }); } /** * present Default Success Notification */ async presentDefaultSuccessNotification( dissmissHandler?: () => void ): Promise { // const mProps: XTypedNotificationParams = { message: XResourceIDs.success_msg, dissmissable: true, onWillDismiss: dissmissHandler, }; await this.presentSuccessNotification(mProps); } /** * present warning notifications * * @param props Notification Properties */ async presentWarningNotification( props: XTypedNotificationParams ): Promise { await this.presentXNotification({ ...props, opt: { ...props.opt, color: XColor.Warning, }, }); } /** * present error notification * * @param props Notification Properties */ async presentDangerNotification( props: XTypedNotificationParams ): Promise { await this.presentXNotification({ ...props, opt: { ...props.opt, color: XColor.Danger, }, }); } /** * present an Exception or Error Message ... * * @param props Notification Properties */ async presentErrorNotification( props: XErrorNotificationParams ): Promise { // const mMessage = this.localizationService.getErrorMessage(props.exception); await this.presentXNotification({ ...props, message: mMessage, dissmissable: props.dissmissable, opt: { ...props.opt, color: XColor.Danger, }, }); } async closeAllNotifications() { this.NOTIFICATION_IDS.forEach(async (id) => { try { await this.toastController.dismiss(null, null, id); } catch {} }); } /** * combines default notification options by * given notification options ... * * @param opt notification options */ private prepareToastOptions(props?: XNotificationParams): ToastOptions { // if (!props) { props = this.getDefaultNotificationOptions(); } // // Handle Dissmissable const mDuration = props.dissmissable ? props.opt.duration : 0; // const result = { ...props.opt, duration: mDuration, }; // return result; } /** * generate default notification options ... */ private getDefaultNotificationOptions(): XNotificationParams { return { playSound: false, type: XActionType.System, dissmissable: true, opt: { color: XColor.Tertiary, position: 'bottom', duration: this.notificationDelay, // , // showCloseButton: true, // closeButtonText: this.localizationService.getValue(XResourceIDs.dismiss) }, }; } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-secure-storage.service.ts import { fromJson, XStorageItem, XExceptionIDs, throwException, isNullOrUndefined } from 'x-framework-core'; import { Injectable, Inject } from '@angular/core'; import { XStorageService } from './x-storage.service'; import { XSecurityService } from './x-security.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root' }) export class XSecureStorageService extends XStorageService { // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, private securitySerive: XSecurityService ) { super(config); } /** * writing a new item in Storage ... * * @param key the item key * @param data the data object which needs to save * @param forceRewrite overwrite item if exists, the default is false, * means if key exists throws an error ... */ write(key: string, data: any, forceRewrite: boolean = false) { // if (!forceRewrite && this.isExists(key)) { throwException(XExceptionIDs.Duplicate); } // const theKey = this.getPreparedKey(key); const encryptedValue = this.securitySerive.encryptWithKey( JSON.stringify(data) ); // localStorage.setItem(theKey, encryptedValue); } /** * read an item from Storage ... * @param key the item key * @param forceExists determine the given key must be exists or not, true is default, * means if key not exists throws an error ... */ read(key: string, forceExists: boolean = true): any | null { // if (forceExists && !this.isExists(key)) { throwException(XExceptionIDs.NotFound); } // const theKey = this.getPreparedKey(key); const item = localStorage.getItem(theKey); if (!isNullOrUndefined(item)) { try { const decryptedValue = this.securitySerive.decryptWithKey(item); return JSON.parse(decryptedValue); } catch {} } // return null; } readOfType(key: string, forceExists: boolean = true): T | null { // if (!this.isExists(key)) { // if (forceExists) { throwException(XExceptionIDs.NotFound); } // return null; } // const valStr = this.read(key, forceExists); return fromJson(valStr); } /** * get a List of Stored items as an Array of StorageItem ... * @param force true is defualt, means only return list of items * from Storage which Stored by Service ... */ list(force: boolean = true, decrypt: boolean = false): XStorageItem[] | null { // if (localStorage.length === 0) { return null; } // const items: XStorageItem[] = []; for (let i = 0; i < localStorage.length; i++) { // const mKey = localStorage.key(i); // const mValue = localStorage.getItem(mKey); const mValueRes = decrypt ? this.securitySerive.decryptWithKey(mValue) : mValue; // if (force) { const theRawKey = this.getRawKey(mKey); if (!isNullOrUndefined(theRawKey)) { // items.push({ key: theRawKey, value: mValueRes }); } } else { // items.push({ key: mKey, value: mValueRes }); } } // return items; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-security.service.ts import * as CryptoJS from 'crypto-js'; import { DomSanitizer } from '@angular/platform-browser'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { toMd5, XBaseService, isNullOrEmptyString } from 'x-framework-core'; import { Injectable, Inject, Sanitizer, SecurityContext } from '@angular/core'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XSecurityService extends XBaseService { // private readonly SECRET_KEY: string; private readonly CIPHER_KEY: string; private readonly CIPHER_IV: string; private readonly CIPHER_OPTION: CryptoJS.lib.CipherOption; // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, private sanitizer: Sanitizer, private domSanitizer: DomSanitizer ) { super(config); // this.SECRET_KEY = toMd5(config.secretKey); // const forIv = this.SECRET_KEY.substring(0, 16); this.CIPHER_IV = CryptoJS.enc.Utf8.parse(forIv).toString(); // const forKey = this.SECRET_KEY.substring(0, 32); this.CIPHER_KEY = CryptoJS.enc.Utf8.parse(forKey).toString(); // this.CIPHER_OPTION = { iv: CryptoJS.enc.Utf8.parse(this.CIPHER_IV), mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }; } encryptWithKey( value: string, key?: string, options?: CryptoJS.lib.CipherOption ) { // if (isNullOrEmptyString(value)) { return null; } // if (!key) { key = this.CIPHER_KEY; } // if (!options) { options = this.CIPHER_OPTION; } // return CryptoJS.AES.encrypt(value, key, options).toString(); } encryptWithSecret( value: string, secret?: string, options?: CryptoJS.lib.CipherOption ) { // if (isNullOrEmptyString(value)) { return null; } // if (!secret) { secret = this.SECRET_KEY; } // if (!options) { options = this.CIPHER_OPTION; } // return CryptoJS.AES.encrypt(value, secret, options); } decryptWithKey( cipherValue: string, key?: string, options?: CryptoJS.lib.CipherOption ) { // if (isNullOrEmptyString(cipherValue)) { return null; } // if (!key) { key = this.CIPHER_KEY; } // if (!options) { options = this.CIPHER_OPTION; } // const result = CryptoJS.AES.decrypt(cipherValue, key, options).toString( CryptoJS.enc.Utf8 ); // return result; } decryptWithSecret( cipherValue: string, secret?: string, options?: CryptoJS.lib.CipherOption ) { // if (isNullOrEmptyString(cipherValue)) { return null; } // if (!secret) { secret = this.SECRET_KEY; } // if (!options) { options = this.CIPHER_OPTION; } // return CryptoJS.AES.decrypt(cipherValue, secret, options).toString(); } toMd5(value: string) { return toMd5(value); } toSafeString(value: string, context: SecurityContext = SecurityContext.NONE) { return this.sanitizer.sanitize(context, value); } toSafeHTML(value: string) { return this.domSanitizer.bypassSecurityTrustHtml(value); } toSafeResourceURL(value: string) { return this.domSanitizer.bypassSecurityTrustResourceUrl(value); } toSafeURL(value: string) { return this.domSanitizer.bypassSecurityTrustUrl(value); } toSafeScript(value: string) { return this.domSanitizer.bypassSecurityTrustScript(value); } toSafeStyle(value: string) { return this.domSanitizer.bypassSecurityTrustStyle(value); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-settings.service.ts import { isArray, XLocale, XDeviceInfo, XValidators, XOrientation, XBaseService, XDeviceTypes, XOneOrManyType, XCssProperties, XLanguageDirection, XSettingsStorageKey, isNullOrEmptyString, } from 'x-framework-core'; import { Breakpoints, BreakpointState, BreakpointObserver, } from '@angular/cdk/layout'; import { Observable } from 'rxjs'; import { Md5 } from 'md5-typescript'; import { map } from 'rxjs/operators'; import { Platform } from '@ionic/angular'; import { Injectable, Inject } from '@angular/core'; import { XStorageService } from './x-storage.service'; import { DeviceDetectorService } from 'ngx-device-detector'; import { XLocalizationService } from './x-localization.service'; import { Meta, Title, MetaDefinition } from '@angular/platform-browser'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XSettingsService extends XBaseService { // private PREFIX = '--'; private DEVICE_INFO: XDeviceInfo; private SIDE_MENU_OPENED: boolean; // //#region Breakpoint Observers ... isMobile$: Observable; isXSmall$: Observable; isSmall$: Observable; isMedium$: Observable; isLarge$: Observable; isXLarge$: Observable; isTablet$: Observable; isWeb$: Observable; isPortrait$: Observable; isLandscape$: Observable; orientation$: Observable; //#endregion // //#region Properties ... // get uiDirection(): XLanguageDirection { return this.localizationService.direction; } //#endregion constructor( public platform: Platform, private meta: Meta, private titleService: Title, @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig, private storageService: XStorageService, private localizationService: XLocalizationService, private deviceService: DeviceDetectorService, private breakPointObserver: BreakpointObserver ) { // super(config); // // Handle Ui Directions based on Current Locale ... this.applyCurrentLocale(); // // Generate Device Info ... this.prepareDeviceInfo(); // // define objservable ... this.defineUiBreakPointObservers(); // // Handle Metas for Theme ... this.handleThemeMetaTags(); // // Prepare Toolbar Height ... } /** * restart application ... */ restart() { // if (!window || !window.location) { return; } // const href = window.location.href; setTimeout(() => { window.location.href = href; window.location.reload(); }, 100) } /** * change system locale ... * * @param locale available locale */ async changeLocale(locale: XLocale, refresh: boolean = false) { // XValidators.validateNotNull(locale); if (locale === this.localizationService.locale) { return; } // this.storageService.write(XSettingsStorageKey.Locale, locale, true); this.localizationService.changeLocale(locale); this.applyCurrentLocale(); // if (refresh) { this.restart(); } } // //#region Met Seo Service ... addTag(tag: MetaDefinition, forceCreation?: boolean) { this.meta.addTag(tag, forceCreation); } addTags(tags: MetaDefinition[], forceCreation?: boolean) { this.meta.addTags(tags, forceCreation); } getTag(attrSelector: string) { this.meta.getTag(attrSelector); } getTags(attrSelector: string) { this.meta.getTags(attrSelector); } updateTag(tag: MetaDefinition, attrSelector?: string) { this.meta.updateTag(tag, attrSelector); } removeTag(attrSelector: string) { this.meta.removeTag(attrSelector); } removeTagElement(meta: HTMLMetaElement) { this.meta.removeTagElement(meta); } //#endregion // //#region Title Service ... /** * set Page ( Current Document ) Title * in Browser ... */ setTitle(title?: string) { // const appNameKey = this.config.appNameResource; const appName = this.localizationService.getValue(appNameKey); // const pageTitle = !isNullOrEmptyString(title) ? `${appName} > ${title}` : appName; // this.titleService.setTitle(pageTitle); } /** * get the Current Document Title ... */ getTitle() { return this.titleService.getTitle(); } //#endregion // //#region Device Service ... /** * get Current Device Model Info */ get device() { return this.DEVICE_INFO; } /** * get Current Device token */ get deviceToken() { return this.DEVICE_INFO.token; } //#endregion // //#region Css Property Handler ... /** * reading the CSS Property ... * * @param key the key of property */ readCssProperty(key: XCssProperties): string { // const bodyStyles = window.getComputedStyle(document.body); return bodyStyles.getPropertyValue(this.prepareCssKey(key)); } getCssVar(name: XCssProperties, element?: HTMLElement) { // const docElement = element ? getComputedStyle(element) : getComputedStyle(document.documentElement); return !name || !docElement || isNullOrEmptyString(name) ? '' : docElement.getPropertyValue(this.prepareCssKey(name)); } setCssVar( name: XCssProperties, value: string, elements?: XOneOrManyType ) { // if (isNullOrEmptyString(name)) { return; } // if (!elements || !isArray(elements)) { // const docElement = elements ? (elements as HTMLElement).style : document.documentElement.style; // docElement.setProperty(this.prepareCssKey(name), value); } else { (elements as HTMLElement[]).forEach((e) => { e.style.setProperty(this.prepareCssKey(name), value); }); } } //#endregion // //#region Theme Manager ... //#endregion // //#region Private private applyCurrentLocale() { // let storedLocale = this.localizationService.locale; const isExistsLocale = this.storageService.isExists( XSettingsStorageKey.Locale ); if (isExistsLocale) { storedLocale = this.storageService.readOfType( XSettingsStorageKey.Locale ); this.localizationService.changeLocale(storedLocale); } // this.storageService.write(XSettingsStorageKey.Locale, storedLocale, true); // //#region Handle Ui Directions based on Current Locale ... document.documentElement.lang = this.localizationService.language; document.documentElement.dir = this.localizationService.direction; // this.setTitle(); // // Document CSS ... document.body.style.setProperty( this.prepareCssKey('ui-direction'), this.localizationService.direction ); // const isRtl = this.localizationService.direction === 'rtl'; document.body.style.setProperty( this.prepareCssKey('is-rtl'), isRtl.toString() ); //#endregion } private prepareDeviceInfo() { // //#region Generate Device Info ... // // Reading Device Specifications ... const deviceOs = this.deviceService.os; const deviceBrowser = this.deviceService.browser; const deviceOsVersion = this.deviceService.os_version; const deviceUserAgent = this.deviceService.userAgent; // // Generating Device Type ... let mDeviceType: XDeviceTypes; if (this.deviceService.isDesktop()) { mDeviceType = XDeviceTypes.Desktop; } else if (this.deviceService.isTablet()) { mDeviceType = XDeviceTypes.Tablet; } else if (this.deviceService.isMobile()) { mDeviceType = XDeviceTypes.Mobile; } else { mDeviceType = XDeviceTypes.Unknown; } // // Generating Device Identifier and it's token ... const deviceIdentifier = `[${deviceOs}]-[${deviceOsVersion}]-[${mDeviceType}]-[${deviceBrowser}]-[${deviceUserAgent}]`; const deviceToken = Md5.init(deviceIdentifier); // this.DEVICE_INFO = { os: deviceOs, browser: deviceBrowser, osVersion: deviceOsVersion, userAgent: deviceUserAgent, deviceType: mDeviceType, identifier: deviceIdentifier, token: deviceToken, }; //#endregion } private defineUiBreakPointObservers() { // //#region define objservable ... this.isPortrait$ = this.breakPointObserver .observe([ Breakpoints.WebPortrait, Breakpoints.TabletPortrait, Breakpoints.HandsetPortrait, ]) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isLandscape$ = this.breakPointObserver .observe([ Breakpoints.WebLandscape, Breakpoints.TabletLandscape, Breakpoints.HandsetLandscape, ]) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.orientation$ = this.breakPointObserver .observe([ Breakpoints.WebPortrait, Breakpoints.TabletPortrait, Breakpoints.HandsetPortrait, Breakpoints.WebLandscape, Breakpoints.TabletLandscape, Breakpoints.HandsetLandscape, ]) .pipe( map(() => { if ( this.breakPointObserver.isMatched([ Breakpoints.WebPortrait, Breakpoints.TabletPortrait, Breakpoints.HandsetPortrait, ]) ) { return 'portrait'; } else { return 'landscape'; } }) ); // this.isXSmall$ = this.breakPointObserver .observe(Breakpoints.XSmall) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isSmall$ = this.breakPointObserver .observe(Breakpoints.Small) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isMedium$ = this.breakPointObserver .observe(Breakpoints.Medium) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isLarge$ = this.breakPointObserver .observe(Breakpoints.Large) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isXLarge$ = this.breakPointObserver .observe(Breakpoints.XLarge) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isTablet$ = this.breakPointObserver .observe(Breakpoints.Tablet) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isWeb$ = this.breakPointObserver .observe(Breakpoints.Web) .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); // this.isMobile$ = this.breakPointObserver .observe('(max-width: 768px)') .pipe(map((breakPointState: BreakpointState) => breakPointState.matches)); //#endregion } private handleThemeMetaTags() { // //#region Handle Metas for Theme ... const darkPrimaryColor = this.readCssProperty('x-app-bar-color'); this.addTag( { name: 'theme-color', content: darkPrimaryColor, }, true ); this.addTag( { name: 'msapplication-navbutton-color', content: darkPrimaryColor, }, true ); this.addTag( { name: 'apple-mobile-web-app-capable', content: 'yes', }, true ); this.addTag( { name: 'apple-mobile-web-app-status-bar-style', content: darkPrimaryColor, }, true ); //#endregion } private prepareCssKey(key: XCssProperties) { return `${this.PREFIX}${key}`; } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-storage.service.ts import { fromJson, XStorageItem, XBaseService, XExceptionIDs, throwException, isNullOrUndefined } from 'x-framework-core'; import { Injectable, Inject } from '@angular/core'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root' }) export class XStorageService extends XBaseService { // private keyPrefix: string; // constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig ) { super(config); // if (isNullOrUndefined(typeof Storage)) { throwException(XExceptionIDs.StorageNotSupported); } // this.keyPrefix = `${config.appInstanceName}`; } /** * determine a key exists in storage or not ... * @param key the item key */ isExists(key: string) { // const theKey = this.getPreparedKey(key); const result = localStorage.getItem(theKey) !== null; // return result; } /** * writing a new item in Storage ... * * @param key the item key * @param data the data object which needs to save * @param forceRewrite overwrite item if exists, the default is false, * means if key exists throws an error ... */ write(key: string, data: any, forceRewrite: boolean = false) { // if (!forceRewrite && this.isExists(key)) { throwException(XExceptionIDs.Duplicate); } // const theKey = this.getPreparedKey(key); localStorage.setItem(theKey, JSON.stringify(data)); } /** * read an item from Storage ... * @param key the item key * @param forceExists determine the given key must be exists or not, true is default, * means if key not exists throws an error ... */ read(key: string, forceExists: boolean = true): any | null { // if (forceExists && !this.isExists(key)) { throwException(XExceptionIDs.NotFound); } // const theKey = this.getPreparedKey(key); const item = localStorage.getItem(theKey); if (!isNullOrUndefined(item)) { try { return JSON.parse(item); } catch {} } // return null; } readOfType(key: string, forceExists: boolean = true): T | null { // if (!this.isExists(key)) { // if (forceExists) { throwException(XExceptionIDs.NotFound); } // return null; } // const valStr = this.read(key, forceExists); return fromJson(valStr); } /** * remove an stored item from Storage ... * @param key the item key * @param forceExists determine the given key must be exists or not, true is default, * means if key not exists throws an error ... */ remove(key: string, forceExists: boolean = true) { // if (forceExists && !this.isExists(key)) { throwException(XExceptionIDs.NotFound); } // const theKey = this.getPreparedKey(key); localStorage.removeItem(theKey); } /** * get a List of Stored items as an Array of StorageItem ... * @param force true is defualt, means only return list of items * from Storage which Stored by Service ... */ list(force: boolean = true): XStorageItem[] | null { // if (localStorage.length === 0) { return null; } // const items: XStorageItem[] = []; for (let i = 0; i < localStorage.length; i++) { // const mKey = localStorage.key(i); // if (force) { const theRawKey = this.getRawKey(mKey); if (!isNullOrUndefined(theRawKey)) { // items.push({ key: theRawKey, value: localStorage.getItem(mKey) }); } } else { // items.push({ key: mKey, value: localStorage.getItem(mKey) }); } } // return items; } /** * get the number of items which stored in Storage ... * @param force true is defualt, means only return number of items * from Storage which Stored by Service ... */ length(force: boolean = true) { // if (force) { return this.list().length; } // return localStorage.length; } /** * clear all items from Storage ... * @param force true is defualt, means only clear items * from Storage which Stored by Service ... */ clear(force: boolean = true) { localStorage.clear(); } protected getPreparedKey(key: string) { return `${this.keyPrefix}_${key}`; } protected getRawKey(key: string): string | null { // const baseKeySubstr = `${this.keyPrefix}_`; if (key.indexOf(baseKeySubstr) === -1) { return null; } // return key.replace(baseKeySubstr, ''); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-task-manager.service.ts import { XTask, XException, XBaseService, XTaskPriority, isValidException, getErrorException, } from 'x-framework-core'; import { Injectable, Inject } from '@angular/core'; import { concatMap, catchError, tap } from 'rxjs/operators'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { Subscription, Subject, BehaviorSubject, of, throwError } from 'rxjs'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; @Injectable({ providedIn: 'root', }) export class XTaskManagerService extends XBaseService { // //#region Props ... // subscription: Subscription; // // Notify loading ... public allTasksFinished = new Subject(); public loading = new BehaviorSubject(false); // // notify Specific Task Start or Finished ... public taskStart = new Subject>(); public taskError = new Subject>(); public taskFinished = new Subject>(); // private isPaused = false; private isStarted = false; private tasks = new Map>(); private taskQueue = new Subject>(); /** * retrieve a Collection of Tasks which Pending to run ... */ get taskList() { return this.getSortedTasksLists(); } /** * retrieve Running State of Tasks ... */ get paused() { return this.isPaused; } //#endregion // //#region Constructor ... constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig ) { super(config); // // Register Task Queue Runner ... this.taskQueue.asObservable().subscribe((t) => { this.handleTaskRun(t); }); // this.allTasksFinished.asObservable().subscribe(() => { this.loading.next(false); }); } //#endregion // //#region Actions ... /** * determines a Tasks is in Pending List or not ... */ has(taskName: string) { return this.tasks.has(taskName); } /** * delete a task from Pending List ... */ delete(taskName: string) { return this.tasks.delete(taskName); } /** * add a Task to Pending List ... */ add(task: XTask) { // // Prevent Duplicate ... if (this.has(task.name)) { return false; } // // add Task to Pending List ... this.tasks.set(task.name, task); // // Start Running if it's not Started Before ... if (!this.isStarted) { this.requestNext(); } // return true; } /** * Change Specific Tasks Priority ... */ changePriority(taskName: string, priority: XTaskPriority) { // if (!this.has(taskName)) { return; } // this.tasks.get(taskName).priority = priority; } /** * Count Pending List Tasks ... */ count() { return this.tasks.size; } /** * Remove All Pending List Task ... */ clear() { this.isStarted = false; this.tasks.clear(); } /** * Pause Running of Tasks ... */ pause() { this.isPaused = true; } /** * Continue Running Pending Tasks ... */ continue() { // if (!this.isPaused) { return; } // this.isPaused = false; this.requestNext(); } /** * Toggle Pause/Continue Tasks Running ... */ toggle() { // if (this.isPaused) { this.continue(); } else { this.pause(); } } //#endregion // //#region Private ... private requestNext() { // if (this.isPaused) { return; } // const task = this.popTask(); // if (task) { // this.isStarted = true; this.taskQueue.next(task); } else { // this.isStarted = false; if (this.tasks.size === 0) { // this.loading.next(false); this.allTasksFinished.next(); } } } private popTask() { // const result = this.getSortedTasksLists().pop() || null; // if (result) { this.tasks.delete(result.name); } return result; } private getSortedTasksLists() { // return Array.from(this.tasks.values()) .sort((a, b) => a.priority - b.priority) .reverse(); } private applyWrapperToTask(task: XTask) { // return of(task).pipe( concatMap((res) => { // if (res.affectLoading) { this.loading.next(true); } // this.taskStart.next(res); // return res.task.pipe( catchError((err) => { // this.isStarted = false; this.loading.next(false); // res.error = getErrorException(err); // if (isValidException(err.error)) { res.error = err.error as XException; } // this.taskError.next(res); // this.handleUnSubscribe(); return throwError(res.error); }), tap((tRes) => { // this.isStarted = false; this.loading.next(false); // res.result = tRes; this.taskFinished.next(res); // this.handleUnSubscribe(); this.requestNext(); }) ); }) ); } private handleTaskRun(task: XTask) { // const mXTObs = this.applyWrapperToTask(task); // this.subscription = mXTObs.subscribe( (_) => {}, (_) => {} ); } private handleUnSubscribe() { // if (this.subscription) { // this.subscription.unsubscribe(); this.subscription = null; } } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-theme-manager.service.ts import { keys, hasChild, XThemeType, XThemePack, XThemeColors, downloadFile, XBaseService, XExceptionIDs, XThemeCssVars, toNormalString, isNullOrUndefined, isNullOrEmptyString, XExceptionIdentifier, XThemeTypeIdentifier, XThemeCssVarsIdentifier, } from 'x-framework-core'; import { XStorageService } from './x-storage.service'; import { XSettingsService } from './x-settings.service'; import { XNotificationService } from './x-notification.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens'; import { Injectable, Inject, EventEmitter, ElementRef } from '@angular/core'; import { XFrameworkServicesConfig } from './config/x-framework-services.config'; const XThemeManagerStorageKeys = { CurrentTheme: 'current_theme', CurrentThemeType: 'current_theme_type', Themes: 'themes', }; @Injectable({ providedIn: 'root', }) export class XThemeManagerService extends XBaseService { // //#region Props ... // private PREFIX = '--'; readonly ColorCssVars = Object.assign({}, XThemeCssVars); // notifyChanges = new EventEmitter(); //#endregion // //#region Constructor ... constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) public config: XFrameworkServicesConfig, private storageService: XStorageService, private settingsService: XSettingsService, private notificationService: XNotificationService ) { // super(config); // this.initializeService(); } //#endregion // //#region Actions ... async applyCurrentTheme(element?: ElementRef) { // const currentTheme = await this.getCurrentTheme(); const isDefaultThemeExists = !isNullOrUndefined(currentTheme); if (isDefaultThemeExists) { // const type = await this.getCurrentThemeType(); await this.setTheme(currentTheme, type, false, false, element); // this.notifyChanges.emit(); } } async getCurrentThemeName() { // const mKey = XThemeManagerStorageKeys.CurrentTheme; // const isExists = this.storageService.isExists(mKey); if (!isExists) { return ''; } // const result = this.storageService.readOfType(mKey); // return result; } async setCurrentThemeName(themeName: string, notifyChanges: boolean = true) { // const isExists = await this.isThemeExists(themeName); if (!isExists) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const mKey = XThemeManagerStorageKeys.CurrentTheme; // this.storageService.write(mKey, themeName, true); // if (notifyChanges) { // this.notifyChanges.emit(); await this.issueSuccessNotification(); } // return true; } async getCurrentThemeType() { // const mKey = XThemeManagerStorageKeys.CurrentThemeType; // const isExists = this.storageService.isExists(mKey); if (!isExists) { return XThemeType.Light; } // const result = this.storageService.readOfType(mKey); // return result; } async setCurrentThemeType( themeType: XThemeTypeIdentifier, notifyChanges: boolean = true ) { // if (isNullOrEmptyString(themeType)) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.InvalidArgs); } // return false; } // const mKey = XThemeManagerStorageKeys.CurrentThemeType; // this.storageService.write(mKey, themeType, true); // if (notifyChanges) { // this.notifyChanges.emit(); await this.issueSuccessNotification(); } // return true; } async setTheme( theme: XThemePack, whichType: XThemeTypeIdentifier = XThemeType.Light, notifyChanges: boolean = true, restart: boolean = true, element?: ElementRef ) { // if (isNullOrUndefined(theme)) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.InvalidArgs); } // return false; } // const isExists = await this.isThemeExists(theme.name); if (!isExists) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // let result = false; switch (whichType) { // case XThemeType.Light: result = await this.setThemeColors(theme.light.colors, element); break; // case XThemeType.Dark: result = await this.setThemeColors(theme.dark.colors, element); break; } // if (result) { // await this.setCurrentThemeType(whichType, false); await this.setCurrentThemeName(theme.name, false); } // if (result && notifyChanges) { // this.notifyChanges.emit(); await this.issueSuccessNotification(); } // if (result && restart) { this.settingsService.restart(); } // return result; } async cloneTheme( themeName: string, clonedThemeName: string, notifyChanges: boolean = true ) { // const isExists = await this.isThemeExists(themeName); if (!isExists) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const isClonedThemeNameReserved = await this.isThemeExists(clonedThemeName); if (isClonedThemeNameReserved) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.Duplicate); } // return false; } // const theme = await this.getTheme(themeName); if (!theme) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // theme.name = clonedThemeName; const result = await this.saveTheme(theme, false); // if (result && notifyChanges) { this.notifyChanges.emit(); } // return result; } async exportTheme(themeName: string) { // if (isNullOrEmptyString(themeName)) { return; } // const theme = await this.getTheme(themeName); if (isNullOrUndefined(theme)) { return; } // const theJSON = JSON.stringify(theme); // downloadFile(theJSON, 'text/json', `x-framework-${theme.name}-theme.json`); } async removeTheme(themeName: string, notifyChanges: boolean = true) { // const isExists = await this.isThemeExists(themeName); if (!isExists) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const currentThemeName = await this.getCurrentThemeName(); if (!currentThemeName) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const themes = await this.getThemes(); if (!hasChild(themes) || themes.length === 1) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const filteredThemes = themes.filter( (th) => toNormalString(th.name) !== toNormalString(themeName) ); // let result = false; try { // result = true; this.writeThemes(filteredThemes); } catch { result = false; } // const isCurrentRemoved = toNormalString(currentThemeName) === toNormalString(themeName); if (isCurrentRemoved) { // const newCurrentTheme = filteredThemes[0]; const themeType = await this.getCurrentThemeType(); result = await this.setTheme(newCurrentTheme, themeType, false, false); } // if (result && notifyChanges) { // this.notifyChanges.emit(); await this.issueSuccessNotification(); } // if (result && isCurrentRemoved) { this.settingsService.restart(); } // return result; } async saveTheme(theme: XThemePack, notifyChanges: boolean = true) { // if (isNullOrUndefined(theme)) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.InvalidArgs); } // return false; } // const isExists = await this.isThemeExists(theme.name); if (isExists) { // if (notifyChanges) { await this.issueFailedNotification(XExceptionIDs.Duplicate); } // return false; } // const themeType = await this.getCurrentThemeType(); // const themes = await this.getThemes(); if (!hasChild(themes)) { // const newThemes = [theme]; // this.writeThemes(newThemes); // const result = await this.setTheme(theme, themeType, true); return result; } else { // const themeIndex = themes.findIndex((th) => th.name === theme.name); if (themeIndex === -1) { themes.push(theme); } else { themes[themeIndex] = theme; } // this.writeThemes(themes); // if (notifyChanges) { // this.notifyChanges.emit(); await this.issueSuccessNotification(); } // return true; } } async updateTheme( themeName: string, updatedTheme: XThemePack, notifiChanges: boolean = true, restartIfCurrent: boolean = true ) { // if (isNullOrEmptyString(themeName) || isNullOrUndefined(updatedTheme)) { // if (notifiChanges) { await this.issueFailedNotification(XExceptionIDs.InvalidArgs); } // return false; } // const isExists = await this.isThemeExists(themeName); if (!isExists) { // if (notifiChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return false; } // const currentThemeName = await this.getCurrentThemeName(); const isCurrent = toNormalString(themeName) === toNormalString(currentThemeName); // let result = false; const themes = this.readThemes(); const themeIndex = themes.findIndex( (th) => toNormalString(th.name) === toNormalString(themeName) ); if (themeIndex < 0) { // if (notifiChanges) { await this.issueFailedNotification(XExceptionIDs.NotFound); } // return result; } // themes[themeIndex] = updatedTheme; try { result = true; this.writeThemes(themes); } catch { // if (notifiChanges) { await this.issueFailedNotification(XExceptionIDs.ActionFailed); } // return false; } // if (result && isCurrent) { // const mode = await this.getCurrentThemeType(); const isSetted = await this.setTheme(updatedTheme, mode, false, false); if (!isSetted) { // if (notifiChanges) { await this.issueFailedNotification(XExceptionIDs.ActionFailed); } // return false; } } // if (result && notifiChanges) { await this.issueSuccessNotification(); } // if (isCurrent && restartIfCurrent) { this.settingsService.restart(); } // return result; } async getCurrentTheme() { // const currentThemeName = await this.getCurrentThemeName(); const isExists = await this.isThemeExists(currentThemeName); if (!isExists) { return null; } // const result = await this.getTheme(currentThemeName); return result; } async getThemeNames() { // const themes = await this.getThemes(); if (!hasChild(themes)) { return []; } // return themes.map((th) => th.name); } async getThemes() { // const result = this.readThemes(); // return result; } async getTheme(themeName: string) { // const isExists = await this.isThemeExists(themeName); if (!isExists) { return null; } // const themes = await this.getThemes(); return themes.find( (th) => toNormalString(th.name) === toNormalString(themeName) ); } async isThemeExists(themeName: string) { // if (isNullOrEmptyString(themeName)) { return false; } // const themes = await this.getThemeNames(); const result = themes.findIndex( (th) => toNormalString(th) === toNormalString(themeName) ) > -1; // return result; } async setLightMode() { // const currentTheme = await this.getCurrentTheme(); if (isNullOrUndefined(currentTheme)) { return false; } // return await this.setTheme(currentTheme, XThemeType.Light, false, true); } async setDarkMode() { // const currentTheme = await this.getCurrentTheme(); if (isNullOrUndefined(currentTheme)) { return false; } // return await this.setTheme(currentTheme, XThemeType.Dark, false, true); } async toggleMode() { // const currentTheme = await this.getCurrentTheme(); const currentThemeMode = await this.getCurrentThemeType(); if (isNullOrUndefined(currentTheme)) { return false; } // const mode: XThemeType = currentThemeMode === XThemeType.Light ? XThemeType.Dark : XThemeType.Light; // return await this.setTheme(currentTheme, mode, false, true); } //#endregion // //#region Private ... private async initializeService() { // const currentTheme = await this.getCurrentTheme(); const isDefaultThemeExists = !isNullOrUndefined(currentTheme); if (!isDefaultThemeExists) { // const defaultTheme: XThemePack = { name: 'default', light: { type: XThemeType.Light, colors: { // //#region Primary ... // XColorPrimary: this.getCssVar(XThemeCssVars.XColorPrimary), XColorPrimaryContrast: this.getCssVar( XThemeCssVars.XColorPrimaryContrast ), // XColorPrimaryShade: this.getCssVar( XThemeCssVars.XColorPrimaryShade ), XColorPrimaryShadeContrast: this.getCssVar( XThemeCssVars.XColorPrimaryShadeContrast ), // XColorPrimaryTint: this.getCssVar(XThemeCssVars.XColorPrimaryTint), XColorPrimaryTintContrast: this.getCssVar( XThemeCssVars.XColorPrimaryTintContrast ), //#endregion // //#region Secondary ... // XColorSecondary: this.getCssVar(XThemeCssVars.XColorSecondary), XColorSecondaryContrast: this.getCssVar( XThemeCssVars.XColorSecondaryContrast ), // XColorSecondaryShade: this.getCssVar( XThemeCssVars.XColorSecondaryShade ), XColorSecondaryShadeContrast: this.getCssVar( XThemeCssVars.XColorSecondaryShadeContrast ), // XColorSecondaryTint: this.getCssVar( XThemeCssVars.XColorSecondaryTint ), XColorSecondaryTintContrast: this.getCssVar( XThemeCssVars.XColorSecondaryTintContrast ), //#endregion // //#region Tertiary ... // XColorTertiary: this.getCssVar(XThemeCssVars.XColorTertiary), XColorTertiaryContrast: this.getCssVar( XThemeCssVars.XColorTertiaryContrast ), // XColorTertiaryShade: this.getCssVar( XThemeCssVars.XColorTertiaryShade ), XColorTertiaryShadeContrast: this.getCssVar( XThemeCssVars.XColorTertiaryShadeContrast ), // XColorTertiaryTint: this.getCssVar( XThemeCssVars.XColorTertiaryTint ), XColorTertiaryTintContrast: this.getCssVar( XThemeCssVars.XColorTertiaryTintContrast ), //#endregion // //#region Success ... // XColorSuccess: this.getCssVar(XThemeCssVars.XColorSuccess), XColorSuccessContrast: this.getCssVar( XThemeCssVars.XColorSuccessContrast ), // XColorSuccessShade: this.getCssVar( XThemeCssVars.XColorSuccessShade ), XColorSuccessShadeContrast: this.getCssVar( XThemeCssVars.XColorSuccessShadeContrast ), // XColorSuccessTint: this.getCssVar(XThemeCssVars.XColorSuccessTint), XColorSuccessTintContrast: this.getCssVar( XThemeCssVars.XColorSuccessTintContrast ), //#endregion // //#region Warning ... // XColorWarning: this.getCssVar(XThemeCssVars.XColorWarning), XColorWarningContrast: this.getCssVar( XThemeCssVars.XColorWarningContrast ), // XColorWarningShade: this.getCssVar( XThemeCssVars.XColorWarningShade ), XColorWarningShadeContrast: this.getCssVar( XThemeCssVars.XColorWarningShadeContrast ), // XColorWarningTint: this.getCssVar(XThemeCssVars.XColorWarningTint), XColorWarningTintContrast: this.getCssVar( XThemeCssVars.XColorWarningTintContrast ), //#endregion // //#region Danger ... // XColorDanger: this.getCssVar(XThemeCssVars.XColorDanger), XColorDangerContrast: this.getCssVar( XThemeCssVars.XColorDangerContrast ), // XColorDangerShade: this.getCssVar(XThemeCssVars.XColorDangerShade), XColorDangerShadeContrast: this.getCssVar( XThemeCssVars.XColorDangerShadeContrast ), // XColorDangerTint: this.getCssVar(XThemeCssVars.XColorDangerTint), XColorDangerTintContrast: this.getCssVar( XThemeCssVars.XColorDangerTintContrast ), //#endregion // //#region Dark ... // XColorDark: this.getCssVar(XThemeCssVars.XColorDark), XColorDarkContrast: this.getCssVar( XThemeCssVars.XColorDarkContrast ), // XColorDarkShade: this.getCssVar(XThemeCssVars.XColorDarkShade), XColorDarkShadeContrast: this.getCssVar( XThemeCssVars.XColorDarkShadeContrast ), // XColorDarkTint: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorDarkTintContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), //#endregion // //#region Medium ... // XColorMedium: this.getCssVar(XThemeCssVars.XColorMedium), XColorMediumContrast: this.getCssVar( XThemeCssVars.XColorMediumContrast ), // XColorMediumShade: this.getCssVar(XThemeCssVars.XColorMediumShade), XColorMediumShadeContrast: this.getCssVar( XThemeCssVars.XColorMediumShadeContrast ), // XColorMediumTint: this.getCssVar(XThemeCssVars.XColorMediumTint), XColorMediumTintContrast: this.getCssVar( XThemeCssVars.XColorMediumTintContrast ), //#endregion // //#region Light ... // XColorLight: this.getCssVar(XThemeCssVars.XColorLight), XColorLightContrast: this.getCssVar( XThemeCssVars.XColorLightContrast ), // XColorLightShade: this.getCssVar(XThemeCssVars.XColorLightShade), XColorLightShadeContrast: this.getCssVar( XThemeCssVars.XColorLightShadeContrast ), // XColorLightTint: this.getCssVar(XThemeCssVars.XColorLightTint), XColorLightTintContrast: this.getCssVar( XThemeCssVars.XColorLightTintContrast ), //#endregion }, }, dark: { type: XThemeType.Dark, colors: { // //#region Primary ... // XColorPrimary: this.getCssVar(XThemeCssVars.XColorDark), XColorPrimaryContrast: this.getCssVar( XThemeCssVars.XColorDarkContrast ), // XColorPrimaryShade: this.getCssVar(XThemeCssVars.XColorDarkShade), XColorPrimaryShadeContrast: this.getCssVar( XThemeCssVars.XColorDarkShadeContrast ), // XColorPrimaryTint: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorPrimaryTintContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), //#endregion // //#region Secondary ... // XColorSecondary: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorSecondaryContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), // XColorSecondaryShade: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorSecondaryShadeContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), // XColorSecondaryTint: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorSecondaryTintContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), //#endregion // //#region Tertiary ... // XColorTertiary: this.getCssVar(XThemeCssVars.XColorTertiary), XColorTertiaryContrast: this.getCssVar( XThemeCssVars.XColorTertiaryContrast ), // XColorTertiaryShade: this.getCssVar( XThemeCssVars.XColorTertiaryShade ), XColorTertiaryShadeContrast: this.getCssVar( XThemeCssVars.XColorTertiaryShadeContrast ), // XColorTertiaryTint: this.getCssVar( XThemeCssVars.XColorTertiaryTint ), XColorTertiaryTintContrast: this.getCssVar( XThemeCssVars.XColorTertiaryTintContrast ), //#endregion // //#region Success ... // XColorSuccess: this.getCssVar(XThemeCssVars.XColorSuccess), XColorSuccessContrast: this.getCssVar( XThemeCssVars.XColorSuccessContrast ), // XColorSuccessShade: this.getCssVar( XThemeCssVars.XColorSuccessShade ), XColorSuccessShadeContrast: this.getCssVar( XThemeCssVars.XColorSuccessShadeContrast ), // XColorSuccessTint: this.getCssVar(XThemeCssVars.XColorSuccessTint), XColorSuccessTintContrast: this.getCssVar( XThemeCssVars.XColorSuccessTintContrast ), //#endregion // //#region Warning ... // XColorWarning: this.getCssVar(XThemeCssVars.XColorWarning), XColorWarningContrast: this.getCssVar( XThemeCssVars.XColorWarningContrast ), // XColorWarningShade: this.getCssVar( XThemeCssVars.XColorWarningShade ), XColorWarningShadeContrast: this.getCssVar( XThemeCssVars.XColorWarningShadeContrast ), // XColorWarningTint: this.getCssVar(XThemeCssVars.XColorWarningTint), XColorWarningTintContrast: this.getCssVar( XThemeCssVars.XColorWarningTintContrast ), //#endregion // //#region Danger ... // XColorDanger: this.getCssVar(XThemeCssVars.XColorDanger), XColorDangerContrast: this.getCssVar( XThemeCssVars.XColorDangerContrast ), // XColorDangerShade: this.getCssVar(XThemeCssVars.XColorDangerShade), XColorDangerShadeContrast: this.getCssVar( XThemeCssVars.XColorDangerShadeContrast ), // XColorDangerTint: this.getCssVar(XThemeCssVars.XColorDangerTint), XColorDangerTintContrast: this.getCssVar( XThemeCssVars.XColorDangerTintContrast ), //#endregion // //#region Dark ... // XColorDark: this.getCssVar(XThemeCssVars.XColorDark), XColorDarkContrast: this.getCssVar( XThemeCssVars.XColorDarkContrast ), // XColorDarkShade: this.getCssVar(XThemeCssVars.XColorDarkShade), XColorDarkShadeContrast: this.getCssVar( XThemeCssVars.XColorDarkShadeContrast ), // XColorDarkTint: this.getCssVar(XThemeCssVars.XColorDarkTint), XColorDarkTintContrast: this.getCssVar( XThemeCssVars.XColorDarkTintContrast ), //#endregion // //#region Medium ... // XColorMedium: this.getCssVar(XThemeCssVars.XColorMedium), XColorMediumContrast: this.getCssVar( XThemeCssVars.XColorMediumContrast ), // XColorMediumShade: this.getCssVar(XThemeCssVars.XColorMediumShade), XColorMediumShadeContrast: this.getCssVar( XThemeCssVars.XColorMediumShadeContrast ), // XColorMediumTint: this.getCssVar(XThemeCssVars.XColorMediumTint), XColorMediumTintContrast: this.getCssVar( XThemeCssVars.XColorMediumTintContrast ), //#endregion // //#region Light ... // XColorLight: this.getCssVar(XThemeCssVars.XColorLight), XColorLightContrast: this.getCssVar( XThemeCssVars.XColorLightContrast ), // XColorLightShade: this.getCssVar(XThemeCssVars.XColorLightShade), XColorLightShadeContrast: this.getCssVar( XThemeCssVars.XColorLightShadeContrast ), // XColorLightTint: this.getCssVar(XThemeCssVars.XColorLightTint), XColorLightTintContrast: this.getCssVar( XThemeCssVars.XColorLightTintContrast ), //#endregion }, }, }; // await this.saveTheme(defaultTheme, false); } else { // const type = await this.getCurrentThemeType(); await this.setTheme(currentTheme, type, false, false); } // this.notifyChanges.emit(); } private async issueFailedNotification(exception?: XExceptionIdentifier) { // if (isNullOrUndefined(exception)) { exception = XExceptionIDs.ActionFailed; } // await this.notificationService.presentErrorNotification({ exception, dissmissable: false, }); } private async issueSuccessNotification() { // await this.notificationService.presentDefaultSuccessNotification(); } // //#region Read and Write Storage ... private writeThemes(themes: XThemePack[]) { // const mKey = XThemeManagerStorageKeys.Themes; // this.storageService.write(mKey, themes, true); } private readThemes() { // const mKey = XThemeManagerStorageKeys.Themes; // const isExists = this.storageService.isExists(mKey); if (!isExists) { return []; } // return this.storageService.readOfType(mKey, false); } //#endregion // //#region CssVar Manipulators ... /** * prepare a css var name * * @param key css variable name */ private prepareCssKey(key: XThemeCssVarsIdentifier) { return `${this.PREFIX}${key}`; } /** * remove css key prefix ... * * @param key a prepared css var ... */ private removeCssKeyPrefix(key: XThemeCssVarsIdentifier) { return key.replace(this.PREFIX, ''); } /** * read specific css var value of an element * @param name css variable name * @param element destination element */ private getCssVar(name: XThemeCssVarsIdentifier) { // return getComputedStyle(document.body).getPropertyValue( this.prepareCssKey(name) ); } /** * set css var into element ... * * @param name css var name * @param value css var value * @param elements destination element of array of elements */ private setCssVar( name: XThemeCssVarsIdentifier, value: string, element?: ElementRef ) { // if (isNullOrEmptyString(name)) { return; } // // Setting Variable on Element if exists ... if (element && element.nativeElement) { (element.nativeElement as HTMLElement).style.setProperty( this.prepareCssKey(name), value ); } // // Setting Variable on root ... document.documentElement.style.setProperty(this.prepareCssKey(name), value); } private async setThemeColors(theme: XThemeColors, element?: ElementRef) { // if (isNullOrUndefined(theme)) { return false; } // const colorKeys = keys(theme); colorKeys.forEach((cKey) => { // const cssKey = this.ColorCssVars[cKey] as string; const ionCssKey = cssKey.replace('x-', 'ion-'); const cssValue = toNormalString(theme[cKey]); // this.setCssVar(cssKey, cssValue, element); this.setCssVar(ionCssKey, cssValue, element); }); // return true; } //#endregion //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\config\x-framework-services.config.ts import { XFrameworkCoreConfig } from 'x-framework-core'; // tslint:disable-next-line:no-empty-interface export interface XFrameworkServicesConfig extends XFrameworkCoreConfig { geoLocationConfig?: PositionOptions } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-currency-formatter.directive.ts import { Input, Inject, Renderer2, Directive, ElementRef, forwardRef, HostListener } from '@angular/core'; import { XLocale, removeAll, applyLocale, isNullOrEmptyString } from 'x-framework-core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from '../config/x-framework-services.config'; export const X_CURRENCY_FORMATTER: any = { useExisting: forwardRef(() => XCurrencyFormatterDirective), provide: NG_VALUE_ACCESSOR, multi: true }; @Directive({ // tslint:disable-next-line:directive-selector selector: '[xCurrencyFormatter]', providers: [X_CURRENCY_FORMATTER] }) export class XCurrencyFormatterDirective implements ControlValueAccessor { // //#region Props ... @Input() locale: XLocale; @Input() applyLocaleToCurrency: boolean; @Input() currencySeperator: string; @Input() enabledCurrencyFormatter: boolean; onChange = (_: any) => {}; onTouched = () => {}; //#endregion // //#region Constructor ... constructor( private renderer: Renderer2, private elementRef: ElementRef, @Inject(X_FRAMEWORK_SERVICES_CONFIG) private config: XFrameworkServicesConfig ) {} //#endregion // //#region Host Bindings ... @HostListener('change', ['$event.target.value']) change(value: string) { // const res = this.getUnformattedValue(value); this.onChange(res); } @HostListener('input', ['$event.target.value']) input(value: string) { // const res = this.getUnformattedValue(value); this.onChange(res); } @HostListener('blur') onBlur() { this.onTouched(); } @HostListener('keydown', ['$event']) onKeyDown(event: any) { if (this.enabledCurrencyFormatter) { this.setOnlyNumberType(event); } } //#endregion // //#region Implemenntation of Interface ... writeValue(value: string): void { this.setValue(value); } registerOnChange(fn: (_: string | any | null) => void): void { this.onChange = value => { // fn(this.enabledCurrencyFormatter ? +value : value); this.setValue(value); }; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.renderer.setProperty( this.elementRef.nativeElement, 'disabled', isDisabled ); } //#endregion // //#region Private ... private isElementValid() { return this.elementRef && this.elementRef.nativeElement; } private getFormattedValue(value: string) { // if (!this.enabledCurrencyFormatter || !value) { return value || ''; } // if (this.applyLocaleToCurrency) { value = applyLocale(value, this.locale || this.config.defaultLanguage); } // const result = value .toString() .replace(/\B(?=(\d{3})+(?!\d))/g, this.currencySeperator); // return result; } private getUnformattedValue(value: string) { // const result = removeAll(value, this.currencySeperator, true); return result; } private getNormalizedValue(value: string) { // if (!this.isElementValid()) { return value; } // value = isNullOrEmptyString(value) ? '' : this.getUnformattedValue(value); // if (this.enabledCurrencyFormatter) { value = this.getFormattedValue(value); } else { value = this.getUnformattedValue(value); } // return value; } private setValue(value: string) { // const normalizedValue = this.getNormalizedValue(value); this.renderer.setProperty( this.elementRef.nativeElement, 'value', normalizedValue ); } private setOnlyNumberType(e: any) { // const keyCode = e.code as string; const isValidKey = keyCode.includes('Digit') || keyCode.includes('Backspace'); // if (!isValidKey) { e.preventDefault(); } } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-date-presenter.directive.ts import { XLocale, formatDate, getDateOfBirthDateFormatString, } from 'x-framework-core'; import { XLocalizationService } from '../x-localization.service'; import { Directive, ElementRef, OnInit, Input, OnChanges, SimpleChanges, } from '@angular/core'; @Directive({ // tslint:disable-next-line:directive-selector selector: '[xDatePresenter]', }) export class XDatePresenterDirective implements OnInit, OnChanges { // @Input() date?: Date | string; @Input() locale?: XLocale; @Input() format?: string; @Input() isUtc?: boolean; @Input() toUtc?: boolean; constructor( private element: ElementRef, private localizationService: XLocalizationService ) {} ngOnInit() { this.presentDate(); } ngOnChanges(changes: SimpleChanges): void { this.presentDate(); } private presentDate() { // if (!this.locale) { this.locale = this.localizationService.locale; } // if (!this.date) { this.date = new Date(); } // if (!this.format) { this.format = getDateOfBirthDateFormatString(this.locale); } // if (!this.toUtc) { this.toUtc = false; } // let dateStr: string; try { dateStr = formatDate( this.date, this.locale, this.format, this.isUtc, this.toUtc ); } catch { dateStr = '---'; } // this.element.nativeElement.innerHTML = dateStr; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-from-input-formatter.directive.ts import { Input, Inject, Directive, Renderer2, ElementRef, forwardRef, HostListener, } from '@angular/core'; import { XLocale, hasChild, removeAll, getDigits, toXString, applyLocale, getNonDigits, removeSpaces, isNullOrUndefined, extractUniqueChars, isNullOrEmptyString, } from 'x-framework-core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from '../config/x-framework-services.config'; export const X_FORM_INPUT_FORMATTER: any = { useExisting: forwardRef(() => XFromInputFormatterDirective), provide: NG_VALUE_ACCESSOR, multi: true, }; export enum XFormInputFormatter { ApplyLocale = 'apply_locale', FormatCurrency = 'format_currency', StringFormatter = 'string_formatter', StringInputFormatter = 'string_input_formatter', FormatCurrencyAndApplyLocale = 'format_currency_apply_locale', StringFormatterAndApplyLocale = 'string_formatter_apply_locale', StringInputFormatterAndApplyLocale = 'string_input_formatter_apply_locale', } export type XFormInputFormatterIdentifier = XFormInputFormatter | string; export enum XStringInputFormatType { None = 'none', LowerCase = 'lowercase', UpperCase = 'uppercase', NonSpace = 'non_space', NonDigits = 'none_digits', OnlyDigits = 'only_digits', UniqueChars = 'unique_chars', } export type XStringInputFormatTypeIdentifier = XStringInputFormatType | string; @Directive({ // tslint:disable-next-line:directive-selector selector: '[xFromInputFormatter]', providers: [X_FORM_INPUT_FORMATTER], }) export class XFromInputFormatterDirective implements ControlValueAccessor { // //#region Props ... @Input() locale: XLocale; @Input() inputFormatterType: XFormInputFormatterIdentifier; @Input() stringInputFormatterType: XStringInputFormatTypeIdentifier; @Input() seperator: string; @Input() currencyLable: string; @Input() stringFormatter: number[]; @Input() enabledInputFormatter: boolean; // onChange = (_: any) => {}; onTouched = () => {}; onFocused = () => {}; //#endregion // //#region Constructor ... constructor( private renderer: Renderer2, private elementRef: ElementRef, @Inject(X_FRAMEWORK_SERVICES_CONFIG) private config: XFrameworkServicesConfig ) {} //#endregion // //#region Type Detectors ... isCurrencyType() { return ( this.inputFormatterType === XFormInputFormatter.FormatCurrency || this.inputFormatterType === XFormInputFormatter.FormatCurrencyAndApplyLocale ); } isStringFormatterType() { return ( this.inputFormatterType === XFormInputFormatter.StringFormatter || this.inputFormatterType === XFormInputFormatter.StringFormatterAndApplyLocale || this.inputFormatterType === XFormInputFormatter.StringInputFormatter || this.inputFormatterType === XFormInputFormatter.StringInputFormatterAndApplyLocale ); } isLocaleType() { return ( this.inputFormatterType === XFormInputFormatter.ApplyLocale || this.inputFormatterType === XFormInputFormatter.FormatCurrencyAndApplyLocale || this.inputFormatterType === XFormInputFormatter.StringFormatterAndApplyLocale || this.inputFormatterType === XFormInputFormatter.StringInputFormatterAndApplyLocale ); } //#endregion // //#region Host Bindings ... @HostListener('change', ['$event.target.value']) change(value: string) { // const res = this.getUnformattedValue(value); this.onChange(res); } @HostListener('input', ['$event.target.value']) input(value: string) { // const res = this.getUnformattedValue(value); this.onChange(res); } @HostListener('focus') onFocus() { this.onFocused(); if (this.isCurrencyType()) { this.clearCurrencyLabel(); } } @HostListener('blur') onBlur() { this.onTouched(); if (this.isCurrencyType()) { this.applyCurrencyLabel(); } } @HostListener('keydown', ['$event']) onKeyDown(event: any) { // if (this.isCurrencyType()) { // this.setOnlyNumberType(event); // } } //#endregion // //#region Implemenntation of Interface ... writeValue(value: string): void { this.setValue(value); } registerOnChange(fn: (_: string | any | null) => void): void { this.onChange = (value) => { // fn(this.isCurrencyType() ? +value : value); // this.setValue(value); }; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { // if (isDisabled && this.isCurrencyType()) { this.applyCurrencyLabel(); } // this.renderer.setProperty( this.elementRef.nativeElement, 'disabled', isDisabled ); } //#endregion // //#region Private ... private isElementValid() { return this.elementRef && this.elementRef.nativeElement; } private getFormattedValue(value: string) { // // Normallize Value ... if (isNullOrEmptyString(value) || !this.enabledInputFormatter) { return ''; } // // Prepared Formatted Value ... let result = this.isCurrencyType() ? this.getCurrencyFormattedValue(value) : this.isStringFormatterType() ? this.getStringFormattedValue(value) : value || ''; // // Apply Locale if Localeable Input Type ... if (this.isLocaleType()) { result = this.getLocaleFormattedValue(result); } // return result; } private getUnformattedValue(value: string) { // let result = value.toString() || ''; // const seperator = isNullOrEmptyString(this.seperator) ? '' : this.seperator; // // Remove All occurence of seperator ... if (this.enabledInputFormatter) { result = removeAll(value, seperator, true); } // // Currency Lable ... if (this.isCurrencyType() && !isNullOrEmptyString(this.currencyLable)) { result = result.replace(this.currencyLable, '').trim(); } // // Change Locale to Default ... if (this.isLocaleType()) { result = !isNullOrEmptyString(result) ? applyLocale(result, 'en-US') : ''; } // return result; } private getNormalizedValue(value: string) { // if (!this.isElementValid()) { return value; } // // Normallize Value and prevent from null ... let result = value ? value.toString() || '' : ''; result = isNullOrEmptyString(value) ? '' : this.getUnformattedValue(value); if (!this.enabledInputFormatter) { return result; } // // Handle Apply Locale ... if (this.inputFormatterType === XFormInputFormatter.ApplyLocale) { // result = applyLocale(value, this.locale || this.config.defaultLanguage); return result; } // // Handle Formatter ... if (this.isCurrencyType() || this.isStringFormatterType()) { return this.getFormattedValue(result); } // return value; } private setValue(value: string, normalizeValue = true) { // const normalizedValue = normalizeValue ? this.getNormalizedValue(value) : value || ''; this.renderer.setProperty( this.elementRef.nativeElement, 'value', normalizedValue ); } private getValue() { return this.elementRef.nativeElement.value ? (this.elementRef.nativeElement.value as string) : ''; } private setOnlyNumberType(e: any) { // const keyCode = e.code as string; const numPadKeys = [...new Array(10).keys()].map((c, i) => `Numpad${i}`); const isValidKey = keyCode.includes('Tab') || keyCode.includes('Digit') || keyCode.includes('Backspace') || numPadKeys.includes(keyCode); // if (!isValidKey) { e.preventDefault(); } } // //#region Formatter Actions ... private getLocaleFormattedValue(value: any) { // const mValue = value ? (value.toString() as string) : ''; return applyLocale(mValue, this.locale || this.config.defaultLanguage); } private getStringFormattedValue(value: any) { // const mValue = !isNullOrUndefined(value) ? toXString(value) : ''; // let mResultValue = ''; // if ( this.inputFormatterType === XFormInputFormatter.StringFormatter || this.inputFormatterType === XFormInputFormatter.StringFormatterAndApplyLocale ) { // if (!hasChild(this.stringFormatter)) { return mValue; } // let mSource = mValue; this.stringFormatter.forEach((l, i) => { if (mSource.length >= l) { // const selected = mSource.substring(0, l); // mResultValue += i === this.stringFormatter.length ? selected : `${selected}${this.seperator}`; // mSource = mSource.substr(l, mValue.length); } }); // if (mSource.length > 0) { mResultValue += `${mSource}`; } } else if ( this.inputFormatterType === XFormInputFormatter.StringInputFormatter || this.inputFormatterType === XFormInputFormatter.StringInputFormatterAndApplyLocale ) { // switch (this.stringInputFormatterType) { // case XStringInputFormatType.LowerCase: mResultValue = mValue.toLowerCase(); break; // case XStringInputFormatType.UpperCase: mResultValue = mValue.toUpperCase(); break; // case XStringInputFormatType.NonDigits: // mResultValue = getNonDigits(mValue); break; // case XStringInputFormatType.UniqueChars: // mResultValue = extractUniqueChars(mValue); break; // case XStringInputFormatType.NonSpace: mResultValue = removeSpaces(mValue.trim()); break; // case XStringInputFormatType.OnlyDigits: mResultValue = getDigits(mValue); break; // default: mResultValue = mValue; break; } } // return mResultValue; } private getCurrencyFormattedValue(value: any) { // const mValue = value ? getDigits(value.toString() as string) : ''; const seperator = isNullOrEmptyString(this.seperator) ? '' : this.seperator; const formattedValue = mValue.replace(/\B(?=(\d{3})+(?!\d))/g, seperator); // const result = !isNullOrEmptyString(formattedValue) ? formattedValue : ''; // return result; } private applyCurrencyLabel() { // if (!this.isCurrencyType()) { return; } // let value = this.getValue(); // if ( !isNullOrEmptyString(value) && !isNullOrEmptyString(this.currencyLable) ) { value = `${value} ${this.currencyLable}`; } // this.setValue(value, false); } private clearCurrencyLabel() { // if (!this.isCurrencyType()) { return; } // let value = this.getValue(); // if ( !isNullOrEmptyString(value) && !isNullOrEmptyString(this.currencyLable) ) { value = value.replace(this.currencyLable, ''); } // this.setValue(value); } //#endregion //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-locale-input-formatter.directive.ts import { Input, Inject, Directive, Renderer2, ElementRef, forwardRef, HostListener, } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens'; import { XLocale, applyLocale, isNullOrEmptyString } from 'x-framework-core'; import { XFrameworkServicesConfig } from '../config/x-framework-services.config'; export const X_LOCALE_FORMATTER: any = { useExisting: forwardRef(() => XLocaleInputFormatterDirective), provide: NG_VALUE_ACCESSOR, multi: true, }; @Directive({ // tslint:disable-next-line:directive-selector selector: '[xLocaleInputFormatter]', providers: [X_LOCALE_FORMATTER], }) export class XLocaleInputFormatterDirective implements ControlValueAccessor { // //#region Props ... @Input() locale: XLocale; @Input() enabledLocaleFormatter: boolean; onChange = (_: any) => {}; onTouched = () => {}; //#endregion // //#region Constructor ... constructor( private renderer: Renderer2, private elementRef: ElementRef, @Inject(X_FRAMEWORK_SERVICES_CONFIG) private config: XFrameworkServicesConfig ) {} //#endregion // //#region Host Bindings ... @HostListener('change', ['$event.target.value']) change(value: string) { this.onChange(value); } @HostListener('input', ['$event.target.value']) input(value: string) { this.onChange(value); } @HostListener('blur') onBlur() { this.onTouched(); } //#endregion // //#region Implemenntation of Interface ... writeValue(value: string): void { this.setValue(value); } registerOnChange(fn: (_: string | any | null) => void): void { this.onChange = (value) => { // fn(value); this.setValue(value); }; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.renderer.setProperty( this.elementRef.nativeElement, 'disabled', isDisabled ); } //#endregion // //#region Private ... private isElementValid() { return this.elementRef && this.elementRef.nativeElement; } private getFormattedValue(value: string) { // if (!this.enabledLocaleFormatter || !value) { return value || ''; } // value = applyLocale(value, this.locale || this.config.defaultLanguage); // return value; } private getNormalizedValue(value: string) { // if (!this.isElementValid()) { return value; } // value = isNullOrEmptyString(value) ? '' : this.getFormattedValue(value); // return value; } private setValue(value: string) { // const normalizedValue = this.getNormalizedValue(value); this.renderer.setProperty( this.elementRef.nativeElement, 'value', normalizedValue ); } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-swipable.directive.ts import { Input, OnInit, Output, OnChanges, Directive, OnDestroy, ElementRef, EventEmitter, SimpleChanges, AfterViewInit, } from '@angular/core'; import { Subject, Observable } from 'rxjs'; import { keys, nameof } from 'x-framework-core'; import { GestureController } from '@ionic/angular'; import { Gesture, GestureDetail } from '@ionic/core'; import { takeUntil, debounceTime } from 'rxjs/operators'; import { XSettingsService } from '../x-settings.service'; export enum XSwipeDirection { UP = 'up', DOWN = 'down', LEFT = 'left', START = 'start', RIGHT = 'right', END = 'end', } export type XSwipeDirectionIdentifier = XSwipeDirection | string; export enum XSwipeSupportedDirections { VERTICALL, HORIZONTAL_LEFT_RIGHT, HORIZONTAL_START_END, ALL, } export interface XSwipeEvent { deltaX: number; deltaY: number; direction: XSwipeDirectionIdentifier; } @Directive({ // tslint:disable-next-line:directive-selector selector: '[xSwipable]', }) export class XSwipableDirective implements OnInit, AfterViewInit, OnDestroy, OnChanges { // //#region Props ... private gesture: Gesture; private unsubscriber = new Subject(); private issueSwipeEvents$ = new Subject(); private uiDirection = this.settingsService.uiDirection; //#endregion // //#region Inputs ... @Input() threshold = 60; @Input() swipeDisabled = false; @Input() debounceTime = 300; @Input() supportedDirections: XSwipeSupportedDirections = XSwipeSupportedDirections.HORIZONTAL_START_END; //#endregion // //#region Event Emitters ... @Output() swipe = new EventEmitter(); @Output() swipeUp = new EventEmitter(); @Output() swipeDown = new EventEmitter(); @Output() swipeLeft = new EventEmitter(); @Output() swipeStart = new EventEmitter(); @Output() swipeRight = new EventEmitter(); @Output() swipeEnd = new EventEmitter(); //#endregion // //#region Constructor ... constructor( private elementRef: ElementRef, private gestureCtrl: GestureController, private settingsService: XSettingsService ) {} //#endregion // //#region LifeCycles ... ngOnInit() { this.prepareGesture(); } ngAfterViewInit() { this.registerIssueSwipeHandler(); } ngOnDestroy() { this.destroyGesture(); this.issueSwipeEvents$.complete(); this.releaseUnsubscriber(); } ngOnChanges(changes: SimpleChanges) { // const changeKesy = keys(changes); // const isThresholdChanged = changeKesy.includes( nameof('threshold') ); if (isThresholdChanged) { this.prepareGesture(); } // const isDebounceTimeChanged = changeKesy.includes( nameof('debounceTime') ); if (isDebounceTimeChanged) { this.registerIssueSwipeHandler(); } } //#endregion // //#region Private ... private prepareGesture() { // this.destroyGesture(); // this.gesture = this.gestureCtrl.create({ el: this.elementRef.nativeElement, threshold: this.threshold, gestureName: 'x-gesture', onMove: (detail) => { this.onMoveHandler(detail); }, }); // this.gesture.enable(); } private destroyGesture() { // if (this.gesture) { // this.gesture.destroy(); this.gesture = null; } } private releaseUnsubscriber() { // if (!this.unsubscriber.closed) { this.unsubscriber.next(); this.unsubscriber.complete(); } } private applyTakeUntilWrapper(task: Observable): Observable { return task.pipe(takeUntil(this.unsubscriber)); } private registerIssueSwipeHandler() { // this.applyTakeUntilWrapper( this.issueSwipeEvents$ .asObservable() .pipe(debounceTime(this.debounceTime)) ).subscribe((gDetail) => { // if (this.swipeDisabled) { return; } // const mSwipeEvent: Partial = { deltaX: gDetail.deltaX, deltaY: gDetail.deltaY, }; // // Handle Vertical ... if ( this.supportedDirections === XSwipeSupportedDirections.ALL || this.supportedDirections === XSwipeSupportedDirections.VERTICALL ) { // let swipeDir: XSwipeDirection; // if (gDetail.deltaY >= 0) { // swipeDir = XSwipeDirection.DOWN; // this.swipeDown.emit(); } else { // swipeDir = XSwipeDirection.UP; // this.swipeUp.emit(); } // // Handle Global Event ... mSwipeEvent.direction = swipeDir; this.swipe.emit(mSwipeEvent as XSwipeEvent); } // // Handle Horizontal Left Right ... if ( this.supportedDirections === XSwipeSupportedDirections.ALL || this.supportedDirections === XSwipeSupportedDirections.HORIZONTAL_LEFT_RIGHT ) { // let swipeDir: XSwipeDirection; // if (gDetail.deltaX >= 0) { // swipeDir = XSwipeDirection.RIGHT; // this.swipeRight.emit(); } else { // swipeDir = XSwipeDirection.LEFT; // this.swipeLeft.emit(); } // // Handle Global Event ... mSwipeEvent.direction = swipeDir; this.swipe.emit(mSwipeEvent as XSwipeEvent); } // // Handle Horizontal Start End ... if ( this.supportedDirections === XSwipeSupportedDirections.ALL || this.supportedDirections === XSwipeSupportedDirections.HORIZONTAL_START_END ) { // let swipeDir: XSwipeDirection; // if (gDetail.deltaX >= 0) { // if (this.uiDirection === 'ltr') { // swipeDir = XSwipeDirection.END; // this.swipeEnd.emit(); } else { // swipeDir = XSwipeDirection.START; // this.swipeStart.emit(); } } else { // if (this.uiDirection === 'ltr') { // swipeDir = XSwipeDirection.START; // this.swipeStart.emit(); } else { // swipeDir = XSwipeDirection.END; // this.swipeEnd.emit(); } } // // Handle Global Event ... mSwipeEvent.direction = swipeDir; this.swipe.emit(mSwipeEvent as XSwipeEvent); } }); } private onMoveHandler(ev: GestureDetail) { // if (this.swipeDisabled) { return; } // this.issueSwipeEvents$.next(ev); } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\modules\x-directives.module.ts import { NgModule } from '@angular/core'; import { IonicModule } from '@ionic/angular'; import { CommonModule } from '@angular/common'; import { XTranslatePipe } from '../pipes/x-translate.pipe'; import { XSwipableDirective } from '../directives/x-swipable.directive'; import { XDatePresenterDirective } from '../directives/x-date-presenter.directive'; import { XCurrencyFormatterDirective } from '../directives/x-currency-formatter.directive'; import { XFromInputFormatterDirective } from '../directives/x-from-input-formatter.directive'; import { XLocaleInputFormatterDirective } from '../directives/x-locale-input-formatter.directive'; @NgModule({ declarations: [ // // Pipes ... XTranslatePipe, // // Directives XSwipableDirective, XDatePresenterDirective, XCurrencyFormatterDirective, XFromInputFormatterDirective, XLocaleInputFormatterDirective ], imports: [CommonModule, IonicModule], exports: [ // CommonModule, IonicModule, // // Pipes ... XTranslatePipe, // // Directives XSwipableDirective, XDatePresenterDirective, XCurrencyFormatterDirective, XFromInputFormatterDirective, XLocaleInputFormatterDirective ] }) export class XDirectivesModule {} ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\pipes\x-translate.pipe.ts import { XLocale, toNumber, isString, XResourceIDs, XTranslationItem } from 'x-framework-core'; import { Pipe, PipeTransform } from '@angular/core'; import { XLocalizationService } from '../x-localization.service'; @Pipe({ name: 'xTranslate' }) export class XTranslatePipe implements PipeTransform { // constructor(private localizationService: XLocalizationService) {} /** * translate a resource to specific language in a pipe * * @param key the resource identifier * @param locale the selected or default locale */ transform( key: XResourceIDs | XTranslationItem | string, locale?: XLocale ): string { // if (!locale) { locale = this.localizationService.locale; } // const isStringKey = isString(key); if (!isStringKey) { key = toNumber(key) as XResourceIDs; } // const isExist = isStringKey ? this.localizationService.isExistsIdOfLocale(locale, key as string) : this.localizationService.isExistsIdOfLocale( locale, key as XResourceIDs ); if (!isExist) { return ''; } // return isStringKey ? this.localizationService.getValueOfLocale(locale, key as string) : this.localizationService.getValueOfLocale(locale, key as XResourceIDs); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\tokens\x-injectable-tokens.ts import { InjectionToken } from '@angular/core'; import { XFrameworkServicesConfig } from '../config/x-framework-services.config'; export const X_FRAMEWORK_SERVICES_CONFIG = new InjectionToken< XFrameworkServicesConfig >('x_config'); ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-base.service.ts import { Location } from '@angular/common'; import { XBaseService } from 'x-framework-core'; import { Platform } from '@angular/cdk/platform'; import { HttpClient } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { XDialogService } from '../x-dialog.service'; import { XHistoryService } from '../x-history.service'; import { XStorageService } from '../x-storage.service'; import { XSecurityService } from '../x-security.service'; import { Router, ActivatedRoute } from '@angular/router'; import { XSettingsService } from '../x-settings.service'; import { MenuController, NavController } from '@ionic/angular'; import { XGeolocationService } from '../x-geolocation.service'; import { XTaskManagerService } from '../x-task-manager.service'; import { XNotificationService } from '../x-notification.service'; import { XLocalizationService } from '../x-localization.service'; import { XThemeManagerService } from '../x-theme-manager.service'; import { XSecureStorageService } from '../x-secure-storage.service'; import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens'; import { XFrameworkServicesConfig } from '../config/x-framework-services.config'; @Injectable() export abstract class XManagerBaseService extends XBaseService { constructor( @Inject(X_FRAMEWORK_SERVICES_CONFIG) public config: XFrameworkServicesConfig, public router: Router, public platform: Platform, public location: Location, public httpClient: HttpClient, public dialogService: XDialogService, public menuController: MenuController, public activatedRoute: ActivatedRoute, public historyService: XHistoryService, public storageService: XStorageService, public securityService: XSecurityService, public settingsService: XSettingsService, public navigationController: NavController, public geoLocationService: XGeolocationService, public taskManagerService: XTaskManagerService, public themeManagerService: XThemeManagerService, public notificationService: XNotificationService, public localizationService: XLocalizationService, public secureStorageService: XSecureStorageService ) { super(config); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-final.service.ts import { XManagerRouteService } from './x-manager-route.service'; export abstract class XManagerFinalService extends XManagerRouteService {} ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-route.service.ts import { keys, XPage, toArray, fromJson, hasChild, XRouterTarget, XOneOrManyType, XParamIdentifier, isNullOrEmptyString, } from 'x-framework-core'; import { XManagerUIStateService } from './x-manager-ui-state.service'; import { Params, UrlTree, ParamMap, NavigationExtras } from '@angular/router'; export abstract class XManagerRouteService extends XManagerUIStateService { // //#region Props ... // public routeDataChanged$ = this.router.routerState.root.data; public routeParmChanged$ = this.router.routerState.root.params; public routeQueryParmChanged$ = this.router.routerState.root.queryParams; //#endregion // //#region Route Related Actions ... /** * some times we had to force change location ... * * @param route the specified route */ changeLocation(route?: string) { window.location.href = this.getFullUrl(route); } /** * retrieve base url (Origin) address */ getBaseUrl() { return window.location.origin; } /** * retrieve current route */ getRoute() { return this.router && this.router.url ? this.router.url : '/'; } /** * merge several parts of a url ... * * @param route an instance of url tree array ... */ mergeRoutes(route: XOneOrManyType) { // if (!hasChild(route)) { return '/'; } // try { return toArray(route).join('/').replace('//', '/'); } catch {} // return '/'; } /** * retrieve page route ... * * @param page an instance of XPage ... */ getPageRoute(page: XPage) { // if (!page || !hasChild(page.route)) { return null; } // return this.mergeRoutes(page.route); } /** * generate and retrieve the fully qualified URL address of * specified route * * @param route the selected app route */ getFullUrl(route?: string) { // const mBase = this.getBaseUrl().endsWith('/') ? this.getBaseUrl() : `${this.getBaseUrl()}/`; const mRoute = !route ? '' : !route.startsWith('/') ? route : route.substring(1); // return `${mBase}${mRoute}`; } /** * navigate to specific location ... * * @param commands url or url tree parts which required to navigate * @param extras the navigation params or options */ navigate(commands: any[], extras?: NavigationExtras) { return this.router.navigate(commands, extras); } /** * navigate to specific location ... * * @param commands url or url tree parts which required to navigate * @param extras the navigation params or options * @param replaceUrl determines the url replaced or not */ navigateReplace( commands: any[], extras?: NavigationExtras, replaceUrl: boolean = true ) { return this.router.navigate(commands, { ...extras, replaceUrl }); } /** * navigate to specific location by it's url ... * * @param url specific url address for navigating * @param extras the navigation params or options */ navigateByUrl(url: string | UrlTree, extras?: NavigationExtras) { return this.router.navigate([url], extras); } /** * navigate to specific location by it's url ... * * @param url specific url address for navigating * @param extras the navigation params or options * @param replaceUrl determines the url replaced or not */ navigateByUrlReplace( url: string | UrlTree, extras?: NavigationExtras, replaceUrl: boolean = true ) { return this.router.navigate([url], { ...extras, replaceUrl }); } /** * navigate to Specific Page ... * * @param page an instance of XPage * @param extras the navigation params or options */ navigateByPage(page: XPage, extras?: NavigationExtras) { // const route = this.getPageRoute(page); if (isNullOrEmptyString(route)) { return false; } // return this.navigateByUrl(route, extras); } /** * navigate to Specific Page ... * * @param page an instance of XPage * @param extras the navigation params or options * @param replaceUrl determines the url replaced or not */ navigateByPageReplace( page: XPage, extras?: NavigationExtras, replaceUrl: boolean = true ) { // const route = this.getPageRoute(page); if (isNullOrEmptyString(route)) { return false; } // return this.navigateByUrl(route, { ...extras, replaceUrl }); } /** * Applies an array of commands to the current URL tree and creates a new URL tree. * * When given an activated route, applies the given commands starting from the route. * Otherwise, applies the given command starting from the root. * * @param commands An array of commands to apply. * @param navigationExtras Options that control the navigation strategy. * @returns The new URL tree. */ createUrlTree(commands: any[], navigationExtras?: NavigationExtras): UrlTree { return this.router.createUrlTree(commands, navigationExtras); } /** Serializes a `UrlTree` into a string */ serializeUrl(url: UrlTree): string { return this.router.serializeUrl(url); } /** Parses a string into a `UrlTree` */ parseUrl(url: string): UrlTree { return this.router.parseUrl(url); } /** Returns whether the url is activated */ isActive(url: string | UrlTree, exact: boolean): boolean { return this.router.isActive(url, exact); } /** * open specifc url ... * * @param url URL address * @param target link taget */ openUrl(url: string, target: XRouterTarget = XRouterTarget.BLANK) { // if (isNullOrEmptyString(url)) { return; } // const link = document.createElement('a'); link.target = target; link.href = url; // link.click(); link.remove(); } //#endregion // //#region Handling Query Param actions ... /** * change page Query Params ... * @param params Query Parameters */ changeQueryParams(params: Params) { // return this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: params, queryParamsHandling: 'merge', }); } clearQueryParams() { // return this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: {}, }); } /** * Get CurrentPages Query Params ... */ getQueryParams(): Params { return this.router.routerState.snapshot.root.queryParams; } getQueryParamMap(): ParamMap { return this.router.routerState.snapshot.root.queryParamMap; } isContainQueryParam(param: XParamIdentifier) { return this.getQueryParamMap().has(param); } getQueryParamVal(param: XParamIdentifier) { // if (!this.isContainQueryParam(param)) { return null; } // return this.getQueryParamMap().get(param); } getQueryParamValOfType(param: XParamIdentifier) { // if (!this.isContainQueryParam(param)) { return null; } // return fromJson(this.getQueryParamMap().get(param)); } //#endregion // //#region Handling Param actions ... /** * Get CurrentPages Query Params ... */ getParams(): Params { return this.router.routerState.snapshot.root.params; } getParamMap(): Params { return this.router.routerState.snapshot.root.paramMap; } isContainParam(param: XParamIdentifier) { return this.getParamMap().has(param); } changeParam(params: Params) { // return this.router.navigate(['', params], { relativeTo: this.activatedRoute, replaceUrl: true, }); } getParamVal(param: XParamIdentifier) { // if (!this.isContainParam(param)) { return null; } // return this.getParamMap().get(param); } getParamValOfType(param: XParamIdentifier) { // if (!this.isContainParam(param)) { return null; } // return fromJson(this.getParamMap().get(param)); } //#endregion // //#region State Handling ... /** * change page state ... * @param params State Parameters */ changeState(params: Params) { // return this.router.navigate([], { relativeTo: this.activatedRoute, replaceUrl: true, state: params, }); } getStates(): Params { return this.router.getCurrentNavigation().extras.state || {}; } isContainState(param: XParamIdentifier) { // const paramKeys = keys(this.getStates()); const result = paramKeys.includes(param); // return result; } getStateVal(param: XParamIdentifier) { // if (!this.isContainState(param)) { return null; } // return this.getStates()[param] || null; } getStateValOfType(param: XParamIdentifier) { // if (!this.isContainState(param)) { return null; } // return fromJson(this.getStateVal(param)) || null; } //#endregion } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-ui-state.service.ts import { XLocale, XUiEvent, notValue, XException, XLanguageDirection, isNullOrEmptyString, } from 'x-framework-core'; import { Subject, of } from 'rxjs'; import { filter, concatMap } from 'rxjs/operators'; import { XManagerBaseService } from './x-manager-base.service'; export abstract class XManagerUIStateService extends XManagerBaseService { // //#region props ... private IS_LOADING: boolean; private UI_DISABLED: boolean; private ERROR: XException = null; // public uiStateChanged = new Subject(); // public isMobileUi$ = this.settingsService.isMobile$; public isNotMobileUi$ = notValue(this.settingsService.isMobile$); // public isLoading$ = this.uiStateChanged.asObservable().pipe( filter((uiState) => [XUiEvent.StartLoading, XUiEvent.StopLoading].includes(uiState) ), concatMap((state) => { return of(state === XUiEvent.StartLoading ? true : false); }) ); //#endregion // //#region Getter(s) ... set uiDisabled(v: boolean) { // if (v === this.UI_DISABLED) { return; } this.UI_DISABLED = v; this.uiStateChanged.next(v ? XUiEvent.Disabled : XUiEvent.Enabled); } // get uiDisabled() { return this.UI_DISABLED; } // set loading(v: boolean) { // if (v === this.IS_LOADING) { return; } // this.IS_LOADING = v; this.uiStateChanged.next(v ? XUiEvent.StartLoading : XUiEvent.StopLoading); } // get isLoading() { return this.IS_LOADING; } // set error(exception: XException | null) { // if (exception === this.ERROR) { return; } // this.ERROR = exception; // if (exception) { // if (this.loading) { this.loading = false; } // this.uiDisabled = true; } else { // this.uiDisabled = false; } } // get error() { return this.ERROR; } // get hasError() { return !!this.ERROR; } // get uiDirection(): XLanguageDirection { return this.settingsService.uiDirection; } // get currentLanguage() { return this.localizationService.language; } // get currentLocale(): XLocale { return this.localizationService.locale; } // get isRtl() { return this.settingsService.uiDirection === 'rtl'; } // get isLtr() { return this.settingsService.uiDirection === 'ltr'; } //#endregion // //#region UI Actions ... // public dispatchResizeEvent() { // window.dispatchEvent(new Event('resize')); setTimeout(() => window.dispatchEvent(new Event('resize')), 500); } /** * save a text value to clipboard ... * * @param value the content which reuired to save to clipboard ... */ public saveToClipboard(value: string) { // if (isNullOrEmptyString(value)) { return false; } // if ( document.queryCommandSupported && document.queryCommandSupported('copy') ) { // const textarea = document.createElement('textarea'); textarea.textContent = value; // Prevent scrolling to bottom of page in Microsoft Edge. textarea.style.position = 'fixed'; document.body.appendChild(textarea); textarea.select(); // try { // Security exception may be thrown by some browsers. return document.execCommand('copy'); } catch (ex) { return false; } finally { document.body.removeChild(textarea); } } // return false; } //#endregion // //#region Private ... //#endregion }