diff --git a/extension/content_scripts/notify.js b/extension/content_scripts/notify.js index e99dabc32..4749fe9bf 100644 --- a/extension/content_scripts/notify.js +++ b/extension/content_scripts/notify.js @@ -44,6 +44,8 @@ var TalerNotify; var params = { amount: JSON.stringify(e.detail.amount), callback_url: URI(e.detail.callback_url).absoluteTo(document.location.href), + bank_url: document.location.href, + suggested_mint: e.detail.suggested_mint, }; var uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html")); document.location.href = uri.query(params).href(); diff --git a/extension/content_scripts/notify.ts b/extension/content_scripts/notify.ts index 47f57b6a0..9a64bcf0c 100644 --- a/extension/content_scripts/notify.ts +++ b/extension/content_scripts/notify.ts @@ -53,6 +53,8 @@ namespace TalerNotify { let params = { amount: JSON.stringify(e.detail.amount), callback_url: URI(e.detail.callback_url).absoluteTo(document.location.href), + bank_url: document.location.href, + suggested_mint: e.detail.suggested_mint, }; let uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html")); document.location.href = uri.query(params).href(); diff --git a/extension/lib/decl/mithril.d.ts b/extension/lib/decl/mithril.d.ts index d2646cbef..c87102260 100644 --- a/extension/lib/decl/mithril.d.ts +++ b/extension/lib/decl/mithril.d.ts @@ -1,879 +1,926 @@ -// Mithril type definitions for Typescript - -/** - * This is the module containing all the types/declarations/etc. for Mithril - */ -declare 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 - */ - (selector: string, - attributes: MithrilAttributes, - ...children: Array | - MithrilComponent>): MithrilVirtualElement; - - /** - * Initializes a component for use with m.render, m.mount, etc. - * - * @param component A component. - * @param args Arguments to optionally pass to the component. - * @return A component. - * - * @see m.render - * @see m.mount - * @see m - */ - (component: MithrilComponent, - ...args: any[]): MithrilComponent; - - /** - * 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 - */ - (selector: string, - ...children: Array | - MithrilComponent>): MithrilVirtualElement; - - /** - * 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 - */ - (component: MithrilComponent, - ...args: any[]): MithrilComponent; - - /** - * 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(promise: Thennable) : MithrilPromiseProperty; - - /** - * 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(value: T): MithrilBasicProperty; - - /** - * 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(): MithrilBasicProperty; - - /** - * 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, - callbackThis: any): (e: Event) => any; - - /** - * @deprecated Use m.mount instead - */ - module(rootElement: Node, - component: MithrilComponent): 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(rootElement: Node, - component: MithrilComponent): 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(component: MithrilComponent, - ...args: any[]): MithrilComponent; - - /** - * 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(rootElement: Element, - children: MithrilVirtualElement|MithrilVirtualElement[], - 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: { - /** - * 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: { - /** - * 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. - */ - (rootElement: Element, - defaultRoute: string, - routes: MithrilRoutes): 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}); - * ``` - */ - (element: Element, - isInitialized: boolean, - context?: MithrilContext, - vdom?: MithrilVirtualElement): 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 - } - - /** - * 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(options: MithrilXHROptions): MithrilPromise; - - deferred: { - /** - * 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 - */ - (): MithrilDeferred; - - /** - * 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; - } - - /** - * 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(promises: Thennable[]): MithrilPromise; - - /** - * 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; - - /** - * 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 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 { - /** - * 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; - - /** - * The children of this element. - */ - children?: Array|MithrilComponent>; -} - -/** - * 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 { - /** - * 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. - */ - (element: Element, - isInitialized: boolean, - context: MithrilContext, - vdom: MithrilVirtualElement): void; -} - -/** - * This represents the attributes available for configuring virtual elements, - * beyond the applicable DOM attributes. - * - * @see m - */ -interface MithrilAttributes { - /** - * 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; - - /** - * Any other virtual element properties including attributes and - * event handlers - */ - [property: string]: any; -} - -/** - * The basis of a Mithril controller instance. - */ -interface MithrilController { - /** - * An optional handler to call when the associated virtual element is - * destroyed. - * - * @param evt An associated event. - */ - onunload?(evt: MithrilEvent): any; -} - -/** - * This represents a controller function. - * - * @see MithrilControllerConstructor - */ -interface MithrilControllerFunction { - (): T; -} - -/** - * This represents a controller constructor. - * - * @see MithrilControllerFunction - */ -interface MithrilControllerConstructor { - new(): T; -} - -/** - * This represents a view factory. - */ -interface MithrilView { - /** - * Creates a view out of virtual elements. - */ - (ctrl: T): MithrilVirtualElement; -} - -/** - * This represents a Mithril component. - * - * @see m - * @see m.component - */ -interface MithrilComponent { - /** - * The component's controller. - * - * @see m.component - */ - controller?: MithrilControllerFunction | - MithrilControllerConstructor; - - /** - * Creates a view out of virtual elements. - * - * @see m.component - */ - view(ctrl: T): MithrilVirtualElement; -} - -/** - * This is the base interface for property getter-setters - * - * @see m.prop - */ -interface MithrilProperty { - /** - * 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 extends MithrilProperty { - /** - * Makes this serializable to JSON. - */ - toJSON(): T; -} - -/** - * This represents a promise getter-setter function. - * - * @see m.prop which returns objects that implement this interface. - */ -interface MithrilPromiseProperty extends MithrilPromise, - MithrilProperty> { - /** - * Gets the contained promise. - * - * @return The contained value. - */ - (): MithrilPromise; - - /** - * Sets the contained promise. - * - * @param value The new value to set. - * @return The newly set value. - */ - (value: MithrilPromise): MithrilPromise; - - /** - * Sets the contained wrapped value. - * - * @param value The new value to set. - * @return The newly set value. - */ - (value: T): MithrilPromise; -} - -/** - * This represents a key-value mapping linking routes to components. - */ -interface MithrilRoutes { - /** - * The key represents the route. The value represents the corresponding - * component. - */ - [key: string]: MithrilComponent; -} - -/** - * This represents a Mithril deferred object. - */ -interface MithrilDeferred { - /** - * Resolve this deferred's promise with a value. - * - * @param value The value to resolve the promise with. - */ - resolve(value?: T): 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; -} - -/** - * This represents a thennable success callback. - */ -interface MithrilSuccessCallback { - (value: T): U | Thennable; -} - -/** - * This represents a thennable error callback. - */ -interface MithrilErrorCallback { - (value: Error): T | Thennable; -} - -/** - * This represents a thennable. - */ -interface Thennable { - then(success: (value: T) => U): Thennable; - then(success: (value: T) => U, - error: (value: Error) => V): Thennable|Thennable; - catch?: (error: (value: Error) => U) => Thennable; -} - -/** - * This represents a Mithril promise object. - */ -interface MithrilPromise extends Thennable, MithrilProperty> { - /** - * 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(success: MithrilSuccessCallback): MithrilPromise; - - /** - * 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(success: MithrilSuccessCallback, - error: MithrilErrorCallback): MithrilPromise | MithrilPromise; - - /** - * 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(error: MithrilErrorCallback): MithrilPromise | - MithrilPromise; -} - -/** - * This represents the available options for configuring m.request. - * - * @see m.request - */ -interface MithrilXHROptions { - /** - * 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; - - /** - * 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; - - /** - * 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): 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): 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; -} +// 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 + */ + ( + selector: string, + attributes: MithrilAttributes, + ...children: Array | + MithrilComponent> + ): MithrilVirtualElement; + + /** + * Initializes a component for use with m.render, m.mount, etc. + * + * @param component A component. + * @param args Arguments to optionally pass to the component. + * @return A component. + * + * @see m.render + * @see m.mount + * @see m + */ + ( + component: MithrilComponent, + ...args: any[] + ): MithrilComponent; + + /** + * 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 + */ + ( + selector: string, + ...children: Array | + MithrilComponent> + ): MithrilVirtualElement; + + /** + * 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 + */ + ( + component: MithrilComponent, + ...args: any[] + ): MithrilComponent; + + /** + * 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(promise: Thennable) : MithrilPromiseProperty; + + /** + * 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(value: T): MithrilBasicProperty; + + /** + * 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(): MithrilBasicProperty; + + /** + * 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, + callbackThis: any + ): (e: Event) => any; + + /** + * Returns a event handler that can be bound to an element, firing with + * the specified property. + * + * @param attributeName Name of the element's attribute to bind to. + * @param property The property to bind. + * @return A function suitable for listening to an event. + */ + withAttr( + attributeName: string, + property: MithrilBasicProperty + ) : (e: Event) => any; + + /** + * @deprecated Use m.mount instead + */ + module( + rootElement: Node, + component: MithrilComponent + ): 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( + rootElement: Node, + component: MithrilComponent + ): 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( + component: MithrilComponent, + ...args: any[] + ): MithrilComponent; + + /** + * 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( + rootElement: Element, + children: MithrilVirtualElement|MithrilVirtualElement[], + 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: { + /** + * 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: { + /** + * 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. + */ + ( + rootElement: Element, + defaultRoute: string, + routes: MithrilRoutes + ): 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}); + * ``` + */ + ( + element: Element, + isInitialized: boolean, + context?: MithrilContext, + vdom?: MithrilVirtualElement + ): 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 + } + + /** + * 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(options: MithrilXHROptions): MithrilPromise; + + deferred: { + /** + * 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 + */ + (): MithrilDeferred; + + /** + * 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; + } + + /** + * 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(promises: Thennable[]): MithrilPromise; + + /** + * 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; + + /** + * 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 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 { + /** + * 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; + + /** + * The children of this element. + */ + children?: Array|MithrilComponent>; + } + + /** + * 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 { + /** + * 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. + */ + ( + element: Element, + isInitialized: boolean, + context: MithrilContext, + vdom: MithrilVirtualElement + ): void; + } + + /** + * This represents the attributes available for configuring virtual elements, + * beyond the applicable DOM attributes. + * + * @see m + */ + interface MithrilAttributes { + /** + * 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; + + /** + * Any other virtual element properties including attributes and + * event handlers + */ + [property: string]: any; + } + + /** + * The basis of a Mithril controller instance. + */ + interface MithrilController { + /** + * An optional handler to call when the associated virtual element is + * destroyed. + * + * @param evt An associated event. + */ + onunload?(evt: MithrilEvent): any; + } + + /** + * This represents a controller function. + * + * @see MithrilControllerConstructor + */ + interface MithrilControllerFunction { + (opts?: any): T; + } + + /** + * This represents a controller constructor. + * + * @see MithrilControllerFunction + */ + interface MithrilControllerConstructor { + new(): T; + } + + /** + * This represents a view factory. + */ + interface MithrilView { + /** + * Creates a view out of virtual elements. + */ + (ctrl: T): MithrilVirtualElement; + } + + /** + * This represents a Mithril component. + * + * @see m + * @see m.component + */ + interface MithrilComponent { + /** + * The component's controller. + * + * @see m.component + */ + controller: MithrilControllerFunction | + MithrilControllerConstructor; + + /** + * Creates a view out of virtual elements. + * + * @see m.component + */ + view(ctrl?: T, opts?: any): MithrilVirtualElement; + } + + /** + * This is the base interface for property getter-setters + * + * @see m.prop + */ + interface MithrilProperty { + /** + * 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 extends MithrilProperty { + /** + * Makes this serializable to JSON. + */ + toJSON(): T; + } + + /** + * This represents a promise getter-setter function. + * + * @see m.prop which returns objects that implement this interface. + */ + interface MithrilPromiseProperty extends MithrilPromise, + MithrilProperty> { + /** + * Gets the contained promise. + * + * @return The contained value. + */ + (): MithrilPromise; + + /** + * Sets the contained promise. + * + * @param value The new value to set. + * @return The newly set value. + */ + (value: MithrilPromise): MithrilPromise; + + /** + * Sets the contained wrapped value. + * + * @param value The new value to set. + * @return The newly set value. + */ + (value: T): MithrilPromise; + } + + /** + * This represents a key-value mapping linking routes to components. + */ + interface MithrilRoutes { + /** + * The key represents the route. The value represents the corresponding + * component. + */ + [key: string]: MithrilComponent; + } + + /** + * This represents a Mithril deferred object. + */ + interface MithrilDeferred { + /** + * Resolve this deferred's promise with a value. + * + * @param value The value to resolve the promise with. + */ + resolve(value?: T): 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; + } + + /** + * This represents a thennable success callback. + */ + interface MithrilSuccessCallback { + (value: T): U | Thennable; + } + + /** + * This represents a thennable error callback. + */ + interface MithrilErrorCallback { + (value: Error): T | Thennable; + } + + /** + * This represents a thennable. + */ + interface Thennable { + then(success: (value: T) => U): Thennable; + then(success: (value: T) => U, error: (value: Error) => V): Thennable|Thennable; + catch?: (error: (value: Error) => U) => Thennable; + } + + /** + * This represents a Mithril promise object. + */ + interface MithrilPromise extends Thennable, MithrilProperty> { + /** + * 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(success: MithrilSuccessCallback): MithrilPromise; + + /** + * 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( + success: MithrilSuccessCallback, + error: MithrilErrorCallback + ): MithrilPromise | MithrilPromise; + + /** + * 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(error: MithrilErrorCallback): MithrilPromise | + MithrilPromise; + } + + /** + * This represents the available options for configuring m.request. + * + * @see m.request + */ + interface MithrilXHROptions { + /** + * 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; + + /** + * 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; + + /** + * 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): 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): 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; + } +} + +declare var Mithril: _mithril.MithrilStatic; +declare var m: _mithril.MithrilStatic; + +declare module "mithril" { + export = m; +} diff --git a/extension/lib/module-trampoline.js b/extension/lib/module-trampoline.js index 4cdc9aab3..22173aa42 100644 --- a/extension/lib/module-trampoline.js +++ b/extension/lib/module-trampoline.js @@ -30,6 +30,16 @@ System.config({ defaultJSExtensions: true, }); + +// Register mithril as a module, +// but only if it is ambient. +if (m) { + let mod = System.newModule({default: m}); + let modName = "mithril"; + System.set(modName, mod); +} + + let me = window.location.protocol + "//" + window.location.host + window.location.pathname.replace(/[.]html$/, ".js"); diff --git a/extension/lib/vendor/mithril.js b/extension/lib/vendor/mithril.js index 89652690a..d023ac34c 100644 --- a/extension/lib/vendor/mithril.js +++ b/extension/lib/vendor/mithril.js @@ -1,1406 +1,2132 @@ -var m = (function app(window, undefined) { - "use strict"; - var VERSION = "v0.2.2-rc.1"; - function isFunction(object) { - return typeof object === "function"; - } - function isObject(object) { - return type.call(object) === "[object Object]"; - } - function isString(object) { - return type.call(object) === "[object String]"; - } - var isArray = Array.isArray || function (object) { - return type.call(object) === "[object Array]"; - }; - var type = {}.toString; - var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/; - var voidElements = /^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/; - var noop = function () {}; - - // caching commonly used variables - var $document, $location, $requestAnimationFrame, $cancelAnimationFrame; - - // self invoking function needed because of the way mocks work - function initialize(window) { - $document = window.document; - $location = window.location; - $cancelAnimationFrame = window.cancelAnimationFrame || window.clearTimeout; - $requestAnimationFrame = window.requestAnimationFrame || window.setTimeout; - } - - initialize(window); - - m.version = function() { - return VERSION; - }; - - /** - * @typedef {String} Tag - * A string that looks like -> div.classname#id[param=one][param2=two] - * Which describes a DOM node - */ - - /** - * - * @param {Tag} The DOM node tag - * @param {Object=[]} optional key-value pairs to be mapped to DOM attrs - * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, or splat (optional) - * - */ - function m(tag, pairs) { - for (var args = [], i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - if (isObject(tag)) return parameterize(tag, args); - var hasAttrs = pairs != null && isObject(pairs) && !("tag" in pairs || "view" in pairs || "subtree" in pairs); - var attrs = hasAttrs ? pairs : {}; - var classAttrName = "class" in attrs ? "class" : "className"; - var cell = {tag: "div", attrs: {}}; - var match, classes = []; - if (!isString(tag)) throw new Error("selector in m(selector, attrs, children) should be a string"); - while ((match = parser.exec(tag)) != null) { - if (match[1] === "" && match[2]) cell.tag = match[2]; - else if (match[1] === "#") cell.attrs.id = match[2]; - else if (match[1] === ".") classes.push(match[2]); - else if (match[3][0] === "[") { - var pair = attrParser.exec(match[3]); - cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true); - } - } - - var children = hasAttrs ? args.slice(1) : args; - if (children.length === 1 && isArray(children[0])) { - cell.children = children[0]; - } - else { - cell.children = children; - } - - for (var attrName in attrs) { - if (attrs.hasOwnProperty(attrName)) { - if (attrName === classAttrName && attrs[attrName] != null && attrs[attrName] !== "") { - classes.push(attrs[attrName]); - cell.attrs[attrName] = ""; //create key in correct iteration order - } - else cell.attrs[attrName] = attrs[attrName]; - } - } - if (classes.length) cell.attrs[classAttrName] = classes.join(" "); - - return cell; - } - function forEach(list, f) { - for (var i = 0; i < list.length && !f(list[i], i++);) {} - } - function forKeys(list, f) { - forEach(list, function (attrs, i) { - return (attrs = attrs && attrs.attrs) && attrs.key != null && f(attrs, i); - }); - } - // This function was causing deopts in Chrome. - function dataToString(data) { - //data.toString() might throw or return null if data is the return value of Console.log in Firefox (behavior depends on version) - try { - if (data == null || data.toString() == null) return ""; - } catch (e) { - return ""; - } - return data; - } - // This function was causing deopts in Chrome. - function injectTextNode(parentElement, first, index, data) { - try { - insertNode(parentElement, first, index); - first.nodeValue = data; - } catch (e) {} //IE erroneously throws error when appending an empty text node after a null - } - - function flatten(list) { - //recursively flatten array - for (var i = 0; i < list.length; i++) { - if (isArray(list[i])) { - list = list.concat.apply([], list); - //check current index again and flatten until there are no more nested arrays at that index - i--; - } - } - return list; - } - - function insertNode(parentElement, node, index) { - parentElement.insertBefore(node, parentElement.childNodes[index] || null); - } - - var DELETION = 1, INSERTION = 2, MOVE = 3; - - function handleKeysDiffer(data, existing, cached, parentElement) { - forKeys(data, function (key, i) { - existing[key = key.key] = existing[key] ? { - action: MOVE, - index: i, - from: existing[key].index, - element: cached.nodes[existing[key].index] || $document.createElement("div") - } : {action: INSERTION, index: i}; - }); - var actions = []; - for (var prop in existing) actions.push(existing[prop]); - var changes = actions.sort(sortChanges), newCached = new Array(cached.length); - newCached.nodes = cached.nodes.slice(); - - forEach(changes, function (change) { - var index = change.index; - if (change.action === DELETION) { - clear(cached[index].nodes, cached[index]); - newCached.splice(index, 1); - } - if (change.action === INSERTION) { - var dummy = $document.createElement("div"); - dummy.key = data[index].attrs.key; - insertNode(parentElement, dummy, index); - newCached.splice(index, 0, { - attrs: {key: data[index].attrs.key}, - nodes: [dummy] - }); - newCached.nodes[index] = dummy; - } - - if (change.action === MOVE) { - var changeElement = change.element; - var maybeChanged = parentElement.childNodes[index]; - if (maybeChanged !== changeElement && changeElement !== null) { - parentElement.insertBefore(changeElement, maybeChanged || null); - } - newCached[index] = cached[change.from]; - newCached.nodes[index] = changeElement; - } - }); - - return newCached; - } - - function diffKeys(data, cached, existing, parentElement) { - var keysDiffer = data.length !== cached.length; - if (!keysDiffer) { - forKeys(data, function (attrs, i) { - var cachedCell = cached[i]; - return keysDiffer = cachedCell && cachedCell.attrs && cachedCell.attrs.key !== attrs.key; - }); - } - - return keysDiffer ? handleKeysDiffer(data, existing, cached, parentElement) : cached; - } - - function diffArray(data, cached, nodes) { - //diff the array itself - - //update the list of DOM nodes by collecting the nodes from each item - forEach(data, function (_, i) { - if (cached[i] != null) nodes.push.apply(nodes, cached[i].nodes); - }) - //remove items from the end of the array if the new array is shorter than the old one. if errors ever happen here, the issue is most likely - //a bug in the construction of the `cached` data structure somewhere earlier in the program - forEach(cached.nodes, function (node, i) { - if (node.parentNode != null && nodes.indexOf(node) < 0) clear([node], [cached[i]]); - }) - if (data.length < cached.length) cached.length = data.length; - cached.nodes = nodes; - } - - function buildArrayKeys(data) { - var guid = 0; - forKeys(data, function () { - forEach(data, function (attrs) { - if ((attrs = attrs && attrs.attrs) && attrs.key == null) attrs.key = "__mithril__" + guid++; - }) - return 1; - }); - } - - function maybeRecreateObject(data, cached, dataAttrKeys) { - //if an element is different enough from the one in cache, recreate it - if (data.tag !== cached.tag || - dataAttrKeys.sort().join() !== Object.keys(cached.attrs).sort().join() || - data.attrs.id !== cached.attrs.id || - data.attrs.key !== cached.attrs.key || - (m.redraw.strategy() === "all" && (!cached.configContext || cached.configContext.retain !== true)) || - (m.redraw.strategy() === "diff" && cached.configContext && cached.configContext.retain === false)) { - if (cached.nodes.length) clear(cached.nodes); - if (cached.configContext && isFunction(cached.configContext.onunload)) cached.configContext.onunload(); - if (cached.controllers) { - forEach(cached.controllers, function (controller) { - if (controller.unload) controller.onunload({preventDefault: noop}); - }); - } - } - } - - function getObjectNamespace(data, namespace) { - return data.attrs.xmlns ? data.attrs.xmlns : - data.tag === "svg" ? "http://www.w3.org/2000/svg" : - data.tag === "math" ? "http://www.w3.org/1998/Math/MathML" : - namespace; - } - - function unloadCachedControllers(cached, views, controllers) { - if (controllers.length) { - cached.views = views; - cached.controllers = controllers; - forEach(controllers, function (controller) { - if (controller.onunload && controller.onunload.$old) controller.onunload = controller.onunload.$old; - if (pendingRequests && controller.onunload) { - var onunload = controller.onunload; - controller.onunload = noop; - controller.onunload.$old = onunload; - } - }); - } - } - - function scheduleConfigsToBeCalled(configs, data, node, isNew, cached) { - //schedule configs to be called. They are called after `build` - //finishes running - if (isFunction(data.attrs.config)) { - var context = cached.configContext = cached.configContext || {}; - - //bind - configs.push(function() { - return data.attrs.config.call(data, node, !isNew, context, cached); - }); - } - } - - function buildUpdatedNode(cached, data, editable, hasKeys, namespace, views, configs, controllers) { - var node = cached.nodes[0]; - if (hasKeys) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace); - cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs); - cached.nodes.intact = true; - - if (controllers.length) { - cached.views = views; - cached.controllers = controllers; - } - - return node; - } - - function handleNonexistentNodes(data, parentElement, index) { - var nodes; - if (data.$trusted) { - nodes = injectHTML(parentElement, index, data); - } - else { - nodes = [$document.createTextNode(data)]; - if (!parentElement.nodeName.match(voidElements)) insertNode(parentElement, nodes[0], index); - } - - var cached = typeof data === "string" || typeof data === "number" || typeof data === "boolean" ? new data.constructor(data) : data; - cached.nodes = nodes; - return cached; - } - - function reattachNodes(data, cached, parentElement, editable, index, parentTag) { - var nodes = cached.nodes; - if (!editable || editable !== $document.activeElement) { - if (data.$trusted) { - clear(nodes, cached) - nodes = injectHTML(parentElement, index, data) - } else if (parentTag === "textarea") { - //