import * as htmlTags from 'html-tags'; import { ConnectorTemplate } from '..' import { DOMRender , NodeTemplate } from "../dom/dom-render"; import { Observer , Observers , Mutation, PageController , ThoriumController , ViewController , ViewDesignPatern } from '../controller'; import { Transactions , TransactionPatern } from '../controller/transactions'; import { Effects , EffectPatern } from '../controller/effects'; import * as DOMCSSOM from 'dom-cssom'; import { VirtualElement } from '../dom/dom-virtual-v2'; export interface DesignPatern extends ConnectorTemplate{ baseName:string; observedAttibutes?:string[]; content?:string; styles?:string[]; __getter__?:Record void>; __setter__?:Record void>; } /** * Représente un élément personnalisé qui combine les fonctionnalités d'un HTMLElement existant et des méthodes personnalisées. * * @typeparam T - L'interface de l'HTMLElement existant. * @typeparam X - L'interface personnalisée définie par le développeur pour étendre l'HTMLElement existant. * @typeparam ITransaction - Le type des transactions utilisées par l'élément personnalisé (optionnel). * @typeparam IEffect - Le type des effets utilisés par l'élément personnalisé (optionnel). */ export type CustomElement = T & X & { $Thorium:any; patern:NodeTemplate | DesignPatern; isMounted:boolean; /** * Récupère le contexte de l'élément personnalisé. * * @method context * @typeparam T - Le type de l'élément contextuel recherché. * @param contextNameToFind - Le nom optionnel du contexte à rechercher. * @returns L'élément contextuel correspondant ou `undefined` si aucun contexte n'est trouvé. */ context(contextName?:string):CustomElement; useContext( hook:( context:T ) => void ):void; useVirtual( hook:( context:VirtualElement ) => void ):void; onmutation(mutation:Mutation):void; beforeMounting(target:CustomElement):void; afterMounting(target:CustomElement):void; onunmount():void; oncontextchange(newContext:string):void; /** * Active une transaction spécifique sur le composant. * * @method useTransaction * @param transactionName - Le nom de la transaction à activer. */ useTransaction(transactionName:ITransaction):void; /** * Ajoute une transaction au contrôleur Thorium. * * @method addTransaction * @param transaction - La transaction à ajouter. * @returns L'ID de la transaction ajoutée. */ addTransaction():void; /** * Supprime une transaction au contrôleur Thorium. * * @method removeTransaction * @param transactionId - L'ID de la transaction à supprimer. * @returns True si la transaction a été supprimée avec succès, sinon null. */ removeTransaction():void; /** * Active un effet spécifique du contrôleur Thorium. * * @method useEffect * @param operationName - Le nom de l'effet à activer. * @param options - Options supplémentaires à transmettre à l'effet. */ useEffect(effectName:IEffect):void; /** * Ajoute un nouvel effet au contrôleur Thorium. * * @method addEffect * @param effect - L'effet à ajouter, représenté par un objet contenant les propriétés `name` (nom de l'effet) et `callback` (fonction callback de l'effet). * @returns L'ID de l'effet ajouté. */ addEffect():void; /** * Supprime un effet du contrôleur Thorium. * * @method removeEffect * @param effectId - L'ID de l'effet à supprimer. * @returns `true` si l'effet a été supprimé avec succès, sinon `false`. */ removeEffect():void; /** * Map contenant les observateurs pour chaque attribut. * Chaque clé de la map correspond à un nom d'attribut, * et chaque valeur est un map contenant les observateurs * associés à cet attribut. */ oberservers:Observers; /** * Récupère l'observateur correspondant à l'ID spécifié. * * @param observerId L'ID de l'observateur à récupérer. * @returns L'observateur correspondant à l'ID spécifié, s'il existe ; sinon, null. */ getObserver(observerId:string):Observer; /** * Supprime l'observateur correspondant à l'ID spécifié. * * @param observerId L'ID de l'observateur à supprimer. * @returns True si l'observateur a été supprimé avec succès ; sinon, false. */ removeObserver(observerId:string):void; /** * Déclenche les rappels des observateurs en réponse à une mutation observée. * * @param mutation La mutation observée. */ delegateObservedMutation(mutation:Mutation):void; /** * Ajoute un observateur pour surveiller les modifications d'attributs d'un composant tiers. * @param sourceElement L'élément personnalisé ou l'élément HTML correspondant au composant tiers. * @param event L'événement correspondant à la modification d'attribut à observer. * @param callback La fonction de rappel à appeler lorsque la modification d'attribut est détectée. * @returns L'observateur créé pour la surveillance des modifications d'attributs. * @throws Une erreur si `sourceElement` n'est pas un composant Thorium valide. */ addComponentObserver(sourceElement:CustomElement | Element , event:string , callback:(mutation:Mutation)=>void):Observer; /** * Attache un observateur à un attribut spécifique d'un élément personnalisé ou d'un élément DOM. * L'observateur sera déclenché lorsqu'un changement est détecté sur l'attribut spécifié. * * @param attributeName - Le nom de l'attribut à observer. * @param callback - La fonction de rappel qui sera exécutée lorsque le changement est détecté. * La fonction de rappel reçoit un argument contenant des informations sur la mutation. * @param sourceElement - (Facultatif) L'élément personnalisé ou l'élément DOM à observer. * Si non spécifié, l'observateur sera attaché à l'élément courant. * @returns L'observateur créé, qui peut être utilisé pour le détacher ultérieurement. */ on( attributeName:string , callback:(mutation:Mutation)=>void , sourceElement?:CustomElement | Element ):Observer; isStyleSheetAttached:boolean; styleSheetId:string; attachStyleSheet : DOMCSSOM; styleSheet : () => DOMCSSOM; }; /** * Représente le modèle de conception d'un élément personnalisé. * * @typeparam ITransaction - Le type des transactions utilisées par l'élément personnalisé. * @typeparam IEffects - Le type des effets utilisés par l'élément personnalisé. */ export interface CustomElementPatern extends CustomElementConstructor{ transactions:TransactionPatern; transactions_onload:TransactionPatern; effects:EffectPatern; connector:() => (connectorTemplate?:ConnectorTemplate) => NodeTemplate; } /** * Enregistre un composant personnalisé dans le registre des composants. * * @param type - Le type du composant personnalisé. Peut être "page", "thorium", "local" ou "views". * @param patern - Le modèle de conception du composant personnalisé à enregistrer. * @returns Le constructeur de l'élément personnalisé enregistré. */ export const register = ( type : 'page' | 'thorium' | 'local' | 'views' , patern:DesignPatern|ViewDesignPatern):CustomElementPatern => { let paternName = `${type}-${patern.baseName}`; const isUnknownElement = ():boolean => { let tags = Object.values(htmlTags); return !(tags as string[]).includes(patern.baseName); } if(!isUnknownElement() && type == 'local'){ const constructor = (document.createElement(patern.baseName) as any).__proto__.constructor.name as string; if(!customElements.get(paternName))customElements.define(paternName, class extends ThoriumController(paternName,patern,window[constructor]){ static transactions = Transactions(); constructor(){ super(); if(patern.attr)Array.from( Object.keys(patern.attr) , (attributeName) => { (this as unknown as HTMLElement).setAttribute(attributeName , (patern.attr as Record)[attributeName]); }) if(patern.childrens){ const shadow = (this as unknown as HTMLElement).attachShadow({mode: 'open'}); Array.from( patern.childrens , (children) => { DOMRender(children , shadow) } ) } if(patern.proto)Array.from( Object.keys(patern.proto) , (protoKey) => { this[protoKey] = (patern.proto as Record)[protoKey].bind(this); }) } } as CustomElementPatern , { extends : patern.baseName }); return customElements.get(`${type}-${patern.baseName}`) as CustomElementPatern; } else{ if(type == 'page' && !customElements.get(paternName))customElements.define(paternName , PageController(paternName,patern as ViewDesignPatern,HTMLElement)) if(type == 'views' && !customElements.get(paternName))customElements.define(paternName , ViewController(paternName,patern as ViewDesignPatern,HTMLElement)) else if(type == 'thorium' && !customElements.get(paternName))customElements.define(paternName, ThoriumController(paternName , patern , HTMLElement) ) return customElements.get(paternName) as CustomElementPatern; } }