Skip to content

Commit

Permalink
Get rid of El.controller
Browse files Browse the repository at this point in the history
  • Loading branch information
ychetyrko committed Dec 16, 2023
1 parent 813e515 commit e1854ae
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 232 deletions.
51 changes: 24 additions & 27 deletions source/html/El.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,25 @@ import { equalElCoords, parseElCoords } from "./ElUtils.js"

// ElDriver

export class ElDriver<T extends Element, M = unknown, C = unknown> extends BaseDriver<El<T, M, C>> {
allocate(node: RxNode<El<T, M, C>>): El<T, M, C> {
return new ElImpl<T, M, C, void>(node)
export class ElDriver<T extends Element, M = unknown> extends BaseDriver<El<T, M>> {
allocate(node: RxNode<El<T, M>>): El<T, M> {
return new ElImpl<T, M>(node)
}
}

// BaseEl

export interface BaseEl<T = any, M = any, C = any> {
export interface BaseEl<T = any, M = any> {
// System-managed properties
readonly node: RxNode<El<T, M, C>>
readonly node: RxNode<El<T, M>>

// User-manageable properties
model: M
controller: C
}

// El

export interface El<T = any, M = any, C = any> extends BaseEl<T, M, C> {
export interface El<T = any, M = any> extends BaseEl<T, M> {
// System-managed properties
native: T

Expand Down Expand Up @@ -98,17 +97,16 @@ export type ElArea = undefined | string | {

// ElImpl

export class ElImpl<T extends Element = any, M = any, C = any, R = any> implements El<T, M, C> {
export class ElImpl<T extends Element = any, M = any> implements El<T, M> {
// System-managed properties
readonly node: RxNode<El<T, M, C>>
readonly node: RxNode<El<T, M>>
maxColumnCount: number
maxRowCount: number
cursorPosition?: CursorPosition
native: T

// User-defined properties
model: M
controller: C
private _kind: ElKind
private _area: ElArea
private _coords: ElCoords
Expand All @@ -124,7 +122,7 @@ export class ElImpl<T extends Element = any, M = any, C = any, R = any> implemen
private _overlayVisible: boolean | undefined
private _hasStyles: boolean

constructor(node: RxNode<El<T, M, C>>) {
constructor(node: RxNode<El<T, M>>) {
// System-managed properties
this.node = node
this.maxColumnCount = 0
Expand All @@ -133,7 +131,6 @@ export class ElImpl<T extends Element = any, M = any, C = any, R = any> implemen
this.native = undefined as any as T // hack
// User-defined properties
this.model = undefined as any
this.controller = undefined as any as C // hack
this._kind = ElKind.Part
this._area = undefined
this._coords = UndefinedElCoords
Expand Down Expand Up @@ -438,20 +435,20 @@ export class CursorCommand {
rowShift?: number
}

export class CursorCommandDriver extends ElDriver<Element, unknown, void> {
export class CursorCommandDriver extends ElDriver<Element, unknown> {
constructor() {
super("cursor", false, el => el.kind = ElKind.Cursor)
}
}

export class Apply {
static kind<T extends Element>(element: El<T, any, any>, value: ElKind): void {
static kind<T extends Element>(element: El<T, any>, value: ElKind): void {
const kind = Constants.layouts[value]
kind && element.native.setAttribute(Constants.kindAttrName, kind)
VerstakDriversByLayout[value](element as any)
}

static coords<T extends Element>(element: El<T, any, any>, value: ElCoords | undefined): void {
static coords<T extends Element>(element: El<T, any>, value: ElCoords | undefined): void {
if (element.native instanceof HTMLElement) {
const s = element.native.style
if (value) {
Expand All @@ -466,7 +463,7 @@ export class Apply {
}
}

static widthGrowth<T extends Element>(element: El<T, any, any>, value: number): void {
static widthGrowth<T extends Element>(element: El<T, any>, value: number): void {
if (element.native instanceof HTMLElement) {
const s = element.native.style
if (value > 0) {
Expand All @@ -480,17 +477,17 @@ export class Apply {
}
}

static minWidth<T extends Element>(element: El<T, any, any>, value: string): void {
static minWidth<T extends Element>(element: El<T, any>, value: string): void {
if (element.native instanceof HTMLElement)
element.native.style.minWidth = `${value}`
}

static applyMaxWidth<T extends Element>(element: El<T, any, any>, value: string): void {
static applyMaxWidth<T extends Element>(element: El<T, any>, value: string): void {
if (element.native instanceof HTMLElement)
element.native.style.maxWidth = `${value}`
}

static heightGrowth<T extends Element>(element: El<T, any, any>, value: number): void {
static heightGrowth<T extends Element>(element: El<T, any>, value: number): void {
const bNode = element.node
const driver = bNode.driver
if (driver.isPartitionSeparator) {
Expand All @@ -505,24 +502,24 @@ export class Apply {
else {
const hostDriver = bNode.host.driver
if (hostDriver.isPartitionSeparator) {
const host = bNode.host.seat!.instance as RxNode<El<T, any, any>>
const host = bNode.host.seat!.instance as RxNode<El<T, any>>
Apply.elementAlignment(element, Align.ToBounds)
Apply.heightGrowth(host.element, value)
}
}
}

static minHeight<T extends Element>(element: El<T, any, any>, value: string): void {
static minHeight<T extends Element>(element: El<T, any>, value: string): void {
if (element.native instanceof HTMLElement)
element.native.style.minHeight = `${value}`
}

static maxHeight<T extends Element>(element: El<T, any, any>, value: string): void {
static maxHeight<T extends Element>(element: El<T, any>, value: string): void {
if (element.native instanceof HTMLElement)
element.native.style.maxHeight = `${value}`
}

static contentAlignment<T extends Element>(element: El<T, any, any>, value: Align): void {
static contentAlignment<T extends Element>(element: El<T, any>, value: Align): void {
if (element.native instanceof HTMLElement) {
const s = element.native.style
if ((value & Align.Default) === 0) { // if not auto mode
Expand All @@ -538,7 +535,7 @@ export class Apply {
}
}

static elementAlignment<T extends Element>(element: El<T, any, any>, value: Align): void {
static elementAlignment<T extends Element>(element: El<T, any>, value: Align): void {
if (element.native instanceof HTMLElement) {
const s = element.native.style
if ((value & Align.Default) === 0) { // if not auto mode
Expand All @@ -555,7 +552,7 @@ export class Apply {
}
}

static contentWrapping<T extends Element>(element: El<T, any, any>, value: boolean): void {
static contentWrapping<T extends Element>(element: El<T, any>, value: boolean): void {
if (element.native instanceof HTMLElement) {
const s = element.native.style
if (value) {
Expand All @@ -573,7 +570,7 @@ export class Apply {
}
}

static overlayVisible<T extends Element>(element: El<T, any, any>, value: boolean | undefined): void {
static overlayVisible<T extends Element>(element: El<T, any>, value: boolean | undefined): void {
const e = element.native
if (e instanceof HTMLElement) {
const s = e.style
Expand Down Expand Up @@ -607,7 +604,7 @@ export class Apply {
}
}

static style<T extends Element>(element: El<T, any, any>, secondary: boolean, styleName: string, enabled?: boolean): void {
static style<T extends Element>(element: El<T, any>, secondary: boolean, styleName: string, enabled?: boolean): void {
const native = element.native
enabled ??= true
if (secondary)
Expand Down
26 changes: 13 additions & 13 deletions source/html/Elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ import { HtmlElementDriver } from "./HtmlDriver.js"

// Section

export function Section<M = unknown, R = void>(
declaration?: RxNodeDecl<El<HTMLElement, M, R>>,
preset?: RxNodeDecl<El<HTMLElement, M, R>>): RxNode<El<HTMLElement, M, R>> {
export function Section<M = unknown>(
declaration?: RxNodeDecl<El<HTMLElement, M>>,
preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>> {
return RxNode.acquire(Drivers.section, declaration, preset)
}

// Table

export function Table<M = unknown, R = void>(
declaration?: RxNodeDecl<El<HTMLElement, M, R>>,
preset?: RxNodeDecl<El<HTMLElement, M, R>>): RxNode<El<HTMLElement, M, R>> {
declaration?: RxNodeDecl<El<HTMLElement, M>>,
preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>> {
return RxNode.acquire(Drivers.table, declaration, preset)
}

Expand All @@ -66,7 +66,7 @@ export function cursor(areaParams: ElArea): void {
// Note (either plain or html)

export function Note(content: string,
declaration?: RxNodeDecl<El<HTMLElement, void, void>>): RxNode<El<HTMLElement, void, void>> {
declaration?: RxNodeDecl<El<HTMLElement, void>>): RxNode<El<HTMLElement, void>> {
return RxNode.acquire(Drivers.note, declaration, {
update(b) {
b.native.innerText = content
Expand All @@ -75,7 +75,7 @@ export function Note(content: string,
}

export function HtmlNote(content: string,
declaration?: RxNodeDecl<El<HTMLElement, void, void>>): RxNode<El<HTMLElement, void, void>> {
declaration?: RxNodeDecl<El<HTMLElement, void>>): RxNode<El<HTMLElement, void>> {
return RxNode.acquire(Drivers.note, declaration, {
update(b) {
b.native.innerHTML = content
Expand All @@ -86,16 +86,16 @@ export function HtmlNote(content: string,
// Group

export function Group<M = unknown, R = void>(
declaration?: RxNodeDecl<El<HTMLElement, M, R>>,
preset?: RxNodeDecl<El<HTMLElement, M, R>>): RxNode<El<HTMLElement, M, R>> {
declaration?: RxNodeDecl<El<HTMLElement, M>>,
preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>> {
return RxNode.acquire(Drivers.group, declaration, preset)
}

// PseudoElement

export function PseudoElement<M = unknown, R = void>(
declaration?: RxNodeDecl<El<void, M, R>>,
preset?: RxNodeDecl<El<void, M, R>>): RxNode<El<void, M, R>> {
export function PseudoElement<M = unknown>(
declaration?: RxNodeDecl<El<void, M>>,
preset?: RxNodeDecl<El<void, M>>): RxNode<El<void, M>> {
return RxNode.acquire(Drivers.pseudo, declaration, preset)
}

Expand Down Expand Up @@ -131,5 +131,5 @@ const Drivers = {
cursor: new CursorCommandDriver(),

// (no element)
pseudo: new ElDriver<HTMLElement>("pseudo", false, el => el.kind = ElKind.Group) as unknown as RxNodeDriver<El<void, any, any>>,
pseudo: new ElDriver<HTMLElement>("pseudo", false, el => el.kind = ElKind.Group) as unknown as RxNodeDriver<El<void, any>>,
}
40 changes: 22 additions & 18 deletions source/html/HtmlDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ import { Constants, El, ElDriver, ElImpl } from "./El.js"

// WebDriver

export abstract class WebDriver<T extends Element, M = unknown, C = unknown> extends ElDriver<T, M, C> {
export class WebDriver<T extends Element, M = unknown> extends ElDriver<T, M> {

abstract acquireNativeElement(element: El<T, M, C>): T
setNativeElement(node: RxNode<El<T, M>>): void {
// it's up to descendant class to define logic
}

initialize(node: RxNode<El<T, M, C>>): void {
const element = node.element
const native = element.native = this.acquireNativeElement(element)
if (RxSystem.isLogging && !element.node.driver.isPartitionSeparator)
native.setAttribute(Constants.keyAttrName, element.node.key)
initialize(node: RxNode<El<T, M>>): void {
this.setNativeElement(node)
const e = node.element.native
if (RxSystem.isLogging && e !== undefined && !node.driver.isPartitionSeparator)
e.setAttribute(Constants.keyAttrName, node.key)
super.initialize(node)
if (e == undefined && RxSystem.isLogging && !node.driver.isPartitionSeparator)
node.element.native.setAttribute(Constants.keyAttrName, node.key)
}

finalize(node: RxNode<El<T, M, C>>, isLeader: boolean): boolean {
finalize(node: RxNode<El<T, M>>, isLeader: boolean): boolean {
const element = node.element
const native = element.native as T | undefined // hack
if (native) {
Expand All @@ -35,7 +39,7 @@ export abstract class WebDriver<T extends Element, M = unknown, C = unknown> ext
return false // children elements having native HTML elements are not treated as leaders
}

mount(node: RxNode<El<T, M, C>>): void {
mount(node: RxNode<El<T, M>>): void {
const element = node.element
const native = element.native as T | undefined // hack
if (native) {
Expand Down Expand Up @@ -66,7 +70,7 @@ export abstract class WebDriver<T extends Element, M = unknown, C = unknown> ext
}
}

update(node: RxNode<El<T, M, C>>): void | Promise<void> {
update(node: RxNode<El<T, M>>): void | Promise<void> {
const element = node.element
if (element instanceof ElImpl)
element.prepareForUpdate()
Expand Down Expand Up @@ -111,24 +115,24 @@ export class StaticDriver<T extends HTMLElement> extends WebDriver<T> {
this.native = native
}

acquireNativeElement(): T {
return this.native
setNativeElement(node: RxNode<El<T>>): void {
node.element.native = this.native
}
}

// HtmlElementDriver

export class HtmlElementDriver<T extends HTMLElement, M = any, C = any> extends WebDriver<T, M, C> {
acquireNativeElement(element: El<T, M, C>): T {
return document.createElement(element.node.driver.name) as T
export class HtmlElementDriver<T extends HTMLElement, M = any> extends WebDriver<T, M> {
setNativeElement(node: RxNode<El<T, M>>): void {
node.element.native = document.createElement(node.driver.name) as T
}
}

// SvgElementDriver

export class SvgElementDriver<T extends SVGElement, M = any, C = any> extends WebDriver<T, M, C> {
acquireNativeElement(element: El<T, M, C>): T {
return document.createElementNS("http://www.w3.org/2000/svg", element.node.driver.name) as T
export class SvgElementDriver<T extends SVGElement, M = any> extends WebDriver<T, M> {
setNativeElement(node: RxNode<El<T, M>>): void {
node.element.native = document.createElementNS("http://www.w3.org/2000/svg", node.driver.name) as T
}
}

Expand Down
Loading

0 comments on commit e1854ae

Please sign in to comment.