UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

324 lines (284 loc) 10.3 kB
/** * A context that flows through the view resource load process. */ export class ResourceLoadContext { dependencies: Object; /** * Creates an instance of ResourceLoadContext. */ constructor() { this.dependencies = {}; } /** * Tracks a dependency that is being loaded. * @param url The url of the dependency. */ addDependency(url: string): void { this.dependencies[url] = true; } /** * Checks if the current context includes a load of the specified url. * @return True if the url is being loaded in the context; false otherwise. */ hasDependency(url: string): boolean { return url in this.dependencies; } } /** * Specifies how a view should be compiled. */ export class ViewCompileInstruction { targetShadowDOM: boolean; compileSurrogate: boolean; associatedModuleId: any; /** * The normal configuration for view compilation. */ static normal: ViewCompileInstruction; /** * Creates an instance of ViewCompileInstruction. * @param targetShadowDOM Should the compilation target the Shadow DOM. * @param compileSurrogate Should the compilation also include surrogate bindings and behaviors. */ constructor(targetShadowDOM?: boolean = false, compileSurrogate?: boolean = false) { this.targetShadowDOM = targetShadowDOM; this.compileSurrogate = compileSurrogate; this.associatedModuleId = null; } } ViewCompileInstruction.normal = new ViewCompileInstruction(); /** * Specifies how a view should be created. */ interface ViewCreateInstruction { /** * Indicates that the view is being created by enhancing existing DOM. */ enhance?: boolean; /** * Specifies a key/value lookup of part replacements for the view being created. */ partReplacements?: Object; } /** * Indicates how a custom attribute or element should be instantiated in a view. */ export class BehaviorInstruction { initiatedByBehavior: boolean; enhance: boolean; partReplacements: any; viewFactory: ViewFactory; originalAttrName: string; skipContentProcessing: boolean; contentFactory: any; viewModel: Object; anchorIsContainer: boolean; host: Element; attributes: Object; type: HtmlBehaviorResource; attrName: string; inheritBindingContext: boolean; /** * A default behavior used in scenarios where explicit configuration isn't available. */ static normal: BehaviorInstruction; /** * Creates an instruction for element enhancement. * @return The created instruction. */ static enhance(): BehaviorInstruction { let instruction = new BehaviorInstruction(); instruction.enhance = true; return instruction; } /** * Creates an instruction for unit testing. * @param type The HtmlBehaviorResource to create. * @param attributes A key/value lookup of attributes for the behaior. * @return The created instruction. */ static unitTest(type: HtmlBehaviorResource, attributes: Object): BehaviorInstruction { let instruction = new BehaviorInstruction(); instruction.type = type; instruction.attributes = attributes || {}; return instruction; } /** * Creates a custom element instruction. * @param node The node that represents the custom element. * @param type The HtmlBehaviorResource to create. * @return The created instruction. */ static element(node: Node, type: HtmlBehaviorResource): BehaviorInstruction { let instruction = new BehaviorInstruction(); instruction.type = type; instruction.attributes = {}; instruction.anchorIsContainer = !(node.hasAttribute('containerless') || type.containerless); instruction.initiatedByBehavior = true; return instruction; } /** * Creates a custom attribute instruction. * @param attrName The name of the attribute. * @param type The HtmlBehaviorResource to create. * @return The created instruction. */ static attribute(attrName: string, type?: HtmlBehaviorResource): BehaviorInstruction { let instruction = new BehaviorInstruction(); instruction.attrName = attrName; instruction.type = type || null; instruction.attributes = {}; return instruction; } /** * Creates a dynamic component instruction. * @param host The element that will parent the dynamic component. * @param viewModel The dynamic component's view model instance. * @param viewFactory A view factory used in generating the component's view. * @return The created instruction. */ static dynamic(host: Element, viewModel: Object, viewFactory: ViewFactory): BehaviorInstruction { let instruction = new BehaviorInstruction(); instruction.host = host; instruction.viewModel = viewModel; instruction.viewFactory = viewFactory; instruction.inheritBindingContext = true; return instruction; } /** * Creates an instance of BehaviorInstruction. */ constructor() { this.initiatedByBehavior = false; this.enhance = false; this.partReplacements = null; this.viewFactory = null; this.originalAttrName = null; this.skipContentProcessing = false; this.contentFactory = null; this.viewModel = null; this.anchorIsContainer = false; this.host = null; this.attributes = null; this.type = null; this.attrName = null; this.inheritBindingContext = false; } } BehaviorInstruction.normal = new BehaviorInstruction(); /** * Provides all the instructions for how a target element should be enhanced inside of a view. */ export class TargetInstruction { injectorId:number; parentInjectorId:number; shadowSlot:boolean; slotName:string; slotFallbackFactory:any; contentExpression:any; expressions:Array<Object>; behaviorInstructions:Array<BehaviorInstruction>; providers:Array<Function>; viewFactory:ViewFactory; anchorIsContainer:boolean; elementInstruction:BehaviorInstruction; lifting:boolean; values:Object; /** * An empty array used to represent a target with no binding expressions. */ static noExpressions = Object.freeze([]); /** * Creates an instruction that represents a shadow dom slot. * @param parentInjectorId The id of the parent dependency injection container. * @return The created instruction. */ static shadowSlot(parentInjectorId: number): TargetInstruction { let instruction = new TargetInstruction(); instruction.parentInjectorId = parentInjectorId; instruction.shadowSlot = true; return instruction; } /** * Creates an instruction that represents a binding expression in the content of an element. * @param expression The binding expression. * @return The created instruction. */ static contentExpression(expression): TargetInstruction { let instruction = new TargetInstruction(); instruction.contentExpression = expression; return instruction; } /** * Creates an instruction that represents content that was lifted out of the DOM and into a ViewFactory. * @param parentInjectorId The id of the parent dependency injection container. * @param liftingInstruction The behavior instruction of the lifting behavior. * @return The created instruction. */ static lifting(parentInjectorId: number, liftingInstruction: BehaviorInstruction): TargetInstruction { let instruction = new TargetInstruction(); instruction.parentInjectorId = parentInjectorId; instruction.expressions = TargetInstruction.noExpressions; instruction.behaviorInstructions = [liftingInstruction]; instruction.viewFactory = liftingInstruction.viewFactory; instruction.providers = [liftingInstruction.type.target]; instruction.lifting = true; return instruction; } /** * Creates an instruction that represents an element with behaviors and bindings. * @param injectorId The id of the dependency injection container. * @param parentInjectorId The id of the parent dependency injection container. * @param providers The types which will provide behavior for this element. * @param behaviorInstructions The instructions for creating behaviors on this element. * @param expressions Bindings, listeners, triggers, etc. * @param elementInstruction The element behavior for this element. * @return The created instruction. */ static normal(injectorId: number, parentInjectorId: number, providers: Array<Function>, behaviorInstructions: Array<BehaviorInstruction>, expressions: Array<Object>, elementInstruction: BehaviorInstruction): TargetInstruction { let instruction = new TargetInstruction(); instruction.injectorId = injectorId; instruction.parentInjectorId = parentInjectorId; instruction.providers = providers; instruction.behaviorInstructions = behaviorInstructions; instruction.expressions = expressions; instruction.anchorIsContainer = elementInstruction ? elementInstruction.anchorIsContainer : true; instruction.elementInstruction = elementInstruction; return instruction; } /** * Creates an instruction that represents the surrogate behaviors and bindings for an element. * @param providers The types which will provide behavior for this element. * @param behaviorInstructions The instructions for creating behaviors on this element. * @param expressions Bindings, listeners, triggers, etc. * @param values A key/value lookup of attributes to transplant. * @return The created instruction. */ static surrogate(providers: Array<Function>, behaviorInstructions: Array<BehaviorInstruction>, expressions: Array<Object>, values: Object): TargetInstruction { let instruction = new TargetInstruction(); instruction.expressions = expressions; instruction.behaviorInstructions = behaviorInstructions; instruction.providers = providers; instruction.values = values; return instruction; } /** * Creates an instance of TargetInstruction. */ constructor() { this.injectorId = null; this.parentInjectorId = null; this.shadowSlot = false; this.slotName = null; this.slotFallbackFactory = null; this.contentExpression = null; this.expressions = null; this.behaviorInstructions = null; this.providers = null; this.viewFactory = null; this.anchorIsContainer = false; this.elementInstruction = null; this.lifting = false; this.values = null; } }