chore(fast-element): configure production build and add test setup (#3053)
* chore(fast-element): configure production build and add test setup * chore(fast-element): add missing dependency * chore(fast-element): do not remove comments from build output * chore(fast-element): add "test" task to alias verbose node tests for CI * fix(fast-element): correct a package dependency * fix(fast-element): better dts ouput types and fixed break in components * chore(fast-element): add gen for dts bundle, api report, and docs json * add @types related to testing to the no-hoist list to ensure there are no conflicts with the *.d.ts lib check during compilation * chore(fast-element): update .npmignore for better npm pack results * chore(fast-element): configure production build and add test setup * chore(fast-element): add missing dependency * chore(fast-element): do not remove comments from build output * chore(fast-element): add "test" task to alias verbose node tests for CI * fix(fast-element): correct a package dependency * fix(fast-element): better dts ouput types and fixed break in components * chore(fast-element): add gen for dts bundle, api report, and docs json * add @types related to testing to the no-hoist list to ensure there are no conflicts with the *.d.ts lib check during compilation * chore(fast-element): lets see if this fixes CI Co-authored-by: Chris Holt <chhol@microsoft.com>
This commit is contained in:
Родитель
62e4ea63d9
Коммит
200f6a0ae9
|
@ -10,7 +10,7 @@
|
|||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": ["packages/**/*", "sites/fast-color-explorer", "sites/fast-component-explorer", "sites/fast-creator", "sites/site-utilities"],
|
||||
"nohoist": ["**/react-syntax-highlighter"]
|
||||
"nohoist": ["**/react-syntax-highlighter", "**/@types/chai", "**/@types/jest", "**/@types/karma", "**/@types/mocha"]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { html } from "@microsoft/fast-element";
|
||||
import { when } from "@microsoft/fast-element";
|
||||
import { ref } from "@microsoft/fast-element/dist/directives/";
|
||||
import { ref } from "@microsoft/fast-element";
|
||||
import { Dialog } from "./dialog";
|
||||
|
||||
export const DialogTemplate = html<Dialog>`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { html } from "@microsoft/fast-element";
|
||||
import { ref } from "@microsoft/fast-element/dist/directives";
|
||||
import { ref } from "@microsoft/fast-element";
|
||||
import { Slider } from "./slider";
|
||||
|
||||
export const SliderTemplate = html<Slider>`
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.rollupcache
|
||||
coverage
|
||||
tsdoc-metadata.json
|
||||
temp
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"colors": true,
|
||||
"recursive": true,
|
||||
"timeout": 5000,
|
||||
"require": [
|
||||
"jsdom-global/register"
|
||||
]
|
||||
}
|
|
@ -1,14 +1,23 @@
|
|||
# Tests
|
||||
__test__/
|
||||
dist/dts/__test__/
|
||||
dist/esm/__test__/
|
||||
*.spec.*
|
||||
*.test.*
|
||||
coverage/
|
||||
|
||||
# Source files
|
||||
src/
|
||||
docs/
|
||||
|
||||
# config files
|
||||
.eslintignore
|
||||
.eslintrc.js
|
||||
.eslintrc.cjs
|
||||
.prettierignore
|
||||
tsconfig.json
|
||||
tsconfig.json
|
||||
rollup.config.js
|
||||
karma.conf.cjs
|
||||
api-extractor.json
|
||||
.mocharc.json
|
||||
|
||||
# cache
|
||||
.rollupcache
|
||||
temp
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
|
||||
"mainEntryPointFilePath": "dist/dts/index.d.ts",
|
||||
|
||||
"apiReport": {
|
||||
"enabled": true,
|
||||
"reportFolder": "docs",
|
||||
"reportFileName": "api-report.md"
|
||||
},
|
||||
|
||||
"docModel": {
|
||||
"enabled": true,
|
||||
"apiJsonFilePath": "dist/fast-element.api.json"
|
||||
},
|
||||
|
||||
"dtsRollup": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
There are many great open source projects that have inspired us and enabled us to build the `fast-element` library. Below are a few that stand out.
|
||||
|
||||
* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function expressions.
|
||||
* [Aurelia 1 and Aurelia 2](https://aurelia.io/) - Various details of Aurelia 2's decorator and metadata model inspired us in the design of `fast-element`. Additionally, Aurelia 1's mechanisms for array observation, binding, and template compilation also guided us in our work.
|
||||
* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.
|
||||
* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.
|
||||
* [faastjs](https://github.com/faastjs) - A project with a similar name but a very different purpose. Their API documentation approach leveraging [api-extractor](https://api-extractor.com/) was a huge help to us.
|
||||
* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.
|
||||
* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function expressions.
|
||||
* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
Here you'll find preliminary documentation on the `fast-element` library.
|
||||
|
||||
* [Building Components](./building-components.md)
|
||||
* Guides
|
||||
* [Building Components](./guide/building-components.md)
|
|
@ -0,0 +1,664 @@
|
|||
## API Report File for "@microsoft/fast-element"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
|
||||
// @public (undocumented)
|
||||
export interface Accessor {
|
||||
// (undocumented)
|
||||
getValue(source: any): any;
|
||||
// (undocumented)
|
||||
name: string;
|
||||
// (undocumented)
|
||||
setValue(source: any, value: any): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class AdoptedStyleSheetsStyles extends ElementStyles {
|
||||
constructor(styles: InjectableStyles[], styleSheetCache: Map<string, CSSStyleSheet>);
|
||||
// (undocumented)
|
||||
addStylesTo(target: StyleTarget): void;
|
||||
// (undocumented)
|
||||
readonly behaviors: ReadonlyArray<Behavior> | null;
|
||||
// (undocumented)
|
||||
removeStylesFrom(target: StyleTarget): void;
|
||||
// Warning: (ae-forgotten-export) The symbol "InjectableStyles" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
styles: InjectableStyles[];
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class AttachedBehaviorDirective<T = any> extends Directive {
|
||||
constructor(name: string, behavior: AttachedBehaviorType<T>, options: T);
|
||||
// (undocumented)
|
||||
createBehavior(target: any): Behavior;
|
||||
// (undocumented)
|
||||
createPlaceholder(index: number): string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type AttachedBehaviorType<T = any> = new (target: any, options: T) => Behavior;
|
||||
|
||||
// @public
|
||||
export function attr(config?: DecoratorAttributeConfiguration): (target: {}, property: string) => void;
|
||||
|
||||
// @public
|
||||
export function attr(target: {}, prop: string): void;
|
||||
|
||||
// @public (undocumented)
|
||||
export type AttributeConfiguration = {
|
||||
property: string;
|
||||
attribute?: string;
|
||||
mode?: AttributeMode;
|
||||
converter?: ValueConverter;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class AttributeDefinition implements Accessor {
|
||||
constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter | undefined);
|
||||
// (undocumented)
|
||||
readonly attribute: string;
|
||||
// (undocumented)
|
||||
static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;
|
||||
// (undocumented)
|
||||
readonly converter?: ValueConverter | undefined;
|
||||
// (undocumented)
|
||||
getValue(source: HTMLElement): any;
|
||||
// (undocumented)
|
||||
readonly mode: AttributeMode;
|
||||
// (undocumented)
|
||||
readonly name: string;
|
||||
// (undocumented)
|
||||
onAttributeChangedCallback(element: HTMLElement, value: any): void;
|
||||
// (undocumented)
|
||||
readonly Owner: Function;
|
||||
// (undocumented)
|
||||
setValue(source: HTMLElement, newValue: any): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type AttributeMode = "reflect" | "boolean" | "fromView";
|
||||
|
||||
// @public (undocumented)
|
||||
export interface Behavior {
|
||||
// (undocumented)
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
// (undocumented)
|
||||
unbind(source: unknown): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface BehaviorFactory {
|
||||
// (undocumented)
|
||||
createBehavior(target: any): Behavior;
|
||||
// (undocumented)
|
||||
targetIndex: number;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class BindingBehavior implements Behavior {
|
||||
constructor(target: any, expression: Expression, bind: typeof normalBind, unbind: typeof normalUnbind, updateTarget: typeof updatePropertyTarget, targetName?: string | undefined);
|
||||
// Warning: (ae-forgotten-export) The symbol "normalBind" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
bind: typeof normalBind;
|
||||
// (undocumented)
|
||||
classVersions: Record<string, number>;
|
||||
// (undocumented)
|
||||
context: ExecutionContext | null;
|
||||
// (undocumented)
|
||||
expression: Expression;
|
||||
// (undocumented)
|
||||
handleEvent(event: Event): void;
|
||||
// (undocumented)
|
||||
handleExpressionChange(): void;
|
||||
// (undocumented)
|
||||
observableExpression: ObservableExpression | null;
|
||||
// (undocumented)
|
||||
source: unknown;
|
||||
// (undocumented)
|
||||
target: any;
|
||||
// (undocumented)
|
||||
targetName?: string | undefined;
|
||||
// Warning: (ae-forgotten-export) The symbol "normalUnbind" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
unbind: typeof normalUnbind;
|
||||
// Warning: (ae-forgotten-export) The symbol "updatePropertyTarget" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
updateTarget: typeof updatePropertyTarget;
|
||||
// (undocumented)
|
||||
version: number;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class BindingDirective extends Directive {
|
||||
constructor(expression: Expression);
|
||||
// (undocumented)
|
||||
createBehavior(target: any): BindingBehavior;
|
||||
// (undocumented)
|
||||
createPlaceholder: (index: number) => string;
|
||||
// (undocumented)
|
||||
expression: Expression;
|
||||
// (undocumented)
|
||||
makeIntoTextBinding(): void;
|
||||
// (undocumented)
|
||||
get targetName(): string | undefined;
|
||||
set targetName(value: string | undefined);
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const booleanConverter: ValueConverter;
|
||||
|
||||
// @public (undocumented)
|
||||
export type Callable = typeof Function.prototype.call | {
|
||||
call(): void;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface CaptureType<TSource> {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function children<T = any>(propertyOrOptions: (keyof T & string) | ChildrenBehaviorOptions<keyof T & string>): CaptureType<T>;
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "NodeObservationBehavior" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export class ChildrenBehavior extends NodeObservationBehavior<ChildrenBehaviorOptions> {
|
||||
constructor(target: HTMLSlotElement, options: ChildrenBehaviorOptions);
|
||||
// (undocumented)
|
||||
getNodes(): ChildNode[];
|
||||
// (undocumented)
|
||||
observe(): void;
|
||||
// (undocumented)
|
||||
unobserve(): void;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "NodeBehaviorBehaviorOptions" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export interface ChildrenBehaviorOptions<T = any> extends NodeBehaviorBehaviorOptions<T>, MutationObserverInit {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function compileTemplate(template: HTMLTemplateElement, directives: Directive[]): {
|
||||
fragment: DocumentFragment;
|
||||
viewBehaviorFactories: BehaviorFactory[];
|
||||
hostBehaviorFactories: BehaviorFactory[];
|
||||
targetOffset: number;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class Controller extends PropertyChangeNotifier {
|
||||
constructor(element: HTMLElement, definition: FASTElementDefinition);
|
||||
// (undocumented)
|
||||
addBehaviors(behaviors: ReadonlyArray<Behavior>): void;
|
||||
// (undocumented)
|
||||
addStyles(styles: ElementStyles, target?: StyleTarget | null): void;
|
||||
// (undocumented)
|
||||
readonly definition: FASTElementDefinition;
|
||||
// (undocumented)
|
||||
readonly element: HTMLElement;
|
||||
// (undocumented)
|
||||
emit(type: string, detail?: any, options?: Omit<CustomEventInit, "detail">): void | boolean;
|
||||
// (undocumented)
|
||||
static forCustomElement(element: HTMLElement): Controller;
|
||||
// (undocumented)
|
||||
isConnected: boolean;
|
||||
// (undocumented)
|
||||
onAttributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
||||
// (undocumented)
|
||||
onConnectedCallback(): void;
|
||||
// (undocumented)
|
||||
onDisconnectedCallback(): void;
|
||||
// (undocumented)
|
||||
removeBehaviors(behaviors: ReadonlyArray<Behavior>): void;
|
||||
// (undocumented)
|
||||
removeStyles(styles: ElementStyles): void;
|
||||
// (undocumented)
|
||||
view: ElementView | null;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "ElementStyleFactory" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createStyles: ElementStyleFactory;
|
||||
|
||||
// @public (undocumented)
|
||||
export function css(strings: TemplateStringsArray, ...values: InjectableStyles[]): ElementStyles;
|
||||
|
||||
// @public (undocumented)
|
||||
export function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Function) => void;
|
||||
|
||||
// @public (undocumented)
|
||||
export type DecoratorAttributeConfiguration = Omit<AttributeConfiguration, "property">;
|
||||
|
||||
// @public (undocumented)
|
||||
export const defaultExecutionContext: ExecutionContext<any>;
|
||||
|
||||
// @public (undocumented)
|
||||
export abstract class Directive implements BehaviorFactory {
|
||||
// (undocumented)
|
||||
abstract createBehavior(target: any): Behavior;
|
||||
// (undocumented)
|
||||
abstract createPlaceholder(index: number): string;
|
||||
// (undocumented)
|
||||
targetIndex: number;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const DOM: Readonly<{
|
||||
setHTMLPolicy(policy: TrustedTypesPolicy): void;
|
||||
createHTML(html: string): string;
|
||||
isMarker(node: Node): node is Comment;
|
||||
extractDirectiveIndexFromMarker(node: Comment): number;
|
||||
createInterpolationPlaceholder(index: number): string;
|
||||
createCustomAttributePlaceholder(attributeName: string, index: number): string;
|
||||
createBlockPlaceholder(index: number): string;
|
||||
queueUpdate(callable: Callable): void;
|
||||
setAttribute(element: HTMLElement, attributeName: string, value: any): void;
|
||||
setBooleanAttribute(element: HTMLElement, attributeName: string, value: boolean): void;
|
||||
}>;
|
||||
|
||||
// @public (undocumented)
|
||||
export abstract class ElementStyles {
|
||||
// @internal (undocumented)
|
||||
abstract addStylesTo(target: StyleTarget): void;
|
||||
// @internal (undocumented)
|
||||
abstract readonly behaviors: ReadonlyArray<Behavior> | null;
|
||||
// (undocumented)
|
||||
static find(key: string): ElementStyles | null;
|
||||
// @internal (undocumented)
|
||||
abstract removeStylesFrom(target: StyleTarget): void;
|
||||
// @internal (undocumented)
|
||||
abstract readonly styles: ReadonlyArray<InjectableStyles>;
|
||||
// (undocumented)
|
||||
withBehaviors(...behaviors: Behavior[]): this;
|
||||
// (undocumented)
|
||||
withKey(key: string): this;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface ElementView extends View {
|
||||
appendTo(node: Node): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ElementViewTemplate {
|
||||
// (undocumented)
|
||||
create(host: Element): ElementView;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const emptyArray: readonly never[];
|
||||
|
||||
// @public
|
||||
export class ExecutionContext<TParent = any> {
|
||||
// (undocumented)
|
||||
get even(): boolean;
|
||||
// (undocumented)
|
||||
get event(): Event;
|
||||
// (undocumented)
|
||||
get first(): boolean;
|
||||
// (undocumented)
|
||||
index: number;
|
||||
// (undocumented)
|
||||
get last(): boolean;
|
||||
// (undocumented)
|
||||
length: number;
|
||||
// (undocumented)
|
||||
get middle(): boolean;
|
||||
// (undocumented)
|
||||
get odd(): boolean;
|
||||
// (undocumented)
|
||||
parent: TParent;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type Expression<TScope = any, TReturn = any, TParent = any> = (scope: TScope, context: ExecutionContext<TParent>) => TReturn;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ExpressionObserver {
|
||||
// (undocumented)
|
||||
handleExpressionChange(expression: ObservableExpression): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface FASTElement {
|
||||
// (undocumented)
|
||||
$emit(type: string, detail?: any, options?: Omit<CustomEventInit, "detail">): boolean | void;
|
||||
// (undocumented)
|
||||
$fastController: Controller;
|
||||
// (undocumented)
|
||||
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
||||
// (undocumented)
|
||||
connectedCallback(): void;
|
||||
// (undocumented)
|
||||
disconnectedCallback(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const FASTElement: (new () => HTMLElement & FASTElement) & {
|
||||
from<TBase extends {
|
||||
new (): HTMLElement;
|
||||
prototype: HTMLElement;
|
||||
}>(BaseType: TBase): new () => InstanceType<TBase> & FASTElement;
|
||||
define<TType extends Function>(Type: TType, nameOrDef?: string | PartialFASTElementDefinition): TType;
|
||||
getDefinition: typeof getDefinition;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class FASTElementDefinition {
|
||||
constructor(name: string, attributes: ReadonlyArray<AttributeDefinition>, propertyLookup: Record<string, AttributeDefinition>, attributeLookup: Record<string, AttributeDefinition>, template?: ElementViewTemplate | undefined, styles?: ElementStyles | undefined, shadowOptions?: ShadowRootInit | undefined, elementOptions?: ElementDefinitionOptions | undefined);
|
||||
// (undocumented)
|
||||
readonly attributeLookup: Record<string, AttributeDefinition>;
|
||||
// (undocumented)
|
||||
readonly attributes: ReadonlyArray<AttributeDefinition>;
|
||||
// (undocumented)
|
||||
readonly elementOptions?: ElementDefinitionOptions | undefined;
|
||||
// (undocumented)
|
||||
readonly name: string;
|
||||
// (undocumented)
|
||||
readonly propertyLookup: Record<string, AttributeDefinition>;
|
||||
// (undocumented)
|
||||
readonly shadowOptions?: ShadowRootInit | undefined;
|
||||
// (undocumented)
|
||||
readonly styles?: ElementStyles | undefined;
|
||||
// (undocumented)
|
||||
readonly template?: ElementViewTemplate | undefined;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "TemplateValue" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export function html<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: TemplateValue<TSource, TParent>[]): ViewTemplate<TSource, TParent>;
|
||||
|
||||
// @public (undocumented)
|
||||
export class HTMLTemplateBehavior implements Behavior {
|
||||
constructor(template: SyntheticViewTemplate, location: HTMLElement);
|
||||
// (undocumented)
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
// (undocumented)
|
||||
unbind(): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class HTMLView implements ElementView, SyntheticView {
|
||||
constructor(fragment: DocumentFragment, behaviors: Behavior[]);
|
||||
appendTo(node: Node): void;
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
// (undocumented)
|
||||
context: ExecutionContext | null;
|
||||
dispose(): void;
|
||||
static disposeContiguousBatch(views: SyntheticView[]): void;
|
||||
// (undocumented)
|
||||
firstChild: Node;
|
||||
insertBefore(node: Node): void;
|
||||
// (undocumented)
|
||||
lastChild: Node;
|
||||
remove(): void;
|
||||
unbind(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const lastAttributeNameRegex: RegExp;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface Notifier {
|
||||
// (undocumented)
|
||||
notify(source: any, args: any): void;
|
||||
// (undocumented)
|
||||
subscribe(subscriber: Subscriber, context?: any): void;
|
||||
// (undocumented)
|
||||
unsubscribe(subscriber: Subscriber, context?: any): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const nullableNumberConverter: ValueConverter;
|
||||
|
||||
// @public (undocumented)
|
||||
export const Observable: {
|
||||
createArrayObserver(array: any[]): Notifier;
|
||||
getNotifier<T extends Notifier = Notifier>(source: any): T;
|
||||
track(source: unknown, propertyName: string): void;
|
||||
notify(source: unknown, args: any): void;
|
||||
defineProperty(target: {}, nameOrAccessor: string | Accessor): void;
|
||||
getAccessors(target: {}): Accessor[];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export function observable($target: {}, $prop: string): void;
|
||||
|
||||
// @public (undocumented)
|
||||
export class ObservableExpression {
|
||||
constructor(expression: Expression, observer: ExpressionObserver);
|
||||
// @internal (undocumented)
|
||||
call(): void;
|
||||
// (undocumented)
|
||||
dispose(): void;
|
||||
// (undocumented)
|
||||
evaluate(scope: unknown, context: ExecutionContext): any;
|
||||
// @internal (undocumented)
|
||||
handleChange(): void;
|
||||
// @internal (undocumented)
|
||||
observe(source: unknown, propertyName: string): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type PartialFASTElementDefinition = {
|
||||
readonly name: string;
|
||||
readonly template?: ElementViewTemplate;
|
||||
readonly styles?: ElementStyles;
|
||||
readonly attributes?: (AttributeConfiguration | string)[];
|
||||
readonly shadowOptions?: Partial<ShadowRootInit> | null;
|
||||
readonly elementOptions?: ElementDefinitionOptions;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class PropertyChangeNotifier implements Notifier {
|
||||
// (undocumented)
|
||||
notify(source: any, propertyName: string): void;
|
||||
// (undocumented)
|
||||
subscribe(subscriber: Subscriber, propertyName: string): void;
|
||||
// (undocumented)
|
||||
unsubscribe(subscriber: Subscriber, propertyName: string): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function ref<T = any>(propertyName: keyof T & string): CaptureType<T>;
|
||||
|
||||
// @public (undocumented)
|
||||
export class RefBehavior implements Behavior {
|
||||
constructor(target: HTMLElement, propertyName: string);
|
||||
// (undocumented)
|
||||
bind(source: any): void;
|
||||
// (undocumented)
|
||||
unbind(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function repeat<TScope = any, TItem = any>(expression: Expression<TScope, TItem[]>, template: ViewTemplate<Partial<TItem>, TScope>, options?: RepeatOptions): CaptureType<TScope>;
|
||||
|
||||
// @public (undocumented)
|
||||
export class RepeatBehavior implements Behavior, Subscriber {
|
||||
constructor(location: Node, expression: Expression, template: SyntheticViewTemplate, options: RepeatOptions);
|
||||
// (undocumented)
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
// Warning: (ae-forgotten-export) The symbol "Splice" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// (undocumented)
|
||||
handleChange(source: any, args: Splice[]): void;
|
||||
// (undocumented)
|
||||
handleExpressionChange(): void;
|
||||
// (undocumented)
|
||||
unbind(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class RepeatDirective extends Directive {
|
||||
constructor(expression: Expression, template: SyntheticViewTemplate, options: RepeatOptions);
|
||||
// (undocumented)
|
||||
createBehavior(target: any): RepeatBehavior;
|
||||
// (undocumented)
|
||||
createPlaceholder: (index: number) => string;
|
||||
// (undocumented)
|
||||
expression: Expression;
|
||||
// (undocumented)
|
||||
options: RepeatOptions;
|
||||
// (undocumented)
|
||||
template: SyntheticViewTemplate;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface RepeatOptions {
|
||||
// (undocumented)
|
||||
positioning: boolean;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function setCurrentEvent(event: Event | null): void;
|
||||
|
||||
// @public (undocumented)
|
||||
export function slotted<T = any>(propertyOrOptions: (keyof T & string) | SlottedBehaviorOptions<keyof T & string>): CaptureType<T>;
|
||||
|
||||
// @public (undocumented)
|
||||
export class SlottedBehavior extends NodeObservationBehavior<SlottedBehaviorOptions> {
|
||||
constructor(target: HTMLSlotElement, options: SlottedBehaviorOptions);
|
||||
// (undocumented)
|
||||
getNodes(): Node[];
|
||||
// (undocumented)
|
||||
observe(): void;
|
||||
// (undocumented)
|
||||
unobserve(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface SlottedBehaviorOptions<T = any> extends NodeBehaviorBehaviorOptions<T>, AssignedNodesOptions {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class StyleElementStyles extends ElementStyles {
|
||||
constructor(styles: InjectableStyles[]);
|
||||
// (undocumented)
|
||||
addStylesTo(target: StyleTarget): void;
|
||||
// (undocumented)
|
||||
readonly behaviors: ReadonlyArray<Behavior> | null;
|
||||
// (undocumented)
|
||||
removeStylesFrom(target: StyleTarget): void;
|
||||
// (undocumented)
|
||||
styles: InjectableStyles[];
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface StyleTarget {
|
||||
// (undocumented)
|
||||
adoptedStyleSheets?: CSSStyleSheet[];
|
||||
// (undocumented)
|
||||
prepend(node: Node): void;
|
||||
// (undocumented)
|
||||
querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
|
||||
// (undocumented)
|
||||
removeChild(node: Node): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface Subscriber {
|
||||
// (undocumented)
|
||||
handleChange(source: any, args: any): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class SubscriberCollection implements Notifier {
|
||||
// (undocumented)
|
||||
notify(source: any, args: any): void;
|
||||
// (undocumented)
|
||||
subscribe(subscriber: Subscriber): void;
|
||||
// (undocumented)
|
||||
unsubscribe(subscriber: Subscriber): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface SyntheticView extends View {
|
||||
dispose(): void;
|
||||
readonly firstChild: Node;
|
||||
insertBefore(node: Node): void;
|
||||
readonly lastChild: Node;
|
||||
remove(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface SyntheticViewTemplate<TSource = any, TParent = any> {
|
||||
// (undocumented)
|
||||
create(): SyntheticView;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ValueConverter {
|
||||
// (undocumented)
|
||||
fromView(value: string): any;
|
||||
// (undocumented)
|
||||
toView(value: any): string | null;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface View {
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
readonly context: ExecutionContext | null;
|
||||
unbind(): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class ViewTemplate<TSource = any, TParent = any> extends Directive implements ElementViewTemplate, SyntheticViewTemplate {
|
||||
constructor(html: string | HTMLTemplateElement, directives: Directive[]);
|
||||
// (undocumented)
|
||||
create(host?: Element): HTMLView;
|
||||
// (undocumented)
|
||||
createBehavior(target: any): HTMLTemplateBehavior;
|
||||
// (undocumented)
|
||||
createPlaceholder: (index: number) => string;
|
||||
// (undocumented)
|
||||
render(source: TSource, host: HTMLElement | string): HTMLView;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export function when<T = any, K = any>(expression: Expression<T, K>, template: SyntheticViewTemplate): CaptureType<T>;
|
||||
|
||||
// @public (undocumented)
|
||||
export class WhenBehavior implements Behavior {
|
||||
constructor(location: Node, expression: Expression, template: SyntheticViewTemplate);
|
||||
// (undocumented)
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
// (undocumented)
|
||||
handleExpressionChange(): void;
|
||||
// (undocumented)
|
||||
unbind(): void;
|
||||
// (undocumented)
|
||||
updateTarget(show: boolean): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class WhenDirective extends Directive {
|
||||
constructor(expression: Expression, template: SyntheticViewTemplate);
|
||||
// (undocumented)
|
||||
createBehavior(target: any): WhenBehavior;
|
||||
// (undocumented)
|
||||
createPlaceholder: (index: number) => string;
|
||||
// (undocumented)
|
||||
expression: Expression;
|
||||
// (undocumented)
|
||||
template: SyntheticViewTemplate;
|
||||
}
|
||||
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// dist/dts/dom.d.ts:6:5 - (ae-forgotten-export) The symbol "TrustedTypesPolicy" needs to be exported by the entry point index.d.ts
|
||||
// dist/dts/fast-element.d.ts:16:5 - (ae-forgotten-export) The symbol "getDefinition" needs to be exported by the entry point index.d.ts
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
```
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
## Short-term
|
||||
|
||||
* **Experiment**: See if it's possible combine template instantiate and bind, and if that improves initial render time.
|
||||
* **Test**: Testing infrastructure and test coverage.
|
||||
* **Doc:** Re-organize the current docs into a series of smaller articles.
|
||||
* **Feature**: Transform text binding into a content binding that compose HTML dynamically.
|
||||
* **Feature**: Allow `when` and `repeat` to accept an expression that returns the template they generate from.
|
||||
|
||||
## Medium-term
|
||||
|
||||
* **Feature**: Add a `compose` directive that allows arbitrary logic to choose a template or element to render.
|
||||
* **Experiment**: See if it's possible combine template instantiate and bind, and if that improves initial render time.
|
||||
* **Feature**: Improve `when` to enable if/else scenarios.
|
||||
* **Feature**: Dependency injection infrastructure, including simple decorator-based property injection for `FASTElement`.
|
||||
* **Refactor:** Create abstraction for `ElementInternals`.
|
||||
* **Test:** Include perf benchmarks in the automated build process and track changes over time.
|
||||
* **Doc:** Re-organize the current docs into a series of smaller articles.
|
||||
* **Experiment:** See if internal algos can be improved by leveraging typed arrays.
|
||||
* **Feature**: Support `style` bindings on the host.
|
||||
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
const path = require('path');
|
||||
|
||||
const basePath = path.resolve(__dirname);
|
||||
|
||||
const commonChromeFlags = [
|
||||
'--no-default-browser-check',
|
||||
'--no-first-run',
|
||||
'--no-sandbox',
|
||||
'--no-managed-user-acknowledgment-check',
|
||||
'--disable-background-timer-throttling',
|
||||
'--disable-backing-store-limit',
|
||||
'--disable-boot-animation',
|
||||
'--disable-cloud-import',
|
||||
'--disable-contextual-search',
|
||||
'--disable-default-apps',
|
||||
'--disable-extensions',
|
||||
'--disable-infobars',
|
||||
'--disable-translate',
|
||||
];
|
||||
|
||||
module.exports = function(config) {
|
||||
let browsers;
|
||||
if (process.env.BROWSERS) {
|
||||
browsers = [process.env.BROWSERS];
|
||||
} else if (config.browsers) {
|
||||
browsers = config.browsers;
|
||||
} else {
|
||||
browsers = ['Chrome'];
|
||||
}
|
||||
|
||||
const setup = 'setup-browser' + (config.package ? '-' + config.package : '');
|
||||
const options = {
|
||||
basePath,
|
||||
browserDisconnectTimeout: 10000,
|
||||
processKillTimeout: 10000,
|
||||
frameworks: [
|
||||
'source-map-support',
|
||||
'mocha',
|
||||
],
|
||||
files: [
|
||||
`dist/esm/__test__/${setup}.js`,
|
||||
],
|
||||
preprocessors: {
|
||||
[`dist/esm/__test__/${setup}.js`]: [
|
||||
'webpack',
|
||||
'sourcemap',
|
||||
],
|
||||
},
|
||||
webpackMiddleware: {
|
||||
// webpack-dev-middleware configuration
|
||||
// i. e.
|
||||
stats: 'errors-only',
|
||||
},
|
||||
webpack: {
|
||||
mode: 'none',
|
||||
resolve: {
|
||||
extensions: [
|
||||
'.js',
|
||||
],
|
||||
modules: [
|
||||
'dist',
|
||||
'node_modules'
|
||||
],
|
||||
mainFields: [
|
||||
'module', 'main'
|
||||
],
|
||||
},
|
||||
devtool: 'inline-source-map',
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
optimization: {
|
||||
namedModules: false,
|
||||
namedChunks: false,
|
||||
nodeEnv: false,
|
||||
usedExports: true,
|
||||
flagIncludedChunks: false,
|
||||
occurrenceOrder: false,
|
||||
sideEffects: true,
|
||||
concatenateModules: true,
|
||||
splitChunks: {
|
||||
name: false,
|
||||
},
|
||||
runtimeChunk: false,
|
||||
noEmitOnErrors: false,
|
||||
checkWasmTypes: false,
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js\.map$/,
|
||||
use: ['ignore-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'source-map-loader',
|
||||
options: {
|
||||
enforce: 'pre',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
mime: {
|
||||
'text/x-typescript': ['ts']
|
||||
},
|
||||
reporters: [config.reporter || (process.env.CI ? 'min' : 'progress')],
|
||||
browsers: browsers,
|
||||
customLaunchers: {
|
||||
ChromeDebugging: {
|
||||
base: 'Chrome',
|
||||
flags: [
|
||||
...commonChromeFlags,
|
||||
'--remote-debugging-port=9333'
|
||||
],
|
||||
debug: true
|
||||
},
|
||||
ChromeHeadlessOpt: {
|
||||
base: 'ChromeHeadless',
|
||||
flags: [
|
||||
...commonChromeFlags
|
||||
]
|
||||
}
|
||||
},
|
||||
client: {
|
||||
captureConsole: true,
|
||||
mocha: {
|
||||
bail: config['bail'],
|
||||
ui: 'bdd',
|
||||
timeout: 5000,
|
||||
}
|
||||
},
|
||||
logLevel: config.LOG_ERROR // to disable the WARN 404 for image requests
|
||||
};
|
||||
|
||||
if (config.coverage) {
|
||||
options.webpack.module.rules.push({
|
||||
enforce: 'post',
|
||||
exclude: /(__tests__|testing|node_modules|\.spec\.[tj]s$)/,
|
||||
loader: 'istanbul-instrumenter-loader',
|
||||
options: { esModules: true },
|
||||
test: /\.[tj]s$/
|
||||
});
|
||||
options.reporters = ['coverage-istanbul', ...options.reporters];
|
||||
options.coverageIstanbulReporter = {
|
||||
reports: ['html', 'text-summary', 'json', 'lcovonly', 'cobertura'],
|
||||
dir: 'coverage'
|
||||
};
|
||||
options.junitReporter = {
|
||||
outputDir: 'coverage',
|
||||
outputFile: 'test-results.xml',
|
||||
useBrowserName: false
|
||||
};
|
||||
}
|
||||
|
||||
config.set(options);
|
||||
}
|
|
@ -15,19 +15,65 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/fast-dna/issues/new/choose"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./dist/esm/index.js",
|
||||
"type": "module",
|
||||
"types": "./dist/fast-element.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc -p ./tsconfig.json",
|
||||
"clean:dist": "node ../../../build/clean.js dist",
|
||||
"doc": "api-extractor run --local",
|
||||
"build": "tsc -p ./tsconfig.json && rollup -c && npm run doc",
|
||||
"prepare": "yarn clean:dist && yarn build",
|
||||
"prettier": "prettier --config ../../../.prettierrc --write \"**/*.ts\"",
|
||||
"prettier:diff": "prettier --config ../../../.prettierrc \"**/*.ts\" --list-different",
|
||||
"eslint": "eslint . --ext .ts",
|
||||
"eslint:fix": "eslint . --ext .ts --fix"
|
||||
"eslint:fix": "eslint . --ext .ts --fix",
|
||||
"test": "npm run test-node:verbose -- --experimental-modules",
|
||||
"test-node": "mocha --reporter min --exit dist/esm/__test__/setup-node.js dist/esm/**/*.spec.js -- --experimental-modules",
|
||||
"test-node:verbose": "mocha --reporter spec --exit dist/esm/__test__/setup-node.js dist/esm/**/*.spec.js -- --experimental-modules",
|
||||
"test-chrome": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --single-run --coverage -- --experimental-modules",
|
||||
"test-chrome:verbose": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --single-run --coverage --reporter=mocha -- --experimental-modules",
|
||||
"test-chrome:watch": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --coverage --watch-extensions js -- --experimental-modules",
|
||||
"test-chrome:debugger": "karma start karma.conf.cjs --browsers=ChromeDebugging --watch-extensions js-- --experimental-modules",
|
||||
"test-chrome:verbose:watch": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --coverage --watch-extensions js --reporter=mocha -- --experimental-modules",
|
||||
"test-chrome:verbose:debugger": "karma start karma.conf.cjs --browsers=ChromeDebugging --watch-extensions js --reporter=mocha -- --experimental-modules",
|
||||
"test-firefox": "karma start karma.conf.cjs --browsers=FirefoxHeadless --single-run --coverage -- --experimental-modules",
|
||||
"test-firefox:verbose": "karma start karma.conf.cjs --browsers=FirefoxHeadless --single-run --coverage --reporter=mocha -- --experimental-modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/api-extractor": "^7.7.13",
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/karma": "^5.0.0",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/webpack-env": "^1.15.2",
|
||||
"chai": "^4.2.0",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"istanbul": "^0.4.5",
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jsdom": "^16.2.2",
|
||||
"jsdom-global": "3.0.2",
|
||||
"karma": "^5.0.4",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-coverage": "^2.0.2",
|
||||
"karma-coverage-istanbul-reporter": "^3.0.0",
|
||||
"karma-firefox-launcher": "^1.3.0",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-mocha-reporter": "^2.2.5",
|
||||
"karma-source-map-support": "^1.4.0",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^4.0.2",
|
||||
"mocha": "^7.1.2",
|
||||
"prettier": "2.0.2",
|
||||
"typescript": "^3.7.5"
|
||||
"rollup": "^2.7.6",
|
||||
"rollup-plugin-filesize": "^8.0.2",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"rollup-plugin-typescript2": "^0.27.0",
|
||||
"source-map": "^0.7.3",
|
||||
"source-map-loader": "^0.2.4",
|
||||
"ts-loader": "^7.0.2",
|
||||
"ts-node": "^8.9.1",
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"tslib": "^1.11.1",
|
||||
"typescript": "^3.7.5",
|
||||
"webpack": "^4.43.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import typescript from "rollup-plugin-typescript2";
|
||||
import { terser } from "rollup-plugin-terser";
|
||||
import filesize from "rollup-plugin-filesize";
|
||||
|
||||
export default [
|
||||
{
|
||||
input: "src/index.ts",
|
||||
output: [
|
||||
{
|
||||
file: "dist/fast-element.js",
|
||||
format: "esm",
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
typescript({
|
||||
cacheRoot: ".rollupcache",
|
||||
tsconfigOverride: {
|
||||
compilerOptions: {
|
||||
declaration: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
terser(),
|
||||
filesize(),
|
||||
],
|
||||
},
|
||||
];
|
|
@ -0,0 +1,6 @@
|
|||
function importAll(r: __WebpackModuleApi.RequireContext): void {
|
||||
r.keys().forEach(r);
|
||||
}
|
||||
|
||||
// Explicitly add to browser test
|
||||
importAll(require.context("../", true, /\.spec\.js$/));
|
|
@ -0,0 +1,12 @@
|
|||
/* eslint-disable */
|
||||
if (window.document && !window.document.createRange) {
|
||||
window.document.createRange = () => ({
|
||||
setStart: () => {},
|
||||
setEnd: () => {},
|
||||
// @ts-ignore
|
||||
commonAncestorContainer: {
|
||||
nodeName: "BODY",
|
||||
ownerDocument: document,
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { Accessor, Observable } from "./observation/observable";
|
||||
import { DOM } from "./dom";
|
||||
import { Notifier } from "./observation/notifier";
|
||||
import { Accessor, Observable } from "./observation/observable.js";
|
||||
import { DOM } from "./dom.js";
|
||||
import { Notifier } from "./observation/notifier.js";
|
||||
|
||||
export interface ValueConverter {
|
||||
toView(value: any): string | null;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { FASTElementDefinition, getDefinition } from "./fast-definitions";
|
||||
import { ElementView } from "./view";
|
||||
import { PropertyChangeNotifier } from "./observation/notifier";
|
||||
import { defaultExecutionContext, Observable } from "./observation/observable";
|
||||
import { Behavior } from "./directives/behavior";
|
||||
import { ElementStyles, StyleTarget } from "./styles";
|
||||
import { FASTElementDefinition, getDefinition } from "./fast-definitions.js";
|
||||
import { ElementView } from "./view.js";
|
||||
import { PropertyChangeNotifier } from "./observation/notifier.js";
|
||||
import { defaultExecutionContext, Observable } from "./observation/observable.js";
|
||||
import { Behavior } from "./directives/behavior.js";
|
||||
import { ElementStyles, StyleTarget } from "./styles.js";
|
||||
|
||||
const defaultEventOptions: CustomEventInit = {
|
||||
bubbles: true,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ExecutionContext } from "../observation/observable";
|
||||
import { ExecutionContext } from "../observation/observable.js";
|
||||
|
||||
export interface Behavior {
|
||||
bind(source: unknown, context: ExecutionContext): void;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { ExecutionContext, Expression, setCurrentEvent } from "../observation/observable";
|
||||
import { ObservableExpression } from "../observation/observable";
|
||||
import { DOM } from "../dom";
|
||||
import { Directive } from "./directive";
|
||||
import { Behavior } from "./behavior";
|
||||
import {
|
||||
ExecutionContext,
|
||||
Expression,
|
||||
setCurrentEvent,
|
||||
} from "../observation/observable.js";
|
||||
import { ObservableExpression } from "../observation/observable.js";
|
||||
import { DOM } from "../dom.js";
|
||||
import { Directive } from "./directive.js";
|
||||
import { Behavior } from "./behavior.js";
|
||||
|
||||
function normalBind(
|
||||
this: BindingBehavior,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { CaptureType } from "../template";
|
||||
import { AttachedBehaviorDirective } from "./directive";
|
||||
import { NodeBehaviorBehaviorOptions, NodeObservationBehavior } from "./node-observation";
|
||||
import { CaptureType } from "../template.js";
|
||||
import { AttachedBehaviorDirective } from "./directive.js";
|
||||
import {
|
||||
NodeBehaviorBehaviorOptions,
|
||||
NodeObservationBehavior,
|
||||
} from "./node-observation.js";
|
||||
|
||||
export interface ChildrenBehaviorOptions<T = any>
|
||||
extends NodeBehaviorBehaviorOptions<T>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DOM } from "../dom";
|
||||
import { Behavior, BehaviorFactory } from "./behavior";
|
||||
import { DOM } from "../dom.js";
|
||||
import { Behavior, BehaviorFactory } from "./behavior.js";
|
||||
|
||||
export abstract class Directive implements BehaviorFactory {
|
||||
public targetIndex: number = 0;
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
export * from "./behavior";
|
||||
export * from "./binding";
|
||||
export * from "./directive";
|
||||
export * from "./ref";
|
||||
export * from "./repeat";
|
||||
export * from "./when";
|
||||
export * from "./slotted";
|
||||
export * from "./children";
|
|
@ -1,6 +1,6 @@
|
|||
import { Accessor, Observable } from "../observation/observable";
|
||||
import { emptyArray } from "../interfaces";
|
||||
import { Behavior } from "./behavior";
|
||||
import { Accessor, Observable } from "../observation/observable.js";
|
||||
import { emptyArray } from "../interfaces.js";
|
||||
import { Behavior } from "./behavior.js";
|
||||
|
||||
export interface NodeBehaviorBehaviorOptions<T = any> {
|
||||
property: T;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { CaptureType } from "../template";
|
||||
import { Behavior } from "./behavior";
|
||||
import { AttachedBehaviorDirective } from "./directive";
|
||||
import { CaptureType } from "../template.js";
|
||||
import { Behavior } from "./behavior.js";
|
||||
import { AttachedBehaviorDirective } from "./directive.js";
|
||||
|
||||
export class RefBehavior implements Behavior {
|
||||
constructor(private target: HTMLElement, private propertyName: string) {}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { CaptureType, SyntheticViewTemplate, ViewTemplate } from "../template";
|
||||
import { DOM } from "../dom";
|
||||
import { CaptureType, SyntheticViewTemplate, ViewTemplate } from "../template.js";
|
||||
import { DOM } from "../dom.js";
|
||||
import {
|
||||
ExecutionContext,
|
||||
Expression,
|
||||
Observable,
|
||||
ObservableExpression,
|
||||
} from "../observation/observable";
|
||||
import { HTMLView, SyntheticView } from "../view";
|
||||
import { Subscriber } from "../observation/notifier";
|
||||
import { ArrayObserver, enableArrayObservation } from "../observation/array-observer";
|
||||
import { Splice } from "../observation/array-change-records";
|
||||
import { Behavior } from "./behavior";
|
||||
import { Directive } from "./directive";
|
||||
} from "../observation/observable.js";
|
||||
import { HTMLView, SyntheticView } from "../view.js";
|
||||
import { Subscriber } from "../observation/notifier.js";
|
||||
import { ArrayObserver, enableArrayObservation } from "../observation/array-observer.js";
|
||||
import { Splice } from "../observation/array-change-records.js";
|
||||
import { Behavior } from "./behavior.js";
|
||||
import { Directive } from "./directive.js";
|
||||
|
||||
export interface RepeatOptions {
|
||||
positioning: boolean;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { CaptureType } from "../template";
|
||||
import { AttachedBehaviorDirective } from "./directive";
|
||||
import { NodeBehaviorBehaviorOptions, NodeObservationBehavior } from "./node-observation";
|
||||
import { CaptureType } from "../template.js";
|
||||
import { AttachedBehaviorDirective } from "./directive.js";
|
||||
import {
|
||||
NodeBehaviorBehaviorOptions,
|
||||
NodeObservationBehavior,
|
||||
} from "./node-observation.js";
|
||||
|
||||
export interface SlottedBehaviorOptions<T = any>
|
||||
extends NodeBehaviorBehaviorOptions<T>,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { DOM } from "../dom";
|
||||
import { CaptureType, SyntheticViewTemplate } from "../template";
|
||||
import { SyntheticView } from "../view";
|
||||
import { DOM } from "../dom.js";
|
||||
import { CaptureType, SyntheticViewTemplate } from "../template.js";
|
||||
import { SyntheticView } from "../view.js";
|
||||
import {
|
||||
ExecutionContext,
|
||||
Expression,
|
||||
ObservableExpression,
|
||||
} from "../observation/observable";
|
||||
import { Behavior } from "./behavior";
|
||||
import { Directive } from "./directive";
|
||||
} from "../observation/observable.js";
|
||||
import { Behavior } from "./behavior.js";
|
||||
import { Directive } from "./directive.js";
|
||||
|
||||
export class WhenBehavior implements Behavior {
|
||||
private view: SyntheticView | null = null;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Callable } from "./interfaces";
|
||||
import { Callable } from "./interfaces.js";
|
||||
const markerClass = `fast-${Math.random().toString(36).substring(7)}`;
|
||||
const updateQueue = [] as Callable[];
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ElementViewTemplate } from "./template";
|
||||
import { ElementStyles } from "./styles";
|
||||
import { AttributeConfiguration, AttributeDefinition } from "./attributes";
|
||||
import { ElementViewTemplate } from "./template.js";
|
||||
import { ElementStyles } from "./styles.js";
|
||||
import { AttributeConfiguration, AttributeDefinition } from "./attributes.js";
|
||||
|
||||
export class FASTElementDefinition {
|
||||
public constructor(
|
||||
|
|
|
@ -1,24 +1,39 @@
|
|||
import { AttributeDefinition } from "./attributes";
|
||||
import { Controller } from "./controller";
|
||||
import { Observable } from "./observation/observable";
|
||||
import { AttributeDefinition } from "./attributes.js";
|
||||
import { Controller } from "./controller.js";
|
||||
import { Observable } from "./observation/observable.js";
|
||||
import {
|
||||
fastDefinitions,
|
||||
FASTElementDefinition,
|
||||
getDefinition,
|
||||
PartialFASTElementDefinition,
|
||||
} from "./fast-definitions";
|
||||
} from "./fast-definitions.js";
|
||||
|
||||
const defaultShadowOptions: ShadowRootInit = { mode: "open" };
|
||||
const defaultElementOptions: ElementDefinitionOptions = {};
|
||||
|
||||
export interface FASTElement {
|
||||
$fastController: Controller;
|
||||
$emit(
|
||||
type: string,
|
||||
detail?: any,
|
||||
options?: Omit<CustomEventInit, "detail">
|
||||
): boolean | void;
|
||||
connectedCallback(): void;
|
||||
disconnectedCallback(): void;
|
||||
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
||||
function createFASTElement(BaseType: typeof HTMLElement) {
|
||||
return class FASTElement extends BaseType {
|
||||
function createFASTElement<T extends typeof HTMLElement>(
|
||||
BaseType: T
|
||||
): { new (): InstanceType<T> & FASTElement } {
|
||||
return class extends (BaseType as any) implements FASTElement {
|
||||
public $fastController!: Controller;
|
||||
|
||||
public constructor() {
|
||||
/* eslint-disable-next-line */
|
||||
super();
|
||||
Controller.forCustomElement(this);
|
||||
Controller.forCustomElement(this as any);
|
||||
}
|
||||
|
||||
public $emit(
|
||||
|
@ -44,18 +59,18 @@ function createFASTElement(BaseType: typeof HTMLElement) {
|
|||
): void {
|
||||
this.$fastController.onAttributeChangedCallback(name, oldValue, newValue);
|
||||
}
|
||||
};
|
||||
} as any;
|
||||
}
|
||||
|
||||
export const FASTElement = Object.assign(createFASTElement(HTMLElement), {
|
||||
from(BaseType: typeof HTMLElement) {
|
||||
from<TBase extends typeof HTMLElement>(BaseType: TBase) {
|
||||
return createFASTElement(BaseType);
|
||||
},
|
||||
|
||||
define<T extends Function>(
|
||||
Type: T,
|
||||
define<TType extends Function>(
|
||||
Type: TType,
|
||||
nameOrDef: string | PartialFASTElementDefinition = (Type as any).definition
|
||||
): T {
|
||||
): TType {
|
||||
if (typeof nameOrDef === "string") {
|
||||
nameOrDef = { name: nameOrDef };
|
||||
}
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
export * from "./template";
|
||||
export * from "./fast-element";
|
||||
export { FASTElementDefinition, PartialFASTElementDefinition } from "./fast-definitions";
|
||||
export * from "./attributes";
|
||||
export * from "./controller";
|
||||
export * from "./interfaces";
|
||||
export * from "./template-compiler";
|
||||
export * from "./styles";
|
||||
export * from "./view";
|
||||
export * from "./observation/observable";
|
||||
export * from "./observation/notifier";
|
||||
export * from "./dom";
|
||||
export * from "./directives/behavior";
|
||||
export * from "./directives/binding";
|
||||
export * from "./directives/directive";
|
||||
export * from "./directives/ref";
|
||||
export * from "./directives/when";
|
||||
export * from "./directives/repeat";
|
||||
export * from "./directives/slotted";
|
||||
export * from "./directives/children";
|
||||
export * from "./template.js";
|
||||
export * from "./fast-element.js";
|
||||
export {
|
||||
FASTElementDefinition,
|
||||
PartialFASTElementDefinition,
|
||||
} from "./fast-definitions.js";
|
||||
export * from "./attributes.js";
|
||||
export * from "./controller.js";
|
||||
export * from "./interfaces.js";
|
||||
export * from "./template-compiler.js";
|
||||
export * from "./styles.js";
|
||||
export * from "./view.js";
|
||||
export * from "./observation/observable.js";
|
||||
export * from "./observation/notifier.js";
|
||||
export * from "./dom.js";
|
||||
export * from "./directives/behavior.js";
|
||||
export * from "./directives/binding.js";
|
||||
export * from "./directives/directive.js";
|
||||
export * from "./directives/ref.js";
|
||||
export * from "./directives/when.js";
|
||||
export * from "./directives/repeat.js";
|
||||
export * from "./directives/slotted.js";
|
||||
export * from "./directives/children.js";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { emptyArray } from "../interfaces";
|
||||
import { emptyArray } from "../interfaces.js";
|
||||
|
||||
export interface Splice {
|
||||
index: number;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { DOM } from "../dom";
|
||||
import { Observable } from "./observable";
|
||||
import { SubscriberCollection } from "./notifier";
|
||||
import { DOM } from "../dom.js";
|
||||
import { Observable } from "./observable.js";
|
||||
import { SubscriberCollection } from "./notifier.js";
|
||||
import {
|
||||
calcSplices,
|
||||
newSplice,
|
||||
projectArraySplices,
|
||||
Splice,
|
||||
} from "./array-change-records";
|
||||
} from "./array-change-records.js";
|
||||
|
||||
let arrayObservationEnabled = false;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DOM } from "../dom";
|
||||
import { Notifier, PropertyChangeNotifier } from "./notifier";
|
||||
import { DOM } from "../dom.js";
|
||||
import { Notifier, PropertyChangeNotifier } from "./notifier.js";
|
||||
|
||||
const notifierLookup = new WeakMap<any, Notifier>();
|
||||
const accessorLookup = new WeakMap<any, Accessor[]>();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Behavior } from "./directives/behavior";
|
||||
import { Behavior } from "./directives/behavior.js";
|
||||
|
||||
export interface StyleTarget {
|
||||
adoptedStyleSheets?: CSSStyleSheet[];
|
||||
|
@ -101,7 +101,7 @@ export class AdoptedStyleSheetsStyles extends ElementStyles {
|
|||
public removeStylesFrom(target: StyleTarget): void {
|
||||
const sourceSheets = this.styleSheets;
|
||||
target.adoptedStyleSheets = target.adoptedStyleSheets!.filter(
|
||||
(x: CSSStyleSheet) => !sourceSheets.includes(x)
|
||||
(x: CSSStyleSheet) => sourceSheets.indexOf(x) !== -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -140,8 +140,8 @@ export class StyleElementStyles extends ElementStyles {
|
|||
public removeStylesFrom(target: StyleTarget): void {
|
||||
const styles = target.querySelectorAll(`.${this.styleClass}`);
|
||||
|
||||
for (const style of styles) {
|
||||
target.removeChild(style);
|
||||
for (let i = 0, ii = styles.length; i < ii; ++i) {
|
||||
target.removeChild(styles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { BehaviorFactory } from "./directives/behavior";
|
||||
import { DOM } from "./dom";
|
||||
import { BindingDirective } from "./directives/binding";
|
||||
import { AttachedBehaviorDirective, Directive } from "./directives/directive";
|
||||
import { ExecutionContext } from "./observation/observable";
|
||||
import { BehaviorFactory } from "./directives/behavior.js";
|
||||
import { DOM } from "./dom.js";
|
||||
import { BindingDirective } from "./directives/binding.js";
|
||||
import { AttachedBehaviorDirective, Directive } from "./directives/directive.js";
|
||||
import { ExecutionContext } from "./observation/observable.js";
|
||||
|
||||
type InlineDirective = BindingDirective | AttachedBehaviorDirective;
|
||||
const compilationContext = { locatedDirectives: 0, targetIndex: -1 };
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import chai from "chai";
|
||||
import { html, ViewTemplate } from "./template.js";
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
describe("The html tag template helper", () => {
|
||||
it("transforms a string into a ViewTemplate.", () => {
|
||||
const template = html`This is a simple HTML string.`;
|
||||
expect(template).instanceOf(ViewTemplate);
|
||||
});
|
||||
});
|
|
@ -1,14 +1,14 @@
|
|||
import { compileTemplate } from "./template-compiler";
|
||||
import { ElementView, HTMLView, SyntheticView } from "./view";
|
||||
import { DOM } from "./dom";
|
||||
import { Behavior, BehaviorFactory } from "./directives/behavior";
|
||||
import { Directive } from "./directives/directive";
|
||||
import { BindingDirective } from "./directives/binding";
|
||||
import { compileTemplate } from "./template-compiler.js";
|
||||
import { ElementView, HTMLView, SyntheticView } from "./view.js";
|
||||
import { DOM } from "./dom.js";
|
||||
import { Behavior, BehaviorFactory } from "./directives/behavior.js";
|
||||
import { Directive } from "./directives/directive.js";
|
||||
import { BindingDirective } from "./directives/binding.js";
|
||||
import {
|
||||
defaultExecutionContext,
|
||||
ExecutionContext,
|
||||
Expression,
|
||||
defaultExecutionContext,
|
||||
} from "./observation/observable";
|
||||
} from "./observation/observable.js";
|
||||
|
||||
export interface ElementViewTemplate {
|
||||
create(host: Element): ElementView;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Behavior } from "./directives/behavior";
|
||||
import { ExecutionContext } from "./observation/observable";
|
||||
import { Behavior } from "./directives/behavior.js";
|
||||
import { ExecutionContext } from "./observation/observable.js";
|
||||
|
||||
/**
|
||||
* Represents a collection of DOM nodes which can be bound to a data source.
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"baseUrl": ".",
|
||||
"declarationDir": "dist/dts",
|
||||
"outDir": "dist/esm",
|
||||
"strictNullChecks": true,
|
||||
"target": "es2015"
|
||||
"target": "es2015",
|
||||
"module": "ESNext",
|
||||
"types": [
|
||||
"mocha",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES2015"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
"include": ["src"]
|
||||
}
|
2036
yarn.lock
2036
yarn.lock
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче