Merge branch 'next' of https://github.com/impinball/mithril.js into speed
(Update topic branch)
This commit is contained in:
commit
565f9cf334
7 changed files with 852 additions and 131 deletions
|
|
@ -122,4 +122,4 @@ where:
|
|||
|
||||
- **Boolean forceRecreation**
|
||||
|
||||
If set to true, rendering a new virtual tree will completely overwrite an existing one without attempting to diff against it
|
||||
If set to true, rendering a new virtual tree will completely overwrite an existing one without attempting to diff against it
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
## Web Services
|
||||
|
||||
Mithril provides a high-level utility for working with web services, which allows writing asynchronous code relatively procedurally.
|
||||
Mithril allows writing asynchronous code in a procedural way through a high-level utility for working with web services.
|
||||
|
||||
It provides a number of useful features out of the box:
|
||||
This utility provides a number of useful features out of the box:
|
||||
|
||||
- The ability to get an early reference to a container that will hold the asynchronous response
|
||||
- The ability to queue operations to be performed after the asynchronous request completes
|
||||
|
|
|
|||
860
mithril.d.ts
vendored
860
mithril.d.ts
vendored
|
|
@ -1,166 +1,884 @@
|
|||
//Mithril type definitions for Typescript
|
||||
// Mithril type definitions for Typescript
|
||||
|
||||
/**
|
||||
* This is the module containing all the types/declarations/etc. for Mithril
|
||||
*/
|
||||
declare module _mithril {
|
||||
interface MithrilStatic {
|
||||
/**
|
||||
* Creates a virtual element for use with m.render, m.mount, etc.
|
||||
*
|
||||
* @param selector A simple CSS selector. May include SVG tags. Nested
|
||||
* selectors are not supported.
|
||||
* @param attributes Attributes to add. Any DOM attribute may be used
|
||||
* as an attribute, although innerHTML and the like may be overwritten
|
||||
* silently.
|
||||
* @param children Child elements, components, and text to add.
|
||||
* @return A virtual element.
|
||||
*
|
||||
* @see m.render
|
||||
* @see m.mount
|
||||
* @see m.component
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
selector: string,
|
||||
attributes: MithrilAttributes,
|
||||
...children: Array<string |
|
||||
MithrilVirtualElement<T> |
|
||||
MithrilComponent<T>>
|
||||
): MithrilVirtualElement<T>;
|
||||
|
||||
<T extends MithrilController>(selector: string, attributes: MithrilAttributes, ...children: Array<string|MithrilVirtualElement|MithrilComponent<T>>): MithrilVirtualElement;
|
||||
<T extends MithrilController>(selector: string, ...children: Array<string|MithrilVirtualElement|MithrilComponent<T>>): MithrilVirtualElement;
|
||||
/**
|
||||
* Creates a virtual element for use with m.render, m.mount, etc.
|
||||
*
|
||||
* @param selector A simple CSS selector. Nested selectors are not
|
||||
* supported.
|
||||
* @param children Child elements, components, and text to add.
|
||||
* @return A virtual element.
|
||||
*
|
||||
* @see m.render
|
||||
* @see m.mount
|
||||
* @see m.component
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
selector: string,
|
||||
...children: Array<string |
|
||||
MithrilVirtualElement<T> |
|
||||
MithrilComponent<T>>
|
||||
): MithrilVirtualElement<T>;
|
||||
|
||||
prop<T>(promise: MithrilPromise<T>) : MithrilPromiseProperty<T>;
|
||||
prop<T>(value: T): MithrilProperty<T>;
|
||||
prop(): MithrilProperty<Object>; // might be that this should be Property<any>
|
||||
/**
|
||||
* Initializes a component for use with m.render, m.mount, etc.
|
||||
* Shorthand for m.component.
|
||||
*
|
||||
* @param selector A component.
|
||||
* @param args Arguments to optionally pass to the component.
|
||||
* @return A component.
|
||||
*
|
||||
* @see m.render
|
||||
* @see m.mount
|
||||
* @see m.component
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
component: MithrilComponent<T>,
|
||||
...args: any[]
|
||||
): MithrilComponent<T>;
|
||||
|
||||
withAttr(property: string, callback: (value: any) => void): (e: MithrilEvent) => any;
|
||||
/**
|
||||
* Creates a getter-setter function that wraps a Mithril promise. Useful
|
||||
* for uniform data access, m.withAttr, etc.
|
||||
*
|
||||
* @param promise A thennable to initialize the property with. It may
|
||||
* optionally be a Mithril promise.
|
||||
* @return A getter-setter function wrapping the promise.
|
||||
*
|
||||
* @see m.withAttr
|
||||
*/
|
||||
prop<T>(promise: Thennable<T>) : MithrilPromiseProperty<T>;
|
||||
|
||||
module<T extends MithrilController>(rootElement: Node, component: MithrilComponent<T>): T;
|
||||
module<T extends MithrilController>(rootElement: Node): T;
|
||||
mount<T extends MithrilController>(rootElement: Node, component: MithrilComponent<T>): T;
|
||||
mount<T extends MithrilController>(rootElement: Node): T;
|
||||
/**
|
||||
* Creates a getter-setter function that wraps a simple value. Useful
|
||||
* for uniform data access, m.withAttr, etc.
|
||||
*
|
||||
* @param value A value to initialize the property with
|
||||
* @return A getter-setter function wrapping the value.
|
||||
*
|
||||
* @see m.withAttr
|
||||
*/
|
||||
prop<T>(value: T): MithrilBasicProperty<T>;
|
||||
|
||||
component<T extends MithrilController>(component: MithrilComponent<T>, ...args: Array<any>): MithrilComponent<T>
|
||||
|
||||
trust(html: string): string;
|
||||
/**
|
||||
* Creates a getter-setter function that wraps a simple value. Useful
|
||||
* for uniform data access, m.withAttr, etc.
|
||||
*
|
||||
* @return A getter-setter function wrapping the value.
|
||||
*
|
||||
* @see m.withAttr
|
||||
*/
|
||||
prop<T>(): MithrilBasicProperty<T>;
|
||||
|
||||
render(rootElement: Element|HTMLDocument): void;
|
||||
render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement, forceRecreation?: boolean): void;
|
||||
render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement[], forceRecreation?: boolean): void;
|
||||
/**
|
||||
* Returns a event handler that can be bound to an element, firing with
|
||||
* the specified property.
|
||||
*
|
||||
* @param property The property to get from the event.
|
||||
* @param callback The handler to use the value from the event.
|
||||
* @return A function suitable for listening to an event.
|
||||
*/
|
||||
withAttr(
|
||||
property: string,
|
||||
callback: (value: any) => void
|
||||
): (e: Event) => any;
|
||||
|
||||
/**
|
||||
* @deprecated Use m.mount instead
|
||||
*/
|
||||
module<T extends MithrilController>(
|
||||
rootElement: Node,
|
||||
component: MithrilComponent<T>
|
||||
): T;
|
||||
|
||||
/**
|
||||
* Mounts a component to a base DOM node.
|
||||
*
|
||||
* @param rootElement The base node.
|
||||
* @param component The component to mount.
|
||||
* @return An instance of the top-level component's controller
|
||||
*/
|
||||
mount<T extends MithrilController>(
|
||||
rootElement: Node,
|
||||
component: MithrilComponent<T>
|
||||
): T;
|
||||
|
||||
/**
|
||||
* Initializes a component for use with m.render, m.mount, etc.
|
||||
*
|
||||
* @param selector A component.
|
||||
* @param args Arguments to optionally pass to the component.
|
||||
* @return A component.
|
||||
*
|
||||
* @see m.render
|
||||
* @see m.mount
|
||||
* @see m
|
||||
*/
|
||||
component<T extends MithrilController>(
|
||||
component: MithrilComponent<T>,
|
||||
...args: any[]
|
||||
): MithrilComponent<T>;
|
||||
|
||||
/**
|
||||
* Trust this string of HTML.
|
||||
*
|
||||
* @param html The HTML to trust
|
||||
* @return A String object instance with an added internal flag to mark
|
||||
* it as trusted.
|
||||
*/
|
||||
trust(html: string): MithrilTrustedString;
|
||||
|
||||
/**
|
||||
* Render a virtual DOM tree.
|
||||
*
|
||||
* @param rootElement The base element/node to render the tree from.
|
||||
* @param children One or more child nodes to add to the tree.
|
||||
* @param forceRecreation If true, overwrite the entire tree without
|
||||
* diffing against it.
|
||||
*/
|
||||
render<T extends MithrilController>(
|
||||
rootElement: Element,
|
||||
children: MithrilVirtualElement<T>|MithrilVirtualElement<T>[],
|
||||
forceRecreation?: boolean
|
||||
): void;
|
||||
|
||||
redraw: {
|
||||
/**
|
||||
* Force a redraw the active component. It redraws asynchronously by
|
||||
* default to allow for simultaneous events to run before redrawing,
|
||||
* such as the event combination keypress + input frequently used for
|
||||
* input.
|
||||
*
|
||||
* @param force If true, redraw synchronously.
|
||||
*/
|
||||
(force?: boolean): void;
|
||||
strategy: MithrilProperty<string>;
|
||||
|
||||
strategy: {
|
||||
/**
|
||||
* Gets the current redraw strategy, which returns one of the
|
||||
* following:
|
||||
*
|
||||
* "all" - recreates the DOM tree from scratch
|
||||
* "diff" - recreates the DOM tree from scratch
|
||||
* "none" - leaves the DOM tree intact
|
||||
*
|
||||
* This is useful for event handlers, which may want to cancel
|
||||
* the next redraw if the event doesn't update the UI.
|
||||
*
|
||||
* @return The current strategy
|
||||
*/
|
||||
(): string;
|
||||
|
||||
/**
|
||||
* Sets the current redraw strategy. The parameter must be one of
|
||||
* the following values:
|
||||
*
|
||||
* "all" - recreates the DOM tree from scratch
|
||||
* "diff" - recreates the DOM tree from scratch
|
||||
* "none" - leaves the DOM tree intact
|
||||
*
|
||||
* This is useful for event handlers, which may want to cancel
|
||||
* the next redraw if the event doesn't update the UI.
|
||||
*
|
||||
* @param value The value to set
|
||||
* @return The new strategy
|
||||
*/
|
||||
(value: string): string;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Implementation detail - it's a MithrilBasicProperty instance
|
||||
*/
|
||||
toJSON(): string;
|
||||
}
|
||||
}
|
||||
|
||||
route: {
|
||||
<T extends MithrilController>(rootElement: HTMLDocument, defaultRoute: string, routes: MithrilRoutes<T>): void;
|
||||
<T extends MithrilController>(rootElement: Element, defaultRoute: string, routes: MithrilRoutes<T>): void;
|
||||
/**
|
||||
* Enable routing, mounting a controller based on the route. It
|
||||
* automatically mounts the components for you, starting with the one
|
||||
* specified by the default route.
|
||||
*
|
||||
* @param rootElement The element to mount the active controller to.
|
||||
* @param defaultRoute The route to start with.
|
||||
* @param routes A key-value mapping of pathname to controller.
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
rootElement: Element,
|
||||
defaultRoute: string,
|
||||
routes: MithrilRoutes<T>
|
||||
): void;
|
||||
|
||||
(element: Element, isInitialized: boolean, context: Object, vdom: Object): void;
|
||||
/**
|
||||
* This allows m.route to be used as the `config` attribute for a
|
||||
* virtual element, particularly useful for cases like this:
|
||||
*
|
||||
* ```ts
|
||||
* // Note that the '#' is not required in `href`, thanks to the
|
||||
* `config` setting.
|
||||
* m("a[href='/dashboard/alicesmith']", {config: m.route});
|
||||
* ```
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
element: Element,
|
||||
isInitialized: boolean,
|
||||
context?: MithrilContext,
|
||||
vdom?: MithrilVirtualElement<T>
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Programmatically redirect to another route.
|
||||
*
|
||||
* @param path The route to go to.
|
||||
* @param params Parameters to pass as a query string.
|
||||
* @param shouldReplaceHistory Whether to replace the current history
|
||||
* instead of adding a new one.
|
||||
*/
|
||||
(path: string, params?: any, shouldReplaceHistory?: boolean): void;
|
||||
|
||||
/**
|
||||
* Gets the current route.
|
||||
*
|
||||
* @return The current route.
|
||||
*/
|
||||
(): string;
|
||||
|
||||
/**
|
||||
* Gets a route parameter.
|
||||
*
|
||||
* @param key The key to get.
|
||||
* @return The value associated with the parameter key.
|
||||
*/
|
||||
param(key: string): string;
|
||||
|
||||
/**
|
||||
* The current routing mode. This may be changed before calling
|
||||
* m.route to change the part of the URL used to perform the routing.
|
||||
*
|
||||
* The value can be set to one of the following, defaulting to
|
||||
* "hash":
|
||||
*
|
||||
* "search" - Uses the query string. This allows for named anchors to
|
||||
* work on the page, but changes cause IE8 and lower to refresh the
|
||||
* page.
|
||||
*
|
||||
* "hash" - Uses the hash. This is the only routing mode that does
|
||||
* not cause page refreshes on any browser, but it does not support
|
||||
* named anchors.
|
||||
*
|
||||
* "pathname" - Uses the URL pathname. This requires server-side
|
||||
* setup to support bookmarking and page refreshes. It always causes
|
||||
* page refreshes on IE8 and lower. Note that this requires that the
|
||||
* application to be run from the root of the URL.
|
||||
*/
|
||||
mode: string;
|
||||
|
||||
/**
|
||||
* Serialize an object into a query string.
|
||||
*
|
||||
* @param data The data to serialize.
|
||||
* @return The serialized string.
|
||||
*/
|
||||
buildQueryString(data: Object): String
|
||||
|
||||
/**
|
||||
* Parse a query string into an object.
|
||||
*
|
||||
* @param data The data to parse.
|
||||
* @return The parsed object data.
|
||||
*/
|
||||
parseQueryString(data: String): Object
|
||||
}
|
||||
|
||||
request<T>(options: MithrilXHROptions): MithrilPromise<T>;
|
||||
/**
|
||||
* Send a request to a server to server. Note that the `url` option is
|
||||
* required.
|
||||
*
|
||||
* @param options The options to use
|
||||
* @return A promise to the returned data for "GET" requests, or a void
|
||||
* promise for any other request type.
|
||||
*
|
||||
* @see MithrilXHROptions for the available options.
|
||||
*/
|
||||
request<T>(options: MithrilXHROptions<T>): MithrilPromise<T>;
|
||||
|
||||
deferred: {
|
||||
onerror(e: Error): void;
|
||||
/**
|
||||
* Create a Mithril deferred object. It behaves synchronously if
|
||||
* possible, an intentional deviation from Promises/A+. Note that
|
||||
* deferreds are completely separate from the redrawing system, and
|
||||
* never trigger a redraw on their own.
|
||||
*
|
||||
* @return A new Mithril deferred instance.
|
||||
*
|
||||
* @see m.deferred.onerror for the error callback called for Error
|
||||
* subclasses
|
||||
*/
|
||||
<T>(): MithrilDeferred<T>;
|
||||
|
||||
/**
|
||||
* A callback for all uncaught native Error subclasses in deferreds.
|
||||
* This defaults to synchronously rethrowing all errors, a deviation
|
||||
* from Promises/A+, but the behavior is configurable. To restore
|
||||
* Promises/A+-compatible behavior. simply set this to a no-op.
|
||||
*/
|
||||
onerror(e: Error): void;
|
||||
}
|
||||
|
||||
sync<T>(promises: MithrilPromise<T>[]): MithrilPromise<T[]>;
|
||||
/**
|
||||
* Takes a list of promises or thennables and returns a Mithril promise
|
||||
* that resolves once all in the list are resolved, or rejects if any of
|
||||
* them reject.
|
||||
*
|
||||
* @param promises A list of promises to try to resolve.
|
||||
* @return A promise that resolves to all the promises if all resolve, or
|
||||
* rejects with the error contained in the first rejection.
|
||||
*/
|
||||
sync<T>(promises: Thennable<T>[]): MithrilPromise<T[]>;
|
||||
|
||||
/**
|
||||
* Use this and endComputation if your views aren't redrawing after
|
||||
* calls to third-party libraries. For integrating asynchronous code,
|
||||
* this should be called before any asynchronous work is done. For
|
||||
* synchronous code, this should be called at the beginning of the
|
||||
* problematic segment. Note that these calls must be balanced, much like
|
||||
* braces and parentheses. This is mostly used internally. Prefer
|
||||
* m.redraw where possible, especially when making repeated calls.
|
||||
*
|
||||
* @see endComputation
|
||||
* @see m.render
|
||||
*/
|
||||
startComputation(): void;
|
||||
|
||||
/**
|
||||
* Use startComputation and this if your views aren't redrawing after
|
||||
* calls to third-party libraries. For integrating asynchronous code,
|
||||
* this should be called after all asynchronous work completes. For
|
||||
* synchronous code, this should be called at the end of the problematic
|
||||
* segment. Note that these calls must be balanced, much like braces and
|
||||
* parentheses. This is mostly used internally. Prefer m.redraw where
|
||||
* possible, especially when making repeated calls.
|
||||
*
|
||||
* @see startComputation
|
||||
* @see m.render
|
||||
*/
|
||||
endComputation(): void;
|
||||
|
||||
// For test suite
|
||||
deps: {
|
||||
(mockWindow: Window): Window;
|
||||
factory: Object;
|
||||
}
|
||||
|
||||
/**
|
||||
* This overwrites the internal version of window used by Mithril.
|
||||
* It's mostly useful for testing, and is also used internally by
|
||||
* Mithril to test itself. By default Mithril uses `window` for the
|
||||
* dependency.
|
||||
*
|
||||
* @param mockWindow The mock to use for the window.
|
||||
* @return The mock that was passed in.
|
||||
*/
|
||||
deps(mockWindow: Window): Window;
|
||||
}
|
||||
|
||||
interface MithrilVirtualElement {
|
||||
interface MithrilTrustedString extends String {
|
||||
/** @private Implementation detail. Don't depend on it. */
|
||||
$trusted: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface for a virtual element. It's best to consider this immutable
|
||||
* for most use cases.
|
||||
*
|
||||
* @see m
|
||||
*/
|
||||
interface MithrilVirtualElement<T extends MithrilController> {
|
||||
/**
|
||||
* A key to optionally associate with this element.
|
||||
*/
|
||||
key?: number;
|
||||
|
||||
/**
|
||||
* The tag name of this element.
|
||||
*/
|
||||
tag?: string;
|
||||
|
||||
/**
|
||||
* The attributes of this element.
|
||||
*/
|
||||
attrs?: MithrilAttributes;
|
||||
children?: any[];
|
||||
|
||||
/**
|
||||
* The children of this element.
|
||||
*/
|
||||
children?: Array<string|MithrilVirtualElement<T>|MithrilComponent<T>>;
|
||||
}
|
||||
|
||||
// Configuration function for an element
|
||||
/**
|
||||
* An event passed by Mithril to unload event handlers.
|
||||
*/
|
||||
interface MithrilEvent {
|
||||
/**
|
||||
* Prevent the default behavior of scrolling the page and updating the
|
||||
* URL on next route change.
|
||||
*/
|
||||
preventDefault(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A context object for configuration functions.
|
||||
*
|
||||
* @see MithrilElementConfig
|
||||
*/
|
||||
interface MithrilContext {
|
||||
/**
|
||||
* A function to call when the node is unloaded. Useful for cleanup.
|
||||
*/
|
||||
onunload?(): any;
|
||||
|
||||
/**
|
||||
* Set true if the backing DOM node needs to be retained between route
|
||||
* changes if possible. Set false if this node needs to be recreated
|
||||
* every single time, regardless of how "different" it is.
|
||||
*/
|
||||
retain?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a callback function for a virtual element's config
|
||||
* attribute. It's a low-level function useful for extra cleanup after
|
||||
* removal from the tree, storing instances of third-party classes that
|
||||
* need to be associated with the DOM, etc.
|
||||
*
|
||||
* @see MithrilAttributes
|
||||
* @see MithrilContext
|
||||
*/
|
||||
interface MithrilElementConfig {
|
||||
(element: Element, isInitialized: boolean, context?: any, vdom?: MithrilVirtualElement): void;
|
||||
/**
|
||||
* A callback function for a virtual element's config attribute.
|
||||
*
|
||||
* @param element The associated DOM element.
|
||||
* @param isInitialized Whether this is the first call for the virtual
|
||||
* element or not.
|
||||
* @param context The associated context for this element.
|
||||
* @param vdom The associated virtual element.
|
||||
*/
|
||||
<T extends MithrilController>(
|
||||
element: Element,
|
||||
isInitialized: boolean,
|
||||
context: MithrilContext,
|
||||
vdom: MithrilVirtualElement<T>
|
||||
): void;
|
||||
}
|
||||
|
||||
// Attributes on a virtual element
|
||||
/**
|
||||
* This represents the attributes available for configuring virtual elements,
|
||||
* beyond the applicable DOM attributes.
|
||||
*
|
||||
* @see m
|
||||
*/
|
||||
interface MithrilAttributes {
|
||||
title?: string;
|
||||
/**
|
||||
* The class name(s) for this virtual element, as a space-separated list.
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* The class name(s) for this virtual element, as a space-separated list.
|
||||
*/
|
||||
class?: string;
|
||||
|
||||
/**
|
||||
* A custom, low-level configuration in case this element needs special
|
||||
* cleanup after removal from the tree.
|
||||
*
|
||||
* @see MithrilElementConfig
|
||||
*/
|
||||
config?: MithrilElementConfig;
|
||||
}
|
||||
|
||||
// Defines the subset of Event that Mithril needs
|
||||
interface MithrilEvent {
|
||||
currentTarget: Element;
|
||||
}
|
||||
|
||||
/**
|
||||
* The basis of a Mithril controller instance.
|
||||
*/
|
||||
interface MithrilController {
|
||||
onunload?(evt: Event): any;
|
||||
/**
|
||||
* An optional handler to call when the associated virtual element is
|
||||
* destroyed.
|
||||
*
|
||||
* @param evt An associated event.
|
||||
*/
|
||||
onunload?(evt: MithrilEvent): any;
|
||||
}
|
||||
|
||||
interface MithrilControllerFunction extends MithrilController {
|
||||
(): any;
|
||||
/**
|
||||
* This represents a controller function.
|
||||
*
|
||||
* @see MithrilControllerConstructor
|
||||
*/
|
||||
interface MithrilControllerFunction<T extends MithrilController> {
|
||||
(): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a controller constructor.
|
||||
*
|
||||
* @see MithrilControllerFunction
|
||||
*/
|
||||
interface MithrilControllerConstructor<T extends MithrilController> {
|
||||
new(): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a view factory.
|
||||
*/
|
||||
interface MithrilView<T extends MithrilController> {
|
||||
(ctrl: T): string|MithrilVirtualElement;
|
||||
/**
|
||||
* Creates a view out of virtual elements.
|
||||
*/
|
||||
(ctrl: T): MithrilVirtualElement<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a Mithril component.
|
||||
*
|
||||
* @see m
|
||||
* @see m.component
|
||||
*/
|
||||
interface MithrilComponent<T extends MithrilController> {
|
||||
controller: MithrilControllerFunction|{ new(): T };
|
||||
view: MithrilView<T>;
|
||||
/**
|
||||
* The component's controller.
|
||||
*
|
||||
* @see m.component
|
||||
*/
|
||||
controller: MithrilControllerFunction<T> |
|
||||
MithrilControllerConstructor<T>;
|
||||
|
||||
/**
|
||||
* Creates a view out of virtual elements.
|
||||
*
|
||||
* @see m.component
|
||||
*/
|
||||
view(ctrl: T): MithrilVirtualElement<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the base interface for property getter-setters
|
||||
*
|
||||
* @see m.prop
|
||||
*/
|
||||
interface MithrilProperty<T> {
|
||||
/**
|
||||
* Gets the contained value.
|
||||
*
|
||||
* @return The contained value.
|
||||
*/
|
||||
(): T;
|
||||
|
||||
/**
|
||||
* Sets the contained value.
|
||||
*
|
||||
* @param value The new value to set.
|
||||
* @return The newly set value.
|
||||
*/
|
||||
(value: T): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a non-promise getter-setter functions.
|
||||
*
|
||||
* @see m.prop which returns objects that implement this interface.
|
||||
*/
|
||||
interface MithrilBasicProperty<T> extends MithrilProperty<T> {
|
||||
/**
|
||||
* Makes this serializable to JSON.
|
||||
*/
|
||||
toJSON(): T;
|
||||
}
|
||||
|
||||
interface MithrilPromiseProperty<T> extends MithrilPromise<T> {
|
||||
(): T;
|
||||
(value: T): T;
|
||||
toJSON(): T;
|
||||
/**
|
||||
* This represents a promise getter-setter function.
|
||||
*
|
||||
* @see m.prop which returns objects that implement this interface.
|
||||
*/
|
||||
interface MithrilPromiseProperty<T> extends MithrilPromise<T>,
|
||||
MithrilProperty<MithrilPromise<T>> {
|
||||
/**
|
||||
* Gets the contained promise.
|
||||
*
|
||||
* @return The contained value.
|
||||
*/
|
||||
(): MithrilPromise<T>;
|
||||
|
||||
/**
|
||||
* Sets the contained promise.
|
||||
*
|
||||
* @param value The new value to set.
|
||||
* @return The newly set value.
|
||||
*/
|
||||
(value: MithrilPromise<T>): MithrilPromise<T>;
|
||||
|
||||
/**
|
||||
* Sets the contained wrapped value.
|
||||
*
|
||||
* @param value The new value to set.
|
||||
* @return The newly set value.
|
||||
*/
|
||||
(value: T): MithrilPromise<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a key-value mapping linking routes to components.
|
||||
*/
|
||||
interface MithrilRoutes<T extends MithrilController> {
|
||||
/**
|
||||
* The key represents the route. The value represents the corresponding
|
||||
* component.
|
||||
*/
|
||||
[key: string]: MithrilComponent<T>;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This represents a Mithril deferred object.
|
||||
*/
|
||||
interface MithrilDeferred<T> {
|
||||
/**
|
||||
* Resolve this deferred's promise with a value.
|
||||
*
|
||||
* @param value The value to resolve the promise with.
|
||||
*/
|
||||
resolve(value?: T): void;
|
||||
reject(value?: any): void;
|
||||
|
||||
/**
|
||||
* Reject this deferred with an error.
|
||||
*
|
||||
* @param value The reason for rejecting the promise.
|
||||
*/
|
||||
reject(reason?: any): void;
|
||||
|
||||
/**
|
||||
* The backing promise.
|
||||
*
|
||||
* @see MithrilPromise
|
||||
*/
|
||||
promise: MithrilPromise<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a thennable success callback.
|
||||
*/
|
||||
interface MithrilSuccessCallback<T, U> {
|
||||
(value: T): U;
|
||||
(value: T): MithrilPromise<U>;
|
||||
(value: T): U | Thennable<U>;
|
||||
}
|
||||
|
||||
interface MithrilErrorCallback<U> {
|
||||
(value: Error): U;
|
||||
(value: string): U;
|
||||
/**
|
||||
* This represents a thennable error callback.
|
||||
*/
|
||||
interface MithrilErrorCallback<T> {
|
||||
(value: Error): T | Thennable<T>;
|
||||
}
|
||||
|
||||
interface MithrilPromise<T> {
|
||||
(): T;
|
||||
(value: T): T;
|
||||
then<U>(success: (value: T) => U): MithrilPromise<U>;
|
||||
then<U>(success: (value: T) => MithrilPromise<U>): MithrilPromise<U>;
|
||||
then<U,V>(success: (value: T) => U, error: (value: Error) => V): MithrilPromise<U>|MithrilPromise<V>;
|
||||
then<U,V>(success: (value: T) => MithrilPromise<U>, error: (value: Error) => V): MithrilPromise<U>|MithrilPromise<V>;
|
||||
/**
|
||||
* This represents a thennable.
|
||||
*/
|
||||
interface Thennable<T> {
|
||||
then<U>(success: (value: T) => U): Thennable<U>;
|
||||
then<U,V>(success: (value: T) => U, error: (value: Error) => V): Thennable<U>|Thennable<V>;
|
||||
catch?: <U>(error: (value: Error) => U) => Thennable<U>;
|
||||
}
|
||||
interface MithrilXHROptions {
|
||||
|
||||
/**
|
||||
* This represents a Mithril promise object.
|
||||
*/
|
||||
interface MithrilPromise<T> extends Thennable<T>, MithrilProperty<MithrilPromise<T>> {
|
||||
/**
|
||||
* Chain this promise with a simple success callback, propogating
|
||||
* rejections.
|
||||
*
|
||||
* @param success The callback to call when the promise is resolved.
|
||||
* @return The chained promise.
|
||||
*/
|
||||
then<U>(success: MithrilSuccessCallback<T,U>): MithrilPromise<U>;
|
||||
|
||||
/**
|
||||
* Chain this promise with a success callback and error callback, without
|
||||
* propogating rejections.
|
||||
*
|
||||
* @param success The callback to call when the promise is resolved.
|
||||
* @param error The callback to call when the promise is rejected.
|
||||
* @return The chained promise.
|
||||
*/
|
||||
then<U, V>(
|
||||
success: MithrilSuccessCallback<T, U>,
|
||||
error: MithrilErrorCallback<V>
|
||||
): MithrilPromise<U> | MithrilPromise<V>;
|
||||
|
||||
/**
|
||||
* Chain this promise with a single error callback, without propogating
|
||||
* rejections.
|
||||
*
|
||||
* @param error The callback to call when the promise is rejected.
|
||||
* @return The chained promise.
|
||||
*/
|
||||
catch<U>(error: MithrilErrorCallback<U>): MithrilPromise<T> |
|
||||
MithrilPromise<U>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents the available options for configuring m.request.
|
||||
*
|
||||
* @see m.request
|
||||
*/
|
||||
interface MithrilXHROptions<T> {
|
||||
/**
|
||||
* This represents the HTTP method used, one of the following:
|
||||
*
|
||||
* - "GET" (default)
|
||||
* - "POST"
|
||||
* - "PUT"
|
||||
* - "DELETE"
|
||||
* - "HEAD"
|
||||
* - "OPTIONS"
|
||||
*/
|
||||
method?: string;
|
||||
|
||||
/**
|
||||
* The URL to send the request to.
|
||||
*/
|
||||
url: string;
|
||||
|
||||
/**
|
||||
* The username for HTTP authentication.
|
||||
*/
|
||||
user?: string;
|
||||
|
||||
/**
|
||||
* The password for HTTP authentication.
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* The data to be sent. It's automatically serialized in the right format
|
||||
* depending on the method (with exception of HTML5 FormData), and put in
|
||||
* the appropriate section of the request.
|
||||
*/
|
||||
data?: any;
|
||||
|
||||
/**
|
||||
* Whether to run it in the background, i.e. true if it doesn't affect
|
||||
* template rendering.
|
||||
*/
|
||||
background?: boolean;
|
||||
unwrapSuccess?(data: any): any;
|
||||
unwrapError?(data: any): any;
|
||||
|
||||
/**
|
||||
* Set an initial value while the request is working, to populate the
|
||||
* promise getter-setter.
|
||||
*/
|
||||
initialValue?: T;
|
||||
|
||||
/**
|
||||
* An optional preprocessor function to unwrap a successful response, in
|
||||
* case the response contains metadata wrapping the data.
|
||||
*
|
||||
* @param data The data to unwrap.
|
||||
* @return The unwrapped result.
|
||||
*/
|
||||
unwrapSuccess?(data: any): T;
|
||||
|
||||
/**
|
||||
* An optional preprocessor function to unwrap an unsuccessful response,
|
||||
* in case the response contains metadata wrapping the data.
|
||||
*
|
||||
* @param data The data to unwrap.
|
||||
* @return The unwrapped result.
|
||||
*/
|
||||
unwrapError?(data: any): T;
|
||||
|
||||
/**
|
||||
* An optional function to serialize the data. This defaults to
|
||||
* `JSON.stringify`.
|
||||
*
|
||||
* @param dataToSerialize The data to serialize.
|
||||
* @return The serialized form as a string.
|
||||
*/
|
||||
serialize?(dataToSerialize: any): string;
|
||||
|
||||
/**
|
||||
* An optional function to deserialize the data. This defaults to
|
||||
* `JSON.parse`.
|
||||
*
|
||||
* @param dataToSerialize The data to parse.
|
||||
* @return The parsed form.
|
||||
*/
|
||||
deserialize?(dataToDeserialize: string): any;
|
||||
extract?(xhr: XMLHttpRequest, options: MithrilXHROptions): string;
|
||||
type?(data: Object): void;
|
||||
config?(xhr: XMLHttpRequest, options: MithrilXHROptions): XMLHttpRequest;
|
||||
|
||||
/**
|
||||
* An optional function to extract the data from a raw XMLHttpRequest,
|
||||
* useful if the relevant data is in a response header or the status
|
||||
* field.
|
||||
*
|
||||
* @param xhr The associated XMLHttpRequest.
|
||||
* @param options The options passed to this request.
|
||||
* @return string The serialized format.
|
||||
*/
|
||||
extract?(xhr: XMLHttpRequest, options: MithrilXHROptions<T>): string;
|
||||
|
||||
/**
|
||||
* The parsed data, or its children if it's an array, will be passed to
|
||||
* this class constructor if it's given, to parse it into classes.
|
||||
*
|
||||
* @param data The data to parse.
|
||||
* @return The new instance for the list.
|
||||
*/
|
||||
type?: new (data: Object) => any;
|
||||
|
||||
/**
|
||||
* An optional function to run between `open` and `send`, useful for
|
||||
* adding request headers or using XHR2 features such as the `upload`
|
||||
* property. It is even possible to override the XHR altogether with a
|
||||
* similar object, such as an XDomainRequest instance.
|
||||
*
|
||||
* @param xhr The associated XMLHttpRequest.
|
||||
* @param options The options passed to this request.
|
||||
* @return The new XMLHttpRequest, or nothing if the same one is kept.
|
||||
*/
|
||||
config?(xhr: XMLHttpRequest, options: MithrilXHROptions<T>): any;
|
||||
|
||||
/**
|
||||
* For JSONP requests, this must be the string "jsonp". Otherwise, it's
|
||||
* ignored.
|
||||
*/
|
||||
dataType?: string;
|
||||
|
||||
/**
|
||||
* For JSONP requests, this is the query string key for the JSONP
|
||||
* request. This is useful for APIs that don't use common conventions,
|
||||
* such as `www.example.com/?jsonpCallback=doSomething`. It defaults to
|
||||
* `callback` for JSONP requests, and is ignored for any other kind of
|
||||
* request.
|
||||
*/
|
||||
callbackKey?: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1197,6 +1197,9 @@ var m = (function app(window, undefined) {
|
|||
var controller = function() {
|
||||
return (component.controller || noop).apply(this, args) || this
|
||||
}
|
||||
if (component.controller) {
|
||||
controller.prototype = component.controller.prototype
|
||||
}
|
||||
var view = function(ctrl) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i])
|
||||
|
|
|
|||
2
mithril.min.js
vendored
2
mithril.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -7,10 +7,10 @@ var mod = ( function initModulator(){
|
|||
var Map = shim;
|
||||
var WeakMap = shim;
|
||||
}
|
||||
|
||||
|
||||
// Garbage collection flag
|
||||
mod.cleanup = true;
|
||||
|
||||
|
||||
// Registry of instantiation contexts
|
||||
var contexts = new WeakMap();
|
||||
// All automated counts
|
||||
|
|
@ -20,36 +20,36 @@ var mod = ( function initModulator(){
|
|||
var snapRedraw = m.redraw;
|
||||
var redraw;
|
||||
var forced;
|
||||
|
||||
|
||||
for( var key in m.redraw ){
|
||||
queueRedraw[ key ] = snapRedraw[ key ] = m.redraw[ key ];
|
||||
}
|
||||
|
||||
|
||||
return function pause(){
|
||||
m.redraw = queueRedraw;
|
||||
|
||||
|
||||
setTimeout( function unpause(){
|
||||
m.redraw = snapRedraw;
|
||||
|
||||
|
||||
if( redraw ) m.redraw( forced );
|
||||
|
||||
|
||||
redraw = forced = false;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
function queueRedraw( force ){
|
||||
redraw = true;
|
||||
|
||||
|
||||
if( force ) forced = true;
|
||||
}
|
||||
}() );
|
||||
var unique = {};
|
||||
|
||||
|
||||
// Clear counts at the begninning of every redraw
|
||||
m.module( document.createElement( 'x' ), {
|
||||
view : counts.clear.bind( counts )
|
||||
} );
|
||||
|
||||
|
||||
// Shorthand for a component which will always return the same instance
|
||||
mod.unique = function( component ){
|
||||
return mod( component, unique, unique );
|
||||
|
|
@ -58,80 +58,80 @@ var mod = ( function initModulator(){
|
|||
mod.global = function( x ){
|
||||
return mod( x, unique );
|
||||
};
|
||||
|
||||
|
||||
// Extend controllers with extra utility functions
|
||||
mod.extend = true;
|
||||
|
||||
|
||||
return mod;
|
||||
|
||||
|
||||
function mod( component, context, key ){
|
||||
// Stand in for m.module, eg mod( document.body, component, context );
|
||||
if( component instanceof HTMLElement ){
|
||||
// Stand in for m.route
|
||||
if( !component.controller && !component.view ){
|
||||
var routes = {};
|
||||
|
||||
|
||||
for( var route in context ){
|
||||
routes[ route ].controller = mod.unique( {
|
||||
controller : context[ route ].controller || noop
|
||||
} ).bind();
|
||||
}
|
||||
|
||||
|
||||
return m.route( component, routes );
|
||||
}
|
||||
|
||||
|
||||
return m.module( component, mod.apply( undefined, [].slice.call( arguments, 1 ) ) )();
|
||||
}
|
||||
|
||||
|
||||
var components = register( contexts, context || unique, WeakMap );
|
||||
var keys = register( components, component, WeakMap );
|
||||
|
||||
|
||||
return function identify( key ){
|
||||
var count = key === undefined && register( counts, keys, m.prop.bind( undefined, 0 ) );
|
||||
// eg. ctrl.mod( profile ).mapWith( users(), 'username' );
|
||||
apply.mapWith = function( collection ){
|
||||
var path = [].slice.call( arguments, 1 );
|
||||
|
||||
|
||||
return Object.keys( collection ).map( function getItemIdentifier( index ){
|
||||
var key;
|
||||
|
||||
|
||||
if( path.length ){
|
||||
key = path.reduce( function getKeyValue( source, segment ){
|
||||
var node = source[ segment ];
|
||||
|
||||
|
||||
if( node instanceof Function ) node = node.call( source );
|
||||
|
||||
|
||||
return node;
|
||||
}, collection[ index ] );
|
||||
}
|
||||
else {
|
||||
key = index;
|
||||
}
|
||||
|
||||
|
||||
return identify( key )( collection[ index ] );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
return apply;
|
||||
|
||||
|
||||
function apply(){
|
||||
var args = [].slice.call( arguments );
|
||||
var view;
|
||||
|
||||
|
||||
if( count ){
|
||||
key = count( count() + 1 );
|
||||
}
|
||||
|
||||
|
||||
var ctrl = register( keys, key, function newController(){
|
||||
pauseRedraw();
|
||||
|
||||
|
||||
var controller = component.controller || noop;
|
||||
var instance = new ( controller.bind.apply( controller, [ controller ].concat( args ) ) )();
|
||||
|
||||
|
||||
if( mod.cleanup ){
|
||||
garbageCollect( instance );
|
||||
}
|
||||
|
||||
|
||||
if( mod.extend ){
|
||||
// Shorthand for instantiatin sub-modules
|
||||
instance.mod = function( component, key ){
|
||||
|
|
@ -145,14 +145,14 @@ var mod = ( function initModulator(){
|
|||
instance.refresh = function(){
|
||||
args = [].slice.call( arguments );
|
||||
ctrl = register( keys, key, newController, true );
|
||||
|
||||
|
||||
return m.redraw;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return instance;
|
||||
} );
|
||||
|
||||
|
||||
// Return the controller instance if the component is view-less.
|
||||
if( component.view ){
|
||||
if( args.length ){
|
||||
|
|
@ -161,31 +161,31 @@ var mod = ( function initModulator(){
|
|||
else {
|
||||
view = component.view( ctrl );
|
||||
}
|
||||
|
||||
|
||||
if( view instanceof Object ){
|
||||
view.ctrl = ctrl;
|
||||
}
|
||||
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
}( key );
|
||||
|
||||
|
||||
// Performance: when controllers succesfully unload, destroy their associated maps
|
||||
function garbageCollect( ctrl ){
|
||||
onunload = ctrl.onunload;
|
||||
|
||||
|
||||
if( onunload === teardown ){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ctrl.onunload = teardown;
|
||||
|
||||
|
||||
function teardown( e ){
|
||||
var go = true;
|
||||
|
||||
|
||||
if( onunload ){
|
||||
onunload( {
|
||||
preventDefault : function(){
|
||||
|
|
@ -193,39 +193,39 @@ var mod = ( function initModulator(){
|
|||
}
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
if( go ){
|
||||
contexts.delete( context );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convenience map method: retrieve key from map. If it's not registered, set it first with Constructor.
|
||||
function register( map, key, Constructor, force ){
|
||||
return !force && map.has( key ) ? map.get( key ) : map.set( key, new Constructor() ).get( key );
|
||||
}
|
||||
|
||||
|
||||
function shim(){
|
||||
var keys = [];
|
||||
var values = [];
|
||||
var map = {
|
||||
get : function( key ){
|
||||
var index = keys.indexOf( key );
|
||||
|
||||
|
||||
return values[ index ];
|
||||
},
|
||||
has : function( key ){
|
||||
var index = keys.indexOf( key );
|
||||
|
||||
|
||||
return index > -1;
|
||||
},
|
||||
set : function( key, value ){
|
||||
var index = map.has( key ) ? keys.indexOf( key ) : keys.length;
|
||||
|
||||
|
||||
keys[ index ] = key;
|
||||
values[ index ] = value;
|
||||
|
||||
|
||||
return map;
|
||||
},
|
||||
clear : function(){
|
||||
|
|
@ -234,21 +234,21 @@ var mod = ( function initModulator(){
|
|||
},
|
||||
delete : function( key ){
|
||||
var index = keys.indexOf( key );
|
||||
|
||||
|
||||
if( index > -1 ){
|
||||
keys.splice( index, 1 );
|
||||
values.splice( index, 1 );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
function noop(){}
|
||||
}() );
|
||||
</script>
|
||||
|
|
@ -271,4 +271,4 @@ b.view = function(ctrl, count) {
|
|||
return m("li", count)
|
||||
}
|
||||
|
||||
m.module(document.body, a)</script>
|
||||
m.module(document.body, a)</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue