Skip to content

Commit

Permalink
[Live] Fixed idiomorph id child handling & JavaScript cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed Feb 14, 2024
1 parent 9e086b1 commit 6d59382
Show file tree
Hide file tree
Showing 48 changed files with 1,081 additions and 974 deletions.
8 changes: 7 additions & 1 deletion src/LiveComponent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# CHANGELOG

## 2.15.0

- [BC BREAK] The `data-live-id` attribute was changed to `id`.

## 2.14.1

- Fixed a regression in the testing tools related to the default HTTP
method change

## 2.14.0

- [BC BREAK] DOM morphing changed from `morphdom` to `idiomorph`. As this is
a different morphing library, there may be some edge cases where the
morphing behavior is different.
- Add support for URL binding in `LiveProp`
- DOM morphing changed from `morphdom` to `idiomorph`
- Allow multiple `LiveListener` attributes on a single method
- Requests to LiveComponent are sent as POST by default
- Add method prop to AsLiveComponent to still allow GET requests, usage: `#[AsLiveComponent(method: 'get')]`
Expand Down
21 changes: 10 additions & 11 deletions src/LiveComponent/assets/dist/Component/ElementDriver.d.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
import LiveControllerDefault from '../live_controller';
export interface ElementDriver {
getModelName(element: HTMLElement): string | null;
getComponentProps(rootElement: HTMLElement): any;
findChildComponentElement(id: string, element: HTMLElement): HTMLElement | null;
getKeyFromElement(element: HTMLElement): string | null;
getEventsToEmit(element: HTMLElement): Array<{
getComponentProps(): any;
getEventsToEmit(): Array<{
event: string;
data: any;
target: string | null;
componentName: string | null;
}>;
getBrowserEventsToDispatch(element: HTMLElement): Array<{
getBrowserEventsToDispatch(): Array<{
event: string;
payload: any;
}>;
}
export declare class StandardElementDriver implements ElementDriver {
export declare class StimulusElementDriver implements ElementDriver {
private readonly controller;
constructor(controller: LiveControllerDefault);
getModelName(element: HTMLElement): string | null;
getComponentProps(rootElement: HTMLElement): any;
findChildComponentElement(id: string, element: HTMLElement): HTMLElement | null;
getKeyFromElement(element: HTMLElement): string | null;
getEventsToEmit(element: HTMLElement): Array<{
getComponentProps(): any;
getEventsToEmit(): Array<{
event: string;
data: any;
target: string | null;
componentName: string | null;
}>;
getBrowserEventsToDispatch(element: HTMLElement): Array<{
getBrowserEventsToDispatch(): Array<{
event: string;
payload: any;
}>;
Expand Down
20 changes: 4 additions & 16 deletions src/LiveComponent/assets/dist/Component/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@ import ValueStore from './ValueStore';
import { ElementDriver } from './ElementDriver';
import { PluginInterface } from './plugins/PluginInterface';
import BackendResponse from '../Backend/BackendResponse';
import { ModelBinding } from '../Directive/get_model_binding';
export type ComponentFinder = (currentComponent: Component, onlyParents: boolean, onlyMatchName: string | null) => Component[];
export default class Component {
readonly element: HTMLElement;
readonly name: string;
readonly listeners: Map<string, string[]>;
private readonly componentFinder;
private backend;
private readonly elementDriver;
readonly elementDriver: ElementDriver;
id: string | null;
fingerprint: string | null;
fingerprint: string;
readonly valueStore: ValueStore;
private readonly unsyncedInputsTracker;
private hooks;
Expand All @@ -25,14 +22,11 @@ export default class Component {
private requestDebounceTimeout;
private nextRequestPromise;
private nextRequestPromiseResolve;
private children;
private parent;
private externalMutationTracker;
constructor(element: HTMLElement, name: string, props: any, listeners: Array<{
event: string;
action: string;
}>, componentFinder: ComponentFinder, fingerprint: string | null, id: string | null, backend: BackendInterface, elementDriver: ElementDriver);
_swapBackend(backend: BackendInterface): void;
}>, id: string | null, backend: BackendInterface, elementDriver: ElementDriver);
addPlugin(plugin: PluginInterface): void;
connect(): void;
disconnect(): void;
Expand All @@ -44,17 +38,11 @@ export default class Component {
files(key: string, input: HTMLInputElement): void;
render(): Promise<BackendResponse>;
getUnsyncedModels(): string[];
addChild(child: Component, modelBindings?: ModelBinding[]): void;
removeChild(child: Component): void;
getParent(): Component | null;
getChildren(): Map<string, Component>;
emit(name: string, data: any, onlyMatchingComponentsNamed?: string | null): void;
emitUp(name: string, data: any, onlyMatchingComponentsNamed?: string | null): void;
emitSelf(name: string, data: any): void;
private performEmit;
private doEmit;
updateFromNewElementFromParentRender(toEl: HTMLElement): boolean;
onChildComponentModelUpdate(modelName: string, value: any, childComponent: Component): void;
private isTurboEnabled;
private tryStartingRequest;
private performRequest;
Expand All @@ -63,7 +51,7 @@ export default class Component {
private clearRequestDebounceTimeout;
private debouncedStartRequest;
private renderError;
private getChildrenFingerprints;
private resetPromise;
_updateFromParentProps(props: any): void;
}
export declare function proxifyComponent(component: Component): Component;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Component from '../../Component';
import { PluginInterface } from './PluginInterface';
export default class implements PluginInterface {
private readonly component;
private parentModelBindings;
constructor(component: Component);
attachToComponent(component: Component): void;
private getChildrenFingerprints;
private notifyParentModelChange;
private getChildren;
}
15 changes: 7 additions & 8 deletions src/LiveComponent/assets/dist/ComponentRegistry.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import Component from './Component';
export default class {
private componentMapByElement;
private componentMapByComponent;
registerComponent(element: HTMLElement, component: Component): void;
unregisterComponent(component: Component): void;
getComponent(element: HTMLElement): Promise<Component>;
findComponents(currentComponent: Component, onlyParents: boolean, onlyMatchName: string | null): Component[];
}
export declare const resetRegistry: () => void;
export declare const registerComponent: (component: Component) => void;
export declare const unregisterComponent: (component: Component) => void;
export declare const getComponent: (element: HTMLElement) => Promise<Component>;
export declare const findComponents: (currentComponent: Component, onlyParents: boolean, onlyMatchName: string | null) => Component[];
export declare const findChildren: (currentComponent: Component) => Component[];
export declare const findParent: (currentComponent: Component) => Component | null;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function getElementAsTagText(element: HTMLElement): string;
1 change: 0 additions & 1 deletion src/LiveComponent/assets/dist/dom_utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export declare function getModelDirectiveFromElement(element: HTMLElement, throw
export declare function elementBelongsToThisComponent(element: Element, component: Component): boolean;
export declare function cloneHTMLElement(element: HTMLElement): HTMLElement;
export declare function htmlToElement(html: string): HTMLElement;
export declare function getElementAsTagText(element: HTMLElement): string;
48 changes: 39 additions & 9 deletions src/LiveComponent/assets/dist/live_controller.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Controller } from '@hotwired/stimulus';
import Component from './Component';
import ComponentRegistry from './ComponentRegistry';
import { BackendInterface } from './Backend/Backend';
export { Component };
export declare const getComponent: (element: HTMLElement) => Promise<Component>;
export { getComponent } from './ComponentRegistry';
export interface LiveEvent extends CustomEvent {
detail: {
controller: LiveController;
Expand All @@ -17,17 +17,31 @@ export default class LiveControllerDefault extends Controller<HTMLElement> imple
static values: {
name: StringConstructor;
url: StringConstructor;
props: ObjectConstructor;
props: {
type: ObjectConstructor;
default: {};
};
propsUpdatedFromParent: {
type: ObjectConstructor;
default: {};
};
csrf: StringConstructor;
listeners: {
type: ArrayConstructor;
default: never[];
};
eventsToEmit: {
type: ArrayConstructor;
default: never[];
};
eventsToDispatch: {
type: ArrayConstructor;
default: never[];
};
debounce: {
type: NumberConstructor;
default: number;
};
id: StringConstructor;
fingerprint: {
type: StringConstructor;
default: string;
Expand All @@ -44,11 +58,22 @@ export default class LiveControllerDefault extends Controller<HTMLElement> imple
readonly nameValue: string;
readonly urlValue: string;
readonly propsValue: any;
propsUpdatedFromParentValue: any;
readonly csrfValue: string;
readonly listenersValue: Array<{
event: string;
action: string;
}>;
readonly eventsToEmitValue: Array<{
event: string;
data: any;
target: string | null;
componentName: string | null;
}>;
readonly eventsToDispatchValue: Array<{
event: string;
payload: any;
}>;
readonly hasDebounceValue: boolean;
readonly debounceValue: number;
readonly fingerprintValue: string;
Expand All @@ -59,26 +84,31 @@ export default class LiveControllerDefault extends Controller<HTMLElement> imple
};
};
private proxiedComponent;
private mutationObserver;
component: Component;
pendingActionTriggerModelElement: HTMLElement | null;
private elementEventListeners;
private pendingFiles;
static componentRegistry: ComponentRegistry;
static backendFactory: (controller: LiveControllerDefault) => BackendInterface;
initialize(): void;
connect(): void;
disconnect(): void;
update(event: any): void;
action(event: any): void;
$render(): Promise<import("./Backend/BackendResponse").default>;
emit(event: Event): void;
emitUp(event: Event): void;
emitSelf(event: Event): void;
private getEmitDirectives;
$render(): Promise<import("./Backend/BackendResponse").default>;
$updateModel(model: string, value: any, shouldRender?: boolean, debounce?: number | boolean): Promise<import("./Backend/BackendResponse").default>;
propsUpdatedFromParentValueChanged(): void;
fingerprintValueChanged(): void;
private getEmitDirectives;
private createComponent;
private connectComponent;
private disconnectComponent;
private handleInputEvent;
private handleChangeEvent;
private updateModelFromElementEvent;
handleConnectedControllerEvent(event: LiveEvent): void;
handleDisconnectedChildControllerEvent(event: LiveEvent): void;
private dispatchEvent;
private onMutations;
}
Loading

0 comments on commit 6d59382

Please sign in to comment.