Skip to content

Commit

Permalink
chore: move ViewBehaviorOrchestrator to utilities (microsoft#6508)
Browse files Browse the repository at this point in the history
* chore: move ViewBehaviorOrchestrator to utilities

* Change files

* chore: fix change files

Co-authored-by: EisenbergEffect <roeisenb@microsoft.com>
  • Loading branch information
EisenbergEffect and EisenbergEffect authored Nov 8, 2022
1 parent 3c14603 commit 1a1fc0b
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "chore: move ViewBehaviorOrchestrator to utilities",
"packageName": "@microsoft/fast-element",
"email": "roeisenb@microsoft.com",
"dependentChangeType": "prerelease"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "chore: move ViewBehaviorOrchestrator to utilities",
"packageName": "@microsoft/fast-foundation",
"email": "roeisenb@microsoft.com",
"dependentChangeType": "prerelease"
}
13 changes: 0 additions & 13 deletions packages/web-components/fast-element/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -905,19 +905,6 @@ export interface ViewBehaviorFactory {
targetTagName?: string | null;
}

// @public
export interface ViewBehaviorOrchestrator<TSource = any, TParent = any> extends ViewController<TSource, TParent>, HostBehavior<TSource> {
addBehavior(behavior: ViewBehavior): void;
addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;
// (undocumented)
addTarget(nodeId: string, target: Node): void;
}

// @public
export const ViewBehaviorOrchestrator: Readonly<{
create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;
}>;

// @public
export type ViewBehaviorTargets = {
[id: string]: Node;
Expand Down
110 changes: 3 additions & 107 deletions packages/web-components/fast-element/src/templating/html-directive.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { DOM, DOMAspect, DOMPolicy } from "../dom.js";
import { DOMAspect, DOMPolicy } from "../dom.js";
import { Constructable, Mutable, noop } from "../interfaces.js";
import type { Subscriber } from "../observation/notifier.js";
import {
ExecutionContext,
import type {
Expression,
ExpressionController,
ExpressionObserver,
} from "../observation/observable.js";
import { createTypeRegistry } from "../platform.js";
import type { HostBehavior, HostController } from "../styles/host.js";
import { Markup, nextId } from "./markup.js";
import { Markup } from "./markup.js";

/**
* The target nodes available to a behavior.
Expand All @@ -31,108 +29,6 @@ export interface ViewController<TSource = any, TParent = any>
readonly targets: ViewBehaviorTargets;
}

/**
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
* control ViewBehaviors.
* @public
*/
export interface ViewBehaviorOrchestrator<TSource = any, TParent = any>
extends ViewController<TSource, TParent>,
HostBehavior<TSource> {
/**
*
* @param nodeId - The structural id of the DOM node to which a behavior will apply.
* @param target - The DOM node associated with the id.
*/
addTarget(nodeId: string, target: Node): void;

/**
* Adds a behavior.
* @param behavior - The behavior to add.
*/
addBehavior(behavior: ViewBehavior): void;

/**
* Adds a behavior factory.
* @param factory - The behavior factory to add.
* @param target - The target the factory will create behaviors for.
*/
addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;
}

/**
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
* control ViewBehaviors.
* @public
*/
export const ViewBehaviorOrchestrator = Object.freeze({
/**
* Creates a ViewBehaviorOrchestrator.
* @param source - The source to to associate behaviors with.
* @returns A ViewBehaviorOrchestrator.
*/
create<TSource = any, TParent = any>(
source: TSource
): ViewBehaviorOrchestrator<TSource, TParent> {
const behaviors: ViewBehavior[] = [];
const targets: ViewBehaviorTargets = {};
let unbindables: { unbind(controller: ViewController<TSource>) }[] | null = null;
let isConnected = false;

return {
source,
context: ExecutionContext.default,
targets,
get isBound() {
return isConnected;
},
addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void {
const compiled = factory as CompiledViewBehaviorFactory;

compiled.id = compiled.id ?? nextId();
compiled.targetNodeId = compiled.targetNodeId ?? nextId();
compiled.targetTagName = (target as HTMLElement).tagName ?? null;
compiled.policy = compiled.policy ?? DOM.policy;

this.addTarget(compiled.targetNodeId, target);
this.addBehavior(compiled.createBehavior());
},
addTarget(nodeId: string, target: Node) {
targets[nodeId] = target;
},
addBehavior(behavior: ViewBehavior): void {
behaviors.push(behavior);

if (isConnected) {
behavior.bind(this);
}
},
onUnbind(unbindable: { unbind(controller: ViewController<TSource>) }) {
if (unbindables === null) {
unbindables = [];
}

unbindables.push(unbindable);
},
connectedCallback(controller: HostController<TSource>) {
if (!isConnected) {
isConnected = true;
behaviors.forEach(x => x.bind(this));
}
},
disconnectedCallback(controller: HostController<TSource>) {
if (isConnected) {
isConnected = false;

if (unbindables !== null) {
unbindables.forEach(x => x.unbind(this));
}
}
},
};
},
});

/**
* Represents an object that can contribute behavior to a view.
* @public
Expand Down
114 changes: 114 additions & 0 deletions packages/web-components/fast-element/src/utilities.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import { DOM } from "./dom.js";
import { ExecutionContext } from "./observation/observable.js";
import type { HostBehavior, HostController } from "./styles/host.js";
import type {
CompiledViewBehaviorFactory,
ViewBehavior,
ViewBehaviorFactory,
ViewBehaviorTargets,
ViewController,
} from "./templating/html-directive.js";
import { nextId } from "./templating/markup.js";

/**
* Retrieves the "composed parent" element of a node, ignoring DOM tree boundaries.
* When the parent of a node is a shadow-root, it will return the host
Expand Down Expand Up @@ -83,3 +95,105 @@ export class UnobservableMutationObserver extends MutationObserver {
}
}
}

/**
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
* control ViewBehaviors.
* @public
*/
export interface ViewBehaviorOrchestrator<TSource = any, TParent = any>
extends ViewController<TSource, TParent>,
HostBehavior<TSource> {
/**
*
* @param nodeId - The structural id of the DOM node to which a behavior will apply.
* @param target - The DOM node associated with the id.
*/
addTarget(nodeId: string, target: Node): void;

/**
* Adds a behavior.
* @param behavior - The behavior to add.
*/
addBehavior(behavior: ViewBehavior): void;

/**
* Adds a behavior factory.
* @param factory - The behavior factory to add.
* @param target - The target the factory will create behaviors for.
*/
addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;
}

/**
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
* control ViewBehaviors.
* @public
*/
export const ViewBehaviorOrchestrator = Object.freeze({
/**
* Creates a ViewBehaviorOrchestrator.
* @param source - The source to to associate behaviors with.
* @returns A ViewBehaviorOrchestrator.
*/
create<TSource = any, TParent = any>(
source: TSource
): ViewBehaviorOrchestrator<TSource, TParent> {
const behaviors: ViewBehavior[] = [];
const targets: ViewBehaviorTargets = {};
let unbindables: { unbind(controller: ViewController<TSource>) }[] | null = null;
let isConnected = false;

return {
source,
context: ExecutionContext.default,
targets,
get isBound() {
return isConnected;
},
addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void {
const compiled = factory as CompiledViewBehaviorFactory;

compiled.id = compiled.id ?? nextId();
compiled.targetNodeId = compiled.targetNodeId ?? nextId();
compiled.targetTagName = (target as HTMLElement).tagName ?? null;
compiled.policy = compiled.policy ?? DOM.policy;

this.addTarget(compiled.targetNodeId, target);
this.addBehavior(compiled.createBehavior());
},
addTarget(nodeId: string, target: Node) {
targets[nodeId] = target;
},
addBehavior(behavior: ViewBehavior): void {
behaviors.push(behavior);

if (isConnected) {
behavior.bind(this);
}
},
onUnbind(unbindable: { unbind(controller: ViewController<TSource>) }) {
if (unbindables === null) {
unbindables = [];
}

unbindables.push(unbindable);
},
connectedCallback(controller: HostController<TSource>) {
if (!isConnected) {
isConnected = true;
behaviors.forEach(x => x.bind(this));
}
},
disconnectedCallback(controller: HostController<TSource>) {
if (isConnected) {
isConnected = false;

if (unbindables !== null) {
unbindables.forEach(x => x.unbind(this));
}
}
},
};
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {
FASTElement,
observable,
RepeatDirective,
ViewBehaviorOrchestrator,
ViewTemplate,
} from "@microsoft/fast-element";
import { ViewBehaviorOrchestrator } from "@microsoft/fast-element/utilities";
import {
eventFocusOut,
eventKeyDown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
observable,
RepeatDirective,
Updates,
ViewBehaviorOrchestrator,
} from "@microsoft/fast-element";
import { ViewBehaviorOrchestrator } from "@microsoft/fast-element/utilities";
import {
eventFocus,
eventFocusOut,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
ref,
RepeatDirective,
Updates,
ViewBehaviorOrchestrator,
ViewTemplate,
} from "@microsoft/fast-element";
import { ViewBehaviorOrchestrator } from "@microsoft/fast-element/utilities";
import {
keyArrowDown,
keyArrowLeft,
Expand Down

0 comments on commit 1a1fc0b

Please sign in to comment.